Skip to content

Commit

Permalink
Contextual insights
Browse files Browse the repository at this point in the history
  • Loading branch information
dgieselaar committed Jul 23, 2023
1 parent 3a2e069 commit b9cb795
Show file tree
Hide file tree
Showing 43 changed files with 1,290 additions and 388 deletions.
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,6 @@
"@opentelemetry/sdk-metrics-base": "^0.31.0",
"@opentelemetry/semantic-conventions": "^1.4.0",
"@reduxjs/toolkit": "1.7.2",
"@sindresorhus/fnv1a": "^3.0.0",
"@slack/webhook": "^5.0.4",
"@tanstack/react-query": "^4.29.12",
"@tanstack/react-query-devtools": "^4.29.12",
Expand Down Expand Up @@ -840,6 +839,7 @@
"fast-deep-equal": "^3.1.1",
"fflate": "^0.6.9",
"file-saver": "^1.3.8",
"fnv-plus": "^1.3.1",
"font-awesome": "4.7.0",
"formik": "^2.2.9",
"fp-ts": "^2.3.1",
Expand Down Expand Up @@ -1437,7 +1437,6 @@
"faker": "^5.1.0",
"fetch-mock": "^7.3.9",
"file-loader": "^4.2.0",
"fnv-plus": "^1.3.1",
"form-data": "^4.0.0",
"geckodriver": "^4.0.0",
"gulp-brotli": "^3.0.0",
Expand Down Expand Up @@ -1551,4 +1550,4 @@
"xmlbuilder": "13.0.2",
"yargs": "^15.4.1"
}
}
}
8 changes: 5 additions & 3 deletions x-pack/plugins/apm/kibana.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"dataViews",
"lens",
"maps",
"uiActions"
"uiActions",
"observabilityAIAssistant"
],
"optionalPlugins": [
"actions",
Expand All @@ -47,7 +48,7 @@
"usageCollection",
"customIntegrations", // Move this to requiredPlugins after completely migrating from the Tutorials Home App
"licenseManagement",
"profiling"
"profiling",
],
"requiredBundles": [
"advancedSettings",
Expand All @@ -57,7 +58,8 @@
"ml",
"observability",
"esUiShared",
"maps"
"maps",
"observabilityAIAssistant"
]
}
}
1 change: 1 addition & 0 deletions x-pack/plugins/apm/public/application/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const renderApp = ({
unifiedSearch: pluginsStart.unifiedSearch,
lens: pluginsStart.lens,
uiActions: pluginsStart.uiActions,
observabilityAIAssistant: pluginsStart.observabilityAIAssistant,
};

// render APM feedback link in global help menu
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,91 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React, { useMemo, useState } from 'react';
import { useCoPilot, CoPilotPrompt } from '@kbn/observability-plugin/public';
import { EuiFlexItem, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { CoPilotPromptId } from '@kbn/observability-plugin/common';
import {
useObservabilityAIAssistant,
ContextualInsight,
type Message,
MessageRole,
} from '@kbn/observability-ai-assistant-plugin/public';
import React, { useMemo, useState } from 'react';
import { APMError } from '../../../../../typings/es_schemas/ui/apm_error';
import { Transaction } from '../../../../../typings/es_schemas/ui/transaction';
import { exceptionStacktraceTab, logStacktraceTab } from './error_tabs';
import { ErrorSampleDetailTabContent } from './error_sample_detail';
import { exceptionStacktraceTab, logStacktraceTab } from './error_tabs';

export function ErrorSampleCoPilotPrompt({
export function ErrorSampleContextualInsight({
error,
transaction,
}: {
error: APMError;
transaction?: Transaction;
}) {
const coPilot = useCoPilot();
const aiAssistant = useObservabilityAIAssistant();

const [logStacktrace, setLogStacktrace] = useState('');
const [exceptionStacktrace, setExceptionStacktrace] = useState('');

const promptParams = useMemo(() => {
return {
serviceName: error.service.name,
languageName: error.service.language?.name ?? '',
runtimeName: error.service.runtime?.name ?? '',
runtimeVersion: error.service.runtime?.version ?? '',
transactionName: transaction?.transaction.name ?? '',
logStacktrace,
exceptionStacktrace,
};
const messages = useMemo<Message[]>(() => {
const now = new Date().toISOString();

const serviceName = error.service.name;
const languageName = error.service.language?.name ?? '';
const runtimeName = error.service.runtime?.name ?? '';
const runtimeVersion = error.service.runtime?.version ?? '';
const transactionName = transaction?.transaction.name ?? '';

return [
{
'@timestamp': now,
message: {
role: MessageRole.System,
content: `You are apm-gpt, a helpful assistant for performance analysis, optimisation and
root cause analysis of software. Answer as concisely as possible.`,
},
},
{
'@timestamp': now,
message: {
role: MessageRole.User,
content: `I'm an SRE. I am looking at an exception and trying to understand what it means.
Your task is to describe what the error means and what it could be caused by.
The error occurred on a service called ${serviceName}, which is a ${runtimeName} service written in ${languageName}. The
runtime version is ${runtimeVersion}.
The request it occurred for is called ${transactionName}.
${
logStacktrace
? `The log stacktrace:
${logStacktrace}`
: ''
}
${
exceptionStacktrace
? `The exception stacktrace:
${exceptionStacktrace}`
: ''
}
`,
},
},
];
}, [error, transaction, logStacktrace, exceptionStacktrace]);

return coPilot?.isEnabled() && promptParams ? (
return aiAssistant.isEnabled() && messages ? (
<>
<EuiFlexItem>
<CoPilotPrompt
coPilot={coPilot}
<ContextualInsight
messages={messages}
title={i18n.translate(
'xpack.apm.errorGroupCoPilotPrompt.explainErrorTitle',
{ defaultMessage: "What's this error?" }
)}
promptId={CoPilotPromptId.ApmExplainError}
params={promptParams}
feedbackEnabled={false}
/>
</EuiFlexItem>
<EuiSpacer size="s" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ import { UserAgentSummaryItem } from '../../../shared/summary/user_agent_summary
import { TimestampTooltip } from '../../../shared/timestamp_tooltip';
import { PlaintextStacktrace } from './plaintext_stacktrace';
import { TransactionTab } from '../../transaction_details/waterfall_with_summary/transaction_tabs';
import { ErrorSampleCoPilotPrompt } from './error_sample_co_pilot_prompt';
import { ErrorTab, ErrorTabKey, getTabs } from './error_tabs';
import { ErrorUiActionsContextMenu } from './error_ui_actions_context_menu';
import { ExceptionStacktrace } from './exception_stacktrace';
import { SampleSummary } from './sample_summary';
import { ErrorSampleContextualInsight } from './error_sample_contextual_insight';

const TransactionLinkName = euiStyled.div`
margin-left: ${({ theme }) => theme.eui.euiSizeS};
Expand Down Expand Up @@ -337,7 +337,7 @@ export function ErrorSampleDetails({
<SampleSummary error={error} />
)}

<ErrorSampleCoPilotPrompt error={error} transaction={transaction} />
<ErrorSampleContextualInsight error={error} transaction={transaction} />

<EuiTabs>
{tabs.map(({ key, label }) => {
Expand Down
37 changes: 19 additions & 18 deletions x-pack/plugins/apm/public/components/routing/app_root/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ import {
useUiSetting$,
} from '@kbn/kibana-react-plugin/public';
import { Storage } from '@kbn/kibana-utils-plugin/public';
import { InspectorContextProvider } from '@kbn/observability-shared-plugin/public';
import { HeaderMenuPortal } from '@kbn/observability-shared-plugin/public';
import { ObservabilityAIAssistantProvider } from '@kbn/observability-ai-assistant-plugin/public';
import {
HeaderMenuPortal,
InspectorContextProvider,
} from '@kbn/observability-shared-plugin/public';
import { Route } from '@kbn/shared-ux-router';
import { RouteRenderer, RouterProvider } from '@kbn/typed-react-router-config';
import { euiDarkVars, euiLightVars } from '@kbn/ui-theme';
import React from 'react';
import { Route } from '@kbn/shared-ux-router';
import { DefaultTheme, ThemeProvider } from 'styled-components';
import { CoPilotContextProvider } from '@kbn/observability-plugin/public';
import { AnomalyDetectionJobsContextProvider } from '../../../context/anomaly_detection_jobs/anomaly_detection_jobs_context';
import {
ApmPluginContext,
Expand All @@ -31,15 +33,15 @@ import { LicenseProvider } from '../../../context/license/license_context';
import { TimeRangeIdContextProvider } from '../../../context/time_range_id/time_range_id_context';
import { UrlParamsProvider } from '../../../context/url_params_context/url_params_context';
import { ApmPluginStartDeps } from '../../../plugin';
import { ScrollToTopOnPathChange } from './scroll_to_top_on_path_change';
import { ApmErrorBoundary } from '../apm_error_boundary';
import { apmRouter } from '../apm_route_config';
import { TrackPageview } from '../track_pageview';
import { ApmHeaderActionMenu } from './apm_header_action_menu';
import { RedirectDependenciesToDependenciesInventory } from './redirect_dependencies_to_dependencies_inventory';
import { RedirectWithDefaultDateRange } from './redirect_with_default_date_range';
import { RedirectWithDefaultEnvironment } from './redirect_with_default_environment';
import { RedirectWithOffset } from './redirect_with_offset';
import { ApmErrorBoundary } from '../apm_error_boundary';
import { apmRouter } from '../apm_route_config';
import { RedirectDependenciesToDependenciesInventory } from './redirect_dependencies_to_dependencies_inventory';
import { TrackPageview } from '../track_pageview';
import { ScrollToTopOnPathChange } from './scroll_to_top_on_path_change';
import { UpdateExecutionContextOnRouteChange } from './update_execution_context_on_route_change';

const storage = new Storage(localStorage);
Expand All @@ -55,9 +57,6 @@ export function ApmAppRoot({
const { history } = appMountParameters;
const i18nCore = core.i18n;

const coPilotService =
apmPluginContextValue.plugins.observability.getCoPilotService();

return (
<RedirectAppLinks
application={core.application}
Expand All @@ -68,9 +67,11 @@ export function ApmAppRoot({
<ApmPluginContext.Provider value={apmPluginContextValue}>
<KibanaContextProvider services={{ ...core, ...pluginsStart, storage }}>
<i18nCore.Context>
<TimeRangeIdContextProvider>
<RouterProvider history={history} router={apmRouter as any}>
<CoPilotContextProvider value={coPilotService}>
<ObservabilityAIAssistantProvider
value={apmPluginContextValue.observabilityAIAssistant}
>
<TimeRangeIdContextProvider>
<RouterProvider history={history} router={apmRouter as any}>
<ApmErrorBoundary>
<RedirectDependenciesToDependenciesInventory>
<RedirectWithDefaultEnvironment>
Expand Down Expand Up @@ -105,9 +106,9 @@ export function ApmAppRoot({
</RedirectWithDefaultEnvironment>
</RedirectDependenciesToDependenciesInventory>
</ApmErrorBoundary>
</CoPilotContextProvider>
</RouterProvider>
</TimeRangeIdContextProvider>
</RouterProvider>
</TimeRangeIdContextProvider>
</ObservabilityAIAssistantProvider>
</i18nCore.Context>
</KibanaContextProvider>
</ApmPluginContext.Provider>
Expand Down
22 changes: 12 additions & 10 deletions x-pack/plugins/apm/public/context/apm_plugin/apm_plugin_context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@
* 2.0.
*/

import { AppMountParameters, CoreStart } from '@kbn/core/public';
import type { AppMountParameters, CoreStart } from '@kbn/core/public';
import { createContext } from 'react';
import type { ObservabilityRuleTypeRegistry } from '@kbn/observability-plugin/public';
import { MapsStartApi } from '@kbn/maps-plugin/public';
import { ObservabilityPublicStart } from '@kbn/observability-plugin/public';
import { Start as InspectorPluginStart } from '@kbn/inspector-plugin/public';
import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
import { DataPublicPluginStart } from '@kbn/data-plugin/public';
import { UiActionsStart } from '@kbn/ui-actions-plugin/public';
import type { MapsStartApi } from '@kbn/maps-plugin/public';
import type { ObservabilityPublicStart } from '@kbn/observability-plugin/public';
import type { Start as InspectorPluginStart } from '@kbn/inspector-plugin/public';
import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
import type { UiActionsStart } from '@kbn/ui-actions-plugin/public';
import type { InfraClientStartExports } from '@kbn/infra-plugin/public';
import { ApmPluginSetupDeps } from '../../plugin';
import { ConfigSchema } from '../..';
import type { ObservabilityAIAssistantPluginStart } from '@kbn/observability-ai-assistant-plugin/public';
import type { ApmPluginSetupDeps } from '../../plugin';
import type { ConfigSchema } from '../..';

export interface ApmPluginContextValue {
appMountParameters: AppMountParameters;
Expand All @@ -32,6 +33,7 @@ export interface ApmPluginContextValue {
data: DataPublicPluginStart;
unifiedSearch: UnifiedSearchPublicPluginStart;
uiActions: UiActionsStart;
observabilityAIAssistant: ObservabilityAIAssistantPluginStart;
}

export const ApmPluginContext = createContext({} as ApmPluginContextValue);
2 changes: 2 additions & 0 deletions x-pack/plugins/apm/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import {
DiscoverStart,
DiscoverSetup,
} from '@kbn/discover-plugin/public/plugin';
import type { ObservabilityAIAssistantPluginStart } from '@kbn/observability-ai-assistant-plugin/public';
import { registerApmRuleTypes } from './components/alerting/rule_types/register_apm_rule_types';
import {
getApmEnrollmentFlyoutData,
Expand Down Expand Up @@ -130,6 +131,7 @@ export interface ApmPluginStartDeps {
lens: LensPublicStart;
uiActions: UiActionsStart;
profiling?: ProfilingPluginStart;
observabilityAIAssistant: ObservabilityAIAssistantPluginStart;
}

const servicesTitle = i18n.translate('xpack.apm.navigation.servicesTitle', {
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/apm/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@
"@kbn/profiling-plugin",
"@kbn/logs-shared-plugin",
"@kbn/unified-field-list",
"@kbn/discover-plugin"
"@kbn/discover-plugin",
"@kbn/observability-ai-assistant-plugin"
],
"exclude": ["target/**/*"]
}
9 changes: 9 additions & 0 deletions x-pack/plugins/observability_ai_assistant/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

export type { Message, Conversation } from './types';
export { MessageRole } from './types';
6 changes: 5 additions & 1 deletion x-pack/plugins/observability_ai_assistant/kibana.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
],
"requiredPlugins": [
"triggersActionsUi",
"actions"
"actions",
"security"
],
"requiredBundles": [
"kibanaReact"
],
"optionalPlugins": [],
"extraPublicDirs": []
Expand Down
Loading

0 comments on commit b9cb795

Please sign in to comment.