mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[APM] Add AWS Lambda metrics to "Metrics" tab UI (#140550)
* [APM] AWS lambda metrics api * fixing typo * fixing duration * fixing * tests * addressing pr comments * yformater time * tests * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * addressing pr comments * addressing PR comments * fixing compute usage * fixing ci * fixing ci * addressing PR comments * fixing synthtrace * refactoring * showing metrics tab * synthtrace * addressing pr comments * adding beta badge * fixing tests * fixing active instaces query * addressing PR comments * fixing calc * fixing * removing merge conflic * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * addressing PR changes * remiving unused import * adding feature flag Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
9fa1f04725
commit
99e367446b
20 changed files with 172 additions and 64 deletions
|
@ -522,6 +522,10 @@ export const stackManagementSchema: MakeSchemaFrom<UsageStats> = {
|
|||
type: 'boolean',
|
||||
_meta: { description: 'Non-default value of setting.' },
|
||||
},
|
||||
'observability:enableAwsLambdaMetrics': {
|
||||
type: 'boolean',
|
||||
_meta: { description: 'Non-default value of setting.' },
|
||||
},
|
||||
'observability:apmProgressiveLoading': {
|
||||
type: 'keyword',
|
||||
_meta: { description: 'Non-default value of setting.' },
|
||||
|
|
|
@ -141,6 +141,7 @@ export interface UsageStats {
|
|||
'metrics:allowCheckingForFailedShards': boolean;
|
||||
'observability:apmOperationsTab': boolean;
|
||||
'observability:apmLabsButton': boolean;
|
||||
'observability:enableAwsLambdaMetrics': boolean;
|
||||
'observability:apmProgressiveLoading': string;
|
||||
'observability:apmServiceGroupMaxNumberOfServices': number;
|
||||
'observability:apmServiceInventoryOptimizedSorting': boolean;
|
||||
|
|
|
@ -8828,6 +8828,12 @@
|
|||
"description": "Non-default value of setting."
|
||||
}
|
||||
},
|
||||
"observability:enableAwsLambdaMetrics": {
|
||||
"type": "boolean",
|
||||
"_meta": {
|
||||
"description": "Non-default value of setting."
|
||||
}
|
||||
},
|
||||
"observability:apmProgressiveLoading": {
|
||||
"type": "keyword",
|
||||
"_meta": {
|
||||
|
@ -10317,4 +10323,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,10 +14,11 @@ import {
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { omit } from 'lodash';
|
||||
import React from 'react';
|
||||
import { enableAwsLambdaMetrics } from '@kbn/observability-plugin/common';
|
||||
import {
|
||||
isMobileAgentName,
|
||||
isJavaAgentName,
|
||||
isJRubyAgent,
|
||||
isMobileAgentName,
|
||||
isRumAgentName,
|
||||
isServerlessAgent,
|
||||
} from '../../../../../common/agent_name';
|
||||
|
@ -29,13 +30,13 @@ import { ServiceAnomalyTimeseriesContextProvider } from '../../../../context/ser
|
|||
import { useApmParams } from '../../../../hooks/use_apm_params';
|
||||
import { useApmRouter } from '../../../../hooks/use_apm_router';
|
||||
import { useTimeRange } from '../../../../hooks/use_time_range';
|
||||
import { SearchBar } from '../../../shared/search_bar';
|
||||
import { ServiceIcons } from '../../../shared/service_icons';
|
||||
import { ApmMainTemplate } from '../apm_main_template';
|
||||
import { AnalyzeDataButton } from './analyze_data_button';
|
||||
import { getAlertingCapabilities } from '../../../alerting/get_alerting_capabilities';
|
||||
import { BetaBadge } from '../../../shared/beta_badge';
|
||||
import { SearchBar } from '../../../shared/search_bar';
|
||||
import { ServiceIcons } from '../../../shared/service_icons';
|
||||
import { TechnicalPreviewBadge } from '../../../shared/technical_preview_badge';
|
||||
import { ApmMainTemplate } from '../apm_main_template';
|
||||
import { AnalyzeDataButton } from './analyze_data_button';
|
||||
|
||||
type Tab = NonNullable<EuiPageHeaderProps['tabs']>[0] & {
|
||||
key:
|
||||
|
@ -139,17 +140,21 @@ function TemplateWithContext({
|
|||
export function isMetricsTabHidden({
|
||||
agentName,
|
||||
runtimeName,
|
||||
isAwsLambdaEnabled,
|
||||
}: {
|
||||
agentName?: string;
|
||||
runtimeName?: string;
|
||||
isAwsLambdaEnabled?: boolean;
|
||||
}) {
|
||||
if (isServerlessAgent(runtimeName)) {
|
||||
return !isAwsLambdaEnabled;
|
||||
}
|
||||
return (
|
||||
!agentName ||
|
||||
isRumAgentName(agentName) ||
|
||||
isJavaAgentName(agentName) ||
|
||||
isMobileAgentName(agentName) ||
|
||||
isJRubyAgent(agentName, runtimeName) ||
|
||||
isServerlessAgent(runtimeName)
|
||||
isJRubyAgent(agentName, runtimeName)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -192,6 +197,11 @@ function useTabs({ selectedTab }: { selectedTab: Tab['key'] }) {
|
|||
|
||||
const router = useApmRouter();
|
||||
|
||||
const isAwsLambdaEnabled = core.uiSettings.get<boolean>(
|
||||
enableAwsLambdaMetrics,
|
||||
true
|
||||
);
|
||||
|
||||
const {
|
||||
path: { serviceName },
|
||||
query: queryFromUrl,
|
||||
|
@ -257,7 +267,14 @@ function useTabs({ selectedTab }: { selectedTab: Tab['key'] }) {
|
|||
label: i18n.translate('xpack.apm.serviceDetails.metricsTabLabel', {
|
||||
defaultMessage: 'Metrics',
|
||||
}),
|
||||
hidden: isMetricsTabHidden({ agentName, runtimeName }),
|
||||
append: isServerlessAgent(runtimeName) ? (
|
||||
<TechnicalPreviewBadge icon="beaker" />
|
||||
) : undefined,
|
||||
hidden: isMetricsTabHidden({
|
||||
agentName,
|
||||
runtimeName,
|
||||
isAwsLambdaEnabled,
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: 'nodes',
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiTitle } from '@elastic/eui';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiIconTip, EuiTitle } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import { APIReturnType } from '../../../../services/rest/create_call_apm_api';
|
||||
import {
|
||||
|
@ -60,9 +60,22 @@ interface Props {
|
|||
export function MetricsChart({ chart, fetchStatus }: Props) {
|
||||
return (
|
||||
<>
|
||||
<EuiTitle size="xs">
|
||||
<span>{chart.title}</span>
|
||||
</EuiTitle>
|
||||
<EuiFlexGroup gutterSize="s">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle size="xs">
|
||||
<span>{chart.title}</span>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
{chart.description && (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIconTip
|
||||
content={chart.description}
|
||||
position="top"
|
||||
type="questionInCircle"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
</EuiFlexGroup>
|
||||
<TimeseriesChart
|
||||
fetchStatus={fetchStatus}
|
||||
id={chart.key}
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
AnnotationDomainType,
|
||||
AreaSeries,
|
||||
Axis,
|
||||
BarSeries,
|
||||
Chart,
|
||||
CurveType,
|
||||
LegendItemListener,
|
||||
|
@ -171,6 +172,17 @@ export function TimeseriesChart({
|
|||
opacity: theme.darkMode ? 0.6 : 0.2,
|
||||
};
|
||||
|
||||
function getChartType(type: string) {
|
||||
switch (type) {
|
||||
case 'area':
|
||||
return AreaSeries;
|
||||
case 'bar':
|
||||
return BarSeries;
|
||||
default:
|
||||
return LineSeries;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ChartContainer
|
||||
hasData={!isEmpty}
|
||||
|
@ -281,7 +293,7 @@ export function TimeseriesChart({
|
|||
/>
|
||||
|
||||
{allSeries.map((serie) => {
|
||||
const Series = serie.type === 'area' ? AreaSeries : LineSeries;
|
||||
const Series = getChartType(serie.type);
|
||||
|
||||
return (
|
||||
<Series
|
||||
|
|
|
@ -32,7 +32,7 @@ export function useServiceMetricChartsFetcher({
|
|||
} = useApmParams('/services/{serviceName}');
|
||||
|
||||
const { start, end } = useTimeRange({ rangeFrom, rangeTo });
|
||||
const { agentName, serviceName } = useApmServiceContext();
|
||||
const { agentName, serviceName, runtimeName } = useApmServiceContext();
|
||||
|
||||
const {
|
||||
data = INITIAL_DATA,
|
||||
|
@ -53,13 +53,23 @@ export function useServiceMetricChartsFetcher({
|
|||
start,
|
||||
end,
|
||||
agentName,
|
||||
serviceRuntimeName: runtimeName,
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
[environment, kuery, serviceName, start, end, agentName, serviceNodeName]
|
||||
[
|
||||
environment,
|
||||
kuery,
|
||||
serviceName,
|
||||
start,
|
||||
end,
|
||||
agentName,
|
||||
serviceNodeName,
|
||||
runtimeName,
|
||||
]
|
||||
);
|
||||
|
||||
return {
|
||||
|
|
|
@ -13,7 +13,6 @@ import {
|
|||
SERVICE_NODE_NAME,
|
||||
} from '../../../../../common/elasticsearch_fieldnames';
|
||||
import { environmentQuery } from '../../../../../common/utils/environment_query';
|
||||
import { getVizColorForIndex } from '../../../../../common/viz_colors';
|
||||
import { getMetricsDateHistogramParams } from '../../../../lib/helpers/metrics';
|
||||
import { Setup } from '../../../../lib/helpers/setup_request';
|
||||
import {
|
||||
|
@ -92,7 +91,14 @@ export async function getActiveInstances({
|
|||
defaultMessage: 'Active instances',
|
||||
}),
|
||||
key: 'active_instances',
|
||||
yUnit: 'number',
|
||||
yUnit: 'integer',
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentMetrics.serverless.activeInstances.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'This chart shows the number of active instances of your serverless function over time. Multiple active instances may be a result of provisioned concurrency for your function or an increase in concurrent load that scales your function on-demand. An increase in active instance can be an indicator for an increase in concurrent invocations.',
|
||||
}
|
||||
),
|
||||
series: [
|
||||
{
|
||||
title: i18n.translate(
|
||||
|
@ -100,8 +106,8 @@ export async function getActiveInstances({
|
|||
{ defaultMessage: 'Active instances' }
|
||||
),
|
||||
key: 'active_instances',
|
||||
type: 'linemark',
|
||||
color: getVizColorForIndex(0, theme),
|
||||
type: 'bar',
|
||||
color: theme.euiColorVis1,
|
||||
overallValue: aggregations?.activeInstances.value ?? 0,
|
||||
data:
|
||||
aggregations?.timeseriesData.buckets.map((timeseriesBucket) => ({
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { termQuery } from '@kbn/observability-plugin/server';
|
||||
import { euiLightVars as theme } from '@kbn/ui-theme';
|
||||
import {
|
||||
FAAS_COLDSTART,
|
||||
METRICSET_NAME,
|
||||
|
@ -20,13 +21,14 @@ const chartBase: ChartBase = {
|
|||
defaultMessage: 'Cold start',
|
||||
}),
|
||||
key: 'cold_start_count',
|
||||
type: 'linemark',
|
||||
yUnit: 'number',
|
||||
type: 'bar',
|
||||
yUnit: 'integer',
|
||||
series: {
|
||||
coldStart: {
|
||||
title: i18n.translate('xpack.apm.agentMetrics.serverless.coldStart', {
|
||||
defaultMessage: 'Cold start',
|
||||
}),
|
||||
color: theme.euiColorVis5,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { euiLightVars as theme } from '@kbn/ui-theme';
|
||||
import { FAAS_COLDSTART_DURATION } from '../../../../../common/elasticsearch_fieldnames';
|
||||
import { Setup } from '../../../../lib/helpers/setup_request';
|
||||
import { fetchAndTransformMetrics } from '../../fetch_and_transform_metrics';
|
||||
|
@ -24,8 +25,16 @@ const chartBase: ChartBase = {
|
|||
'xpack.apm.agentMetrics.serverless.coldStartDuration',
|
||||
{ defaultMessage: 'Cold start duration' }
|
||||
),
|
||||
color: theme.euiColorVis5,
|
||||
},
|
||||
},
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentMetrics.serverless.coldStartDuration.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Cold start duration shows the execution duration of the serverless runtime for requests that experience cold starts.',
|
||||
}
|
||||
),
|
||||
};
|
||||
|
||||
export function getColdStartDuration({
|
||||
|
|
|
@ -21,27 +21,9 @@ import {
|
|||
} from '../../../../../common/elasticsearch_fieldnames';
|
||||
import { environmentQuery } from '../../../../../common/utils/environment_query';
|
||||
import { isFiniteNumber } from '../../../../../common/utils/is_finite_number';
|
||||
import { getVizColorForIndex } from '../../../../../common/viz_colors';
|
||||
import { getMetricsDateHistogramParams } from '../../../../lib/helpers/metrics';
|
||||
import { Setup } from '../../../../lib/helpers/setup_request';
|
||||
import { GenericMetricsChart } from '../../fetch_and_transform_metrics';
|
||||
import { ChartBase } from '../../types';
|
||||
|
||||
const chartBase: ChartBase = {
|
||||
title: i18n.translate('xpack.apm.agentMetrics.serverless.computeUsage', {
|
||||
defaultMessage: 'Compute usage',
|
||||
}),
|
||||
key: 'compute_usage',
|
||||
type: 'linemark',
|
||||
yUnit: 'number',
|
||||
series: {
|
||||
computeUsage: {
|
||||
title: i18n.translate('xpack.apm.agentMetrics.serverless.computeUsage', {
|
||||
defaultMessage: 'Compute usage',
|
||||
}),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* To calculate the compute usage we need to multiply the "system.memory.total" by "faas.billed_duration".
|
||||
|
@ -126,9 +108,18 @@ export async function getComputeUsage({
|
|||
const timeseriesData = aggregations?.timeseriesData;
|
||||
|
||||
return {
|
||||
title: chartBase.title,
|
||||
key: chartBase.key,
|
||||
yUnit: chartBase.yUnit,
|
||||
title: i18n.translate('xpack.apm.agentMetrics.serverless.computeUsage', {
|
||||
defaultMessage: 'Compute usage',
|
||||
}),
|
||||
key: 'compute_usage',
|
||||
yUnit: 'number',
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentMetrics.serverless.computeUsage.description',
|
||||
{
|
||||
defaultMessage:
|
||||
"Compute usage (in GB-seconds) is the execution time multiplied by the available memory size of your function's instances. The compute usage is a direct indicator for the costs of your serverless function.",
|
||||
}
|
||||
),
|
||||
series:
|
||||
!timeseriesData || timeseriesData.buckets.length === 0
|
||||
? []
|
||||
|
@ -139,12 +130,12 @@ export async function getComputeUsage({
|
|||
{ defaultMessage: 'Compute usage' }
|
||||
),
|
||||
key: 'compute_usage',
|
||||
type: 'linemark',
|
||||
type: 'bar',
|
||||
overallValue: calculateComputeUsageGBSeconds({
|
||||
faasBilledDuration: aggregations?.avgFaasBilledDuration.value,
|
||||
totalMemory: aggregations?.avgTotalMemory.value,
|
||||
}),
|
||||
color: getVizColorForIndex(0, theme),
|
||||
color: theme.euiColorVis0,
|
||||
data: timeseriesData.buckets.map((bucket) => {
|
||||
const computeUsage = calculateComputeUsageGBSeconds({
|
||||
faasBilledDuration: bucket.avgFaasBilledDuration.value,
|
||||
|
|
|
@ -51,9 +51,9 @@ export function getServerlessAgentMetricCharts({
|
|||
...options,
|
||||
searchAggregatedTransactions,
|
||||
}),
|
||||
getMemoryChartData(options),
|
||||
getColdStartDuration(options),
|
||||
getColdStartCount(options),
|
||||
getMemoryChartData(options),
|
||||
getComputeUsage(options),
|
||||
getActiveInstances({ ...options, searchAggregatedTransactions }),
|
||||
]);
|
||||
|
|
|
@ -32,6 +32,13 @@ const chartBase: ChartBase = {
|
|||
type: 'linemark',
|
||||
yUnit: 'time',
|
||||
series: {},
|
||||
description: i18n.translate(
|
||||
'xpack.apm.agentMetrics.serverless.avgDuration.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Transaction duration is the time spent processing and responding to a request. If the request is queued it will not be contribute to the transaction duration but will contribute the overall billed duration',
|
||||
}
|
||||
),
|
||||
};
|
||||
|
||||
async function getServerlessLantecySeries({
|
||||
|
|
|
@ -21,6 +21,7 @@ import {
|
|||
serviceNodeNameQuery,
|
||||
} from '../../../common/utils/environment_query';
|
||||
import { SERVICE_NAME } from '../../../common/elasticsearch_fieldnames';
|
||||
import { ChartType, Coordinate, YUnit } from '../../../typings/timeseries';
|
||||
|
||||
type MetricsAggregationMap = Unionize<{
|
||||
min: AggregationOptionsByType['min'];
|
||||
|
@ -42,9 +43,22 @@ export type GenericMetricsRequest = APMEventESSearchRequest & {
|
|||
};
|
||||
};
|
||||
|
||||
export type GenericMetricsChart = Awaited<
|
||||
ReturnType<typeof fetchAndTransformMetrics>
|
||||
>;
|
||||
export type GenericMetricsChart = Awaited<FetchAndTransformMetrics>;
|
||||
|
||||
export interface FetchAndTransformMetrics {
|
||||
title: string;
|
||||
key: string;
|
||||
yUnit: YUnit;
|
||||
series: Array<{
|
||||
title: string;
|
||||
key: string;
|
||||
type: ChartType;
|
||||
color: string;
|
||||
overallValue: number;
|
||||
data: Coordinate[];
|
||||
}>;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export async function fetchAndTransformMetrics<T extends MetricAggs>({
|
||||
environment,
|
||||
|
@ -70,7 +84,7 @@ export async function fetchAndTransformMetrics<T extends MetricAggs>({
|
|||
aggs: T;
|
||||
additionalFilters?: QueryDslQueryContainer[];
|
||||
operationName: string;
|
||||
}) {
|
||||
}): Promise<FetchAndTransformMetrics> {
|
||||
const { apmEventClient, config } = setup;
|
||||
|
||||
const params: GenericMetricsRequest = {
|
||||
|
@ -115,6 +129,7 @@ export async function fetchAndTransformMetrics<T extends MetricAggs>({
|
|||
title: chartBase.title,
|
||||
key: chartBase.key,
|
||||
yUnit: chartBase.yUnit,
|
||||
description: chartBase.description,
|
||||
series:
|
||||
hits.total.value === 0
|
||||
? []
|
||||
|
|
|
@ -9,6 +9,7 @@ import * as t from 'io-ts';
|
|||
import { setupRequest } from '../../lib/helpers/setup_request';
|
||||
import { createApmServerRoute } from '../apm_routes/create_apm_server_route';
|
||||
import { environmentRt, kueryRt, rangeRt } from '../default_api_types';
|
||||
import { FetchAndTransformMetrics } from './fetch_and_transform_metrics';
|
||||
import { getMetricsChartDataByAgent } from './get_metrics_chart_data_by_agent';
|
||||
|
||||
const metricsChartsRoute = createApmServerRoute({
|
||||
|
@ -34,19 +35,7 @@ const metricsChartsRoute = createApmServerRoute({
|
|||
handler: async (
|
||||
resources
|
||||
): Promise<{
|
||||
charts: Array<{
|
||||
title: string;
|
||||
key: string;
|
||||
yUnit: import('./../../../typings/timeseries').YUnit;
|
||||
series: Array<{
|
||||
title: string;
|
||||
key: string;
|
||||
type: import('./../../../typings/timeseries').ChartType;
|
||||
color: string;
|
||||
overallValue: number;
|
||||
data: Array<{ x: number; y: number | null }>;
|
||||
}>;
|
||||
}>;
|
||||
charts: FetchAndTransformMetrics[];
|
||||
}> => {
|
||||
const { params } = resources;
|
||||
const setup = await setupRequest(resources);
|
||||
|
|
|
@ -18,4 +18,5 @@ export interface ChartBase {
|
|||
color?: string;
|
||||
};
|
||||
};
|
||||
description?: string;
|
||||
}
|
||||
|
|
|
@ -69,5 +69,5 @@ export interface APMChartSpec<
|
|||
groupId?: string;
|
||||
}
|
||||
|
||||
export type ChartType = 'area' | 'linemark';
|
||||
export type ChartType = 'area' | 'linemark' | 'bar';
|
||||
export type YUnit = 'percent' | 'bytes' | 'number' | 'time' | 'integer';
|
||||
|
|
|
@ -25,6 +25,7 @@ export {
|
|||
apmOperationsTab,
|
||||
apmLabsButton,
|
||||
enableInfrastructureHostsView,
|
||||
enableAwsLambdaMetrics,
|
||||
} from './ui_settings_keys';
|
||||
|
||||
export {
|
||||
|
|
|
@ -20,3 +20,4 @@ export const apmTraceExplorerTab = 'observability:apmTraceExplorerTab';
|
|||
export const apmOperationsTab = 'observability:apmOperationsTab';
|
||||
export const apmLabsButton = 'observability:apmLabsButton';
|
||||
export const enableInfrastructureHostsView = 'observability:enableInfrastructureHostsView';
|
||||
export const enableAwsLambdaMetrics = 'observability:enableAwsLambdaMetrics';
|
||||
|
|
|
@ -23,6 +23,7 @@ import {
|
|||
apmOperationsTab,
|
||||
apmLabsButton,
|
||||
enableInfrastructureHostsView,
|
||||
enableAwsLambdaMetrics,
|
||||
} from '../common/ui_settings_keys';
|
||||
|
||||
const technicalPreviewLabel = i18n.translate(
|
||||
|
@ -254,4 +255,26 @@ export const uiSettings: Record<string, UiSettings> = {
|
|||
}),
|
||||
schema: schema.boolean(),
|
||||
},
|
||||
[enableAwsLambdaMetrics]: {
|
||||
category: [observabilityFeatureId],
|
||||
name: i18n.translate('xpack.observability.enableAwsLambdaMetrics', {
|
||||
defaultMessage: 'AWS Lambda Metrics',
|
||||
}),
|
||||
description: i18n.translate('xpack.observability.enableAwsLambdaMetricsDescription', {
|
||||
defaultMessage: 'Display Amazon Lambda metrics in the service metrics tab. {feedbackLink}',
|
||||
values: {
|
||||
feedbackLink:
|
||||
'<a href="https://ela.st/feedback-aws-lambda" target="_blank" rel="noopener noreferrer">' +
|
||||
i18n.translate('xpack.observability.awsLambdaDescription', {
|
||||
defaultMessage: 'Send feedback',
|
||||
}) +
|
||||
'</a>',
|
||||
},
|
||||
}),
|
||||
schema: schema.boolean(),
|
||||
value: true,
|
||||
requiresPageReload: true,
|
||||
type: 'boolean',
|
||||
showInLabs: true,
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue