Skip to content

Commit

Permalink
[Log Explorer] Add Explorer app locator (elastic#165962)
Browse files Browse the repository at this point in the history
closes elastic#164995
closes elastic#165618
closes elastic#166596

## 📝  Summary

### Observability Log Explorer Locators:

This PR adds 2 new customized locators to the Observability log explorer
profile. At the moment we implemented:

       1- Single dataset selector locator
       2- All dataset selector locator

With more locators to come in the future depending on the use cases.

### Log Explorer Locators:

We also added a log explorer locator that navigates to discover, this
can be used in case the **Observability Log Explorer** plugin is
disabled.

### Logs Onboarding:

The PR also replaces the temp navigation to the default discover we
implemented for[ 8.10
here](elastic#163218) with the above new
Observability Log Explorer locators.

### APM:

After [disabling infra plugin in serverless
projects](elastic#165289), APM links to
infra locators in serverless have been replaced to use the above
locators.

### Observability Landing Page:

The landing page now redirects to the Log Explorer if `logs-*-*` has
data in it, otherwise the flow continues as before.

### Necessary Refactoring:

To avoid the circular dependency between `ObservabilityLogExplorer` &
`ObservabilityOnboarding` after each one using the other's locator and
importing the necessary types, I moved the type definition for all
locators in the `deeplinks` package.

## ✅  Testing

- Onboarding Wizard in Serverless and Stateful

    1. Navigate to the onboarding flow `/app/observabilityOnboarding/`
    2. Choose either System logs or Stream log files
    3. Go through the onboarding wizard
    4. Click the Explore logs button at the end
5. You should be redirected to observability log explorer with the
integration and dataset preselected.

- APM links in Serverless

1. Navigate to APM and click on the logs links as shown in the Demos
below
2. All links should navigate to Observability Log Explorer with the
queries set in the search bar.

## 🎥 Demos

- APM Serverless


https://github.com/elastic/kibana/assets/11225826/7161364e-333f-4ac4-87d5-7f1ffec699b3


- APM Stateful


https://github.com/elastic/kibana/assets/11225826/058c9587-b766-4d4f-a73d-50fd381be4bb


- Onboarding Serverless



https://github.com/elastic/kibana/assets/11225826/ee1cab42-f91c-4558-aa5f-4fa7e8963427

- Onboarding Stateful



https://github.com/elastic/kibana/assets/11225826/a376a12b-499b-4488-a75a-d06e81f8e21d

- Observability Landing Page 



https://github.com/elastic/kibana/assets/11225826/c1c084ca-b1b1-4c4b-a4e6-ae8e157dcf57

---------

Co-authored-by: kibanamachine <[email protected]>
Co-authored-by: Marco Antonio Ghiani <[email protected]>
Co-authored-by: Marco Antonio Ghiani <[email protected]>
  • Loading branch information
4 people authored and gergoabraham committed Sep 21, 2023
1 parent a7321ac commit 9c41ae4
Show file tree
Hide file tree
Showing 79 changed files with 1,549 additions and 411 deletions.
2 changes: 2 additions & 0 deletions packages/deeplinks/observability/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@
export { OBSERVABILITY_ONBOARDING_APP_ID } from './constants';

export type { AppId, DeepLinkId } from './deep_links';

export * from './locators';
11 changes: 11 additions & 0 deletions packages/deeplinks/observability/locators/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

export * from './log_explorer';
export * from './observability_log_explorer';
export * from './observability_onboarding';
51 changes: 51 additions & 0 deletions packages/deeplinks/observability/locators/log_explorer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import type { SerializableRecord } from '@kbn/utility-types';
import type { Filter, TimeRange, Query, AggregateQuery } from '@kbn/es-query';

// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
export type RefreshInterval = {
pause: boolean;
value: number;
};

export const LOG_EXPLORER_LOCATOR_ID = 'LOG_EXPLORER_LOCATOR';

export interface LogExplorerNavigationParams extends SerializableRecord {
/**
* Optionally set the time range in the time picker.
*/
timeRange?: TimeRange;
/**
* Optionally set the refresh interval.
*/
refreshInterval?: RefreshInterval;
/**
* Optionally set a query.
*/
query?: Query | AggregateQuery;
/**
* Columns displayed in the table
*/
columns?: string[];
/**
* Array of the used sorting [[field,direction],...]
*/
sort?: string[][];
/**
* Optionally apply filters.
*/
filters?: Filter[];
}

export interface LogExplorerLocatorParams extends LogExplorerNavigationParams {
/**
* Dataset name to be selected.
*/
dataset?: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { LogExplorerNavigationParams } from './log_explorer';

export type DatasetLocatorParams = LogExplorerNavigationParams;

// All datasets locator
export const ALL_DATASETS_LOCATOR_ID = 'ALL_DATASETS_LOCATOR';

export type AllDatasetsLocatorParams = DatasetLocatorParams;

// Single dataset locator
export const SINGLE_DATASET_LOCATOR_ID = 'SINGLE_DATASET_LOCATOR';

export interface SingleDatasetLocatorParams extends DatasetLocatorParams {
/**
* Integration name to be selected.
*/
integration?: string;
/**
* Dataset name to be selected.
* ex: system.syslog
*/
dataset: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { SerializableRecord } from '@kbn/utility-types';

export const OBSERVABILITY_ONBOARDING_LOCATOR = 'OBSERVABILITY_ONBOARDING_LOCATOR' as const;

export interface ObservabilityOnboardingLocatorParams extends SerializableRecord {
/** If given, it will load the given map else will load the create a new map page. */
source?: 'customLogs' | 'systemLogs';
}
2 changes: 2 additions & 0 deletions packages/deeplinks/observability/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@
"target/**/*"
],
"kbn_references": [
"@kbn/utility-types",
"@kbn/es-query",
]
}
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 @@ -58,6 +58,7 @@ export const renderApp = ({
lens: pluginsStart.lens,
uiActions: pluginsStart.uiActions,
observabilityAIAssistant: pluginsStart.observabilityAIAssistant,
share: pluginsSetup.share,
};

// render APM feedback link in global help menu
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ import {
SectionSubtitle,
SectionTitle,
} from '@kbn/observability-shared-plugin/public';
import {
AllDatasetsLocatorParams,
ALL_DATASETS_LOCATOR_ID,
} from '@kbn/deeplinks-observability/locators';
import { isJavaAgentName } from '../../../../../../common/agent_name';
import { SERVICE_NODE_NAME } from '../../../../../../common/es_fields/apm';
import { useApmPluginContext } from '../../../../../context/apm_plugin/use_apm_plugin_context';
Expand All @@ -40,7 +44,7 @@ export function InstanceActionsMenu({
kuery,
onClose,
}: Props) {
const { core, infra } = useApmPluginContext();
const { core, infra, share } = useApmPluginContext();
const { data, status } = useInstanceDetailsFetcher({
serviceName,
serviceNodeName,
Expand All @@ -52,6 +56,10 @@ export function InstanceActionsMenu({
const metricOverviewHref = useMetricOverviewHref(serviceName);
const history = useHistory();

const allDatasetsLocator = share.url.locators.get<AllDatasetsLocatorParams>(
ALL_DATASETS_LOCATOR_ID
)!;

if (isPending(status)) {
return (
<div
Expand Down Expand Up @@ -90,6 +98,7 @@ export function InstanceActionsMenu({
onFilterByInstanceClick: handleFilterByInstanceClick,
metricsHref,
infraLocators: infra?.locators,
allDatasetsLocator,
});

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import { i18n } from '@kbn/i18n';
import { IBasePath } from '@kbn/core/public';
import moment from 'moment';
import type { InfraLocators } from '@kbn/infra-plugin/common/locators';
import type { LocatorPublic } from '@kbn/share-plugin/public';
import { AllDatasetsLocatorParams } from '@kbn/deeplinks-observability/locators';
import { getNodeLogsHref } from '../../../../shared/links/observability_logs_link';
import { APIReturnType } from '../../../../../services/rest/create_call_apm_api';
import { getInfraHref } from '../../../../shared/links/infra_link';
import {
Expand Down Expand Up @@ -39,12 +42,14 @@ export function getMenuSections({
onFilterByInstanceClick,
metricsHref,
infraLocators,
allDatasetsLocator,
}: {
instanceDetails: InstaceDetails;
basePath: IBasePath;
onFilterByInstanceClick: () => void;
metricsHref: string;
infraLocators: InfraLocators;
infraLocators?: InfraLocators;
allDatasetsLocator: LocatorPublic<AllDatasetsLocatorParams>;
}) {
const podId = instanceDetails.kubernetes?.pod?.uid;
const containerId = instanceDetails.container?.id;
Expand All @@ -54,69 +59,72 @@ export function getMenuSections({
const infraMetricsQuery = getInfraMetricsQuery(instanceDetails['@timestamp']);
const infraNodeLocator = infraLocators?.nodeLogsLocator;

const podActions: Action[] = infraNodeLocator
? [
{
key: 'podLogs',
label: i18n.translate(
'xpack.apm.serviceOverview.instancesTable.actionMenus.podLogs',
{ defaultMessage: 'Pod logs' }
),
href: infraNodeLocator?.getRedirectUrl({
nodeId: podId!,
nodeType: 'pod',
time,
}),
condition: !!podId,
},
{
key: 'podMetrics',
label: i18n.translate(
'xpack.apm.serviceOverview.instancesTable.actionMenus.podMetrics',
{ defaultMessage: 'Pod metrics' }
),
href: getInfraHref({
app: 'metrics',
basePath,
path: `/link-to/pod-detail/${podId}`,
query: infraMetricsQuery,
}),
condition: !!podId,
},
]
: [];
const podLogsHref = getNodeLogsHref(
'pod',
podId!,
time,
allDatasetsLocator,
infraNodeLocator
);
const containerLogsHref = getNodeLogsHref(
'container',
containerId!,
time,
allDatasetsLocator,
infraNodeLocator
);

const containerActions: Action[] = infraNodeLocator
? [
{
key: 'containerLogs',
label: i18n.translate(
'xpack.apm.serviceOverview.instancesTable.actionMenus.containerLogs',
{ defaultMessage: 'Container logs' }
),
href: infraNodeLocator?.getRedirectUrl({
nodeId: containerId!,
nodeType: 'container',
time,
}),
condition: !!containerId,
},
{
key: 'containerMetrics',
label: i18n.translate(
'xpack.apm.serviceOverview.instancesTable.actionMenus.containerMetrics',
{ defaultMessage: 'Container metrics' }
),
href: getInfraHref({
app: 'metrics',
basePath,
path: `/link-to/container-detail/${containerId}`,
query: infraMetricsQuery,
}),
condition: !!containerId,
},
]
: [];
const podActions: Action[] = [
{
key: 'podLogs',
label: i18n.translate(
'xpack.apm.serviceOverview.instancesTable.actionMenus.podLogs',
{ defaultMessage: 'Pod logs' }
),
href: podLogsHref,
condition: !!podId,
},
{
key: 'podMetrics',
label: i18n.translate(
'xpack.apm.serviceOverview.instancesTable.actionMenus.podMetrics',
{ defaultMessage: 'Pod metrics' }
),
href: getInfraHref({
app: 'metrics',
basePath,
path: `/link-to/pod-detail/${podId}`,
query: infraMetricsQuery,
}),
condition: !!podId && !!infraLocators,
},
];

const containerActions: Action[] = [
{
key: 'containerLogs',
label: i18n.translate(
'xpack.apm.serviceOverview.instancesTable.actionMenus.containerLogs',
{ defaultMessage: 'Container logs' }
),
href: containerLogsHref,
condition: !!containerId,
},
{
key: 'containerMetrics',
label: i18n.translate(
'xpack.apm.serviceOverview.instancesTable.actionMenus.containerMetrics',
{ defaultMessage: 'Container metrics' }
),
href: getInfraHref({
app: 'metrics',
basePath,
path: `/link-to/container-detail/${containerId}`,
query: infraMetricsQuery,
}),
condition: !!containerId && !!infraLocators,
},
];

const apmActions: Action[] = [
{
Expand Down
Loading

0 comments on commit 9c41ae4

Please sign in to comment.