Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.14] [Infra][APM] Fix uptime links display condition in Infra and APM (#181425) #181973

Merged
merged 1 commit into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ export type ApmFields = Fields<{
span: { id: string };
}>;
'url.original': string;
'url.domain': string;
}> &
ApmApplicationMetricFields &
ExperimentalFields;
Expand Down
3 changes: 3 additions & 0 deletions packages/kbn-apm-synthtrace/src/scenarios/simple_trace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ const scenario: Scenario<ApmFields> = async (runOptions) => {
instance
.transaction({ transactionName })
.timestamp(timestamp)
.defaults({
'url.domain': 'foo.bar',
})
.duration(1000)
.success()
.children(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,26 @@ import { IBasePath } from '@kbn/core/public';
import { Transaction } from '../../../../typings/es_schemas/ui/transaction';
import { getSections } from './sections';
import { apmRouter as apmRouterBase, ApmRouter } from '../../routing/apm_route_config';
import {
logsLocatorsMock,
observabilityLogsExplorerLocatorsMock,
} from '../../../context/apm_plugin/mock_apm_plugin_context';
import { logsLocatorsMock } from '../../../context/apm_plugin/mock_apm_plugin_context';
import { sharePluginMock } from '@kbn/share-plugin/public/mocks';

const apmRouter = {
...apmRouterBase,
link: (...args: [any]) => `some-basepath/app/apm${apmRouterBase.link(...args)}`,
} as ApmRouter;

const { allDatasetsLocator } = observabilityLogsExplorerLocatorsMock;
const { nodeLogsLocator, traceLogsLocator } = logsLocatorsMock;
const uptimeLocator = sharePluginMock.createLocator();

const expectLogsLocatorsToBeCalled = () => {
expect(nodeLogsLocator.getRedirectUrl).toBeCalledTimes(3);
expect(traceLogsLocator.getRedirectUrl).toBeCalledTimes(1);
};

const expectUptimeLocatorToBeCalled = () => {
expect(uptimeLocator.getRedirectUrl).toBeCalledTimes(1);
};

describe('Transaction action menu', () => {
const basePath = {
prepend: (url: string) => {
Expand Down Expand Up @@ -60,8 +62,8 @@ describe('Transaction action menu', () => {
basePath,
location,
apmRouter,
allDatasetsLocator,
logsLocators: logsLocatorsMock,
uptimeLocator,
infraLinksAvailable: false,
rangeFrom: 'now-24h',
rangeTo: 'now',
Expand Down Expand Up @@ -110,6 +112,7 @@ describe('Transaction action menu', () => {
},
],
]);
expectUptimeLocatorToBeCalled();
expectLogsLocatorsToBeCalled();
});

Expand All @@ -127,7 +130,7 @@ describe('Transaction action menu', () => {
basePath,
location,
apmRouter,
allDatasetsLocator,
uptimeLocator,
logsLocators: logsLocatorsMock,
infraLinksAvailable: true,
rangeFrom: 'now-24h',
Expand Down Expand Up @@ -195,6 +198,7 @@ describe('Transaction action menu', () => {
},
],
]);
expectUptimeLocatorToBeCalled();
expectLogsLocatorsToBeCalled();
});

Expand All @@ -212,7 +216,7 @@ describe('Transaction action menu', () => {
basePath,
location,
apmRouter,
allDatasetsLocator,
uptimeLocator,
logsLocators: logsLocatorsMock,
infraLinksAvailable: true,
rangeFrom: 'now-24h',
Expand Down Expand Up @@ -280,6 +284,7 @@ describe('Transaction action menu', () => {
},
],
]);
expectUptimeLocatorToBeCalled();
expectLogsLocatorsToBeCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,16 @@ import { Location } from 'history';
import { IBasePath } from '@kbn/core/public';
import { isEmpty, pickBy } from 'lodash';
import moment from 'moment';
import url from 'url';
import type { getLogsLocatorsFromUrlService } from '@kbn/logs-shared-plugin/common';
import { findInventoryFields } from '@kbn/metrics-data-access-plugin/common';
import { LocatorPublic } from '@kbn/share-plugin/common';
import { AllDatasetsLocatorParams } from '@kbn/deeplinks-observability/locators';
import type { ProfilingLocators } from '@kbn/observability-shared-plugin/public';
import { LocatorPublic } from '@kbn/share-plugin/common';
import { SerializableRecord } from '@kbn/utility-types';
import { Environment } from '../../../../common/environment_rt';
import type { Transaction } from '../../../../typings/es_schemas/ui/transaction';
import { getDiscoverHref } from '../links/discover_links/discover_link';
import { getDiscoverQuery } from '../links/discover_links/discover_transaction_link';
import { getInfraHref } from '../links/infra_link';
import { fromQuery } from '../links/url_helpers';
import { SectionRecord, getNonEmptySections, Action } from './sections_helper';
import { HOST_NAME, TRACE_ID } from '../../../../common/es_fields/apm';
import { ApmRouter } from '../../routing/apm_route_config';
Expand All @@ -42,11 +40,11 @@ export const getSections = ({
location,
apmRouter,
infraLinksAvailable,
uptimeLocator,
profilingLocators,
rangeFrom,
rangeTo,
environment,
allDatasetsLocator,
logsLocators,
dataViewId,
}: {
Expand All @@ -55,11 +53,11 @@ export const getSections = ({
location: Location;
apmRouter: ApmRouter;
infraLinksAvailable: boolean;
uptimeLocator?: LocatorPublic<SerializableRecord>;
profilingLocators?: ProfilingLocators;
rangeFrom: string;
rangeTo: string;
environment: Environment;
allDatasetsLocator: LocatorPublic<AllDatasetsLocatorParams>;
logsLocators: ReturnType<typeof getLogsLocatorsFromUrlService>;
dataViewId?: string;
}) => {
Expand All @@ -72,19 +70,16 @@ export const getSections = ({
const time = Math.round(transaction.timestamp.us / 1000);
const infraMetricsQuery = getInfraMetricsQuery(transaction);

const uptimeLink = url.format({
pathname: basePath.prepend('/app/uptime'),
search: `?${fromQuery(
pickBy(
{
dateRangeStart: rangeFrom,
dateRangeEnd: rangeTo,
search: `url.domain:"${transaction.url?.domain}"`,
},
(val) => !isEmpty(val)
)
)}`,
});
const uptimeLink = uptimeLocator?.getRedirectUrl(
pickBy(
{
dateRangeStart: rangeFrom,
dateRangeEnd: rangeTo,
search: `url.domain:"${transaction.url?.domain}"`,
},
(val) => !isEmpty(val)
)
);

// Logs hrefs
const podLogsHref = logsLocators.nodeLogsLocator.getRedirectUrl({
Expand Down Expand Up @@ -231,7 +226,7 @@ export const getSections = ({
defaultMessage: 'Status',
}),
href: uptimeLink,
condition: !!transaction.url?.domain,
condition: !!transaction.url?.domain && !!uptimeLink,
},
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import * as Transactions from './__fixtures__/mock_data';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import * as useAdHocApmDataView from '../../../hooks/use_adhoc_apm_data_view';
import { useProfilingIntegrationSetting } from '../../../hooks/use_profiling_integration_setting';
import { uptimeOverviewLocatorID } from '@kbn/observability-plugin/common';
import { sharePluginMock } from '@kbn/share-plugin/public/mocks';

const apmContextMock = {
...mockApmPluginContextValue,
Expand All @@ -52,6 +54,15 @@ const apmContextMock = {
if (id === TRACE_LOGS_LOCATOR_ID) {
return logsLocatorsMock.traceLogsLocator;
}
if (id === uptimeOverviewLocatorID) {
return {
...sharePluginMock.createLocator(),
getRedirectUrl: jest.fn(
() =>
'http://localhost/basepath/app/uptime?dateRangeStart=now-24h&dateRangeEnd=now&search=url.domain:%22example.com%22'
),
};
}
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,9 @@ import {
import React, { useState } from 'react';
import { useLocation } from 'react-router-dom';
import useAsync from 'react-use/lib/useAsync';
import {
AllDatasetsLocatorParams,
ALL_DATASETS_LOCATOR_ID,
} from '@kbn/deeplinks-observability/locators';
import type { ProfilingLocators } from '@kbn/observability-shared-plugin/public';
import { getLogsLocatorsFromUrlService } from '@kbn/logs-shared-plugin/common';
import { uptimeOverviewLocatorID } from '@kbn/observability-plugin/common';
import { useAnyOfApmParams } from '../../../hooks/use_apm_params';
import { ApmFeatureFlagName } from '../../../../common/apm_feature_flags';
import { Transaction } from '../../../../typings/es_schemas/ui/transaction';
Expand Down Expand Up @@ -124,10 +121,10 @@ function ActionMenuSections({
const apmRouter = useApmRouter();
const { dataView } = useAdHocApmDataView();

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

const uptimeLocator = share.url.locators.get(uptimeOverviewLocatorID);

const infraLinksAvailable = useApmFeatureFlag(ApmFeatureFlagName.InfraUiAvailable);

const {
Expand All @@ -145,11 +142,11 @@ function ActionMenuSections({
location,
apmRouter,
infraLinksAvailable,
uptimeLocator,
profilingLocators,
rangeFrom,
rangeTo,
environment,
allDatasetsLocator,
logsLocators,
dataViewId: dataView?.id,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
import { findInventoryModel, findInventoryFields } from '@kbn/metrics-data-access-plugin/common';
import { InventoryItemType } from '@kbn/metrics-data-access-plugin/common';
import { getLogsLocatorsFromUrlService } from '@kbn/logs-shared-plugin/common';
import { uptimeOverviewLocatorID } from '@kbn/observability-plugin/common';
import { useKibanaContextForPlugin } from '../../../../../hooks/use_kibana';
import { AlertFlyout } from '../../../../../alerting/inventory/components/alert_flyout';
import { InfraWaffleMapNode, InfraWaffleMapOptions } from '../../../../../lib/lib';
Expand All @@ -46,6 +47,7 @@ export const NodeContextMenu: React.FC<Props & { theme?: EuiTheme }> = withTheme
const { services } = useKibanaContextForPlugin();
const { application, share } = services;
const { nodeLogsLocator } = getLogsLocatorsFromUrlService(share.url);
const uptimeLocator = share.url.locators.get(uptimeOverviewLocatorID);
const uiCapabilities = application?.capabilities;
// Due to the changing nature of the fields between APM and this UI,
// We need to have some exceptions until 7.0 & ECS is finalized. Reference
Expand All @@ -60,7 +62,8 @@ export const NodeContextMenu: React.FC<Props & { theme?: EuiTheme }> = withTheme
inventoryModel.crosslinkSupport.apm && uiCapabilities?.apm && uiCapabilities?.apm.show;
const showUptimeLink =
inventoryModel.crosslinkSupport.uptime &&
(['pod', 'container'].includes(nodeType) || node.ip);
(['pod', 'container'].includes(nodeType) || node.ip) &&
!!uptimeLocator;
const showCreateAlertLink = uiCapabilities?.infrastructure?.save;

const inventoryId = useMemo(() => {
Expand Down Expand Up @@ -144,7 +147,7 @@ export const NodeContextMenu: React.FC<Props & { theme?: EuiTheme }> = withTheme
defaultMessage: '{inventoryName} in Uptime',
values: { inventoryName: inventoryModel.singularDisplayName },
}),
onClick: () => navigateToUptime(share.url.locators, nodeType, node),
onClick: () => (showUptimeLink ? navigateToUptime({ uptimeLocator, nodeType, node }) : {}),
isDisabled: !showUptimeLink,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@
* 2.0.
*/

import { uptimeOverviewLocatorID } from '@kbn/observability-plugin/public';
import { LocatorClient } from '@kbn/share-plugin/common/url_service/locators';
import { LocatorPublic } from '@kbn/share-plugin/common/url_service/locators';
import { InventoryItemType } from '@kbn/metrics-data-access-plugin/common';
import { SerializableRecord } from '@kbn/utility-types';
import { InfraWaffleMapNode } from '../../../../lib/lib';

export const navigateToUptime = (
locators: LocatorClient,
nodeType: InventoryItemType,
node: InfraWaffleMapNode
) => {
return locators.get(uptimeOverviewLocatorID)!.navigate({ [nodeType]: node.id, ip: node.ip });
export const navigateToUptime = ({
uptimeLocator,
nodeType,
node,
}: {
uptimeLocator: LocatorPublic<SerializableRecord>;
nodeType: InventoryItemType;
node: InfraWaffleMapNode;
}) => {
return uptimeLocator.navigate({ [nodeType]: node.id, ip: node.ip });
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@
*/
import { LocatorPublic } from '@kbn/share-plugin/public';
import { SerializableRecord } from '@kbn/utility-types';
import { uptimeOverviewNavigatorParams } from './overview';
import { monitorDetailNavigatorParams } from './monitor_detail';
import { editMonitorNavigatorParams } from './edit_monitor';
import { syntheticsSettingsNavigatorParams } from './settings';

export const locators: Array<Pick<LocatorPublic<SerializableRecord>, 'id' | 'getLocation'>> = [
uptimeOverviewNavigatorParams,
monitorDetailNavigatorParams,
editMonitorNavigatorParams,
syntheticsSettingsNavigatorParams,
Expand Down

This file was deleted.