mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Add feature flag for service map api v2 (#214227)
Closes https://github.com/elastic/kibana/issues/213125 ### Summary Added feature flag to enable the new service map api Not specific telemetry for events was added, the advance settings have telemetry already out of the box https://github.com/user-attachments/assets/684bd369-c46d-4ac0-ab07-33b5395a7f71 <img width="778" alt="Screenshot 2025-03-13 at 14 20 37" src="https://github.com/user-attachments/assets/6445e85f-1108-43d1-aeee-a340cdfe99b8" /> ### How to test - Inspect the response. v2 has a `spans` object, and the current version has an `elements` object --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
f2b5f3fe48
commit
3ff1340c01
15 changed files with 120 additions and 15 deletions
|
@ -488,6 +488,10 @@ export const stackManagementSchema: MakeSchemaFrom<UsageStats> = {
|
|||
type: 'integer',
|
||||
_meta: { description: 'Non-default value of setting.' },
|
||||
},
|
||||
'observability:apmEnableServiceMapApiV2': {
|
||||
type: 'boolean',
|
||||
_meta: { description: 'Non-default value of setting.' },
|
||||
},
|
||||
'observability:aiAssistantSimulatedFunctionCalling': {
|
||||
type: 'boolean',
|
||||
_meta: { description: 'Non-default value of setting.' },
|
||||
|
|
|
@ -49,6 +49,7 @@ export interface UsageStats {
|
|||
'observability:apmAgentExplorerView': boolean;
|
||||
'observability:apmEnableTableSearchBar': boolean;
|
||||
'observability:apmEnableServiceInventoryTableSearchBar': boolean;
|
||||
'observability:apmEnableServiceMapApiV2': boolean;
|
||||
'observability:logSources': string[];
|
||||
'observability:newLogsOverview': boolean;
|
||||
'observability:aiAssistantSimulatedFunctionCalling': boolean;
|
||||
|
|
|
@ -11030,6 +11030,12 @@
|
|||
"description": "Non-default value of setting."
|
||||
}
|
||||
},
|
||||
"observability:apmEnableServiceMapApiV2": {
|
||||
"type": "boolean",
|
||||
"_meta": {
|
||||
"description": "Non-default value of setting."
|
||||
}
|
||||
},
|
||||
"observability:aiAssistantSimulatedFunctionCalling": {
|
||||
"type": "boolean",
|
||||
"_meta": {
|
||||
|
|
|
@ -207,7 +207,6 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
|||
'xpack.apm.serviceMapEnabled (boolean?)',
|
||||
'xpack.apm.ui.enabled (boolean?)',
|
||||
'xpack.apm.ui.maxTraceItems (number?)',
|
||||
'xpack.apm.ui.serviceMapApiV2Enabled (boolean?)',
|
||||
'xpack.apm.managedServiceUrl (string?|never)',
|
||||
'xpack.apm.serverlessOnboarding (boolean?|never)',
|
||||
'xpack.apm.latestAgentVersionsUrl (string?)',
|
||||
|
|
|
@ -6,9 +6,20 @@
|
|||
*/
|
||||
|
||||
import { usePerformanceContext } from '@kbn/ebt-tools';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner, EuiPanel, useEuiTheme } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiLoadingSpinner,
|
||||
EuiPanel,
|
||||
EuiSpacer,
|
||||
useEuiTheme,
|
||||
} from '@elastic/eui';
|
||||
import type { ReactNode } from 'react';
|
||||
import React from 'react';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { apmEnableServiceMapApiV2 } from '@kbn/observability-plugin/common';
|
||||
import { useEditableSettings } from '@kbn/observability-shared-plugin/public';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
|
||||
import { isActivePlatinumLicense } from '../../../../common/license_check';
|
||||
import { invalidLicenseMessage, SERVICE_MAP_TIMEOUT_ERROR } from '../../../../common/service_map';
|
||||
|
@ -33,6 +44,7 @@ import { useApmServiceContext } from '../../../context/apm_service/use_apm_servi
|
|||
import { isLogsOnlySignal } from '../../../utils/get_signal_type';
|
||||
import { ServiceTabEmptyState } from '../service_tab_empty_state';
|
||||
import { useServiceMap } from './use_service_map';
|
||||
import { TryItButton } from '../../shared/try_it_button';
|
||||
|
||||
function PromptContainer({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
|
@ -108,8 +120,34 @@ export function ServiceMap({
|
|||
const license = useLicenseContext();
|
||||
const serviceName = useServiceName();
|
||||
|
||||
const { config } = useApmPluginContext();
|
||||
const { config, core } = useApmPluginContext();
|
||||
const { onPageReady } = usePerformanceContext();
|
||||
|
||||
const subscriptions = useRef<Subscription>(new Subscription());
|
||||
const [isServiceMapApiV2Enabled, setIsServiceMapApiV2Enabled] = useState<boolean>(
|
||||
core.settings.client.get(apmEnableServiceMapApiV2)
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
subscriptions.current.add(
|
||||
core.settings.client.get$<boolean>(apmEnableServiceMapApiV2).subscribe((value) => {
|
||||
setIsServiceMapApiV2Enabled(value);
|
||||
})
|
||||
);
|
||||
}, [core.settings]);
|
||||
|
||||
useEffect(() => {
|
||||
const currentSubscriptions = subscriptions.current;
|
||||
return () => {
|
||||
currentSubscriptions.unsubscribe();
|
||||
};
|
||||
}, []);
|
||||
|
||||
const { fields, isSaving, saveSingleSetting } = useEditableSettings([apmEnableServiceMapApiV2]);
|
||||
|
||||
const settingsField = fields[apmEnableServiceMapApiV2];
|
||||
const isServiceMapV2Enabled = Boolean(settingsField?.savedValue ?? settingsField?.defaultValue);
|
||||
|
||||
const { data, status, error } = useServiceMap({
|
||||
environment,
|
||||
kuery,
|
||||
|
@ -117,6 +155,7 @@ export function ServiceMap({
|
|||
end,
|
||||
serviceGroupId,
|
||||
serviceName,
|
||||
isServiceMapApiV2Enabled,
|
||||
});
|
||||
|
||||
const { ref, height } = useRefDimensions();
|
||||
|
@ -182,6 +221,39 @@ export function ServiceMap({
|
|||
return (
|
||||
<>
|
||||
<SearchBar showTimeComparison />
|
||||
<EuiFlexGroup alignItems="center" justifyContent="flexStart" gutterSize="s">
|
||||
<TryItButton
|
||||
isFeatureEnabled={isServiceMapV2Enabled}
|
||||
linkLabel={
|
||||
isServiceMapV2Enabled
|
||||
? i18n.translate('xpack.apm.serviceMap.disableServiceMapApiV2', {
|
||||
defaultMessage: 'Disable the new service map API',
|
||||
})
|
||||
: i18n.translate('xpack.apm.serviceMap.enableServiceMapApiV2', {
|
||||
defaultMessage: 'Enable the new service map API',
|
||||
})
|
||||
}
|
||||
onClick={() => {
|
||||
saveSingleSetting(apmEnableServiceMapApiV2, !isServiceMapV2Enabled);
|
||||
}}
|
||||
isLoading={isSaving}
|
||||
popoverContent={
|
||||
<EuiFlexGroup direction="column" gutterSize="s">
|
||||
<EuiFlexItem grow={false}>
|
||||
{i18n.translate('xpack.apm.serviceMap.serviceMapApiV2PopoverContent', {
|
||||
defaultMessage: 'The new service map API is faster, try it out!',
|
||||
})}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
}
|
||||
hideThisContent={i18n.translate('xpack.apm.serviceMap.hideThisContent', {
|
||||
defaultMessage:
|
||||
'Hide this. The setting can be enabled or disabled in Advanced Settings.',
|
||||
})}
|
||||
calloutId="showServiceMapV2Callout"
|
||||
/>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiPanel hasBorder={true} paddingSize="none">
|
||||
<div data-test-subj="serviceMap" style={{ height: heightWithPadding }} ref={ref}>
|
||||
<Cytoscape
|
||||
|
|
|
@ -31,6 +31,7 @@ export const useServiceMap = ({
|
|||
serviceName,
|
||||
serviceGroupId,
|
||||
kuery,
|
||||
isServiceMapApiV2Enabled,
|
||||
}: {
|
||||
environment: Environment;
|
||||
kuery: string;
|
||||
|
@ -38,6 +39,7 @@ export const useServiceMap = ({
|
|||
end: string;
|
||||
serviceGroupId?: string;
|
||||
serviceName?: string;
|
||||
isServiceMapApiV2Enabled: boolean;
|
||||
}) => {
|
||||
const license = useLicenseContext();
|
||||
const { config } = useApmPluginContext();
|
||||
|
@ -67,7 +69,7 @@ export const useServiceMap = ({
|
|||
serviceName,
|
||||
serviceGroup: serviceGroupId,
|
||||
kuery,
|
||||
useV2: config.ui.serviceMapApiV2Enabled,
|
||||
useV2: isServiceMapApiV2Enabled,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -81,7 +83,7 @@ export const useServiceMap = ({
|
|||
serviceGroupId,
|
||||
kuery,
|
||||
config.serviceMapEnabled,
|
||||
config.ui.serviceMapApiV2Enabled,
|
||||
isServiceMapApiV2Enabled,
|
||||
],
|
||||
{ preservePreviousData: false }
|
||||
);
|
||||
|
|
|
@ -23,6 +23,7 @@ import {
|
|||
apmEnableTableSearchBar,
|
||||
apmEnableTransactionProfiling,
|
||||
apmEnableServiceInventoryTableSearchBar,
|
||||
apmEnableServiceMapApiV2,
|
||||
} from '@kbn/observability-plugin/common';
|
||||
import { isEmpty } from 'lodash';
|
||||
import React from 'react';
|
||||
|
@ -56,6 +57,7 @@ function getApmSettingsKeys(isProfilingIntegrationEnabled: boolean) {
|
|||
enableAgentExplorerView,
|
||||
apmEnableTableSearchBar,
|
||||
apmEnableServiceInventoryTableSearchBar,
|
||||
apmEnableServiceMapApiV2,
|
||||
];
|
||||
|
||||
if (isProfilingIntegrationEnabled) {
|
||||
|
|
|
@ -29,6 +29,8 @@ interface Props {
|
|||
onClick: () => void;
|
||||
popoverContent?: React.ReactElement;
|
||||
isLoading: boolean;
|
||||
calloutId: string;
|
||||
hideThisContent: string;
|
||||
}
|
||||
|
||||
export function TryItButton({
|
||||
|
@ -38,16 +40,15 @@ export function TryItButton({
|
|||
popoverContent,
|
||||
promoLabel,
|
||||
isLoading,
|
||||
calloutId,
|
||||
hideThisContent,
|
||||
}: Props) {
|
||||
const [showFastFilterTryCallout, setShowFastFilterTryCallout] = useLocalStorage(
|
||||
'apm.showFastFilterTryCallout',
|
||||
true
|
||||
);
|
||||
const [showTryCallout, setShowFastFilterTryCallout] = useLocalStorage(`apm.${calloutId}`, true);
|
||||
const { core } = useApmPluginContext();
|
||||
const canEditAdvancedSettings = core.application.capabilities.advancedSettings?.save;
|
||||
const [isPopoverOpen, togglePopover] = useToggle(false);
|
||||
|
||||
if (!showFastFilterTryCallout) {
|
||||
if (!showTryCallout) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -169,7 +170,7 @@ export function TryItButton({
|
|||
function HideThisButton() {
|
||||
return (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiToolTip content="Hide this">
|
||||
<EuiToolTip content={hideThisContent}>
|
||||
<EuiButtonIcon
|
||||
data-test-subj="apmHideThisButtonButton"
|
||||
iconType="cross"
|
||||
|
|
|
@ -92,7 +92,6 @@ const mockCore = merge({}, coreStart, {
|
|||
const mockConfig: ConfigSchema = {
|
||||
serviceMapEnabled: true,
|
||||
ui: {
|
||||
serviceMapApiV2Enabled: false,
|
||||
enabled: false,
|
||||
},
|
||||
latestAgentVersionsUrl: '',
|
||||
|
|
|
@ -12,7 +12,6 @@ import { ApmPlugin } from './plugin';
|
|||
export interface ConfigSchema {
|
||||
serviceMapEnabled: boolean;
|
||||
ui: {
|
||||
serviceMapApiV2Enabled: boolean;
|
||||
enabled: boolean;
|
||||
};
|
||||
latestAgentVersionsUrl: string;
|
||||
|
|
|
@ -36,7 +36,6 @@ const configSchema = schema.object({
|
|||
ui: schema.object({
|
||||
enabled: schema.boolean({ defaultValue: true }),
|
||||
maxTraceItems: schema.number({ defaultValue: 5000 }),
|
||||
serviceMapApiV2Enabled: schema.boolean({ defaultValue: false }),
|
||||
}),
|
||||
searchAggregatedTransactions: schema.oneOf(
|
||||
[
|
||||
|
|
|
@ -53,6 +53,7 @@ export {
|
|||
profilingAzureCostDiscountRate,
|
||||
apmEnableTransactionProfiling,
|
||||
apmEnableServiceInventoryTableSearchBar,
|
||||
apmEnableServiceMapApiV2,
|
||||
profilingFetchTopNFunctionsFromStacktraces,
|
||||
} from './ui_settings_keys';
|
||||
|
||||
|
|
|
@ -46,3 +46,4 @@ export const apmEnableTransactionProfiling = 'observability:apmEnableTransaction
|
|||
export const profilingFetchTopNFunctionsFromStacktraces =
|
||||
'observability:profilingFetchTopNFunctionsFromStacktraces';
|
||||
export const searchExcludedDataTiers = 'observability:searchExcludedDataTiers';
|
||||
export const apmEnableServiceMapApiV2 = 'observability:apmEnableServiceMapApiV2';
|
||||
|
|
|
@ -41,6 +41,7 @@ export {
|
|||
apmServiceGroupMaxNumberOfServices,
|
||||
enableAgentExplorerView,
|
||||
apmEnableTableSearchBar,
|
||||
apmEnableServiceMapApiV2,
|
||||
} from '../common/ui_settings_keys';
|
||||
export {
|
||||
alertsLocatorID,
|
||||
|
|
|
@ -45,6 +45,7 @@ import {
|
|||
apmEnableServiceInventoryTableSearchBar,
|
||||
profilingFetchTopNFunctionsFromStacktraces,
|
||||
searchExcludedDataTiers,
|
||||
apmEnableServiceMapApiV2,
|
||||
} from '../common/ui_settings_keys';
|
||||
|
||||
const betaLabel = i18n.translate('xpack.observability.uiSettings.betaLabel', {
|
||||
|
@ -365,6 +366,23 @@ export const uiSettings: Record<string, UiSettings> = {
|
|||
type: 'boolean',
|
||||
solution: 'oblt',
|
||||
},
|
||||
[apmEnableServiceMapApiV2]: {
|
||||
category: [observabilityFeatureId],
|
||||
name: i18n.translate('xpack.observability.apmEnableServiceMapApiV2', {
|
||||
defaultMessage: 'Service Map API v2',
|
||||
}),
|
||||
description: i18n.translate('xpack.observability.apmEnableServiceMapApiV2Description', {
|
||||
defaultMessage: '{technicalPreviewLabel} Enables the usage of the new Service Map API v2.',
|
||||
values: {
|
||||
technicalPreviewLabel: `<em>[${technicalPreviewLabel}]</em>`,
|
||||
},
|
||||
}),
|
||||
schema: schema.boolean(),
|
||||
value: false,
|
||||
requiresPageReload: false,
|
||||
type: 'boolean',
|
||||
solution: 'oblt',
|
||||
},
|
||||
[apmAWSLambdaPriceFactor]: {
|
||||
category: [observabilityFeatureId],
|
||||
name: i18n.translate('xpack.observability.apmAWSLambdaPricePerGbSeconds', {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue