mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[APM][OTel] Add EDOT support in the Synthtrace OTel client (#214141)
Closes #212564 ## Summary This PR adds EDOT data and scenarios to the OTel synthtrace client. The previous OTel class now lives in `otel_native` folder and the EDOT one in `otel_edot`. It updates the otel native service name and the old tests and adds a simple test for EDOT. ⚠️ Currently the edot service doesn't have an error document (on the [otel demo env](https://otel.demo.elastic.co) I couldn't find any) so there won't be any errors for the `adservice-edot-synth` - same as in [the demo](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) ## Testing Run: - ```node scripts/synthtrace otel_edot_simple_trace.ts ``` - and ```node scripts/synthtrace otel_simple_trace.ts``` Go to APM service inventory - Both services should be visible  - Service overview and other tabs should be visible - Otel native case:   - EDOT case  
This commit is contained in:
parent
ad3b7fce11
commit
ded1b15b87
12 changed files with 664 additions and 30 deletions
|
@ -36,5 +36,6 @@ export { appendHash, hashKeysOf } from './src/lib/utils/hash';
|
|||
export type { ESDocumentWithOperation, SynthtraceESAction, SynthtraceGenerator } from './src/types';
|
||||
export { log, type LogDocument, LONG_FIELD_NAME } from './src/lib/logs';
|
||||
export { syntheticsMonitor, type SyntheticsMonitorDocument } from './src/lib/synthetics';
|
||||
export { otel, type OtelDocument } from './src/lib/otel';
|
||||
export { otel, type OtelDocument } from './src/lib/otel/otel_native';
|
||||
export { otelEdot, type OtelEdotDocument } from './src/lib/otel/otel_edot';
|
||||
export { type EntityFields, entities } from './src/lib/entities';
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* 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 { Fields } from '../../entity';
|
||||
import { Serializable } from '../../serializable';
|
||||
import { OtelEdotMetric } from './metric';
|
||||
import { OtelEdotTransaction } from './transaction';
|
||||
|
||||
interface OtelEdotSharedResourceAttributes {
|
||||
'service.name'?: string;
|
||||
'agent.name'?: string;
|
||||
'agent.version'?: string;
|
||||
'metricset.interval'?: string;
|
||||
'service.instance.id'?: string;
|
||||
'telemetry.sdk.language'?: string;
|
||||
'telemetry.sdk.name'?: string;
|
||||
'telemetry.sdk.version'?: string;
|
||||
}
|
||||
|
||||
export interface OtelEdotDocument extends Fields {
|
||||
data_stream?: {
|
||||
dataset: string;
|
||||
namespace: string;
|
||||
type: string;
|
||||
};
|
||||
attributes?: {
|
||||
'timestamp.us'?: number;
|
||||
'metricset.name'?: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
resource?: {
|
||||
attributes?: OtelEdotSharedResourceAttributes;
|
||||
dropped_attributes_count?: number;
|
||||
schema_url?: string;
|
||||
};
|
||||
scope?: {
|
||||
attributes?: {
|
||||
'service.framework.name'?: string;
|
||||
'service.framework.version'?: string;
|
||||
};
|
||||
dropped_attributes_count?: number;
|
||||
name?: string;
|
||||
};
|
||||
name?: string;
|
||||
trace_id?: string;
|
||||
trace?: { id: string };
|
||||
span_id?: string;
|
||||
span?: { id: string };
|
||||
dropped_attributes_count?: number;
|
||||
dropped_events_count?: number;
|
||||
dropped_links_count?: number;
|
||||
timestamp_us?: number;
|
||||
}
|
||||
|
||||
class OtelEdot extends Serializable<OtelEdotDocument> {
|
||||
constructor(fields: OtelEdotDocument) {
|
||||
super({
|
||||
...fields,
|
||||
});
|
||||
}
|
||||
|
||||
metric() {
|
||||
return new OtelEdotMetric({
|
||||
...this.fields,
|
||||
attributes: {
|
||||
'service.name': 'adservice-edot-synth',
|
||||
'span.kind': 'SPAN_KIND_INTERNAL',
|
||||
'span.name': 'SynchronizationContext#drain',
|
||||
'status.code': 'STATUS_CODE_UNSET',
|
||||
'metricset.name': 'service_summary',
|
||||
'processor.event': 'metric',
|
||||
},
|
||||
data_stream: {
|
||||
dataset: 'generic.otel',
|
||||
namespace: 'default',
|
||||
type: 'metrics',
|
||||
},
|
||||
metrics: {
|
||||
'traces.span.metrics.calls': 1,
|
||||
},
|
||||
resource: {
|
||||
attributes: {
|
||||
'agent.name': 'opentelemetry/java/elastic',
|
||||
'agent.version': '1.0.1-SNAPSHOT',
|
||||
'app.label.name': 'otel-demo-blue-adservice-edot-synth',
|
||||
'cloud.account.id': 'elastic-product',
|
||||
'cloud.availability_zone': 'us-central1-a',
|
||||
'cloud.platform': 'gcp_kubernetes_engine',
|
||||
'cloud.provider': 'gcp',
|
||||
'container.id': 'e4f5dd426472aacd6124e85a0cd8a1ef55c263374c16179d1bf75292224c2dc0',
|
||||
'deployment.environment': 'opentelemetry-demo',
|
||||
'host.arch': 'amd64',
|
||||
'host.id': '8645892066193866279',
|
||||
'host.name': 'gke-demo-elastic-co-pool-5-29a9d3db-t79s',
|
||||
'k8s.cluster.name': 'demo-elastic-co',
|
||||
'k8s.deployment.name': 'otel-demo-blue-adservice-edot-synth',
|
||||
'k8s.namespace.name': 'otel-blue',
|
||||
'k8s.node.name': 'gke-demo-elastic-co-pool-5-29a9d3db-t79s',
|
||||
'k8s.pod.ip': '10.12.3.63',
|
||||
'k8s.pod.name': 'otel-demo-blue-adservice-edot-synth-7c68c8f968-tvf54',
|
||||
'k8s.pod.start_time': '2025-01-15T12:51:39Z',
|
||||
'k8s.pod.uid': 'da7a8507-53be-421c-8d77-984f12397213',
|
||||
'k8s.replicaset.name': 'otel-demo-blue-adservice-edot-synth-7c68c8f968',
|
||||
'os.description': 'Linux 5.15.109+',
|
||||
'os.type': 'linux',
|
||||
'process.command_line':
|
||||
'/opt/java/openjdk/bin/java -javaagent:/usr/src/app/opentelemetry-javaagent.jar oteldemo.AdServiceEdotSynth',
|
||||
'process.executable.path': '/opt/java/openjdk/bin/java',
|
||||
'process.pid': 1,
|
||||
'process.runtime.description': 'Eclipse Adoptium OpenJDK 64-Bit Server VM 21.0.5+11-LTS',
|
||||
'process.runtime.name': 'OpenJDK Runtime Environment',
|
||||
'process.runtime.version': '21.0.5+11-LTS',
|
||||
'service.instance.id': 'da7a8507-53be-421c-8d77-984f12397213',
|
||||
'service.name': 'adservice-edot-synth',
|
||||
'service.namespace': 'opentelemetry-demo',
|
||||
'telemetry.distro.name': 'elastic',
|
||||
'telemetry.distro.version': '1.0.1-SNAPSHOT',
|
||||
'telemetry.sdk.language': 'java',
|
||||
'telemetry.sdk.name': 'opentelemetry',
|
||||
'telemetry.sdk.version': '1.43.0',
|
||||
},
|
||||
},
|
||||
scope: {
|
||||
dropped_attributes_count: 0,
|
||||
name: 'spanmetricsconnector',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
transaction(id: string) {
|
||||
return new OtelEdotTransaction({
|
||||
...this.fields,
|
||||
attributes: {
|
||||
'app.ads.ad_request_type': 'TARGETED',
|
||||
'app.ads.ad_response_type': 'TARGETED',
|
||||
'app.ads.contextKeys': '[travel]',
|
||||
'app.ads.contextKeys.count': 1,
|
||||
'app.ads.count': 1,
|
||||
'event.outcome': 'success',
|
||||
'event.success_count': 1,
|
||||
'network.peer.address': '10.12.9.56',
|
||||
'network.peer.port': 41208,
|
||||
'network.type': 'ipv4',
|
||||
'processor.event': 'transaction',
|
||||
'rpc.grpc.status_code': 0,
|
||||
'rpc.method': 'GetAds',
|
||||
'rpc.service': 'oteldemo.AdServiceEdotSynth',
|
||||
'rpc.system': 'grpc',
|
||||
'server.address': 'otel-demo-blue-adservice-edot-synth',
|
||||
'server.port': 8080,
|
||||
'session.id': 'ce3ed7c7-47d7-42a5-baae-86d0a716752d',
|
||||
'thread.id': 9412,
|
||||
'thread.name': 'grpc-default-executor-23',
|
||||
'timestamp.us': 1740679709260508,
|
||||
'transaction.duration.us': 551,
|
||||
'transaction.id': id,
|
||||
'transaction.name': 'oteldemo.AdServiceEdotSynth/GetAds',
|
||||
'transaction.representative_count': 1,
|
||||
'transaction.result': 'OK',
|
||||
'transaction.root': false,
|
||||
'transaction.sampled': true,
|
||||
'transaction.type': 'request',
|
||||
},
|
||||
data_stream: {
|
||||
dataset: 'generic.otel',
|
||||
namespace: 'default',
|
||||
type: 'traces',
|
||||
},
|
||||
duration: 551551,
|
||||
kind: 'Server',
|
||||
name: 'oteldemo.AdServiceEdotSynth/GetAds',
|
||||
// parent_span_id: 'b8fc0a55e4ae6b53',
|
||||
resource: {
|
||||
attributes: {
|
||||
'agent.name': 'opentelemetry/java/elastic',
|
||||
'agent.version': '1.0.1-SNAPSHOT',
|
||||
'app.label.name': 'otel-demo-blue-adservice-edot-synth',
|
||||
'cloud.account.id': 'elastic-product',
|
||||
'cloud.availability_zone': 'us-central1-a',
|
||||
'cloud.platform': 'gcp_kubernetes_engine',
|
||||
'cloud.provider': 'gcp',
|
||||
'container.id': 'e4f5dd426472aacd6124e85a0cd8a1ef55c263374c16179d1bf75292224c2dc0',
|
||||
'deployment.environment': 'opentelemetry-demo',
|
||||
'host.arch': 'amd64',
|
||||
'host.id': '8645892066193866279',
|
||||
'host.name': 'gke-demo-elastic-co-pool-5-29a9d3db-t79s',
|
||||
'k8s.cluster.name': 'demo-elastic-co',
|
||||
'k8s.deployment.name': 'otel-demo-blue-adservice-edot-synth',
|
||||
'k8s.namespace.name': 'otel-blue',
|
||||
'k8s.node.name': 'gke-demo-elastic-co-pool-5-29a9d3db-t79s',
|
||||
'k8s.pod.ip': '10.12.3.63',
|
||||
'k8s.pod.name': 'otel-demo-blue-adservice-edot-synth-7c68c8f968-tvf54',
|
||||
'k8s.pod.start_time': '2025-01-15T12:51:39Z',
|
||||
'k8s.pod.uid': 'da7a8507-53be-421c-8d77-984f12397213',
|
||||
'k8s.replicaset.name': 'otel-demo-blue-adservice-edot-synth-7c68c8f968',
|
||||
'os.description': 'Linux 5.15.109+',
|
||||
'os.type': 'linux',
|
||||
'process.command_line':
|
||||
'/opt/java/openjdk/bin/java -javaagent:/usr/src/app/opentelemetry-javaagent.jar oteldemo.AdServiceEdotSynth',
|
||||
'process.executable.path': '/opt/java/openjdk/bin/java',
|
||||
'process.pid': 1,
|
||||
'process.runtime.description': 'Eclipse Adoptium OpenJDK 64-Bit Server VM 21.0.5+11-LTS',
|
||||
'process.runtime.name': 'OpenJDK Runtime Environment',
|
||||
'process.runtime.version': '21.0.5+11-LTS',
|
||||
'service.instance.id': 'da7a8507-53be-421c-8d77-984f12397213',
|
||||
'service.name': 'adservice-edot-synth',
|
||||
'service.namespace': 'opentelemetry-demo',
|
||||
'telemetry.distro.name': 'elastic',
|
||||
'telemetry.distro.version': '1.0.1-SNAPSHOT',
|
||||
'telemetry.sdk.language': 'java',
|
||||
'telemetry.sdk.name': 'opentelemetry',
|
||||
'telemetry.sdk.version': '1.43.0',
|
||||
},
|
||||
// schema_url: 'https://opentelemetry.io/schemas/1.24.0',
|
||||
},
|
||||
scope: {
|
||||
attributes: {
|
||||
'service.framework.name': 'io.opentelemetry.grpc-1.6',
|
||||
'service.framework.version': '2.9.0-alpha',
|
||||
},
|
||||
dropped_attributes_count: 0,
|
||||
name: 'io.opentelemetry.grpc-1.6',
|
||||
// version: '2.9.0-alpha',
|
||||
},
|
||||
span_id: '8884909eca61b9d5',
|
||||
status: {
|
||||
code: 'Unset',
|
||||
},
|
||||
trace_id: '70219abfdc4f0e17ca0975a339c2c135',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function create(id: string): OtelEdot {
|
||||
return new OtelEdot({
|
||||
trace_id: id,
|
||||
dropped_attributes_count: 0,
|
||||
dropped_events_count: 0,
|
||||
dropped_links_count: 0,
|
||||
});
|
||||
}
|
||||
|
||||
export const otelEdot = {
|
||||
create,
|
||||
};
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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 { OtelEdotDocument } from '.';
|
||||
import { Serializable } from '../../serializable';
|
||||
|
||||
export interface OtelEdotMetricDocument extends OtelEdotDocument {
|
||||
attributes?: {
|
||||
'metricset.name'?: string;
|
||||
'processor.event'?: string;
|
||||
'event.outcome'?: string;
|
||||
'service.name'?: string;
|
||||
'span.name'?: string;
|
||||
'span.kind'?: string;
|
||||
'status.code'?: string;
|
||||
'span.destination.service.resource'?: string;
|
||||
};
|
||||
metrics?: {
|
||||
service_summary?: number;
|
||||
'traces.span.metrics.calls'?: number;
|
||||
};
|
||||
resource?: {
|
||||
attributes?: {
|
||||
'agent.name'?: string;
|
||||
'agent.version'?: string;
|
||||
'app.label.name'?: string;
|
||||
'cloud.account.id'?: string;
|
||||
'cloud.availability_zone'?: string;
|
||||
'cloud.platform'?: string;
|
||||
'cloud.provider'?: string;
|
||||
'container.id'?: string;
|
||||
'deployment.environment'?: string;
|
||||
'host.arch'?: string;
|
||||
'host.id'?: string;
|
||||
'host.name'?: string;
|
||||
'k8s.cluster.name'?: string;
|
||||
'k8s.deployment.name'?: string;
|
||||
'k8s.namespace.name'?: string;
|
||||
'k8s.node.name'?: string;
|
||||
'k8s.pod.ip'?: string;
|
||||
'k8s.pod.name'?: string;
|
||||
'k8s.pod.uid'?: string;
|
||||
'k8s.replicaset.name'?: string;
|
||||
'k8s.pod.start_time'?: string;
|
||||
'os.description'?: string;
|
||||
'os.type'?: string;
|
||||
'process.command_args'?: string;
|
||||
'process.command_line'?: string;
|
||||
'process.executable.path'?: string;
|
||||
'process.pid'?: number;
|
||||
'process.runtime.description'?: string;
|
||||
'process.runtime.name'?: string;
|
||||
'process.runtime.version'?: string;
|
||||
'service.instance.id'?: string;
|
||||
'service.name'?: string;
|
||||
'service.namespace'?: string;
|
||||
'telemetry.distro.name'?: string;
|
||||
'telemetry.distro.version'?: string;
|
||||
'telemetry.sdk.language'?: string;
|
||||
'telemetry.sdk.name'?: string;
|
||||
'telemetry.sdk.version'?: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
export class OtelEdotMetric extends Serializable<OtelEdotMetricDocument> {
|
||||
constructor(fields: OtelEdotMetricDocument) {
|
||||
super({
|
||||
...fields,
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* 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 { OtelEdotDocument } from '.';
|
||||
import { Serializable } from '../../serializable';
|
||||
|
||||
export interface OtelEdotTransactionDocument extends OtelEdotDocument {
|
||||
attributes?: {
|
||||
'event.outcome'?: string;
|
||||
'event.success_count'?: number;
|
||||
'processor.event'?: string;
|
||||
'timestamp.us'?: number;
|
||||
'transaction.duration.us'?: number;
|
||||
'transaction.id'?: string;
|
||||
'transaction.name'?: string;
|
||||
'transaction.representative_count'?: number;
|
||||
'transaction.result'?: string;
|
||||
'transaction.root'?: boolean;
|
||||
'transaction.sampled'?: boolean;
|
||||
'transaction.type'?: string;
|
||||
'http.response.status_code'?: number;
|
||||
'http.request.method'?: string;
|
||||
'url.full'?: string;
|
||||
'service.name'?: string;
|
||||
'service.namespace'?: string;
|
||||
'service.instance.id'?: string;
|
||||
'service.target.name'?: string;
|
||||
'service.target.type'?: string;
|
||||
'span.name'?: string;
|
||||
'span.destination.service.resource'?: string;
|
||||
'app.ads.ad_request_type'?: string;
|
||||
'app.ads.ad_response_type'?: string;
|
||||
'app.ads.contextKeys'?: string;
|
||||
'app.ads.contextKeys.count'?: number;
|
||||
'app.ads.count'?: number;
|
||||
'network.peer.address'?: string;
|
||||
'network.peer.port'?: number;
|
||||
'network.type'?: string;
|
||||
'rpc.grpc.status_code'?: number;
|
||||
'rpc.method'?: string;
|
||||
'rpc.service'?: string;
|
||||
'rpc.system'?: string;
|
||||
'server.address'?: string;
|
||||
'server.port'?: number;
|
||||
'session.id'?: string;
|
||||
'thread.id'?: number;
|
||||
'thread.name'?: string;
|
||||
};
|
||||
status?: {
|
||||
code?: string;
|
||||
};
|
||||
dropped_events_count?: number;
|
||||
dropped_links_count?: number;
|
||||
duration?: number;
|
||||
kind?: string;
|
||||
name?: string;
|
||||
resource?: {
|
||||
attributes?: {
|
||||
'agent.name'?: string;
|
||||
'agent.version'?: string;
|
||||
'app.label.name'?: string;
|
||||
'cloud.account.id'?: string;
|
||||
'cloud.availability_zone'?: string;
|
||||
'cloud.platform'?: string;
|
||||
'cloud.provider'?: string;
|
||||
'container.id'?: string;
|
||||
'deployment.environment'?: string;
|
||||
'host.arch'?: string;
|
||||
'host.id'?: string;
|
||||
'host.name'?: string;
|
||||
'k8s.cluster.name'?: string;
|
||||
'k8s.deployment.name'?: string;
|
||||
'k8s.namespace.name'?: string;
|
||||
'k8s.node.name'?: string;
|
||||
'k8s.pod.ip'?: string;
|
||||
'k8s.pod.name'?: string;
|
||||
'k8s.pod.uid'?: string;
|
||||
'k8s.pod.start_time'?: string;
|
||||
'k8s.replicaset.name'?: string;
|
||||
'os.description'?: string;
|
||||
'os.type'?: string;
|
||||
'process.command_args'?: string;
|
||||
'process.command_line'?: string;
|
||||
'process.executable.path'?: string;
|
||||
'process.pid'?: number;
|
||||
'process.runtime.description'?: string;
|
||||
'process.runtime.name'?: string;
|
||||
'process.runtime.version'?: string;
|
||||
'service.instance.id'?: string;
|
||||
'service.name'?: string;
|
||||
'service.namespace'?: string;
|
||||
'telemetry.distro.name'?: string;
|
||||
'telemetry.distro.version'?: string;
|
||||
'telemetry.sdk.language'?: string;
|
||||
'telemetry.sdk.name'?: string;
|
||||
'telemetry.sdk.version'?: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export class OtelEdotTransaction extends Serializable<OtelEdotTransactionDocument> {
|
||||
constructor(fields: OtelEdotTransactionDocument) {
|
||||
super({
|
||||
...fields,
|
||||
});
|
||||
}
|
||||
}
|
|
@ -7,8 +7,8 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import type { OtelDocument } from '../../..';
|
||||
import { Serializable } from '../serializable';
|
||||
import type { OtelDocument } from '../../../..';
|
||||
import { Serializable } from '../../serializable';
|
||||
|
||||
export interface OtelErrorDocument extends OtelDocument {
|
||||
'event.name'?: string;
|
|
@ -7,8 +7,8 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import { Fields } from '../entity';
|
||||
import { Serializable } from '../serializable';
|
||||
import type { Fields } from '../../entity';
|
||||
import { Serializable } from '../../serializable';
|
||||
import { OtelError } from './error';
|
||||
import { OtelMetric } from './metric';
|
||||
import { OtelTransaction } from './transaction';
|
||||
|
@ -91,7 +91,7 @@ class Otel extends Serializable<OtelDocument> {
|
|||
attributes: {
|
||||
'agent.name': 'opentelemetry/go',
|
||||
'agent.version': '1.28.0',
|
||||
'service.name': 'sendotlp-synth',
|
||||
'service.name': 'sendotlp-otel-native-synth',
|
||||
'service.instance.id': '89117ac1-0dbf-4488-9e17-4c2c3b76943a',
|
||||
},
|
||||
dropped_attributes_count: 0,
|
||||
|
@ -99,11 +99,11 @@ class Otel extends Serializable<OtelDocument> {
|
|||
},
|
||||
scope: {
|
||||
attributes: {
|
||||
'service.framework.name': 'sendotlp-synth',
|
||||
'service.framework.name': 'sendotlp-otel-native-synth',
|
||||
'service.framework.version': '',
|
||||
},
|
||||
dropped_attributes_count: 0,
|
||||
name: 'sendotlp-synth',
|
||||
name: 'sendotlp-otel-native-synth',
|
||||
},
|
||||
span_id: spanId,
|
||||
});
|
||||
|
@ -116,10 +116,10 @@ class Otel extends Serializable<OtelDocument> {
|
|||
'metricset.name': 'service_destination',
|
||||
'processor.event': 'metric',
|
||||
'event.outcome': 'success',
|
||||
'service.target.name': 'foo_service',
|
||||
'service.target.name': 'foo_service-otel-native-synth',
|
||||
'service.target.type': 'http',
|
||||
'span.name': 'child1',
|
||||
'span.destination.service.resource': 'foo_service:8080',
|
||||
'span.destination.service.resource': 'foo_service-otel-native-synth:8080',
|
||||
},
|
||||
data_stream: {
|
||||
dataset: 'service_destination.10m.otel',
|
||||
|
@ -134,7 +134,7 @@ class Otel extends Serializable<OtelDocument> {
|
|||
'agent.name': 'opentelemetry/nodejs',
|
||||
'agent.version': '1.28.0',
|
||||
'service.instance.id': '89117ac1-0dbf-4488-9e17-4c2c3b76943a',
|
||||
'service.name': 'sendotlp-synth',
|
||||
'service.name': 'sendotlp-otel-native-synth',
|
||||
'metricset.interval': '10m',
|
||||
'telemetry.sdk.name': 'opentelemetry',
|
||||
'telemetry.sdk.language': 'nodejs',
|
||||
|
@ -183,18 +183,18 @@ class Otel extends Serializable<OtelDocument> {
|
|||
'agent.name': 'otlp',
|
||||
'agent.version': '1.28.0',
|
||||
'service.instance.id': '89117ac1-0dbf-4488-9e17-4c2c3b76943a',
|
||||
'service.name': 'sendotlp-synth',
|
||||
'service.name': 'sendotlp-otel-native-synth',
|
||||
},
|
||||
dropped_attributes_count: 0,
|
||||
schema_url: 'https://opentelemetry.io/schemas/1.26.0',
|
||||
},
|
||||
scope: {
|
||||
attributes: {
|
||||
'service.framework.name': 'sendotlp-synth',
|
||||
'service.framework.name': 'sendotlp-otel-native-synth',
|
||||
'service.framework.version': '',
|
||||
},
|
||||
dropped_attributes_count: 0,
|
||||
name: 'sendotlp-synth',
|
||||
name: 'sendotlp-otel-native-synth',
|
||||
},
|
||||
span_id: id,
|
||||
status: {
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import { OtelDocument } from '.';
|
||||
import { Serializable } from '../serializable';
|
||||
import { Serializable } from '../../serializable';
|
||||
|
||||
export interface OtelMetricDocument extends OtelDocument {
|
||||
attributes?: {
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import { OtelDocument } from '.';
|
||||
import { Serializable } from '../serializable';
|
||||
import { Serializable } from '../../serializable';
|
||||
|
||||
export interface OtelTransactionDocument extends OtelDocument {
|
||||
attributes?: {
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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 { generateShortId, OtelEdotDocument, otelEdot } from '@kbn/apm-synthtrace-client';
|
||||
import { times } from 'lodash';
|
||||
import { Scenario } from '../cli/scenario';
|
||||
import { withClient } from '../lib/utils/with_client';
|
||||
|
||||
const scenario: Scenario<OtelEdotDocument> = async (runOptions) => {
|
||||
return {
|
||||
generate: ({ range, clients: { otelEsClient } }) => {
|
||||
const { numOtelTraces = 5 } = runOptions.scenarioOpts || {};
|
||||
const { logger } = runOptions;
|
||||
const traceId = generateShortId();
|
||||
const spanId = generateShortId();
|
||||
|
||||
const otelEdotDocs = times(numOtelTraces / 2).map((index) => otelEdot.create(traceId));
|
||||
|
||||
const otelWithMetricsAndErrors = range
|
||||
.interval('30s')
|
||||
.rate(1)
|
||||
.generator((timestamp) =>
|
||||
otelEdotDocs.flatMap((otelEdotd) => {
|
||||
return [
|
||||
otelEdotd.metric().timestamp(timestamp),
|
||||
otelEdotd.transaction(spanId).timestamp(timestamp),
|
||||
];
|
||||
})
|
||||
);
|
||||
|
||||
return [
|
||||
withClient(
|
||||
otelEsClient,
|
||||
logger.perf('generating_otel_trace', () => otelWithMetricsAndErrors)
|
||||
),
|
||||
];
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export default scenario;
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* 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 url from 'url';
|
||||
import { synthtraceOtel } from '../../../synthtrace';
|
||||
import { adserviceEdot } from '../../fixtures/synthtrace/adservice_edot';
|
||||
import { checkA11y } from '../../support/commands';
|
||||
|
||||
const start = '2021-10-10T00:00:00.000Z';
|
||||
const end = '2021-10-10T00:15:00.000Z';
|
||||
const serviceInstanceId = 'da7a8507-53be-421c-8d77-984f12397213';
|
||||
|
||||
const serviceOverviewPath = '/app/apm/services/adservice-edot-synth/overview';
|
||||
const baseUrl = url.format({
|
||||
pathname: serviceOverviewPath,
|
||||
query: { rangeFrom: start, rangeTo: end },
|
||||
});
|
||||
|
||||
describe('Service Overview', () => {
|
||||
before(() => {
|
||||
synthtraceOtel.index(
|
||||
adserviceEdot({
|
||||
from: new Date(start).getTime(),
|
||||
to: new Date(end).getTime(),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
synthtraceOtel.clean();
|
||||
});
|
||||
|
||||
describe('renders', () => {
|
||||
beforeEach(() => {
|
||||
cy.loginAsViewerUser();
|
||||
cy.visitKibana(baseUrl);
|
||||
});
|
||||
|
||||
it('renders all components on the page', () => {
|
||||
cy.contains('adservice-edot-synth');
|
||||
// set skipFailures to true to not fail the test when there are accessibility failures
|
||||
checkA11y({ skipFailures: true });
|
||||
cy.getByTestSubj('latencyChart');
|
||||
cy.getByTestSubj('throughput');
|
||||
cy.getByTestSubj('transactionsGroupTable');
|
||||
cy.getByTestSubj('serviceOverviewErrorsTable');
|
||||
cy.getByTestSubj('dependenciesTable');
|
||||
cy.getByTestSubj('instancesLatencyDistribution');
|
||||
cy.getByTestSubj('serviceOverviewInstancesTable');
|
||||
});
|
||||
});
|
||||
|
||||
describe('service icons', () => {
|
||||
beforeEach(() => {
|
||||
cy.loginAsViewerUser();
|
||||
});
|
||||
|
||||
it('show information on click', () => {
|
||||
cy.intercept('GET', '/internal/apm/services/adservice-edot-synth/metadata/details?*').as(
|
||||
'metadataDetailsRequest'
|
||||
);
|
||||
|
||||
cy.visitKibana(baseUrl);
|
||||
|
||||
cy.getByTestSubj('opentelemetry').click();
|
||||
cy.wait('@metadataDetailsRequest');
|
||||
cy.contains('dt', 'Language');
|
||||
cy.contains('dd', 'java');
|
||||
});
|
||||
});
|
||||
|
||||
describe('instances table', () => {
|
||||
beforeEach(() => {
|
||||
cy.loginAsViewerUser();
|
||||
});
|
||||
|
||||
it('has data in the table', () => {
|
||||
cy.visitKibana(baseUrl);
|
||||
cy.contains('adservice-edot-synth');
|
||||
cy.getByTestSubj('serviceInstancesTableContainer');
|
||||
cy.contains(serviceInstanceId);
|
||||
});
|
||||
});
|
||||
|
||||
describe('transactions', () => {
|
||||
beforeEach(() => {
|
||||
cy.loginAsViewerUser();
|
||||
});
|
||||
|
||||
it('navigates to transaction detail page', () => {
|
||||
cy.visitKibana(baseUrl);
|
||||
cy.contains('Transactions').click();
|
||||
|
||||
cy.contains('a', 'oteldemo.AdServiceEdotSynth/GetAds').click();
|
||||
cy.contains('h5', 'oteldemo.AdServiceEdotSynth/GetAds');
|
||||
});
|
||||
});
|
||||
|
||||
describe('errors', () => {
|
||||
beforeEach(() => {
|
||||
cy.loginAsViewerUser();
|
||||
cy.visitKibana(baseUrl);
|
||||
});
|
||||
|
||||
it('navigates to the errors page', () => {
|
||||
cy.contains('adservice-edot-synth');
|
||||
cy.contains('a', 'View errors').click();
|
||||
cy.url().should('include', '/adservice-edot-synth/errors');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -14,13 +14,13 @@ const start = '2021-10-10T00:00:00.000Z';
|
|||
const end = '2021-10-10T00:15:00.000Z';
|
||||
const serviceInstanceId = '89117ac1-0dbf-4488-9e17-4c2c3b76943a';
|
||||
|
||||
const serviceOverviewPath = '/app/apm/services/sendotlp-synth/overview';
|
||||
const serviceOverviewPath = '/app/apm/services/sendotlp-otel-native-synth/overview';
|
||||
const baseUrl = url.format({
|
||||
pathname: serviceOverviewPath,
|
||||
query: { rangeFrom: start, rangeTo: end },
|
||||
});
|
||||
|
||||
const transactionTabPath = '/app/apm/services/sendotlp-synth/transactions/view';
|
||||
const transactionTabPath = '/app/apm/services/sendotlp-otel-native-synth/transactions/view';
|
||||
const transactionUrl = url.format({
|
||||
pathname: transactionTabPath,
|
||||
query: { rangeFrom: start, rangeTo: end, transactionName: 'parent-synth' },
|
||||
|
@ -47,7 +47,7 @@ describe('Service Overview', () => {
|
|||
});
|
||||
|
||||
it('renders all components on the page', () => {
|
||||
cy.contains('sendotlp-synth');
|
||||
cy.contains('sendotlp-otel-native-synth');
|
||||
// set skipFailures to true to not fail the test when there are accessibility failures
|
||||
checkA11y({ skipFailures: true });
|
||||
cy.getByTestSubj('latencyChart');
|
||||
|
@ -66,16 +66,17 @@ describe('Service Overview', () => {
|
|||
});
|
||||
|
||||
it('show information on click', () => {
|
||||
cy.intercept('GET', '/internal/apm/services/sendotlp-synth/metadata/details?*').as(
|
||||
'metadataDetailsRequest'
|
||||
);
|
||||
cy.intercept(
|
||||
'GET',
|
||||
'/internal/apm/services/sendotlp-otel-native-synth/metadata/details?*'
|
||||
).as('metadataDetailsRequest');
|
||||
|
||||
cy.visitKibana(baseUrl);
|
||||
|
||||
cy.getByTestSubj('service').click();
|
||||
cy.wait('@metadataDetailsRequest');
|
||||
cy.contains('dt', 'Framework name');
|
||||
cy.contains('dd', 'sendotlp-synth');
|
||||
cy.contains('dd', 'sendotlp-otel-native-synth');
|
||||
|
||||
cy.getByTestSubj('opentelemetry').click();
|
||||
cy.contains('dt', 'Language');
|
||||
|
@ -90,7 +91,7 @@ describe('Service Overview', () => {
|
|||
|
||||
it('has data in the table', () => {
|
||||
cy.visitKibana(baseUrl);
|
||||
cy.contains('sendotlp-synth');
|
||||
cy.contains('sendotlp-otel-native-synth');
|
||||
cy.getByTestSubj('serviceInstancesTableContainer');
|
||||
cy.contains(serviceInstanceId);
|
||||
});
|
||||
|
@ -102,9 +103,10 @@ describe('Service Overview', () => {
|
|||
});
|
||||
|
||||
it('persists transaction type selected when clicking on Transactions tab', () => {
|
||||
cy.intercept('GET', '/internal/apm/services/sendotlp-synth/transaction_types?*').as(
|
||||
'transactionTypesRequest'
|
||||
);
|
||||
cy.intercept(
|
||||
'GET',
|
||||
'/internal/apm/services/sendotlp-otel-native-synth/transaction_types?*'
|
||||
).as('transactionTypesRequest');
|
||||
|
||||
cy.visitKibana(baseUrl);
|
||||
|
||||
|
@ -138,14 +140,14 @@ describe('Service Overview', () => {
|
|||
cy.visitKibana(baseUrl);
|
||||
});
|
||||
it('errors table is populated', () => {
|
||||
cy.contains('sendotlp-synth');
|
||||
cy.contains('sendotlp-otel-native-synth');
|
||||
cy.contains('*errors.errorString');
|
||||
});
|
||||
|
||||
it('navigates to the errors page', () => {
|
||||
cy.contains('sendotlp-synth');
|
||||
cy.contains('sendotlp-otel-native-synth');
|
||||
cy.contains('a', 'View errors').click();
|
||||
cy.url().should('include', '/sendotlp-synth/errors');
|
||||
cy.url().should('include', '/sendotlp-otel-native-synth/errors');
|
||||
});
|
||||
|
||||
it('navigates to error detail page', () => {
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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 { generateShortId, otelEdot, timerange } from '@kbn/apm-synthtrace-client';
|
||||
import { times } from 'lodash';
|
||||
|
||||
export function adserviceEdot({ from, to }: { from: number; to: number }) {
|
||||
const range = timerange(from, to);
|
||||
const traceId = generateShortId();
|
||||
const spanId = generateShortId();
|
||||
|
||||
const otelAdserviceEdot = times(2).map((index) => otelEdot.create(traceId));
|
||||
|
||||
return range
|
||||
.interval('1s')
|
||||
.rate(1)
|
||||
.generator((timestamp) =>
|
||||
otelAdserviceEdot.flatMap((otelDoc) => {
|
||||
return [
|
||||
otelDoc.metric().timestamp(timestamp),
|
||||
otelDoc.transaction(spanId).timestamp(timestamp),
|
||||
];
|
||||
})
|
||||
);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue