Skip to content

Commit ede610b

Browse files
[8.19] [APM][OTel] Add EDOT support in the Synthtrace OTel client (elastic#214141) (elastic#219941)
# Backport This will backport the following commits from `main` to `8.19`: - [[APM][OTel] Add EDOT support in the Synthtrace OTel client (elastic#214141)](elastic#214141) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"jennypavlova","email":"[email protected]"},"sourceCommit":{"committedDate":"2025-03-12T15:50:51Z","message":"[APM][OTel] Add EDOT support in the Synthtrace OTel client (elastic#214141)\n\nCloses elastic#212564 \n\n## Summary\n\nThis PR adds EDOT data and scenarios to the OTel synthtrace client. The\nprevious OTel class now lives in `otel_native` folder and the EDOT one\nin `otel_edot`. It updates the otel native service name and the old\ntests and adds a simple test for EDOT.\n⚠️ Currently the edot service doesn't have an error document (on the\n[otel demo env](https://otel.demo.elastic.co) I couldn't find any) so\nthere won't be any errors for the `adservice-edot-synth` - same as in\n[the\ndemo](https://otel.demo.elastic.co/app/apm/services/adservice/errors?comparisonEnabled=true&environment=ENVIRONMENT_ALL&kuery=&latencyAggregationType=avg&offset=1d&rangeFrom=2025-03-12T12:49:15.506Z&rangeTo=2025-03-12T13:04:19.779Z&serviceGroup=&transactionType=request)\n\n## Testing\nRun: \n- ```node scripts/synthtrace otel_edot_simple_trace.ts ```\n- and ```node scripts/synthtrace otel_simple_trace.ts```\n\nGo to APM service inventory\n- Both services should be visible\n \n\n![image](https://github.com/user-attachments/assets/b698cc14-d40a-4925-861f-4da0d9707f48)\n\n- Service overview and other tabs should be visible \n - Otel native case: \n \n\n![image](https://github.com/user-attachments/assets/4c423ff0-2dee-4eb4-b69b-057bad3a4747)\n\n![image](https://github.com/user-attachments/assets/407907bd-212e-486e-bc2a-0e2370f21be5)\n\n - EDOT case\n \n\n![image](https://github.com/user-attachments/assets/3766e1e2-a8d7-45d4-887d-b67533a1b3eb)\n\n![image](https://github.com/user-attachments/assets/aff544fa-72b5-4826-963f-2b4c44d517bb)","sha":"ded1b15b87ec8f4f933596baf2fd96cfda1977d5","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","backport:skip","Team:obs-ux-infra_services","v9.1.0","v8.19.0"],"title":"[APM][OTel] Add EDOT support in the Synthtrace OTel client","number":214141,"url":"https://github.com/elastic/kibana/pull/214141","mergeCommit":{"message":"[APM][OTel] Add EDOT support in the Synthtrace OTel client (elastic#214141)\n\nCloses elastic#212564 \n\n## Summary\n\nThis PR adds EDOT data and scenarios to the OTel synthtrace client. The\nprevious OTel class now lives in `otel_native` folder and the EDOT one\nin `otel_edot`. It updates the otel native service name and the old\ntests and adds a simple test for EDOT.\n⚠️ Currently the edot service doesn't have an error document (on the\n[otel demo env](https://otel.demo.elastic.co) I couldn't find any) so\nthere won't be any errors for the `adservice-edot-synth` - same as in\n[the\ndemo](https://otel.demo.elastic.co/app/apm/services/adservice/errors?comparisonEnabled=true&environment=ENVIRONMENT_ALL&kuery=&latencyAggregationType=avg&offset=1d&rangeFrom=2025-03-12T12:49:15.506Z&rangeTo=2025-03-12T13:04:19.779Z&serviceGroup=&transactionType=request)\n\n## Testing\nRun: \n- ```node scripts/synthtrace otel_edot_simple_trace.ts ```\n- and ```node scripts/synthtrace otel_simple_trace.ts```\n\nGo to APM service inventory\n- Both services should be visible\n \n\n![image](https://github.com/user-attachments/assets/b698cc14-d40a-4925-861f-4da0d9707f48)\n\n- Service overview and other tabs should be visible \n - Otel native case: \n \n\n![image](https://github.com/user-attachments/assets/4c423ff0-2dee-4eb4-b69b-057bad3a4747)\n\n![image](https://github.com/user-attachments/assets/407907bd-212e-486e-bc2a-0e2370f21be5)\n\n - EDOT case\n \n\n![image](https://github.com/user-attachments/assets/3766e1e2-a8d7-45d4-887d-b67533a1b3eb)\n\n![image](https://github.com/user-attachments/assets/aff544fa-72b5-4826-963f-2b4c44d517bb)","sha":"ded1b15b87ec8f4f933596baf2fd96cfda1977d5"}},"sourceBranch":"main","suggestedTargetBranches":["8.19"],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/214141","number":214141,"mergeCommit":{"message":"[APM][OTel] Add EDOT support in the Synthtrace OTel client (elastic#214141)\n\nCloses elastic#212564 \n\n## Summary\n\nThis PR adds EDOT data and scenarios to the OTel synthtrace client. The\nprevious OTel class now lives in `otel_native` folder and the EDOT one\nin `otel_edot`. It updates the otel native service name and the old\ntests and adds a simple test for EDOT.\n⚠️ Currently the edot service doesn't have an error document (on the\n[otel demo env](https://otel.demo.elastic.co) I couldn't find any) so\nthere won't be any errors for the `adservice-edot-synth` - same as in\n[the\ndemo](https://otel.demo.elastic.co/app/apm/services/adservice/errors?comparisonEnabled=true&environment=ENVIRONMENT_ALL&kuery=&latencyAggregationType=avg&offset=1d&rangeFrom=2025-03-12T12:49:15.506Z&rangeTo=2025-03-12T13:04:19.779Z&serviceGroup=&transactionType=request)\n\n## Testing\nRun: \n- ```node scripts/synthtrace otel_edot_simple_trace.ts ```\n- and ```node scripts/synthtrace otel_simple_trace.ts```\n\nGo to APM service inventory\n- Both services should be visible\n \n\n![image](https://github.com/user-attachments/assets/b698cc14-d40a-4925-861f-4da0d9707f48)\n\n- Service overview and other tabs should be visible \n - Otel native case: \n \n\n![image](https://github.com/user-attachments/assets/4c423ff0-2dee-4eb4-b69b-057bad3a4747)\n\n![image](https://github.com/user-attachments/assets/407907bd-212e-486e-bc2a-0e2370f21be5)\n\n - EDOT case\n \n\n![image](https://github.com/user-attachments/assets/3766e1e2-a8d7-45d4-887d-b67533a1b3eb)\n\n![image](https://github.com/user-attachments/assets/aff544fa-72b5-4826-963f-2b4c44d517bb)","sha":"ded1b15b87ec8f4f933596baf2fd96cfda1977d5"}},{"branch":"8.x","label":"v8.19.0","branchLabelMappingKey":"^v8.19.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: jennypavlova <[email protected]>
1 parent d78e4a2 commit ede610b

File tree

12 files changed

+663
-29
lines changed

12 files changed

+663
-29
lines changed

src/platform/packages/shared/kbn-apm-synthtrace-client/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,6 @@ export type { ESDocumentWithOperation, SynthtraceESAction, SynthtraceGenerator }
3737
export { log, type LogDocument, LONG_FIELD_NAME } from './src/lib/logs';
3838
export { otelLog, type OtelLogDocument } from './src/lib/otel_logs';
3939
export { syntheticsMonitor, type SyntheticsMonitorDocument } from './src/lib/synthetics';
40+
export { otel, type OtelDocument } from './src/lib/otel/otel_native';
41+
export { otelEdot, type OtelEdotDocument } from './src/lib/otel/otel_edot';
4042
export { type EntityFields, entities } from './src/lib/entities';
41-
export { otel, type OtelDocument } from './src/lib/otel';
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
import { Fields } from '../../entity';
11+
import { Serializable } from '../../serializable';
12+
import { OtelEdotMetric } from './metric';
13+
import { OtelEdotTransaction } from './transaction';
14+
15+
interface OtelEdotSharedResourceAttributes {
16+
'service.name'?: string;
17+
'agent.name'?: string;
18+
'agent.version'?: string;
19+
'metricset.interval'?: string;
20+
'service.instance.id'?: string;
21+
'telemetry.sdk.language'?: string;
22+
'telemetry.sdk.name'?: string;
23+
'telemetry.sdk.version'?: string;
24+
}
25+
26+
export interface OtelEdotDocument extends Fields {
27+
data_stream?: {
28+
dataset: string;
29+
namespace: string;
30+
type: string;
31+
};
32+
attributes?: {
33+
'timestamp.us'?: number;
34+
'metricset.name'?: string;
35+
[key: string]: any;
36+
};
37+
resource?: {
38+
attributes?: OtelEdotSharedResourceAttributes;
39+
dropped_attributes_count?: number;
40+
schema_url?: string;
41+
};
42+
scope?: {
43+
attributes?: {
44+
'service.framework.name'?: string;
45+
'service.framework.version'?: string;
46+
};
47+
dropped_attributes_count?: number;
48+
name?: string;
49+
};
50+
name?: string;
51+
trace_id?: string;
52+
trace?: { id: string };
53+
span_id?: string;
54+
span?: { id: string };
55+
dropped_attributes_count?: number;
56+
dropped_events_count?: number;
57+
dropped_links_count?: number;
58+
timestamp_us?: number;
59+
}
60+
61+
class OtelEdot extends Serializable<OtelEdotDocument> {
62+
constructor(fields: OtelEdotDocument) {
63+
super({
64+
...fields,
65+
});
66+
}
67+
68+
metric() {
69+
return new OtelEdotMetric({
70+
...this.fields,
71+
attributes: {
72+
'service.name': 'adservice-edot-synth',
73+
'span.kind': 'SPAN_KIND_INTERNAL',
74+
'span.name': 'SynchronizationContext#drain',
75+
'status.code': 'STATUS_CODE_UNSET',
76+
'metricset.name': 'service_summary',
77+
'processor.event': 'metric',
78+
},
79+
data_stream: {
80+
dataset: 'generic.otel',
81+
namespace: 'default',
82+
type: 'metrics',
83+
},
84+
metrics: {
85+
'traces.span.metrics.calls': 1,
86+
},
87+
resource: {
88+
attributes: {
89+
'agent.name': 'opentelemetry/java/elastic',
90+
'agent.version': '1.0.1-SNAPSHOT',
91+
'app.label.name': 'otel-demo-blue-adservice-edot-synth',
92+
'cloud.account.id': 'elastic-product',
93+
'cloud.availability_zone': 'us-central1-a',
94+
'cloud.platform': 'gcp_kubernetes_engine',
95+
'cloud.provider': 'gcp',
96+
'container.id': 'e4f5dd426472aacd6124e85a0cd8a1ef55c263374c16179d1bf75292224c2dc0',
97+
'deployment.environment': 'opentelemetry-demo',
98+
'host.arch': 'amd64',
99+
'host.id': '8645892066193866279',
100+
'host.name': 'gke-demo-elastic-co-pool-5-29a9d3db-t79s',
101+
'k8s.cluster.name': 'demo-elastic-co',
102+
'k8s.deployment.name': 'otel-demo-blue-adservice-edot-synth',
103+
'k8s.namespace.name': 'otel-blue',
104+
'k8s.node.name': 'gke-demo-elastic-co-pool-5-29a9d3db-t79s',
105+
'k8s.pod.ip': '10.12.3.63',
106+
'k8s.pod.name': 'otel-demo-blue-adservice-edot-synth-7c68c8f968-tvf54',
107+
'k8s.pod.start_time': '2025-01-15T12:51:39Z',
108+
'k8s.pod.uid': 'da7a8507-53be-421c-8d77-984f12397213',
109+
'k8s.replicaset.name': 'otel-demo-blue-adservice-edot-synth-7c68c8f968',
110+
'os.description': 'Linux 5.15.109+',
111+
'os.type': 'linux',
112+
'process.command_line':
113+
'/opt/java/openjdk/bin/java -javaagent:/usr/src/app/opentelemetry-javaagent.jar oteldemo.AdServiceEdotSynth',
114+
'process.executable.path': '/opt/java/openjdk/bin/java',
115+
'process.pid': 1,
116+
'process.runtime.description': 'Eclipse Adoptium OpenJDK 64-Bit Server VM 21.0.5+11-LTS',
117+
'process.runtime.name': 'OpenJDK Runtime Environment',
118+
'process.runtime.version': '21.0.5+11-LTS',
119+
'service.instance.id': 'da7a8507-53be-421c-8d77-984f12397213',
120+
'service.name': 'adservice-edot-synth',
121+
'service.namespace': 'opentelemetry-demo',
122+
'telemetry.distro.name': 'elastic',
123+
'telemetry.distro.version': '1.0.1-SNAPSHOT',
124+
'telemetry.sdk.language': 'java',
125+
'telemetry.sdk.name': 'opentelemetry',
126+
'telemetry.sdk.version': '1.43.0',
127+
},
128+
},
129+
scope: {
130+
dropped_attributes_count: 0,
131+
name: 'spanmetricsconnector',
132+
},
133+
});
134+
}
135+
136+
transaction(id: string) {
137+
return new OtelEdotTransaction({
138+
...this.fields,
139+
attributes: {
140+
'app.ads.ad_request_type': 'TARGETED',
141+
'app.ads.ad_response_type': 'TARGETED',
142+
'app.ads.contextKeys': '[travel]',
143+
'app.ads.contextKeys.count': 1,
144+
'app.ads.count': 1,
145+
'event.outcome': 'success',
146+
'event.success_count': 1,
147+
'network.peer.address': '10.12.9.56',
148+
'network.peer.port': 41208,
149+
'network.type': 'ipv4',
150+
'processor.event': 'transaction',
151+
'rpc.grpc.status_code': 0,
152+
'rpc.method': 'GetAds',
153+
'rpc.service': 'oteldemo.AdServiceEdotSynth',
154+
'rpc.system': 'grpc',
155+
'server.address': 'otel-demo-blue-adservice-edot-synth',
156+
'server.port': 8080,
157+
'session.id': 'ce3ed7c7-47d7-42a5-baae-86d0a716752d',
158+
'thread.id': 9412,
159+
'thread.name': 'grpc-default-executor-23',
160+
'timestamp.us': 1740679709260508,
161+
'transaction.duration.us': 551,
162+
'transaction.id': id,
163+
'transaction.name': 'oteldemo.AdServiceEdotSynth/GetAds',
164+
'transaction.representative_count': 1,
165+
'transaction.result': 'OK',
166+
'transaction.root': false,
167+
'transaction.sampled': true,
168+
'transaction.type': 'request',
169+
},
170+
data_stream: {
171+
dataset: 'generic.otel',
172+
namespace: 'default',
173+
type: 'traces',
174+
},
175+
duration: 551551,
176+
kind: 'Server',
177+
name: 'oteldemo.AdServiceEdotSynth/GetAds',
178+
// parent_span_id: 'b8fc0a55e4ae6b53',
179+
resource: {
180+
attributes: {
181+
'agent.name': 'opentelemetry/java/elastic',
182+
'agent.version': '1.0.1-SNAPSHOT',
183+
'app.label.name': 'otel-demo-blue-adservice-edot-synth',
184+
'cloud.account.id': 'elastic-product',
185+
'cloud.availability_zone': 'us-central1-a',
186+
'cloud.platform': 'gcp_kubernetes_engine',
187+
'cloud.provider': 'gcp',
188+
'container.id': 'e4f5dd426472aacd6124e85a0cd8a1ef55c263374c16179d1bf75292224c2dc0',
189+
'deployment.environment': 'opentelemetry-demo',
190+
'host.arch': 'amd64',
191+
'host.id': '8645892066193866279',
192+
'host.name': 'gke-demo-elastic-co-pool-5-29a9d3db-t79s',
193+
'k8s.cluster.name': 'demo-elastic-co',
194+
'k8s.deployment.name': 'otel-demo-blue-adservice-edot-synth',
195+
'k8s.namespace.name': 'otel-blue',
196+
'k8s.node.name': 'gke-demo-elastic-co-pool-5-29a9d3db-t79s',
197+
'k8s.pod.ip': '10.12.3.63',
198+
'k8s.pod.name': 'otel-demo-blue-adservice-edot-synth-7c68c8f968-tvf54',
199+
'k8s.pod.start_time': '2025-01-15T12:51:39Z',
200+
'k8s.pod.uid': 'da7a8507-53be-421c-8d77-984f12397213',
201+
'k8s.replicaset.name': 'otel-demo-blue-adservice-edot-synth-7c68c8f968',
202+
'os.description': 'Linux 5.15.109+',
203+
'os.type': 'linux',
204+
'process.command_line':
205+
'/opt/java/openjdk/bin/java -javaagent:/usr/src/app/opentelemetry-javaagent.jar oteldemo.AdServiceEdotSynth',
206+
'process.executable.path': '/opt/java/openjdk/bin/java',
207+
'process.pid': 1,
208+
'process.runtime.description': 'Eclipse Adoptium OpenJDK 64-Bit Server VM 21.0.5+11-LTS',
209+
'process.runtime.name': 'OpenJDK Runtime Environment',
210+
'process.runtime.version': '21.0.5+11-LTS',
211+
'service.instance.id': 'da7a8507-53be-421c-8d77-984f12397213',
212+
'service.name': 'adservice-edot-synth',
213+
'service.namespace': 'opentelemetry-demo',
214+
'telemetry.distro.name': 'elastic',
215+
'telemetry.distro.version': '1.0.1-SNAPSHOT',
216+
'telemetry.sdk.language': 'java',
217+
'telemetry.sdk.name': 'opentelemetry',
218+
'telemetry.sdk.version': '1.43.0',
219+
},
220+
// schema_url: 'https://opentelemetry.io/schemas/1.24.0',
221+
},
222+
scope: {
223+
attributes: {
224+
'service.framework.name': 'io.opentelemetry.grpc-1.6',
225+
'service.framework.version': '2.9.0-alpha',
226+
},
227+
dropped_attributes_count: 0,
228+
name: 'io.opentelemetry.grpc-1.6',
229+
// version: '2.9.0-alpha',
230+
},
231+
span_id: '8884909eca61b9d5',
232+
status: {
233+
code: 'Unset',
234+
},
235+
trace_id: '70219abfdc4f0e17ca0975a339c2c135',
236+
});
237+
}
238+
}
239+
240+
export function create(id: string): OtelEdot {
241+
return new OtelEdot({
242+
trace_id: id,
243+
dropped_attributes_count: 0,
244+
dropped_events_count: 0,
245+
dropped_links_count: 0,
246+
});
247+
}
248+
249+
export const otelEdot = {
250+
create,
251+
};
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
import { OtelEdotDocument } from '.';
11+
import { Serializable } from '../../serializable';
12+
13+
export interface OtelEdotMetricDocument extends OtelEdotDocument {
14+
attributes?: {
15+
'metricset.name'?: string;
16+
'processor.event'?: string;
17+
'event.outcome'?: string;
18+
'service.name'?: string;
19+
'span.name'?: string;
20+
'span.kind'?: string;
21+
'status.code'?: string;
22+
'span.destination.service.resource'?: string;
23+
};
24+
metrics?: {
25+
service_summary?: number;
26+
'traces.span.metrics.calls'?: number;
27+
};
28+
resource?: {
29+
attributes?: {
30+
'agent.name'?: string;
31+
'agent.version'?: string;
32+
'app.label.name'?: string;
33+
'cloud.account.id'?: string;
34+
'cloud.availability_zone'?: string;
35+
'cloud.platform'?: string;
36+
'cloud.provider'?: string;
37+
'container.id'?: string;
38+
'deployment.environment'?: string;
39+
'host.arch'?: string;
40+
'host.id'?: string;
41+
'host.name'?: string;
42+
'k8s.cluster.name'?: string;
43+
'k8s.deployment.name'?: string;
44+
'k8s.namespace.name'?: string;
45+
'k8s.node.name'?: string;
46+
'k8s.pod.ip'?: string;
47+
'k8s.pod.name'?: string;
48+
'k8s.pod.uid'?: string;
49+
'k8s.replicaset.name'?: string;
50+
'k8s.pod.start_time'?: string;
51+
'os.description'?: string;
52+
'os.type'?: string;
53+
'process.command_args'?: string;
54+
'process.command_line'?: string;
55+
'process.executable.path'?: string;
56+
'process.pid'?: number;
57+
'process.runtime.description'?: string;
58+
'process.runtime.name'?: string;
59+
'process.runtime.version'?: string;
60+
'service.instance.id'?: string;
61+
'service.name'?: string;
62+
'service.namespace'?: string;
63+
'telemetry.distro.name'?: string;
64+
'telemetry.distro.version'?: string;
65+
'telemetry.sdk.language'?: string;
66+
'telemetry.sdk.name'?: string;
67+
'telemetry.sdk.version'?: string;
68+
};
69+
};
70+
}
71+
export class OtelEdotMetric extends Serializable<OtelEdotMetricDocument> {
72+
constructor(fields: OtelEdotMetricDocument) {
73+
super({
74+
...fields,
75+
});
76+
}
77+
}

0 commit comments

Comments
 (0)