diff --git a/packages/kbn-apm-synthtrace/src/scenarios/many_otel_services.ts b/packages/kbn-apm-synthtrace/src/scenarios/many_otel_services.ts new file mode 100644 index 0000000000000..513f80cf36891 --- /dev/null +++ b/packages/kbn-apm-synthtrace/src/scenarios/many_otel_services.ts @@ -0,0 +1,101 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { ApmFields, apm, Instance } from '@kbn/apm-synthtrace-client'; +import { flatten, random, times } from 'lodash'; +import { Scenario } from '../cli/scenario'; +import { getSynthtraceEnvironment } from '../lib/utils/get_synthtrace_environment'; +import { withClient } from '../lib/utils/with_client'; +import { getRandomNameForIndex } from './helpers/random_names'; + +const ENVIRONMENT = getSynthtraceEnvironment(__filename); + +const scenario: Scenario = async ({ logger, scenarioOpts = { services: 2000 } }) => { + const numServices = scenarioOpts.services; + const transactionName = 'GET /order/{id}'; + const languages = [ + 'go', + 'dotnet', + 'java', + 'python', + 'nodejs', + 'php', + 'webjs', + 'swift', + 'android', + ]; + const agentVersions: Record = { + go: ['2.1.0', '2.0.0', '1.15.0', '1.14.0', '1.13.1'], + dotnet: ['1.18.0', '1.17.0', '1.16.1', '1.16.0', '1.15.0'], + java: ['1.34.1', '1.34.0', '1.33.0', '1.32.0', '1.32.0'], + python: ['6.12.0', '6.11.0', '6.10.2', '6.10.1', '6.10.0'], + nodejs: ['1.34.1', '1.34.0', '1.33.0', '1.32.0', '1.32.0'], + php: ['1.34.1', '1.34.0', '1.33.0', '1.32.0', '1.32.0'], + webjs: ['6.12.0', '6.11.0', '6.10.2', '6.10.1', '6.10.0'], + swift: ['1.18.0', '1.17.0', '1.16.1', '1.16.0', '1.15.0'], + android: ['6.12.0', '6.11.0', '6.10.2', '6.10.1', '6.10.0'], + }; + + return { + generate: ({ range, clients: { apmEsClient } }) => { + const instances = flatten( + times(numServices).map((index) => { + const language = languages[index % languages.length]; + const agentLanguageVersions = agentVersions[language]; + const agentVersion = agentLanguageVersions[index % agentLanguageVersions.length]; + + const numOfInstances = (index % 3) + 1; + return times(numOfInstances).map((instanceIndex) => + apm + .service({ + name: `${getRandomNameForIndex(index)}-${language}-${index}`, + environment: ENVIRONMENT, + agentName: + index % 2 ? `opentelemetry/${language}/elastic` : `otlp/${language}/elastic`, + }) + .instance(`instance-${index}-${instanceIndex}`) + .defaults({ 'agent.version': agentVersion, 'service.language.name': language }) + ); + }) + ); + + const instanceSpans = (instance: Instance) => { + const hasHighDuration = Math.random() > 0.5; + const throughput = random(1, 10); + + return range.ratePerMinute(throughput).generator((timestamp) => { + const parentDuration = hasHighDuration ? random(1000, 5000) : random(100, 1000); + const generateError = random(1, 4) % 3 === 0; + const span = instance + .transaction({ transactionName }) + .timestamp(timestamp) + .duration(parentDuration); + + return !generateError + ? span.success() + : span.failure().errors( + instance + .error({ + message: `No handler for ${transactionName}`, + type: 'No handler', + culprit: 'request', + }) + .timestamp(timestamp + 50) + ); + }); + }; + + return withClient( + apmEsClient, + logger.perf('generating_apm_events', () => instances.map(instanceSpans)) + ); + }, + }; +}; + +export default scenario; diff --git a/packages/kbn-custom-icons/src/components/agent_icon/get_agent_icon.test.ts b/packages/kbn-custom-icons/src/components/agent_icon/get_agent_icon.test.ts index 58dff1afb1095..7318cbcba001c 100644 --- a/packages/kbn-custom-icons/src/components/agent_icon/get_agent_icon.test.ts +++ b/packages/kbn-custom-icons/src/components/agent_icon/get_agent_icon.test.ts @@ -24,6 +24,16 @@ const examples = { 'opentelemetry/python': 'python', 'opentelemetry/ruby': 'ruby', 'opentelemetry/rust': 'rust', + 'opentelemetry/cpp/elastic': 'cpp', // Tests for additional arguments on OpenTelemetry agents + 'opentelemetry/dotnet/elastic': 'dotnet', + 'opentelemetry/erlang/elastic': 'erlang', + 'opentelemetry/go/elastic': 'go', + 'opentelemetry/nodejs/elastic': 'nodejs', + 'opentelemetry/php/elastic': 'php', + 'opentelemetry/python/elastic': 'python', + 'opentelemetry/ruby/elastic': 'ruby', + 'opentelemetry/rust/elastic': 'rust', + opentelemetry: 'opentelemetry', otlp: 'opentelemetry', php: 'php', python: 'python', diff --git a/packages/kbn-custom-icons/src/components/agent_icon/get_agent_icon.ts b/packages/kbn-custom-icons/src/components/agent_icon/get_agent_icon.ts index 7c37f1a86a056..cf3506139c3d3 100644 --- a/packages/kbn-custom-icons/src/components/agent_icon/get_agent_icon.ts +++ b/packages/kbn-custom-icons/src/components/agent_icon/get_agent_icon.ts @@ -10,6 +10,7 @@ import { isIosAgentName, isJavaAgentName, isRumAgentName, + hasOpenTelemetryPrefix, OpenTelemetryAgentName, OPEN_TELEMETRY_AGENT_NAMES, } from '@kbn/elastic-agent-utils'; @@ -64,6 +65,15 @@ const darkAgentIcons: { [key: string]: string } = { rust: darkRustIcon, }; +const sanitizeAgentName = (agentName: string) => { + if (hasOpenTelemetryPrefix(agentName)) { + // for OpenTelemetry only split the agent name by `/` and take the second part, format is `(opentelemetry|otlp)/{agentName}/{details}` + return agentName.split('/')[1]; + } + + return agentName; +}; + // This only needs to be exported for testing purposes, since we stub the SVG // import values in test. export function getAgentIconKey(agentName: string) { @@ -88,11 +98,10 @@ export function getAgentIconKey(agentName: string) { return 'android'; } - // Remove "opentelemetry/" prefix - const agentNameWithoutPrefix = lowercasedAgentName.replace(/^opentelemetry\//, ''); + const cleanAgentName = sanitizeAgentName(lowercasedAgentName); - if (Object.keys(agentIcons).includes(agentNameWithoutPrefix)) { - return agentNameWithoutPrefix; + if (Object.keys(agentIcons).includes(cleanAgentName)) { + return cleanAgentName; } // OpenTelemetry-only agents diff --git a/packages/kbn-elastic-agent-utils/index.ts b/packages/kbn-elastic-agent-utils/index.ts index 62e7a6cd59688..a7949c452c3bd 100644 --- a/packages/kbn-elastic-agent-utils/index.ts +++ b/packages/kbn-elastic-agent-utils/index.ts @@ -7,6 +7,7 @@ */ export { isOpenTelemetryAgentName, + hasOpenTelemetryPrefix, isJavaAgentName, isRumAgentName, isMobileAgentName, diff --git a/packages/kbn-elastic-agent-utils/src/agent_guards.test.ts b/packages/kbn-elastic-agent-utils/src/agent_guards.test.ts index aa55aa94b16ca..884f5a0c52e11 100644 --- a/packages/kbn-elastic-agent-utils/src/agent_guards.test.ts +++ b/packages/kbn-elastic-agent-utils/src/agent_guards.test.ts @@ -7,6 +7,7 @@ */ import { + hasOpenTelemetryPrefix, isAndroidAgentName, isAWSLambdaAgentName, isAzureFunctionsAgentName, @@ -21,23 +22,42 @@ import { } from './agent_guards'; describe('Agents guards', () => { + it('hasOpenTelemetryPrefix should guard if the passed agent has an OpenTelemetry prefix.', () => { + expect(hasOpenTelemetryPrefix('otlp')).toBe(false); + expect(hasOpenTelemetryPrefix('otlp/nodejs')).toBe(true); + expect(hasOpenTelemetryPrefix('otlp/nodejs/elastic')).toBe(true); + expect(hasOpenTelemetryPrefix('opentelemetry')).toBe(false); + expect(hasOpenTelemetryPrefix('opentelemetry/nodejs')).toBe(true); + expect(hasOpenTelemetryPrefix('opentelemetry/nodejs/elastic')).toBe(true); + expect(hasOpenTelemetryPrefix('not-an-agent')).toBe(false); + }); + it('isOpenTelemetryAgentName should guard if the passed agent is an OpenTelemetry one.', () => { expect(isOpenTelemetryAgentName('otlp')).toBe(true); - expect(isOpenTelemetryAgentName('opentelemetry/java')).toBe(true); - expect(isOpenTelemetryAgentName('opentelemetry/java/opentelemetry-java-instrumentation')).toBe( - true - ); + expect(isOpenTelemetryAgentName('otlp/nodejs')).toBe(true); + expect(isOpenTelemetryAgentName('otlp/nodejs/elastic')).toBe(true); + expect(isOpenTelemetryAgentName('opentelemetry')).toBe(true); + expect(isOpenTelemetryAgentName('opentelemetry/nodejs')).toBe(true); + expect(isOpenTelemetryAgentName('opentelemetry/nodejs/elastic')).toBe(true); expect(isOpenTelemetryAgentName('not-an-agent')).toBe(false); }); it('isJavaAgentName should guard if the passed agent is an Java one.', () => { expect(isJavaAgentName('java')).toBe(true); + expect(isJavaAgentName('otlp/java')).toBe(true); + expect(isJavaAgentName('otlp/java/opentelemetry-java-instrumentation')).toBe(true); expect(isJavaAgentName('opentelemetry/java')).toBe(true); expect(isJavaAgentName('opentelemetry/java/opentelemetry-java-instrumentation')).toBe(true); expect(isJavaAgentName('not-an-agent')).toBe(false); }); it('isRumAgentName should guard if the passed agent is an Rum one.', () => { + expect(isRumAgentName('otlp/webjs')).toBe(true); + expect(isRumAgentName('otlp/webjs/elastic')).toBe(true); + expect(isRumAgentName('otlp/fail')).toBe(false); + expect(isRumAgentName('opentelemetry/webjs')).toBe(true); + expect(isRumAgentName('opentelemetry/webjs/elastic')).toBe(true); + expect(isRumAgentName('opentelemetry/fail')).toBe(false); expect(isRumAgentName('rum-js')).toBe(true); expect(isRumAgentName('not-an-agent')).toBe(false); }); @@ -56,11 +76,23 @@ describe('Agents guards', () => { }); it('isIosAgentName should guard if the passed agent is an Ios one.', () => { + expect(isIosAgentName('otlp/swift/elastic')).toBe(true); + expect(isIosAgentName('otlp/swift')).toBe(true); + expect(isIosAgentName('otlp/fail')).toBe(false); + expect(isIosAgentName('opentelemetry/swift/elastic')).toBe(true); + expect(isIosAgentName('opentelemetry/swift')).toBe(true); + expect(isIosAgentName('opentelemetry/fail')).toBe(false); expect(isIosAgentName('ios/swift')).toBe(true); expect(isIosAgentName('not-an-agent')).toBe(false); }); it('isAndroidAgentName should guard if the passed agent is an Android one.', () => { + expect(isAndroidAgentName('otlp/android/elastic')).toBe(true); + expect(isAndroidAgentName('otlp/android')).toBe(true); + expect(isAndroidAgentName('otlp/fail')).toBe(false); + expect(isAndroidAgentName('opentelemetry/android/elastic')).toBe(true); + expect(isAndroidAgentName('opentelemetry/android')).toBe(true); + expect(isAndroidAgentName('opentelemetry/fail')).toBe(false); expect(isAndroidAgentName('android/java')).toBe(true); expect(isAndroidAgentName('not-an-agent')).toBe(false); }); diff --git a/packages/kbn-elastic-agent-utils/src/agent_guards.ts b/packages/kbn-elastic-agent-utils/src/agent_guards.ts index 43cf4cce89f4a..c5838239321d0 100644 --- a/packages/kbn-elastic-agent-utils/src/agent_guards.ts +++ b/packages/kbn-elastic-agent-utils/src/agent_guards.ts @@ -6,31 +6,52 @@ * Side Public License, v 1. */ -import { JAVA_AGENT_NAMES, OPEN_TELEMETRY_AGENT_NAMES, RUM_AGENT_NAMES } from './agent_names'; +import { + ANDROID_AGENT_NAMES, + IOS_AGENT_NAMES, + JAVA_AGENT_NAMES, + OPEN_TELEMETRY_AGENT_NAMES, + RUM_AGENT_NAMES, +} from './agent_names'; import type { + AndroidAgentName, + IOSAgentName, JavaAgentName, OpenTelemetryAgentName, RumAgentName, ServerlessType, } from './agent_names'; +export function hasOpenTelemetryPrefix(agentName?: string, language: string = '') { + if (!agentName) { + return false; + } + + return ( + agentName.startsWith(`opentelemetry/${language}`) || agentName.startsWith(`otlp/${language}`) + ); +} + export function isOpenTelemetryAgentName(agentName: string): agentName is OpenTelemetryAgentName { return ( - agentName?.startsWith('opentelemetry/') || + hasOpenTelemetryPrefix(agentName) || OPEN_TELEMETRY_AGENT_NAMES.includes(agentName as OpenTelemetryAgentName) ); } export function isJavaAgentName(agentName?: string): agentName is JavaAgentName { return ( - agentName?.startsWith('opentelemetry/java') || + hasOpenTelemetryPrefix(agentName, 'java') || JAVA_AGENT_NAMES.includes(agentName! as JavaAgentName) ); } export function isRumAgentName(agentName?: string): agentName is RumAgentName { - return RUM_AGENT_NAMES.includes(agentName! as RumAgentName); + return ( + hasOpenTelemetryPrefix(agentName, 'webjs') || + RUM_AGENT_NAMES.includes(agentName! as RumAgentName) + ); } export function isMobileAgentName(agentName?: string) { @@ -42,12 +63,21 @@ export function isRumOrMobileAgentName(agentName?: string) { } export function isIosAgentName(agentName?: string) { - return agentName?.toLowerCase() === 'ios/swift'; + const lowercasedAgentName = agentName && agentName.toLowerCase(); + + return ( + hasOpenTelemetryPrefix(lowercasedAgentName, 'swift') || + IOS_AGENT_NAMES.includes(lowercasedAgentName! as IOSAgentName) + ); } export function isAndroidAgentName(agentName?: string) { - const lowercased = agentName && agentName.toLowerCase(); - return lowercased === 'android/java'; + const lowercasedAgentName = agentName && agentName.toLowerCase(); + + return ( + hasOpenTelemetryPrefix(lowercasedAgentName, 'android') || + ANDROID_AGENT_NAMES.includes(lowercasedAgentName! as AndroidAgentName) + ); } export function isJRubyAgentName(agentName?: string, runtimeName?: string) { diff --git a/packages/kbn-elastic-agent-utils/src/agent_names.ts b/packages/kbn-elastic-agent-utils/src/agent_names.ts index ca98b64024f8a..37851d62b13ea 100644 --- a/packages/kbn-elastic-agent-utils/src/agent_names.ts +++ b/packages/kbn-elastic-agent-utils/src/agent_names.ts @@ -38,6 +38,7 @@ export const ELASTIC_AGENT_NAMES: ElasticAgentName[] = [ export type OpenTelemetryAgentName = | 'otlp' + | 'opentelemetry' | 'opentelemetry/cpp' | 'opentelemetry/dotnet' | 'opentelemetry/erlang' @@ -50,9 +51,23 @@ export type OpenTelemetryAgentName = | 'opentelemetry/rust' | 'opentelemetry/swift' | 'opentelemetry/android' - | 'opentelemetry/webjs'; + | 'opentelemetry/webjs' + | 'otlp/cpp' + | 'otlp/dotnet' + | 'otlp/erlang' + | 'otlp/go' + | 'otlp/java' + | 'otlp/nodejs' + | 'otlp/php' + | 'otlp/python' + | 'otlp/ruby' + | 'otlp/rust' + | 'otlp/swift' + | 'otlp/android' + | 'otlp/webjs'; export const OPEN_TELEMETRY_AGENT_NAMES: OpenTelemetryAgentName[] = [ 'otlp', + 'opentelemetry', 'opentelemetry/cpp', 'opentelemetry/dotnet', 'opentelemetry/erlang', @@ -66,21 +81,57 @@ export const OPEN_TELEMETRY_AGENT_NAMES: OpenTelemetryAgentName[] = [ 'opentelemetry/swift', 'opentelemetry/android', 'opentelemetry/webjs', + 'otlp/cpp', + 'otlp/dotnet', + 'otlp/erlang', + 'otlp/go', + 'otlp/java', + 'otlp/nodejs', + 'otlp/php', + 'otlp/python', + 'otlp/ruby', + 'otlp/rust', + 'otlp/swift', + 'otlp/android', + 'otlp/webjs', ]; -export type JavaAgentName = 'java' | 'opentelemetry/java'; -export const JAVA_AGENT_NAMES: JavaAgentName[] = ['java', 'opentelemetry/java']; +export type JavaAgentName = 'java' | 'opentelemetry/java' | 'otlp/java'; +export const JAVA_AGENT_NAMES: JavaAgentName[] = ['java', 'opentelemetry/java', 'otlp/java']; -export type RumAgentName = 'js-base' | 'rum-js' | 'opentelemetry/webjs'; -export const RUM_AGENT_NAMES: RumAgentName[] = ['js-base', 'rum-js', 'opentelemetry/webjs']; +export type RumAgentName = 'js-base' | 'rum-js' | 'opentelemetry/webjs' | 'otlp/webjs'; +export const RUM_AGENT_NAMES: RumAgentName[] = [ + 'js-base', + 'rum-js', + 'opentelemetry/webjs', + 'otlp/webjs', +]; + +export type AndroidAgentName = 'android/java' | 'opentelemetry/android' | 'otlp/android'; +export const ANDROID_AGENT_NAMES: AndroidAgentName[] = [ + 'android/java', + 'opentelemetry/android', + 'otlp/android', +]; + +export type IOSAgentName = 'ios/swift' | 'opentelemetry/swift' | 'otlp/swift'; +export const IOS_AGENT_NAMES: IOSAgentName[] = ['ios/swift', 'opentelemetry/swift', 'otlp/swift']; export type ServerlessType = 'aws.lambda' | 'azure.functions'; export const SERVERLESS_TYPE: ServerlessType[] = ['aws.lambda', 'azure.functions']; -export type AgentName = ElasticAgentName | OpenTelemetryAgentName | JavaAgentName | RumAgentName; +export type AgentName = + | ElasticAgentName + | OpenTelemetryAgentName + | JavaAgentName + | RumAgentName + | AndroidAgentName + | IOSAgentName; export const AGENT_NAMES: AgentName[] = [ ...ELASTIC_AGENT_NAMES, ...OPEN_TELEMETRY_AGENT_NAMES, ...JAVA_AGENT_NAMES, ...RUM_AGENT_NAMES, + ...ANDROID_AGENT_NAMES, + ...IOS_AGENT_NAMES, ]; diff --git a/x-pack/plugins/observability_solution/apm/common/__snapshots__/apm_telemetry.test.ts.snap b/x-pack/plugins/observability_solution/apm/common/__snapshots__/apm_telemetry.test.ts.snap index a372355d1db7c..d0aa75c2170f1 100644 --- a/x-pack/plugins/observability_solution/apm/common/__snapshots__/apm_telemetry.test.ts.snap +++ b/x-pack/plugins/observability_solution/apm/common/__snapshots__/apm_telemetry.test.ts.snap @@ -85,6 +85,90 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "description": "Total number of services utilizing the otlp agent within the last day" } }, + "otlp/cpp": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/cpp agent within the last day" + } + }, + "otlp/dotnet": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/dotnet agent within the last day" + } + }, + "otlp/erlang": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/erlang agent within the last day" + } + }, + "otlp/go": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/go agent within the last day" + } + }, + "otlp/java": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/java agent within the last day" + } + }, + "otlp/nodejs": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/nodejs agent within the last day" + } + }, + "otlp/php": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/php agent within the last day" + } + }, + "otlp/python": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/python agent within the last day" + } + }, + "otlp/ruby": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/ruby agent within the last day" + } + }, + "otlp/rust": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/rust agent within the last day" + } + }, + "otlp/swift": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/swift agent within the last day" + } + }, + "otlp/android": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/android agent within the last day" + } + }, + "otlp/webjs": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/webjs agent within the last day" + } + }, + "opentelemetry": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the opentelemetry agent within the last day" + } + }, "opentelemetry/cpp": { "type": "long", "_meta": { @@ -162,6 +246,12 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "_meta": { "description": "Total number of services utilizing the opentelemetry/webjs agent within the last day" } + }, + "ios/swift": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the ios/swift agent within the last day" + } } } }, diff --git a/x-pack/plugins/observability_solution/apm/common/agent_name.ts b/x-pack/plugins/observability_solution/apm/common/agent_name.ts index 608fdf4975353..66ff78e3cdbe4 100644 --- a/x-pack/plugins/observability_solution/apm/common/agent_name.ts +++ b/x-pack/plugins/observability_solution/apm/common/agent_name.ts @@ -8,6 +8,7 @@ export { OPEN_TELEMETRY_AGENT_NAMES, AGENT_NAMES, isOpenTelemetryAgentName, + hasOpenTelemetryPrefix, JAVA_AGENT_NAMES, isJavaAgentName, RUM_AGENT_NAMES, diff --git a/x-pack/plugins/observability_solution/apm/public/components/shared/service_icons/index.tsx b/x-pack/plugins/observability_solution/apm/public/components/shared/service_icons/index.tsx index 0888c1a0f6c11..e6780927e755b 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/shared/service_icons/index.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/shared/service_icons/index.tsx @@ -139,9 +139,7 @@ export function ServiceIcons({ start, end, serviceName, environment }: Props) { title: i18n.translate('xpack.apm.serviceIcons.opentelemetry', { defaultMessage: 'OpenTelemetry', }), - component: ( - - ), + component: , }, { key: 'container', diff --git a/x-pack/plugins/observability_solution/apm/public/components/shared/service_icons/otel_details.tsx b/x-pack/plugins/observability_solution/apm/public/components/shared/service_icons/otel_details.tsx index 410d6a98f7644..04aa2b6f56838 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/shared/service_icons/otel_details.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/shared/service_icons/otel_details.tsx @@ -15,7 +15,6 @@ type ServiceDetailsReturnType = interface Props { opentelemetry: ServiceDetailsReturnType['opentelemetry']; - agentName?: string; } export function OTelDetails({ opentelemetry }: Props) { diff --git a/x-pack/plugins/observability_solution/apm/server/lib/apm_telemetry/schema.ts b/x-pack/plugins/observability_solution/apm/server/lib/apm_telemetry/schema.ts index 32c869beb581f..917237963ef37 100644 --- a/x-pack/plugins/observability_solution/apm/server/lib/apm_telemetry/schema.ts +++ b/x-pack/plugins/observability_solution/apm/server/lib/apm_telemetry/schema.ts @@ -264,6 +264,92 @@ const apmPerAgentSchema: Pick, 'services_per_agen description: 'Total number of services utilizing the otlp agent within the last day', }, }, + 'otlp/cpp': { + type: 'long', + _meta: { + description: 'Total number of services utilizing the otlp/cpp agent within the last day', + }, + }, + 'otlp/dotnet': { + type: 'long', + _meta: { + description: 'Total number of services utilizing the otlp/dotnet agent within the last day', + }, + }, + 'otlp/erlang': { + type: 'long', + _meta: { + description: 'Total number of services utilizing the otlp/erlang agent within the last day', + }, + }, + 'otlp/go': { + type: 'long', + _meta: { + description: 'Total number of services utilizing the otlp/go agent within the last day', + }, + }, + 'otlp/java': { + type: 'long', + _meta: { + description: 'Total number of services utilizing the otlp/java agent within the last day', + }, + }, + 'otlp/nodejs': { + type: 'long', + _meta: { + description: 'Total number of services utilizing the otlp/nodejs agent within the last day', + }, + }, + 'otlp/php': { + type: 'long', + _meta: { + description: 'Total number of services utilizing the otlp/php agent within the last day', + }, + }, + 'otlp/python': { + type: 'long', + _meta: { + description: 'Total number of services utilizing the otlp/python agent within the last day', + }, + }, + 'otlp/ruby': { + type: 'long', + _meta: { + description: 'Total number of services utilizing the otlp/ruby agent within the last day', + }, + }, + 'otlp/rust': { + type: 'long', + _meta: { + description: 'Total number of services utilizing the otlp/rust agent within the last day', + }, + }, + 'otlp/swift': { + type: 'long', + _meta: { + description: 'Total number of services utilizing the otlp/swift agent within the last day', + }, + }, + 'otlp/android': { + type: 'long', + _meta: { + description: + 'Total number of services utilizing the otlp/android agent within the last day', + }, + }, + 'otlp/webjs': { + type: 'long', + _meta: { + description: 'Total number of services utilizing the otlp/webjs agent within the last day', + }, + }, + opentelemetry: { + type: 'long', + _meta: { + description: + 'Total number of services utilizing the opentelemetry agent within the last day', + }, + }, 'opentelemetry/cpp': { type: 'long', _meta: { @@ -355,6 +441,12 @@ const apmPerAgentSchema: Pick, 'services_per_agen 'Total number of services utilizing the opentelemetry/webjs agent within the last day', }, }, + 'ios/swift': { + type: 'long', + _meta: { + description: 'Total number of services utilizing the ios/swift agent within the last day', + }, + }, }, agents: { 'android/java': agentSchema, diff --git a/x-pack/plugins/observability_solution/apm/server/routes/metrics/__snapshots__/queries.test.ts.snap b/x-pack/plugins/observability_solution/apm/server/routes/metrics/__snapshots__/queries.test.ts.snap index 3fac4d595a274..18dd1f4c9835a 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/metrics/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/observability_solution/apm/server/routes/metrics/__snapshots__/queries.test.ts.snap @@ -174,6 +174,7 @@ Object { "agent.name": Array [ "java", "opentelemetry/java", + "otlp/java", ], }, }, @@ -440,6 +441,7 @@ Object { "agent.name": Array [ "java", "opentelemetry/java", + "otlp/java", ], }, }, @@ -522,6 +524,7 @@ Object { "agent.name": Array [ "java", "opentelemetry/java", + "otlp/java", ], }, }, @@ -720,6 +723,7 @@ Object { "agent.name": Array [ "java", "opentelemetry/java", + "otlp/java", ], }, }, @@ -998,6 +1002,7 @@ Object { "agent.name": Array [ "java", "opentelemetry/java", + "otlp/java", ], }, }, @@ -1086,6 +1091,7 @@ Object { "agent.name": Array [ "java", "opentelemetry/java", + "otlp/java", ], }, }, @@ -1262,6 +1268,7 @@ Object { "agent.name": Array [ "java", "opentelemetry/java", + "otlp/java", ], }, }, @@ -1518,6 +1525,7 @@ Object { "agent.name": Array [ "java", "opentelemetry/java", + "otlp/java", ], }, }, @@ -1595,6 +1603,7 @@ Object { "agent.name": Array [ "java", "opentelemetry/java", + "otlp/java", ], }, }, diff --git a/x-pack/plugins/observability_solution/apm/server/routes/services/get_service_metadata_details.ts b/x-pack/plugins/observability_solution/apm/server/routes/services/get_service_metadata_details.ts index d7a81a7902efb..fb44638d8a6b0 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/services/get_service_metadata_details.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/services/get_service_metadata_details.ts @@ -32,7 +32,7 @@ import { ContainerType } from '../../../common/service_metadata'; import { TransactionRaw } from '../../../typings/es_schemas/raw/transaction_raw'; import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; import { should } from './get_service_metadata_icons'; -import { isOpenTelemetryAgentName } from '../../../common/agent_name'; +import { isOpenTelemetryAgentName, hasOpenTelemetryPrefix } from '../../../common/agent_name'; type ServiceMetadataDetailsRaw = Pick< TransactionRaw, @@ -190,11 +190,9 @@ export async function getServiceMetadataDetails({ }; const otelDetails = - !!agent?.name && isOpenTelemetryAgentName(agent.name) + Boolean(agent?.name) && isOpenTelemetryAgentName(agent.name) ? { - language: agent.name.startsWith('opentelemetry') - ? agent.name.replace(/^opentelemetry\//, '') - : undefined, + language: hasOpenTelemetryPrefix(agent.name) ? agent.name.split('/')[1] : undefined, sdkVersion: agent?.version, autoVersion: labels?.telemetry_auto_version as string, } diff --git a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json index a42825ed281f6..be833ff85498f 100644 --- a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json +++ b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @@ -2799,6 +2799,90 @@ "description": "Total number of services utilizing the otlp agent within the last day" } }, + "otlp/cpp": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/cpp agent within the last day" + } + }, + "otlp/dotnet": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/dotnet agent within the last day" + } + }, + "otlp/erlang": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/erlang agent within the last day" + } + }, + "otlp/go": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/go agent within the last day" + } + }, + "otlp/java": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/java agent within the last day" + } + }, + "otlp/nodejs": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/nodejs agent within the last day" + } + }, + "otlp/php": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/php agent within the last day" + } + }, + "otlp/python": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/python agent within the last day" + } + }, + "otlp/ruby": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/ruby agent within the last day" + } + }, + "otlp/rust": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/rust agent within the last day" + } + }, + "otlp/swift": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/swift agent within the last day" + } + }, + "otlp/android": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/android agent within the last day" + } + }, + "otlp/webjs": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the otlp/webjs agent within the last day" + } + }, + "opentelemetry": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the opentelemetry agent within the last day" + } + }, "opentelemetry/cpp": { "type": "long", "_meta": { @@ -2876,6 +2960,12 @@ "_meta": { "description": "Total number of services utilizing the opentelemetry/webjs agent within the last day" } + }, + "ios/swift": { + "type": "long", + "_meta": { + "description": "Total number of services utilizing the ios/swift agent within the last day" + } } } },