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

[APM][OTel] Use telemetry.sdk as a fallback for missing agent.name on non-tracing data #196529

Merged
3 changes: 3 additions & 0 deletions packages/kbn-apm-types/src/es_fields/apm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ export const METRIC_OTEL_JVM_SYSTEM_CPU_PERCENT = 'process.runtime.jvm.system.cp
export const METRIC_OTEL_JVM_GC_DURATION = 'process.runtime.jvm.gc.duration';
export const VALUE_OTEL_JVM_PROCESS_MEMORY_HEAP = 'heap';
export const VALUE_OTEL_JVM_PROCESS_MEMORY_NON_HEAP = 'non_heap';
// OpenTelemetry semconv fields for AgentName https://opentelemetry.io/docs/specs/semconv/resource/#telemetry-sdk
export const TELEMETRY_SDK_NAME = 'telemetry.sdk.name';
rmyz marked this conversation as resolved.
Show resolved Hide resolved
export const TELEMETRY_SDK_LANGUAGE = 'telemetry.sdk.language';

// Metadata
export const TIER = '_tier';
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
*/

import { kqlQuery, rangeQuery, wildcardQuery } from '@kbn/observability-plugin/server';
import { getAgentName } from '../../../utils/get_agent_name';
import { ApmDocumentType } from '../../../../common/document_type';
import {
AGENT_NAME,
SERVICE_ENVIRONMENT,
SERVICE_NAME,
TRANSACTION_TYPE,
SERVICE_OVERFLOW_COUNT,
TELEMETRY_SDK_NAME,
TELEMETRY_SDK_LANGUAGE,
} from '../../../../common/es_fields/apm';
import { RollupInterval } from '../../../../common/rollup';
import { ServiceGroup } from '../../../../common/service_groups';
Expand Down Expand Up @@ -124,6 +127,16 @@ export async function getServiceTransactionStats({
size: maxNumServices,
},
aggs: {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

I don't know if this is the best place in the query for this.

telemetryAgentName: {
terms: {
field: TELEMETRY_SDK_LANGUAGE,
},
},
telemetrySdkName: {
terms: {
field: TELEMETRY_SDK_NAME,
},
},
transactionType: {
terms: {
field: TRANSACTION_TYPE,
Expand Down Expand Up @@ -169,9 +182,11 @@ export async function getServiceTransactionStats({
topTransactionTypeBucket?.environments.buckets.map(
(environmentBucket) => environmentBucket.key as string
) ?? [],
agentName: topTransactionTypeBucket?.sample.top[0].metrics[AGENT_NAME] as
| AgentName
| undefined,
agentName: getAgentName(
topTransactionTypeBucket?.sample.top[0].metrics[AGENT_NAME] as string | null,
bucket.telemetryAgentName.buckets[0]?.key as string | null,
bucket.telemetrySdkName.buckets[0]?.key as string | null
) as AgentName,
latency: topTransactionTypeBucket?.avg_duration.value,
transactionErrorRate: topTransactionTypeBucket
? calculateFailedTransactionRate(topTransactionTypeBucket)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,15 @@

import { kqlQuery, rangeQuery, wildcardQuery } from '@kbn/observability-plugin/server';
import { ProcessorEvent } from '@kbn/observability-plugin/common';
import { getAgentName } from '../../../utils/get_agent_name';
import { AgentName } from '../../../../typings/es_schemas/ui/fields/agent';
import { AGENT_NAME, SERVICE_ENVIRONMENT, SERVICE_NAME } from '../../../../common/es_fields/apm';
import {
AGENT_NAME,
SERVICE_ENVIRONMENT,
SERVICE_NAME,
TELEMETRY_SDK_LANGUAGE,
TELEMETRY_SDK_NAME,
} from '../../../../common/es_fields/apm';
import { environmentQuery } from '../../../../common/utils/environment_query';
import { ServiceGroup } from '../../../../common/service_groups';
import { RandomSampler } from '../../../lib/helpers/get_random_sampler';
Expand Down Expand Up @@ -99,6 +106,16 @@ export async function getServicesWithoutTransactions({
field: SERVICE_ENVIRONMENT,
},
},
telemetryAgentName: {
terms: {
field: TELEMETRY_SDK_LANGUAGE,
},
},
telemetrySdkName: {
terms: {
field: TELEMETRY_SDK_NAME,
},
},
latest: {
top_metrics: {
metrics: [{ field: AGENT_NAME } as const],
Expand All @@ -122,7 +139,11 @@ export async function getServicesWithoutTransactions({
return {
serviceName: bucket.key as string,
environments: bucket.environments.buckets.map((envBucket) => envBucket.key as string),
agentName: bucket.latest.top[0].metrics[AGENT_NAME] as AgentName,
agentName: getAgentName(
bucket.latest.top[0].metrics[AGENT_NAME] as string | null,
bucket.telemetryAgentName.buckets[0]?.key as string | null,
bucket.telemetrySdkName.buckets[0]?.key as string | null
) as AgentName,
};
}) ?? [],
maxCountExceeded,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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 { getAgentName } from './get_agent_name';

describe('getAgentName', () => {
it('returns agent name by default', () => {
expect(getAgentName('nodejs', 'go', 'otlp')).toBe('nodejs');
});

it('returns telemetry sdk name and telemetry agent name if agent name is not defined', () => {
expect(getAgentName(null, 'go', 'otlp')).toBe('otlp/go');
});

it('returns telemetry agent name if agent name and telemetry sdk are not defined', () => {
expect(getAgentName(null, 'go', null)).toBe('go');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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.
*/

export function getAgentName(
rmyz marked this conversation as resolved.
Show resolved Hide resolved
agentName: string | null,
telemetryAgentName: string | null,
telemetrySdkName: string | null
) {
if (agentName) {
return agentName;
}

if (telemetrySdkName && telemetryAgentName) {
return `${telemetrySdkName}/${telemetryAgentName}`;
}

return telemetryAgentName;
}