[8.17] [Profiling x APM Integration] Use both host.hostname or host.name and container.id to correlate profiling data on APM (#201403) (#201635)

# Backport

This will backport the following commits from `main` to `8.17`:
- [[Profiling x APM Integration] Use both host.hostname or host.name and
container.id to correlate profiling data on APM
(#201403)](https://github.com/elastic/kibana/pull/201403)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Cauê
Marcondes","email":"55978943+cauemarcondes@users.noreply.github.com"},"sourceCommit":{"committedDate":"2024-11-25T15:51:23Z","message":"[Profiling
x APM Integration] Use both host.hostname or host.name and container.id
to correlate profiling data on APM (#201403)\n\ncloses
https://github.com/elastic/kibana/issues/180036\r\n\r\nThe logic now,
first checks if there are `container.ids` on the selected\r\nservice, if
not, it falls back to the `host.name` or `host.hostname`.\r\n\r\n##
container.id\r\n<img width=\"1320\" alt=\"Screenshot 2024-11-25 at 10 53
44\"\r\nsrc=\"https://github.com/user-attachments/assets/b0515e7a-0319-4d88-bf39-3fbbba3ad957\">\r\n<img
width=\"1300\" alt=\"Screenshot 2024-11-25 at 10 53
55\"\r\nsrc=\"https://github.com/user-attachments/assets/66ceacfd-dc36-4f18-bdfa-67f656d41d36\">\r\n<img
width=\"1303\" alt=\"Screenshot 2024-11-25 at 11 06
55\"\r\nsrc=\"https://github.com/user-attachments/assets/57516d46-b2ee-41d4-9710-74a8b36124a9\">\r\n\r\n\r\n##
host.name\r\n<img width=\"1314\" alt=\"Screenshot 2024-11-25 at 11 02
49\"\r\nsrc=\"https://github.com/user-attachments/assets/5b7c0cdf-267a-4874-bb29-b9ddba8fb53f\">\r\n<img
width=\"1326\" alt=\"Screenshot 2024-11-25 at 11 03
00\"\r\nsrc=\"https://github.com/user-attachments/assets/ab8eb946-4513-4b4b-8775-6b8be7fe6957\">\r\n<img
width=\"1342\" alt=\"Screenshot 2024-11-25 at 11 03
08\"\r\nsrc=\"https://github.com/user-attachments/assets/80017155-5bcb-4154-91ca-52b154b945b2\">\r\n\r\n##
host.hostname\r\n<img width=\"1323\" alt=\"Screenshot 2024-11-25 at 11
04
24\"\r\nsrc=\"https://github.com/user-attachments/assets/a2a8df63-4049-463e-8bc2-88b7c05c727b\">\r\n<img
width=\"1321\" alt=\"Screenshot 2024-11-25 at 11 04
34\"\r\nsrc=\"https://github.com/user-attachments/assets/29d6532c-8027-4eb4-88bd-46d32ea56353\">\r\n<img
width=\"1311\" alt=\"Screenshot 2024-11-25 at 11 04
51\"\r\nsrc=\"https://github.com/user-attachments/assets/897bd883-014e-4d95-8ed6-d2263eceb490\">","sha":"ff97e5234b58599a503c76549f41afb6ce595dc5","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","backport:prev-minor","ci:project-deploy-observability","Team:obs-ux-infra_services","v8.17.0"],"title":"[Profiling
x APM Integration] Use both host.hostname or host.name and container.id
to correlate profiling data on
APM","number":201403,"url":"https://github.com/elastic/kibana/pull/201403","mergeCommit":{"message":"[Profiling
x APM Integration] Use both host.hostname or host.name and container.id
to correlate profiling data on APM (#201403)\n\ncloses
https://github.com/elastic/kibana/issues/180036\r\n\r\nThe logic now,
first checks if there are `container.ids` on the selected\r\nservice, if
not, it falls back to the `host.name` or `host.hostname`.\r\n\r\n##
container.id\r\n<img width=\"1320\" alt=\"Screenshot 2024-11-25 at 10 53
44\"\r\nsrc=\"https://github.com/user-attachments/assets/b0515e7a-0319-4d88-bf39-3fbbba3ad957\">\r\n<img
width=\"1300\" alt=\"Screenshot 2024-11-25 at 10 53
55\"\r\nsrc=\"https://github.com/user-attachments/assets/66ceacfd-dc36-4f18-bdfa-67f656d41d36\">\r\n<img
width=\"1303\" alt=\"Screenshot 2024-11-25 at 11 06
55\"\r\nsrc=\"https://github.com/user-attachments/assets/57516d46-b2ee-41d4-9710-74a8b36124a9\">\r\n\r\n\r\n##
host.name\r\n<img width=\"1314\" alt=\"Screenshot 2024-11-25 at 11 02
49\"\r\nsrc=\"https://github.com/user-attachments/assets/5b7c0cdf-267a-4874-bb29-b9ddba8fb53f\">\r\n<img
width=\"1326\" alt=\"Screenshot 2024-11-25 at 11 03
00\"\r\nsrc=\"https://github.com/user-attachments/assets/ab8eb946-4513-4b4b-8775-6b8be7fe6957\">\r\n<img
width=\"1342\" alt=\"Screenshot 2024-11-25 at 11 03
08\"\r\nsrc=\"https://github.com/user-attachments/assets/80017155-5bcb-4154-91ca-52b154b945b2\">\r\n\r\n##
host.hostname\r\n<img width=\"1323\" alt=\"Screenshot 2024-11-25 at 11
04
24\"\r\nsrc=\"https://github.com/user-attachments/assets/a2a8df63-4049-463e-8bc2-88b7c05c727b\">\r\n<img
width=\"1321\" alt=\"Screenshot 2024-11-25 at 11 04
34\"\r\nsrc=\"https://github.com/user-attachments/assets/29d6532c-8027-4eb4-88bd-46d32ea56353\">\r\n<img
width=\"1311\" alt=\"Screenshot 2024-11-25 at 11 04
51\"\r\nsrc=\"https://github.com/user-attachments/assets/897bd883-014e-4d95-8ed6-d2263eceb490\">","sha":"ff97e5234b58599a503c76549f41afb6ce595dc5"}},"sourceBranch":"main","suggestedTargetBranches":["8.17"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/201403","number":201403,"mergeCommit":{"message":"[Profiling
x APM Integration] Use both host.hostname or host.name and container.id
to correlate profiling data on APM (#201403)\n\ncloses
https://github.com/elastic/kibana/issues/180036\r\n\r\nThe logic now,
first checks if there are `container.ids` on the selected\r\nservice, if
not, it falls back to the `host.name` or `host.hostname`.\r\n\r\n##
container.id\r\n<img width=\"1320\" alt=\"Screenshot 2024-11-25 at 10 53
44\"\r\nsrc=\"https://github.com/user-attachments/assets/b0515e7a-0319-4d88-bf39-3fbbba3ad957\">\r\n<img
width=\"1300\" alt=\"Screenshot 2024-11-25 at 10 53
55\"\r\nsrc=\"https://github.com/user-attachments/assets/66ceacfd-dc36-4f18-bdfa-67f656d41d36\">\r\n<img
width=\"1303\" alt=\"Screenshot 2024-11-25 at 11 06
55\"\r\nsrc=\"https://github.com/user-attachments/assets/57516d46-b2ee-41d4-9710-74a8b36124a9\">\r\n\r\n\r\n##
host.name\r\n<img width=\"1314\" alt=\"Screenshot 2024-11-25 at 11 02
49\"\r\nsrc=\"https://github.com/user-attachments/assets/5b7c0cdf-267a-4874-bb29-b9ddba8fb53f\">\r\n<img
width=\"1326\" alt=\"Screenshot 2024-11-25 at 11 03
00\"\r\nsrc=\"https://github.com/user-attachments/assets/ab8eb946-4513-4b4b-8775-6b8be7fe6957\">\r\n<img
width=\"1342\" alt=\"Screenshot 2024-11-25 at 11 03
08\"\r\nsrc=\"https://github.com/user-attachments/assets/80017155-5bcb-4154-91ca-52b154b945b2\">\r\n\r\n##
host.hostname\r\n<img width=\"1323\" alt=\"Screenshot 2024-11-25 at 11
04
24\"\r\nsrc=\"https://github.com/user-attachments/assets/a2a8df63-4049-463e-8bc2-88b7c05c727b\">\r\n<img
width=\"1321\" alt=\"Screenshot 2024-11-25 at 11 04
34\"\r\nsrc=\"https://github.com/user-attachments/assets/29d6532c-8027-4eb4-88bd-46d32ea56353\">\r\n<img
width=\"1311\" alt=\"Screenshot 2024-11-25 at 11 04
51\"\r\nsrc=\"https://github.com/user-attachments/assets/897bd883-014e-4d95-8ed6-d2263eceb490\">","sha":"ff97e5234b58599a503c76549f41afb6ce595dc5"}},{"branch":"8.17","label":"v8.17.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Cauê Marcondes <55978943+cauemarcondes@users.noreply.github.com>
This commit is contained in:
Kibana Machine 2024-11-26 04:49:46 +11:00 committed by GitHub
parent 247ea32b2e
commit 86288e107d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 145 additions and 74 deletions

View file

@ -0,0 +1,66 @@
/*
* 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.
*/
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiText, EuiToolTip } from '@elastic/eui';
import React from 'react';
import { i18n } from '@kbn/i18n';
interface Props {
hostNames?: string[];
containerIds?: string[];
}
export function FilterWarning({ containerIds = [], hostNames = [] }: Props) {
const hasContainerIds = containerIds.length > 0;
return hasContainerIds ? (
<FilterWarningToolTip
values={containerIds}
label={i18n.translate('xpack.apm.profiling.topFunctions.filteredLabel.containerId', {
defaultMessage: "Displaying profiling insights from the service's container id(s)",
})}
/>
) : (
<FilterWarningToolTip
values={hostNames}
label={i18n.translate('xpack.apm.profiling.topFunctions.filteredLabel.hostName', {
defaultMessage: "Displaying profiling insights from the service's host(s)",
})}
/>
);
}
interface FilterWarningToolTipProps {
values: string[];
label: string;
}
function FilterWarningToolTip({ values = [], label }: FilterWarningToolTipProps) {
function renderTooltipOptions() {
return (
<ul>
{values.map((value) => (
<li key={value}>{`- ${value}`}</li>
))}
</ul>
);
}
return (
<EuiFlexGroup gutterSize="none">
<EuiFlexItem grow={false}>
<EuiText size="xs" color="subdued">
{label}
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiToolTip content={renderTooltipOptions()}>
<EuiIcon type="questionInCircle" />
</EuiToolTip>
</EuiFlexItem>
</EuiFlexGroup>
);
}

