diff --git a/docs/reference/opentelemetry-bridge.md b/docs/reference/opentelemetry-bridge.md index d41138b868..fc954b5b38 100644 --- a/docs/reference/opentelemetry-bridge.md +++ b/docs/reference/opentelemetry-bridge.md @@ -15,10 +15,8 @@ applies_to: Integration with the OpenTelemetry Tracing API was added as experimental in v3.34.0. Integration with the OpenTelemetry Metrics API was added as experimental in v3.45.0. :::: - The Elastic APM OpenTelemetry bridge allows one to use the vendor-neutral [OpenTelemetry API](https://opentelemetry.io/docs/instrumentation/js/) ([`@opentelemetry/api`](https://www.npmjs.com/package/@opentelemetry/api)) in your code, and have the Elastic Node.js APM agent handle those API calls. This allows one to use the Elastic APM agent for tracing and metrics without any vendor lock-in to the APM agent’s own [public API](/reference/api.md) when adding manual tracing or custom metrics. - ## Using the OpenTelemetry Tracing API [otel-tracing-api] ① First, you will need to add the Elastic APM agent and OpenTelemetry API dependencies to your project. The minimum required OpenTelemetry API version is 1.0.0; see [the OpenTelemetry compatibility section](/reference/supported-technologies.md#compatibility-opentelemetry) for the current maximum supported API version. For example: @@ -52,6 +50,7 @@ require('elastic-apm-node').start({ // Application code ... ``` + 1. Alternatively, you can use `apiKey: ''`. See [the full APM agent configuration reference](/reference/configuration.md) for other configuration options. @@ -59,26 +58,25 @@ See [the full APM agent configuration reference](/reference/configuration.md) fo ③ Finally, you can use the [OpenTelemetry API](https://open-telemetry.github.io/opentelemetry-js/modules/_opentelemetry_api.html) for any manual tracing in your code. For example, the following script uses [Tracer#startActiveSpan()](https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api._opentelemetry_api.Tracer.html#startactivespan) to trace an outgoing HTTPS request: ```js -const https = require('https') -const otel = require('@opentelemetry/api') -const tracer = otel.trace.getTracer('trace-https-request') +const https = require('https'); +const otel = require('@opentelemetry/api'); +const tracer = otel.trace.getTracer('trace-https-request'); -tracer.startActiveSpan('makeRequest', span => { +tracer.startActiveSpan('makeRequest', (span) => { https.get('https://httpstat.us/200', (response) => { - console.log('STATUS:', response.statusCode) - const body = [] - response.on('data', (chunk) => body.push(chunk)) + console.log('STATUS:', response.statusCode); + const body = []; + response.on('data', (chunk) => body.push(chunk)); response.on('end', () => { - console.log('BODY:', body.toString()) - span.end() - }) - }) -}) + console.log('BODY:', body.toString()); + span.end(); + }); + }); +}); ``` The APM agent source code repository includes [some examples using the OpenTelemetry tracing bridge](https://github.com/elastic/apm-agent-nodejs/tree/main/examples/opentelemetry-bridge). - ## Using the OpenTelemetry Metrics API [otel-metrics-api] ① As above, install the needed dependencies. The minimum required OpenTelemetry API version is 1.3.0 (the version when metrics were added); see [the OpenTelemetry compatibility section](/reference/supported-technologies.md#compatibility-opentelemetry) for the current maximum supported API version. For example: @@ -100,62 +98,62 @@ node my-app.js ```js // otel-metrics-hello-world.js <1> -const { createServer } = require('http') -const otel = require('@opentelemetry/api') +const { createServer } = require('http'); +const otel = require('@opentelemetry/api'); -const meter = otel.metrics.getMeter('my-meter') -const numReqs = meter.createCounter('num_requests', { description: 'number of HTTP requests' }) +const meter = otel.metrics.getMeter('my-meter'); +const numReqs = meter.createCounter('num_requests', { + description: 'number of HTTP requests', +}); const server = createServer((req, res) => { - numReqs.add(1) - req.resume() + numReqs.add(1); + req.resume(); req.on('end', () => { - res.end('pong\n') - }) -}) + res.end('pong\n'); + }); +}); server.listen(3000, () => { - console.log('listening at http://127.0.0.1:3000/') -}) + console.log('listening at http://127.0.0.1:3000/'); +}); ``` 1. The full example is [here](https://github.com/elastic/apm-agent-nodejs/blob/main/examples/opentelemetry-metrics/otel-metrics-hello-world.js). - - ### Using the OpenTelemetry Metrics SDK [otel-metrics-sdk] The Elastic APM agent also supports exporting metrics to APM server when the OpenTelemetry Metrics **SDK** is being used directly. You might want to use the OpenTelemetry Metrics SDK to use a [`View`](https://opentelemetry.io/docs/reference/specification/metrics/sdk/#view) to configure histogram bucket sizes, to setup a Prometheus exporter, or for other reasons. For example: ```js // use-otel-metrics-sdk.js <1> -const otel = require('@opentelemetry/api') -const { MeterProvider } = require('@opentelemetry/sdk-metrics') -const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus') +const otel = require('@opentelemetry/api'); +const { MeterProvider } = require('@opentelemetry/sdk-metrics'); +const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus'); -const exporter = new PrometheusExporter({ host: '127.0.0.1', port: 3001 }) -const meterProvider = new MeterProvider() -meterProvider.addMetricReader(exporter) -otel.metrics.setGlobalMeterProvider(meterProvider) +const exporter = new PrometheusExporter({ host: '127.0.0.1', port: 3001 }); +const meterProvider = new MeterProvider({ + readers: [exporter], +}); +otel.metrics.setGlobalMeterProvider(meterProvider); -const meter = otel.metrics.getMeter('my-meter') -const latency = meter.createHistogram('latency', { description: 'Response latency (s)' }) +const meter = otel.metrics.getMeter('my-meter'); +const latency = meter.createHistogram('latency', { + description: 'Response latency (s)', +}); // ... ``` 1. The full example is [here](https://github.com/elastic/apm-agent-nodejs/blob/main/examples/opentelemetry-metrics/use-otel-metrics-sdk.js). - - ### OpenTelemetry Metrics configuration [otel-metrics-conf] A few configuration options can be used to control OpenTelemetry Metrics support. -* Specific metrics names can be filtered out via the [`disableMetrics`](/reference/configuration.md#disable-metrics) configuration option. -* Integration with the OpenTelemetry Metrics API can be disabled via the [`disableInstrumentations: '@opentelemetry/api'`](/reference/configuration.md#disable-instrumentations) configuration option. -* Integration with the OpenTelemetry Metrics SDK can be disabled via the [`disableInstrumentations: '@opentelemetry/sdk-metrics'`](/reference/configuration.md#disable-instrumentations) configuration option. -* All metrics support in the APM agent can be disabled via the [`metricsInterval: '0s'`](/reference/configuration.md#metrics-interval) configuration option. -* The default histogram bucket boundaries are different from the OpenTelemetry default, to provide better resolution. The boundaries used by the APM agent can be configured with the [`customMetricsHistogramBoundaries`](/reference/configuration.md#custom-metrics-histogram-boundaries) configuration option. - +- Specific metrics names can be filtered out via the [`disableMetrics`](/reference/configuration.md#disable-metrics) configuration option. +- Integration with the OpenTelemetry Metrics API can be disabled via the [`disableInstrumentations: '@opentelemetry/api'`](/reference/configuration.md#disable-instrumentations) configuration option. +- Integration with the OpenTelemetry Metrics SDK can be disabled via the [`disableInstrumentations: '@opentelemetry/sdk-metrics'`](/reference/configuration.md#disable-instrumentations) configuration option. +- All metrics support in the APM agent can be disabled via the [`metricsInterval: '0s'`](/reference/configuration.md#metrics-interval) configuration option. +- The default histogram bucket boundaries are different from the OpenTelemetry default, to provide better resolution. The boundaries used by the APM agent can be configured with the [`customMetricsHistogramBoundaries`](/reference/configuration.md#custom-metrics-histogram-boundaries) configuration option. ## Bridge architecture [otel-architecture] @@ -168,33 +166,28 @@ The only difference, from the user’s point of view, is in the setup of tracing
The OpenTelemetry Metrics support, is slightly different. If your code uses just the Metrics **API**, then the APM agent provides a full MeterProvider so that metrics are accumulated and sent to APM server. If your code uses the Metrics **SDK**, then the APM agents adds a MetricReader to your MeterProvider to send metrics on to APM server. This allows you to use the APM agent as either an easy setup for using metrics or in conjunction with your existing OpenTelemetry Metrics configuration. - ## Caveats [otel-caveats] Not all features of the OpenTelemetry API are supported. This section describes any limitations and differences. - #### Tracing [otel-caveats-tracing] -* Span Link Attributes. Adding links when [starting a span](https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api._opentelemetry_api.Tracer.html) is supported, but any added span link **attributes** are silently dropped. -* Span events ([`Span#addEvent()`](https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api._opentelemetry_api.Span.html#addevent)) are not currently supported. Events will be silently dropped. -* [Propagating baggage](https://open-telemetry.github.io/opentelemetry-js/classes/_opentelemetry_api._opentelemetry_api.PropagationAPI.html) within or outside the process is not supported. Baggage items are silently dropped. - +- Span Link Attributes. Adding links when [starting a span](https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api._opentelemetry_api.Tracer.html) is supported, but any added span link **attributes** are silently dropped. +- Span events ([`Span#addEvent()`](https://open-telemetry.github.io/opentelemetry-js/interfaces/_opentelemetry_api._opentelemetry_api.Span.html#addevent)) are not currently supported. Events will be silently dropped. +- [Propagating baggage](https://open-telemetry.github.io/opentelemetry-js/classes/_opentelemetry_api._opentelemetry_api.PropagationAPI.html) within or outside the process is not supported. Baggage items are silently dropped. #### Metrics [otel-caveats-metrics] -* Metrics [exemplars](https://opentelemetry.io/docs/reference/specification/metrics/data-model/#exemplars) are not supported. -* [Summary metrics](https://opentelemetry.io/docs/reference/specification/metrics/data-model/#summary-legacy) are not supported. -* [Exponential Histograms](https://opentelemetry.io/docs/reference/specification/metrics/data-model/#exponentialhistogram) are not yet supported. -* The `sum`, `count`, `min` and `max` within the OpenTelemetry histogram data are discarded. -* The default histogram bucket boundaries are different from the OpenTelemetry default. They provide better resolution. They can be configured with the [`customMetricsHistogramBoundaries`](/reference/configuration.md#custom-metrics-histogram-boundaries) configuration option. -* Metrics label names are dedotted (`s/\./_/g`) in APM server to avoid possible mapping collisions in Elasticsearch. -* The default [Aggregation Temporality](https://github.com/elastic/apm/blob/main/specs/agents/metrics-otel.md#aggregation-temporality) used differs from the OpenTelemetry default — preferring **delta**-temporality (nicer for visualizing in Kibana) to cumulative-temporality. +- Metrics [exemplars](https://opentelemetry.io/docs/reference/specification/metrics/data-model/#exemplars) are not supported. +- [Summary metrics](https://opentelemetry.io/docs/reference/specification/metrics/data-model/#summary-legacy) are not supported. +- [Exponential Histograms](https://opentelemetry.io/docs/reference/specification/metrics/data-model/#exponentialhistogram) are not yet supported. +- The `sum`, `count`, `min` and `max` within the OpenTelemetry histogram data are discarded. +- The default histogram bucket boundaries are different from the OpenTelemetry default. They provide better resolution. They can be configured with the [`customMetricsHistogramBoundaries`](/reference/configuration.md#custom-metrics-histogram-boundaries) configuration option. +- Metrics label names are dedotted (`s/\./_/g`) in APM server to avoid possible mapping collisions in Elasticsearch. +- The default [Aggregation Temporality](https://github.com/elastic/apm/blob/main/specs/agents/metrics-otel.md#aggregation-temporality) used differs from the OpenTelemetry default — preferring **delta**-temporality (nicer for visualizing in Kibana) to cumulative-temporality. Metrics support requires an APM server >=7.11 — for earlier APM server versions, metrics with label names including `.`, `*`, or `"` will get dropped. - #### Logs [otel-caveats-logs] The OpenTelemetry Logs API is currently not support — only the Tracing and Metrics APIs. - diff --git a/examples/opentelemetry-metrics/package.json b/examples/opentelemetry-metrics/package.json index 78e7913c7d..bc418963bb 100644 --- a/examples/opentelemetry-metrics/package.json +++ b/examples/opentelemetry-metrics/package.json @@ -3,9 +3,9 @@ "version": "1.0.0", "private": true, "dependencies": { - "@opentelemetry/api": "^1.4.1", - "@opentelemetry/exporter-prometheus": ">=0.41.0 <2", - "@opentelemetry/sdk-metrics": "^1.12.0", + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/exporter-prometheus": ">=0.200.0", + "@opentelemetry/sdk-metrics": "^2.0.0", "elastic-apm-node": "file:../.." } } diff --git a/examples/opentelemetry-metrics/use-otel-metrics-sdk.js b/examples/opentelemetry-metrics/use-otel-metrics-sdk.js index c5f5cfada5..643a4523a7 100644 --- a/examples/opentelemetry-metrics/use-otel-metrics-sdk.js +++ b/examples/opentelemetry-metrics/use-otel-metrics-sdk.js @@ -29,26 +29,28 @@ const { performance } = require('perf_hooks'); const otel = require('@opentelemetry/api'); const { MeterProvider, - View, - ExplicitBucketHistogramAggregation, + AggregationType, } = require('@opentelemetry/sdk-metrics'); const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus'); const exporter = new PrometheusExporter({ host: '127.0.0.1', port: 3001 }); const meterProvider = new MeterProvider({ views: [ - new View({ + { instrumentName: 'latency', - aggregation: new ExplicitBucketHistogramAggregation( - // Use the same default buckets as in `prom-client` for comparison. - // This is to demonstrate using a View. The default buckets used by the - // APM agent would suffice as well. - [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10], - ), - }), + aggregation: { + type: AggregationType.EXPLICIT_BUCKET_HISTOGRAM, + options: { + // Use the same default buckets as in `prom-client` for comparison. + // This is to demonstrate using a View. The default buckets used by the + // APM agent would suffice as well. + boundaries: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10], + }, + }, + }, ], + readers: [exporter], }); -meterProvider.addMetricReader(exporter); otel.metrics.setGlobalMeterProvider(meterProvider); console.log('Prometheus metrics at http://127.0.0.1:3001/metrics'); diff --git a/lib/instrumentation/modules/@opentelemetry/sdk-metrics.js b/lib/instrumentation/modules/@opentelemetry/sdk-metrics.js index e266852f3e..16a49da5d9 100644 --- a/lib/instrumentation/modules/@opentelemetry/sdk-metrics.js +++ b/lib/instrumentation/modules/@opentelemetry/sdk-metrics.js @@ -40,7 +40,7 @@ module.exports = function (mod, agent, { version, enabled }) { // Minimum supported version is 1.11.0 because that version included the fix // for side-effects from having two MetricReaders. // https://github.com/open-telemetry/opentelemetry-js/issues/3664 - if (!semver.satisfies(version, '>=1.11.0 <2', { includePrerelease: true })) { + if (!semver.satisfies(version, '>=2.0.0 <3', { includePrerelease: true })) { log.debug( '@opentelemetry/sdk-metrics@%s is not supported, skipping @opentelemetry/sdk-metrics instrumentation', version, @@ -56,15 +56,13 @@ module.exports = function (mod, agent, { version, enabled }) { } class ApmMeterProvider extends mod.MeterProvider { - constructor(...args) { - super(...args); - // We create a new metric reader for each new MeterProvider instance, - // because they shutdown independently -- they cannot be shared between - // multiple MeterProviders. + constructor(options = {}) { + const readers = options.readers ? [...options.readers] : []; + readers.push(createOTelMetricReader(agent)); log.trace( '@opentelemetry/sdk-metrics ins: create Elastic APM MetricReader', ); - this.addMetricReader(createOTelMetricReader(agent)); + super({ ...options, readers }); } } Object.defineProperty(mod, 'MeterProvider', { diff --git a/lib/opentelemetry-metrics/ElasticApmMetricExporter.js b/lib/opentelemetry-metrics/ElasticApmMetricExporter.js index 0aad0813ca..5f4137358d 100644 --- a/lib/opentelemetry-metrics/ElasticApmMetricExporter.js +++ b/lib/opentelemetry-metrics/ElasticApmMetricExporter.js @@ -8,11 +8,8 @@ const { ExportResultCode } = require('@opentelemetry/core'); const { AggregationTemporality, InstrumentType, - ExplicitBucketHistogramAggregation, - SumAggregation, - LastValueAggregation, - DropAggregation, DataPointType, + AggregationType, } = require('@opentelemetry/sdk-metrics'); const { LRUCache } = require('lru-cache'); @@ -96,12 +93,15 @@ function fillIntakeHistogramSample(sample, otelDataPoint) { class ElasticApmMetricExporter { constructor(agent) { this._agent = agent; - this._histogramAggregation = new ExplicitBucketHistogramAggregation( - this._agent._conf.customMetricsHistogramBoundaries, - ); - this._sumAggregation = new SumAggregation(); - this._lastValueAggregation = new LastValueAggregation(); - this._dropAggregation = new DropAggregation(); + this._histogramAggregation = { + type: AggregationType.EXPLICIT_BUCKET_HISTOGRAM, + options: { + boundaries: this._agent._conf.customMetricsHistogramBoundaries, + }, + }; + this._sumAggregation = { type: AggregationType.SUM }; + this._lastValueAggregation = { type: AggregationType.LAST_VALUE }; + this._dropAggregation = { type: AggregationType.DROP }; this._attrDropWarnCache = new LRUCache({ max: 1000 }); this._dataPointTypeDropWarnCache = new LRUCache({ max: 1000 }); } diff --git a/lib/opentelemetry-metrics/index.js b/lib/opentelemetry-metrics/index.js index 441ea26189..b9f06b9eca 100644 --- a/lib/opentelemetry-metrics/index.js +++ b/lib/opentelemetry-metrics/index.js @@ -38,8 +38,9 @@ function createOTelMetricReader(agent) { } function createOTelMeterProvider(agent) { - const meterProvider = new MeterProvider(); - meterProvider.addMetricReader(createOTelMetricReader(agent)); + const meterProvider = new MeterProvider({ + readers: [createOTelMetricReader(agent)], + }); return meterProvider; } diff --git a/package-lock.json b/package-lock.json index 4dbae90427..b2fbd6eb1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,9 +10,9 @@ "license": "BSD-2-Clause", "dependencies": { "@elastic/ecs-pino-format": "^1.5.0", - "@opentelemetry/api": "^1.4.1", - "@opentelemetry/core": "^1.11.0", - "@opentelemetry/sdk-metrics": "^1.12.0", + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/sdk-metrics": "^2.0.0", "after-all-results": "^2.0.0", "agentkeepalive": "^4.2.1", "async-value-promise": "^1.1.1", @@ -4403,30 +4403,6 @@ "node": ">=20" } }, - "node_modules/@elastic/transport/node_modules/@opentelemetry/core": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", - "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", - "dev": true, - "dependencies": { - "@opentelemetry/semantic-conventions": "^1.29.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.10.0" - } - }, - "node_modules/@elastic/transport/node_modules/@opentelemetry/semantic-conventions": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", - "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", - "dev": true, - "engines": { - "node": ">=14" - } - }, "node_modules/@elastic/transport/node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -5430,53 +5406,57 @@ } }, "node_modules/@opentelemetry/core": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", - "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", "dependencies": { - "@opentelemetry/semantic-conventions": "1.28.0" + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "node_modules/@opentelemetry/resources": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", - "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.0.tgz", + "integrity": "sha512-F8W52ApePshpoSrfsSk1H2yJn9aKjCrbpQF1M9Qii0GHzbfVeFUB+rc3X4aggyZD8x9Gu3Slua+s6krmq6Dt8g==", + "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "1.30.1", - "@opentelemetry/semantic-conventions": "1.28.0" + "@opentelemetry/core": "2.5.0", + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.10.0" + "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "node_modules/@opentelemetry/sdk-metrics": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.30.1.tgz", - "integrity": "sha512-q9zcZ0Okl8jRgmy7eNW3Ku1XSgg3sDLa5evHZpCwjspw7E8Is4K/haRPDJrBcX3YSn/Y7gUvFnByNYEKQNbNog==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.5.0.tgz", + "integrity": "sha512-BeJLtU+f5Gf905cJX9vXFQorAr6TAfK3SPvTFqP+scfIpDQEJfRaGJWta7sJgP+m4dNtBf9y3yvBKVAZZtJQVA==", + "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "1.30.1", - "@opentelemetry/resources": "1.30.1" + "@opentelemetry/core": "2.5.0", + "@opentelemetry/resources": "2.5.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": ">=1.3.0 <1.10.0" + "@opentelemetry/api": ">=1.9.0 <1.10.0" } }, "node_modules/@opentelemetry/semantic-conventions": { - "version": "1.28.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", - "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.39.0.tgz", + "integrity": "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg==", + "license": "Apache-2.0", "engines": { "node": ">=14" } @@ -20129,21 +20109,6 @@ "undici": "^7.16.0" }, "dependencies": { - "@opentelemetry/core": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.2.0.tgz", - "integrity": "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==", - "dev": true, - "requires": { - "@opentelemetry/semantic-conventions": "^1.29.0" - } - }, - "@opentelemetry/semantic-conventions": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", - "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", - "dev": true - }, "debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -20978,35 +20943,35 @@ "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==" }, "@opentelemetry/core": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", - "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", "requires": { - "@opentelemetry/semantic-conventions": "1.28.0" + "@opentelemetry/semantic-conventions": "^1.29.0" } }, "@opentelemetry/resources": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", - "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.0.tgz", + "integrity": "sha512-F8W52ApePshpoSrfsSk1H2yJn9aKjCrbpQF1M9Qii0GHzbfVeFUB+rc3X4aggyZD8x9Gu3Slua+s6krmq6Dt8g==", "requires": { - "@opentelemetry/core": "1.30.1", - "@opentelemetry/semantic-conventions": "1.28.0" + "@opentelemetry/core": "2.5.0", + "@opentelemetry/semantic-conventions": "^1.29.0" } }, "@opentelemetry/sdk-metrics": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.30.1.tgz", - "integrity": "sha512-q9zcZ0Okl8jRgmy7eNW3Ku1XSgg3sDLa5evHZpCwjspw7E8Is4K/haRPDJrBcX3YSn/Y7gUvFnByNYEKQNbNog==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.5.0.tgz", + "integrity": "sha512-BeJLtU+f5Gf905cJX9vXFQorAr6TAfK3SPvTFqP+scfIpDQEJfRaGJWta7sJgP+m4dNtBf9y3yvBKVAZZtJQVA==", "requires": { - "@opentelemetry/core": "1.30.1", - "@opentelemetry/resources": "1.30.1" + "@opentelemetry/core": "2.5.0", + "@opentelemetry/resources": "2.5.0" } }, "@opentelemetry/semantic-conventions": { - "version": "1.28.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", - "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==" + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.39.0.tgz", + "integrity": "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg==" }, "@pinojs/redact": { "version": "0.4.0", diff --git a/package.json b/package.json index bc7ebdce0e..b8e53852e3 100644 --- a/package.json +++ b/package.json @@ -91,9 +91,9 @@ "homepage": "https://github.com/elastic/apm-agent-nodejs", "dependencies": { "@elastic/ecs-pino-format": "^1.5.0", - "@opentelemetry/api": "^1.4.1", - "@opentelemetry/core": "^1.11.0", - "@opentelemetry/sdk-metrics": "^1.12.0", + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/sdk-metrics": "^2.0.0", "after-all-results": "^2.0.0", "agentkeepalive": "^4.2.1", "async-value-promise": "^1.1.1", diff --git a/test/opentelemetry-metrics/fixtures/package-lock.json b/test/opentelemetry-metrics/fixtures/package-lock.json index cef242197a..5bd01a0397 100644 --- a/test/opentelemetry-metrics/fixtures/package-lock.json +++ b/test/opentelemetry-metrics/fixtures/package-lock.json @@ -9,8 +9,8 @@ "version": "1.0.0", "dependencies": { "@opentelemetry/api": "^1.9.0", - "@opentelemetry/exporter-prometheus": ">=0.41.2 <2", - "@opentelemetry/sdk-metrics": "^1.30.0" + "@opentelemetry/exporter-prometheus": ">=0.200.0", + "@opentelemetry/sdk-metrics": "^2.0.0" } }, "node_modules/@opentelemetry/api": { @@ -22,70 +22,74 @@ } }, "node_modules/@opentelemetry/core": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", - "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", "dependencies": { - "@opentelemetry/semantic-conventions": "1.28.0" + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "node_modules/@opentelemetry/exporter-prometheus": { - "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-prometheus/-/exporter-prometheus-0.57.2.tgz", - "integrity": "sha512-VqIqXnuxWMWE/1NatAGtB1PvsQipwxDcdG4RwA/umdBcW3/iOHp0uejvFHTRN2O78ZPged87ErJajyUBPUhlDQ==", + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-prometheus/-/exporter-prometheus-0.211.0.tgz", + "integrity": "sha512-cD0WleEL3TPqJbvxwz5MVdVJ82H8jl8mvMad4bNU24cB5SH2mRW5aMLDTuV4614ll46R//R3RMmci26mc2L99g==", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "1.30.1", - "@opentelemetry/resources": "1.30.1", - "@opentelemetry/sdk-metrics": "1.30.1" + "@opentelemetry/core": "2.5.0", + "@opentelemetry/resources": "2.5.0", + "@opentelemetry/sdk-metrics": "2.5.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "node_modules/@opentelemetry/resources": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", - "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.0.tgz", + "integrity": "sha512-F8W52ApePshpoSrfsSk1H2yJn9aKjCrbpQF1M9Qii0GHzbfVeFUB+rc3X4aggyZD8x9Gu3Slua+s6krmq6Dt8g==", + "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "1.30.1", - "@opentelemetry/semantic-conventions": "1.28.0" + "@opentelemetry/core": "2.5.0", + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.10.0" + "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "node_modules/@opentelemetry/sdk-metrics": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.30.1.tgz", - "integrity": "sha512-q9zcZ0Okl8jRgmy7eNW3Ku1XSgg3sDLa5evHZpCwjspw7E8Is4K/haRPDJrBcX3YSn/Y7gUvFnByNYEKQNbNog==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.5.0.tgz", + "integrity": "sha512-BeJLtU+f5Gf905cJX9vXFQorAr6TAfK3SPvTFqP+scfIpDQEJfRaGJWta7sJgP+m4dNtBf9y3yvBKVAZZtJQVA==", + "license": "Apache-2.0", "dependencies": { - "@opentelemetry/core": "1.30.1", - "@opentelemetry/resources": "1.30.1" + "@opentelemetry/core": "2.5.0", + "@opentelemetry/resources": "2.5.0" }, "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "@opentelemetry/api": ">=1.3.0 <1.10.0" + "@opentelemetry/api": ">=1.9.0 <1.10.0" } }, "node_modules/@opentelemetry/semantic-conventions": { - "version": "1.28.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", - "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.39.0.tgz", + "integrity": "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg==", + "license": "Apache-2.0", "engines": { "node": ">=14" } @@ -98,45 +102,45 @@ "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==" }, "@opentelemetry/core": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", - "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", "requires": { - "@opentelemetry/semantic-conventions": "1.28.0" + "@opentelemetry/semantic-conventions": "^1.29.0" } }, "@opentelemetry/exporter-prometheus": { - "version": "0.57.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-prometheus/-/exporter-prometheus-0.57.2.tgz", - "integrity": "sha512-VqIqXnuxWMWE/1NatAGtB1PvsQipwxDcdG4RwA/umdBcW3/iOHp0uejvFHTRN2O78ZPged87ErJajyUBPUhlDQ==", + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-prometheus/-/exporter-prometheus-0.211.0.tgz", + "integrity": "sha512-cD0WleEL3TPqJbvxwz5MVdVJ82H8jl8mvMad4bNU24cB5SH2mRW5aMLDTuV4614ll46R//R3RMmci26mc2L99g==", "requires": { - "@opentelemetry/core": "1.30.1", - "@opentelemetry/resources": "1.30.1", - "@opentelemetry/sdk-metrics": "1.30.1" + "@opentelemetry/core": "2.5.0", + "@opentelemetry/resources": "2.5.0", + "@opentelemetry/sdk-metrics": "2.5.0" } }, "@opentelemetry/resources": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", - "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.0.tgz", + "integrity": "sha512-F8W52ApePshpoSrfsSk1H2yJn9aKjCrbpQF1M9Qii0GHzbfVeFUB+rc3X4aggyZD8x9Gu3Slua+s6krmq6Dt8g==", "requires": { - "@opentelemetry/core": "1.30.1", - "@opentelemetry/semantic-conventions": "1.28.0" + "@opentelemetry/core": "2.5.0", + "@opentelemetry/semantic-conventions": "^1.29.0" } }, "@opentelemetry/sdk-metrics": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.30.1.tgz", - "integrity": "sha512-q9zcZ0Okl8jRgmy7eNW3Ku1XSgg3sDLa5evHZpCwjspw7E8Is4K/haRPDJrBcX3YSn/Y7gUvFnByNYEKQNbNog==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.5.0.tgz", + "integrity": "sha512-BeJLtU+f5Gf905cJX9vXFQorAr6TAfK3SPvTFqP+scfIpDQEJfRaGJWta7sJgP+m4dNtBf9y3yvBKVAZZtJQVA==", "requires": { - "@opentelemetry/core": "1.30.1", - "@opentelemetry/resources": "1.30.1" + "@opentelemetry/core": "2.5.0", + "@opentelemetry/resources": "2.5.0" } }, "@opentelemetry/semantic-conventions": { - "version": "1.28.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", - "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==" + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.39.0.tgz", + "integrity": "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg==" } } } diff --git a/test/opentelemetry-metrics/fixtures/package.json b/test/opentelemetry-metrics/fixtures/package.json index 8c10129770..f1fdd852e4 100644 --- a/test/opentelemetry-metrics/fixtures/package.json +++ b/test/opentelemetry-metrics/fixtures/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@opentelemetry/api": "^1.9.0", - "@opentelemetry/exporter-prometheus": ">=0.41.2 <2", - "@opentelemetry/sdk-metrics": "^1.30.0" + "@opentelemetry/exporter-prometheus": ">=0.200.0", + "@opentelemetry/sdk-metrics": "^2.0.0" } } diff --git a/test/opentelemetry-metrics/fixtures/use-just-otel-sdk.js b/test/opentelemetry-metrics/fixtures/use-just-otel-sdk.js index 078c32f56e..9abb57e362 100644 --- a/test/opentelemetry-metrics/fixtures/use-just-otel-sdk.js +++ b/test/opentelemetry-metrics/fixtures/use-just-otel-sdk.js @@ -16,24 +16,26 @@ const { MeterProvider, - View, - ExplicitBucketHistogramAggregation, + AggregationType, } = require('@opentelemetry/sdk-metrics'); const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus'); const exporter = new PrometheusExporter({ host: '127.0.0.1' }); const meterProvider = new MeterProvider({ views: [ - new View({ + { instrumentName: 'test_histogram_viewbuckets', - aggregation: new ExplicitBucketHistogramAggregation( - // Use the same default buckets as in `prom-client`. - [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10], - ), - }), + aggregation: { + type: AggregationType.EXPLICIT_BUCKET_HISTOGRAM, + options: { + // Use the same default buckets as in `prom-client`. + boundaries: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10], + }, + }, + }, ], + readers: [exporter], }); -meterProvider.addMetricReader(exporter); const meter = meterProvider.getMeter('test-meter'); diff --git a/test/opentelemetry-metrics/fixtures/use-otel-api-with-registered-meter-provider.js b/test/opentelemetry-metrics/fixtures/use-otel-api-with-registered-meter-provider.js index b0231d3e70..32b7af45a2 100644 --- a/test/opentelemetry-metrics/fixtures/use-otel-api-with-registered-meter-provider.js +++ b/test/opentelemetry-metrics/fixtures/use-otel-api-with-registered-meter-provider.js @@ -23,8 +23,9 @@ const { MeterProvider } = require('@opentelemetry/sdk-metrics'); const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus'); const exporter = new PrometheusExporter({ host: '127.0.0.1' }); -const meterProvider = new MeterProvider(); -meterProvider.addMetricReader(exporter); +const meterProvider = new MeterProvider({ + readers: [exporter], +}); otel.metrics.setGlobalMeterProvider(meterProvider); const meter = otel.metrics.getMeter('test-meter');