From c9596b5bed3f4316302fb5aadcd21b1848eac804 Mon Sep 17 00:00:00 2001 From: Sergi Romeu Date: Fri, 20 Sep 2024 09:07:14 +0200 Subject: [PATCH] [APM UI] Fix OpenTelemetry agent names (#193134) ## Summary Fixes https://github.com/elastic/kibana/issues/180444 This PR fixes the agent names not being able to properly be retrieved by the APM UI, changing the way we map OpenTelemetry agent names. As the format changed from `(opentelemetry|otlp)/{agentName}` to `(opentelemetry|otlp)/{agentName}/{details}`, we now get the second part splitting by `/`. Added mappings for RUM, Android, and iOS OpenTelemetry client, also fixed `get_service_metadata_details` to get the correct OpenTelemetry details. |Before|After| |-|-| |![image](https://github.com/user-attachments/assets/28732018-511b-44e0-ac86-cdbe7ed0d1e0)|![image](https://github.com/user-attachments/assets/45a29cc6-f939-4c52-bcc7-54dc15b1a403)| ## How to test 1. Checkout to this branch 2. Run `node scripts/synthtrace many_otel_services.ts --live --clean` which will fill some APM Otel services. 3. Check that the icon is now rendering (cherry picked from commit 735e216a952670eb57eaea1229be16e89f9bf1cd) # Conflicts: # src/plugins/telemetry/schema/oss_plugins.json --- .../src/scenarios/many_otel_services.ts | 102 ++++++++++++++++++ .../agent_icon/get_agent_icon.test.ts | 10 ++ .../components/agent_icon/get_agent_icon.ts | 17 ++- packages/kbn-elastic-agent-utils/index.ts | 1 + .../src/agent_guards.test.ts | 40 ++++++- .../src/agent_guards.ts | 44 ++++++-- .../src/agent_names.ts | 63 +++++++++-- src/plugins/telemetry/schema/oss_plugins.json | 18 ++++ .../__snapshots__/apm_telemetry.test.ts.snap | 90 ++++++++++++++++ .../apm/common/agent_name.ts | 1 + .../components/shared/service_icons/index.tsx | 4 +- .../shared/service_icons/otel_details.tsx | 1 - .../apm/server/lib/apm_telemetry/schema.ts | 92 ++++++++++++++++ .../__snapshots__/queries.test.ts.snap | 9 ++ .../services/get_service_metadata_details.ts | 8 +- .../schema/xpack_plugins.json | 90 ++++++++++++++++ 16 files changed, 560 insertions(+), 30 deletions(-) create mode 100644 packages/kbn-apm-synthtrace/src/scenarios/many_otel_services.ts 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..70825e7bf4338 --- /dev/null +++ b/packages/kbn-apm-synthtrace/src/scenarios/many_otel_services.ts @@ -0,0 +1,102 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public + * License v3.0 only", 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/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index 52304c13fc7e5..1fb46d6ea5d7c 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -10474,6 +10474,15 @@ } } }, + "observability:logSources": { + "type": "array", + "items": { + "type": "keyword", + "_meta": { + "description": "Non-default value of setting." + } + } + }, "banners:placement": { "type": "keyword", "_meta": { @@ -10749,6 +10758,15 @@ "_meta": { "description": "Non-default value of setting." } + }, + "observability:searchExcludedDataTiers": { + "type": "array", + "items": { + "type": "keyword", + "_meta": { + "description": "Non-default value of setting." + } + } } } }, 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" + } } } },