View file

@ -1,42 +0,0 @@
/*
* 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.
*/
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiText, EuiToolTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
interface Props {
hostNames?: string[];
}
export function HostnamesFilterWarning({ hostNames = [] }: Props) {
function renderTooltipOptions() {
return (
<ul>
{hostNames.map((hostName) => (
<li key={hostName}>{`- ${hostName}`}</li>
))}
</ul>
);
}
return (
<EuiFlexGroup gutterSize="none">
<EuiFlexItem grow={false}>
<EuiText size="xs" color="subdued">
{i18n.translate('xpack.apm.profiling.flamegraph.filteredLabel', {
defaultMessage: "Displaying profiling insights from the service's host(s)",
})}
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiToolTip content={renderTooltipOptions()}>
<EuiIcon type="questionInCircle" />
</EuiToolTip>
</EuiFlexItem>
</EuiFlexGroup>
);
}

View file

@ -9,12 +9,12 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
import React from 'react';
import { ApmDataSourceWithSummary } from '../../../../common/data_source';
import { ApmDocumentType } from '../../../../common/document_type';
import { HOST_NAME } from '../../../../common/es_fields/apm';
import { CONTAINER_ID, HOST_NAME } from '../../../../common/es_fields/apm';
import { mergeKueries, toKueryFilterFormat } from '../../../../common/utils/kuery_utils';
import { useFetcher } from '../../../hooks/use_fetcher';
import { FlamegraphChart } from '../../shared/charts/flamegraph';
import { ProfilingFlamegraphLink } from '../../shared/profiling/flamegraph/flamegraph_link';
import { HostnamesFilterWarning } from './host_names_filter_warning';
import { FilterWarning } from './filter_warning';
interface Props {
serviceName: string;
@ -60,17 +60,20 @@ export function ProfilingHostsFlamegraph({
[dataSource, serviceName, start, end, environment, kuery]
);
const hostNamesKueryFormat = toKueryFilterFormat(HOST_NAME, data?.hostNames || []);
const profilingKueryFilter =
data?.containerIds && data.containerIds.length > 0
? toKueryFilterFormat(CONTAINER_ID, data?.containerIds || [])
: toKueryFilterFormat(HOST_NAME, data?.hostNames || []);
return (
<>
<EuiFlexGroup>
<EuiFlexItem grow={false}>
<HostnamesFilterWarning hostNames={data?.hostNames} />
<FilterWarning containerIds={data?.containerIds} hostNames={data?.hostNames} />
</EuiFlexItem>
<EuiFlexItem>
<ProfilingFlamegraphLink
kuery={mergeKueries([`(${hostNamesKueryFormat})`, kuery])}
kuery={mergeKueries([`(${profilingKueryFilter})`, kuery])}
rangeFrom={rangeFrom}
rangeTo={rangeTo}
justifyContent="flexEnd"

View file

@ -10,11 +10,11 @@ import { EmbeddableFunctions } from '@kbn/observability-shared-plugin/public';
import React from 'react';
import { ApmDataSourceWithSummary } from '../../../../common/data_source';
import { ApmDocumentType } from '../../../../common/document_type';
import { HOST_NAME } from '../../../../common/es_fields/apm';
import { CONTAINER_ID, HOST_NAME } from '../../../../common/es_fields/apm';
import { mergeKueries, toKueryFilterFormat } from '../../../../common/utils/kuery_utils';
import { isPending, useFetcher } from '../../../hooks/use_fetcher';
import { ProfilingTopNFunctionsLink } from '../../shared/profiling/top_functions/top_functions_link';
import { HostnamesFilterWarning } from './host_names_filter_warning';
import { FilterWarning } from './filter_warning';
interface Props {
serviceName: string;
@ -66,17 +66,20 @@ export function ProfilingHostsTopNFunctions({
[dataSource, serviceName, start, end, environment, startIndex, endIndex, kuery]
);
const hostNamesKueryFormat = toKueryFilterFormat(HOST_NAME, data?.hostNames || []);
const profilingKueryFilter =
data?.containerIds && data.containerIds.length > 0
? toKueryFilterFormat(CONTAINER_ID, data?.containerIds || [])
: toKueryFilterFormat(HOST_NAME, data?.hostNames || []);
return (
<>
<EuiFlexGroup>
<EuiFlexItem grow={false}>
<HostnamesFilterWarning hostNames={data?.hostNames} />
<FilterWarning containerIds={data?.containerIds} hostNames={data?.hostNames} />
</EuiFlexItem>
<EuiFlexItem>
<ProfilingTopNFunctionsLink
kuery={mergeKueries([`(${hostNamesKueryFormat})`, kuery])}
kuery={mergeKueries([`(${profilingKueryFilter})`, kuery])}
rangeFrom={rangeFrom}
rangeTo={rangeTo}
justifyContent="flexEnd"

View file

@ -5,13 +5,26 @@
* 2.0.
*/
import { rangeQuery } from '@kbn/observability-plugin/server';
import { ApmServiceTransactionDocumentType } from '../../../common/document_type';
import { HOST_HOSTNAME, SERVICE_NAME } from '../../../common/es_fields/apm';
import { RollupInterval } from '../../../common/rollup';
import type { ApmServiceTransactionDocumentType } from '../../../common/document_type';
import {
CONTAINER_ID,
HOST_HOSTNAME,
HOST_NAME,
SERVICE_NAME,
} from '../../../common/es_fields/apm';
import type { RollupInterval } from '../../../common/rollup';
import { environmentQuery } from '../../../common/utils/environment_query';
import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client';
import type { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client';
export async function getServiceHostNames({
const getBucketKeysAsString = (
buckets?: Array<{
doc_count: number;
key: string | number;
key_as_string?: string | undefined;
}>
) => buckets?.map((bucket) => bucket.key as string) || [];
export async function getServiceCorrelationFields({
apmEventClient,
serviceName,
start,
@ -45,15 +58,36 @@ export async function getServiceHostNames({
},
},
aggs: {
hostNames: {
hostHostNames: {
terms: {
field: HOST_HOSTNAME,
size: 500,
},
},
hostNames: {
terms: {
field: HOST_NAME,
size: 500,
},
},
containerIds: {
terms: {
field: CONTAINER_ID,
size: 500,
},
},
},
},
});
return response.aggregations?.hostNames.buckets.map((bucket) => bucket.key as string) || [];
const allHostNames = [
...getBucketKeysAsString(response.aggregations?.hostHostNames.buckets),
...getBucketKeysAsString(response.aggregations?.hostNames.buckets),
];
const hostNames = new Set<string>(allHostNames);
return {
hostNames: Array.from(hostNames),
containerIds: getBucketKeysAsString(response.aggregations?.containerIds.buckets),
};
}

View file

@ -8,7 +8,7 @@
import { toNumberRt } from '@kbn/io-ts-utils';
import type { BaseFlameGraph, TopNFunctions } from '@kbn/profiling-utils';
import * as t from 'io-ts';
import { HOST_NAME } from '../../../../common/es_fields/apm';
import { CONTAINER_ID, HOST_NAME } from '../../../../common/es_fields/apm';
import { mergeKueries, toKueryFilterFormat } from '../../../../common/utils/kuery_utils';
import { getApmEventClient } from '../../../lib/helpers/get_apm_event_client';
import { createApmServerRoute } from '../../apm_routes/create_apm_server_route';
@ -20,7 +20,7 @@ import {
} from '../../default_api_types';
import { fetchFlamegraph } from '../fetch_flamegraph';
import { fetchFunctions } from '../fetch_functions';
import { getServiceHostNames } from '../get_service_host_names';
import { getServiceCorrelationFields } from '../get_service_correlation_fields';
const profilingHostsFlamegraphRoute = createApmServerRoute({
endpoint: 'GET /internal/apm/services/{serviceName}/profiling/hosts/flamegraph',
@ -31,7 +31,9 @@ const profilingHostsFlamegraphRoute = createApmServerRoute({
options: { tags: ['access:apm'] },
handler: async (
resources
): Promise<{ flamegraph: BaseFlameGraph; hostNames: string[] } | undefined> => {
): Promise<
{ flamegraph: BaseFlameGraph; hostNames: string[]; containerIds: string[] } | undefined
> => {
const { context, plugins, params } = resources;
const core = await context.core;
const [esClient, apmEventClient, profilingDataAccessStart] = await Promise.all([
@ -43,7 +45,7 @@ const profilingHostsFlamegraphRoute = createApmServerRoute({
const { start, end, environment, documentType, rollupInterval, kuery } = params.query;
const { serviceName } = params.path;
const serviceHostNames = await getServiceHostNames({
const { hostNames, containerIds } = await getServiceCorrelationFields({
apmEventClient,
start,
end,
@ -53,7 +55,7 @@ const profilingHostsFlamegraphRoute = createApmServerRoute({
rollupInterval,
});
if (!serviceHostNames.length) {
if (!hostNames.length && !containerIds.length) {
return undefined;
}
const startSecs = start / 1000;
@ -65,10 +67,13 @@ const profilingHostsFlamegraphRoute = createApmServerRoute({
esClient: esClient.asCurrentUser,
start: startSecs,
end: endSecs,
kuery: mergeKueries([`(${toKueryFilterFormat(HOST_NAME, serviceHostNames)})`, kuery]),
kuery:
containerIds.length > 0
? mergeKueries([`(${toKueryFilterFormat(CONTAINER_ID, containerIds)})`, kuery])
: mergeKueries([`(${toKueryFilterFormat(HOST_NAME, hostNames)})`, kuery]),
});
return { flamegraph, hostNames: serviceHostNames };
return { flamegraph, hostNames, containerIds };
}
return undefined;
@ -90,7 +95,9 @@ const profilingHostsFunctionsRoute = createApmServerRoute({
options: { tags: ['access:apm'] },
handler: async (
resources
): Promise<{ functions: TopNFunctions; hostNames: string[] } | undefined> => {
): Promise<
{ functions: TopNFunctions; hostNames: string[]; containerIds: string[] } | undefined
> => {
const { context, plugins, params } = resources;
const core = await context.core;
const [esClient, apmEventClient, profilingDataAccessStart] = await Promise.all([
@ -103,7 +110,7 @@ const profilingHostsFunctionsRoute = createApmServerRoute({
params.query;
const { serviceName } = params.path;
const serviceHostNames = await getServiceHostNames({
const { hostNames, containerIds } = await getServiceCorrelationFields({
apmEventClient,
start,
end,
@ -113,7 +120,7 @@ const profilingHostsFunctionsRoute = createApmServerRoute({
rollupInterval,
});
if (!serviceHostNames.length) {
if (!hostNames.length && !containerIds.length) {
return undefined;
}
@ -128,10 +135,13 @@ const profilingHostsFunctionsRoute = createApmServerRoute({
endIndex,
start: startSecs,
end: endSecs,
kuery: mergeKueries([`(${toKueryFilterFormat(HOST_NAME, serviceHostNames)})`, kuery]),
kuery:
containerIds.length > 0
? mergeKueries([`(${toKueryFilterFormat(CONTAINER_ID, containerIds)})`, kuery])
: mergeKueries([`(${toKueryFilterFormat(HOST_NAME, hostNames)})`, kuery]),
});
return { functions, hostNames: serviceHostNames };
return { functions, hostNames, containerIds };
}
return undefined;

View file

@ -11542,7 +11542,6 @@
"xpack.apm.profiling.callout.dismiss": "Rejeter",
"xpack.apm.profiling.callout.learnMore": "En savoir plus",
"xpack.apm.profiling.callout.title": "Affichage des informations de profilage de l'hôte ou des hôtes exécutant des services {serviceName}",
"xpack.apm.profiling.flamegraph.filteredLabel": "Affichage des informations de profilage du ou des hôtes des services",
"xpack.apm.profiling.flamegraph.link": "Accéder au flame-graph d'Universal Profiling",
"xpack.apm.profiling.flamegraph.noDataFound": "Aucune donnée trouvée",
"xpack.apm.profiling.tabs.flamegraph": "Flame-graph",

View file

@ -11525,7 +11525,6 @@
"xpack.apm.profiling.callout.dismiss": "閉じる",
"xpack.apm.profiling.callout.learnMore": "詳細",
"xpack.apm.profiling.callout.title": "{serviceName}サービスを実行しているホストからプロファイリングインサイトを表示しています",
"xpack.apm.profiling.flamegraph.filteredLabel": "サービスのホストからプロファイリングインサイトを表示しています",
"xpack.apm.profiling.flamegraph.link": "ユニバーサルプロファイリングFlamegraphに移動",
"xpack.apm.profiling.flamegraph.noDataFound": "データが見つかりません",
"xpack.apm.profiling.tabs.flamegraph": "Flamegraph",

View file

@ -11551,7 +11551,6 @@
"xpack.apm.profiling.callout.dismiss": "关闭",
"xpack.apm.profiling.callout.learnMore": "了解详情",
"xpack.apm.profiling.callout.title": "正在显示运行 {serviceName} 服务的主机中的分析洞见",
"xpack.apm.profiling.flamegraph.filteredLabel": "正在显示服务主机中的分析洞见",
"xpack.apm.profiling.flamegraph.link": "前往 Universal Profiling 火焰图",
"xpack.apm.profiling.flamegraph.noDataFound": "未找到任何数据",
"xpack.apm.profiling.tabs.flamegraph": "火焰图",