diff --git a/examples/package-lock.json b/examples/package-lock.json index 3bac6b7e..c57a8ff0 100644 --- a/examples/package-lock.json +++ b/examples/package-lock.json @@ -17,56 +17,57 @@ }, "../packages/opentelemetry-node": { "name": "@elastic/opentelemetry-node", - "version": "0.3.0", + "version": "0.5.0", "license": "Apache-2.0", "dependencies": { - "@opentelemetry/exporter-logs-otlp-grpc": "^0.53.0", - "@opentelemetry/exporter-logs-otlp-http": "^0.53.0", - "@opentelemetry/exporter-logs-otlp-proto": "^0.53.0", - "@opentelemetry/exporter-metrics-otlp-grpc": "^0.53.0", - "@opentelemetry/exporter-metrics-otlp-http": "^0.53.0", - "@opentelemetry/exporter-metrics-otlp-proto": "^0.53.0", + "@opentelemetry/exporter-logs-otlp-grpc": "^0.54.0", + "@opentelemetry/exporter-logs-otlp-http": "^0.54.0", + "@opentelemetry/exporter-logs-otlp-proto": "^0.54.0", + "@opentelemetry/exporter-metrics-otlp-grpc": "^0.54.0", + "@opentelemetry/exporter-metrics-otlp-http": "^0.54.0", + "@opentelemetry/exporter-metrics-otlp-proto": "^0.54.0", "@opentelemetry/host-metrics": "^0.35.0", - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/instrumentation-aws-sdk": "^0.44.0", - "@opentelemetry/instrumentation-bunyan": "^0.41.0", - "@opentelemetry/instrumentation-connect": "^0.39.0", - "@opentelemetry/instrumentation-cucumber": "^0.9.0", - "@opentelemetry/instrumentation-dataloader": "^0.12.0", - "@opentelemetry/instrumentation-dns": "^0.39.0", - "@opentelemetry/instrumentation-express": "^0.42.0", - "@opentelemetry/instrumentation-fastify": "^0.39.0", - "@opentelemetry/instrumentation-generic-pool": "^0.39.0", - "@opentelemetry/instrumentation-grpc": "^0.53.0", - "@opentelemetry/instrumentation-hapi": "^0.41.0", - "@opentelemetry/instrumentation-http": "^0.53.0", - "@opentelemetry/instrumentation-ioredis": "^0.43.0", - "@opentelemetry/instrumentation-knex": "^0.40.0", - "@opentelemetry/instrumentation-koa": "^0.43.0", - "@opentelemetry/instrumentation-lru-memoizer": "^0.40.0", - "@opentelemetry/instrumentation-memcached": "^0.39.0", - "@opentelemetry/instrumentation-mongodb": "^0.47.0", - "@opentelemetry/instrumentation-nestjs-core": "^0.40.0", - "@opentelemetry/instrumentation-net": "^0.39.0", - "@opentelemetry/instrumentation-pg": "^0.44.0", - "@opentelemetry/instrumentation-pino": "^0.42.0", - "@opentelemetry/instrumentation-redis": "^0.42.0", - "@opentelemetry/instrumentation-redis-4": "^0.42.0", - "@opentelemetry/instrumentation-restify": "^0.41.0", - "@opentelemetry/instrumentation-router": "^0.40.0", - "@opentelemetry/instrumentation-socket.io": "^0.42.0", - "@opentelemetry/instrumentation-tedious": "^0.14.0", - "@opentelemetry/instrumentation-undici": "^0.6.0", - "@opentelemetry/instrumentation-winston": "^0.40.0", + "@opentelemetry/instrumentation": "^0.54.0", + "@opentelemetry/instrumentation-aws-sdk": "^0.46.0", + "@opentelemetry/instrumentation-bunyan": "^0.42.0", + "@opentelemetry/instrumentation-connect": "^0.40.0", + "@opentelemetry/instrumentation-cucumber": "^0.10.0", + "@opentelemetry/instrumentation-dataloader": "^0.13.0", + "@opentelemetry/instrumentation-dns": "^0.40.0", + "@opentelemetry/instrumentation-express": "^0.44.0", + "@opentelemetry/instrumentation-fastify": "^0.41.0", + "@opentelemetry/instrumentation-generic-pool": "^0.40.0", + "@opentelemetry/instrumentation-grpc": "^0.54.0", + "@opentelemetry/instrumentation-hapi": "^0.42.0", + "@opentelemetry/instrumentation-http": "^0.54.0", + "@opentelemetry/instrumentation-ioredis": "^0.44.0", + "@opentelemetry/instrumentation-knex": "^0.41.0", + "@opentelemetry/instrumentation-koa": "^0.44.0", + "@opentelemetry/instrumentation-lru-memoizer": "^0.41.0", + "@opentelemetry/instrumentation-memcached": "^0.40.0", + "@opentelemetry/instrumentation-mongodb": "^0.48.0", + "@opentelemetry/instrumentation-nestjs-core": "^0.41.0", + "@opentelemetry/instrumentation-net": "^0.40.0", + "@opentelemetry/instrumentation-pg": "^0.47.0", + "@opentelemetry/instrumentation-pino": "^0.43.0", + "@opentelemetry/instrumentation-redis": "^0.43.0", + "@opentelemetry/instrumentation-redis-4": "^0.43.0", + "@opentelemetry/instrumentation-restify": "^0.42.0", + "@opentelemetry/instrumentation-router": "^0.41.0", + "@opentelemetry/instrumentation-runtime-node": "^0.9.0", + "@opentelemetry/instrumentation-socket.io": "^0.43.0", + "@opentelemetry/instrumentation-tedious": "^0.15.0", + "@opentelemetry/instrumentation-undici": "^0.7.0", + "@opentelemetry/instrumentation-winston": "^0.41.0", "@opentelemetry/resource-detector-alibaba-cloud": "^0.29.1", "@opentelemetry/resource-detector-aws": "^1.6.1", "@opentelemetry/resource-detector-azure": "^0.2.11", - "@opentelemetry/resource-detector-container": "^0.4.1", + "@opentelemetry/resource-detector-container": "^0.5.0", "@opentelemetry/resource-detector-gcp": "^0.29.11", "@opentelemetry/resources": "^1.26.0", - "@opentelemetry/sdk-logs": "^0.53.0", - "@opentelemetry/sdk-node": "^0.53.0", - "@opentelemetry/winston-transport": "^0.6.0", + "@opentelemetry/sdk-logs": "^0.54.0", + "@opentelemetry/sdk-node": "^0.54.0", + "@opentelemetry/winston-transport": "^0.7.0", "safe-stable-stringify": "^2.4.3" }, "devDependencies": { @@ -1012,53 +1013,54 @@ "@grpc/proto-loader": "^0.7.13", "@hapi/hapi": "^21.3.10", "@opentelemetry/api": "^1.3.0", - "@opentelemetry/exporter-logs-otlp-grpc": "^0.53.0", - "@opentelemetry/exporter-logs-otlp-http": "^0.53.0", - "@opentelemetry/exporter-logs-otlp-proto": "^0.53.0", - "@opentelemetry/exporter-metrics-otlp-grpc": "^0.53.0", - "@opentelemetry/exporter-metrics-otlp-http": "^0.53.0", - "@opentelemetry/exporter-metrics-otlp-proto": "^0.53.0", + "@opentelemetry/exporter-logs-otlp-grpc": "^0.54.0", + "@opentelemetry/exporter-logs-otlp-http": "^0.54.0", + "@opentelemetry/exporter-logs-otlp-proto": "^0.54.0", + "@opentelemetry/exporter-metrics-otlp-grpc": "^0.54.0", + "@opentelemetry/exporter-metrics-otlp-http": "^0.54.0", + "@opentelemetry/exporter-metrics-otlp-proto": "^0.54.0", "@opentelemetry/host-metrics": "^0.35.0", - "@opentelemetry/instrumentation": "^0.53.0", - "@opentelemetry/instrumentation-aws-sdk": "^0.44.0", - "@opentelemetry/instrumentation-bunyan": "^0.41.0", - "@opentelemetry/instrumentation-connect": "^0.39.0", - "@opentelemetry/instrumentation-cucumber": "^0.9.0", - "@opentelemetry/instrumentation-dataloader": "^0.12.0", - "@opentelemetry/instrumentation-dns": "^0.39.0", - "@opentelemetry/instrumentation-express": "^0.42.0", - "@opentelemetry/instrumentation-fastify": "^0.39.0", - "@opentelemetry/instrumentation-generic-pool": "^0.39.0", - "@opentelemetry/instrumentation-grpc": "^0.53.0", - "@opentelemetry/instrumentation-hapi": "^0.41.0", - "@opentelemetry/instrumentation-http": "^0.53.0", - "@opentelemetry/instrumentation-ioredis": "^0.43.0", - "@opentelemetry/instrumentation-knex": "^0.40.0", - "@opentelemetry/instrumentation-koa": "^0.43.0", - "@opentelemetry/instrumentation-lru-memoizer": "^0.40.0", - "@opentelemetry/instrumentation-memcached": "^0.39.0", - "@opentelemetry/instrumentation-mongodb": "^0.47.0", - "@opentelemetry/instrumentation-nestjs-core": "^0.40.0", - "@opentelemetry/instrumentation-net": "^0.39.0", - "@opentelemetry/instrumentation-pg": "^0.44.0", - "@opentelemetry/instrumentation-pino": "^0.42.0", - "@opentelemetry/instrumentation-redis": "^0.42.0", - "@opentelemetry/instrumentation-redis-4": "^0.42.0", - "@opentelemetry/instrumentation-restify": "^0.41.0", - "@opentelemetry/instrumentation-router": "^0.40.0", - "@opentelemetry/instrumentation-socket.io": "^0.42.0", - "@opentelemetry/instrumentation-tedious": "^0.14.0", - "@opentelemetry/instrumentation-undici": "^0.6.0", - "@opentelemetry/instrumentation-winston": "^0.40.0", + "@opentelemetry/instrumentation": "^0.54.0", + "@opentelemetry/instrumentation-aws-sdk": "^0.46.0", + "@opentelemetry/instrumentation-bunyan": "^0.42.0", + "@opentelemetry/instrumentation-connect": "^0.40.0", + "@opentelemetry/instrumentation-cucumber": "^0.10.0", + "@opentelemetry/instrumentation-dataloader": "^0.13.0", + "@opentelemetry/instrumentation-dns": "^0.40.0", + "@opentelemetry/instrumentation-express": "^0.44.0", + "@opentelemetry/instrumentation-fastify": "^0.41.0", + "@opentelemetry/instrumentation-generic-pool": "^0.40.0", + "@opentelemetry/instrumentation-grpc": "^0.54.0", + "@opentelemetry/instrumentation-hapi": "^0.42.0", + "@opentelemetry/instrumentation-http": "^0.54.0", + "@opentelemetry/instrumentation-ioredis": "^0.44.0", + "@opentelemetry/instrumentation-knex": "^0.41.0", + "@opentelemetry/instrumentation-koa": "^0.44.0", + "@opentelemetry/instrumentation-lru-memoizer": "^0.41.0", + "@opentelemetry/instrumentation-memcached": "^0.40.0", + "@opentelemetry/instrumentation-mongodb": "^0.48.0", + "@opentelemetry/instrumentation-nestjs-core": "^0.41.0", + "@opentelemetry/instrumentation-net": "^0.40.0", + "@opentelemetry/instrumentation-pg": "^0.47.0", + "@opentelemetry/instrumentation-pino": "^0.43.0", + "@opentelemetry/instrumentation-redis": "^0.43.0", + "@opentelemetry/instrumentation-redis-4": "^0.43.0", + "@opentelemetry/instrumentation-restify": "^0.42.0", + "@opentelemetry/instrumentation-router": "^0.41.0", + "@opentelemetry/instrumentation-runtime-node": "^0.9.0", + "@opentelemetry/instrumentation-socket.io": "^0.43.0", + "@opentelemetry/instrumentation-tedious": "^0.15.0", + "@opentelemetry/instrumentation-undici": "^0.7.0", + "@opentelemetry/instrumentation-winston": "^0.41.0", "@opentelemetry/resource-detector-alibaba-cloud": "^0.29.1", "@opentelemetry/resource-detector-aws": "^1.6.1", "@opentelemetry/resource-detector-azure": "^0.2.11", - "@opentelemetry/resource-detector-container": "^0.4.1", + "@opentelemetry/resource-detector-container": "^0.5.0", "@opentelemetry/resource-detector-gcp": "^0.29.11", "@opentelemetry/resources": "^1.26.0", - "@opentelemetry/sdk-logs": "^0.53.0", - "@opentelemetry/sdk-node": "^0.53.0", - "@opentelemetry/winston-transport": "^0.6.0", + "@opentelemetry/sdk-logs": "^0.54.0", + "@opentelemetry/sdk-node": "^0.54.0", + "@opentelemetry/winston-transport": "^0.7.0", "@types/tape": "^5.6.4", "bunyan": "^1.8.15", "dotenv": "^16.4.5", diff --git a/packages/opentelemetry-node/docs/metrics.md b/packages/opentelemetry-node/docs/metrics.md index 9eead766..245f71a7 100644 --- a/packages/opentelemetry-node/docs/metrics.md +++ b/packages/opentelemetry-node/docs/metrics.md @@ -1,4 +1,13 @@ - + # Metrics @@ -20,7 +29,32 @@ node -r @elastic/opentelemetry-node/start.js my-app.js You can tune how often metrics data is exported to the endpoint and the max time to export data you can use the env vars already defined in [the spec](https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/#periodic-exporting-metricreader). -## Host metrics +## Process & runtime metrics + +EDOT Node.js gathers metrics from the nodejs process your application is +running. In order to do that EDOT Node.js is using the following packages: + +- `@opentelemetry/host-metrics` to gather `process.cpu.*` and `process.memory.*` metrics ([ref](https://github.com/open-telemetry/semantic-conventions/blob/80988c54712ee336cb3a6240b8845e9dfa8c9f49/docs/system/process-metrics.md?plain=1#L22)) +- `@opentelemetry/instrumentation-runtime-node` to gather `nodejs.eventloop.*` ([ref](https://github.com/open-telemetry/semantic-conventions/blob/80988c54712ee336cb3a6240b8845e9dfa8c9f49/model/nodejs/metrics.yaml)) and `v8js.*` ([ref](https://github.com/open-telemetry/semantic-conventions/blob/80988c54712ee336cb3a6240b8845e9dfa8c9f49/model/v8js/metrics.yaml)) metrics + +These metrics are useful when you're checking the performance of your +instrumented service. A subset of them are useful to detect possible +issues when doing an overview of the instrumented service. These are: + +- `nodejs.eventloop.delay.p50` and `nodejs.eventloop.delay.p90` are the + 50th and 90th [percentiles](https://en.wikipedia.org/wiki/Percentile) of + the event loop delay. The event loop delay measures the time span between + the scheduling of a callback and its execution. The bigger the number, + the more sync work you have in your service blocking the event loop. +- `nodejs.eventloop.utilization` is the utiliation of the event loop reported + by [`performance.eventLoopUtilization([utilization1[, utilization2]])`](https://nodejs.org/api/perf_hooks.html#performanceeventlooputilizationutilization1-utilization2) gives which + the percentage of time the event loop is being used (not idle). +- `process.cpu.utilization` is the percentage of time the CPU is running + the service code. Big values in this metric suggest your service is doing + compute intensive tasks. +- `process.memory.usage` is the value of [Resident Set Size](https://nodejs.org/api/process.html#processmemoryusagerss) in bytes. It + measures how much memory the process is allocating. + -EDOT Node.js also gathers metrics from the -host machine with `@opentelemetry/host-metrics` package. +If your service is instrumented by EDOT Node.js, or by custom instrumentation that includes the packages mentioned above, Kibana will +display them as part of the [service metrics](https://www.elastic.co/guide/en/observability/current/apm-metrics.html) in its UI. \ No newline at end of file diff --git a/packages/opentelemetry-node/lib/instrumentations.js b/packages/opentelemetry-node/lib/instrumentations.js index 00169a64..0ad43e4c 100644 --- a/packages/opentelemetry-node/lib/instrumentations.js +++ b/packages/opentelemetry-node/lib/instrumentations.js @@ -50,6 +50,7 @@ * "@opentelemetry/instrumentation-redis-4": import('@opentelemetry/instrumentation-redis-4').RedisInstrumentationConfig | InstrumentationFactory, * "@opentelemetry/instrumentation-restify": import('@opentelemetry/instrumentation-restify').RestifyInstrumentationConfig | InstrumentationFactory, * "@opentelemetry/instrumentation-router": import('@opentelemetry/instrumentation').InstrumentationConfig | InstrumentationFactory, + * "@opentelemetry/instrumentation-runtime-node": import('@opentelemetry/instrumentation-runtime-node').RuntimeNodeInstrumentationConfig | InstrumentationFactory, * "@opentelemetry/instrumentation-socket.io": import('@opentelemetry/instrumentation-socket.io').SocketIoInstrumentationConfig | InstrumentationFactory, * "@opentelemetry/instrumentation-tedious": import('@opentelemetry/instrumentation-tedious').TediousInstrumentationConfig | InstrumentationFactory, * "@opentelemetry/instrumentation-undici": import('@opentelemetry/instrumentation-undici').UndiciInstrumentationConfig | InstrumentationFactory, @@ -84,6 +85,7 @@ const {RedisInstrumentation} = require('@opentelemetry/instrumentation-redis'); const {RedisInstrumentation: RedisFourInstrumentation} = require('@opentelemetry/instrumentation-redis-4'); const {RestifyInstrumentation} = require('@opentelemetry/instrumentation-restify'); const {RouterInstrumentation} = require('@opentelemetry/instrumentation-router'); +const {RuntimeNodeInstrumentation} = require('@opentelemetry/instrumentation-runtime-node'); const {SocketIoInstrumentation} = require('@opentelemetry/instrumentation-socket.io'); const {TediousInstrumentation} = require('@opentelemetry/instrumentation-tedious'); const {UndiciInstrumentation} = require('@opentelemetry/instrumentation-undici'); @@ -126,6 +128,7 @@ const INSTRUMENTATIONS = { '@opentelemetry/instrumentation-redis-4': (cfg) => new RedisFourInstrumentation(cfg), '@opentelemetry/instrumentation-restify': (cfg) => new RestifyInstrumentation(cfg), '@opentelemetry/instrumentation-router': (cfg) => new RouterInstrumentation(cfg), + '@opentelemetry/instrumentation-runtime-node': (cfg) => new RuntimeNodeInstrumentation(cfg), '@opentelemetry/instrumentation-socket.io': (cfg) => new SocketIoInstrumentation(cfg), '@opentelemetry/instrumentation-tedious': (cfg) => new TediousInstrumentation(cfg), '@opentelemetry/instrumentation-undici': (cfg) => new UndiciInstrumentation(cfg), @@ -232,6 +235,16 @@ function getInstrumentations(opts = {}) { return; } + // Skip if metrics are disabled by env var + const isMetricsDisabled = + process.env.ELASTIC_OTEL_METRICS_DISABLED === 'true'; + if ( + isMetricsDisabled && + name === '@opentelemetry/instrumentation-runtime-node' + ) { + return; + } + const isFactory = typeof opts[name] === 'function'; const isObject = typeof opts[name] === 'object'; const instrFactory = isFactory ? opts[name] : INSTRUMENTATIONS[name]; diff --git a/packages/opentelemetry-node/lib/metrics/host.js b/packages/opentelemetry-node/lib/metrics/host.js index 4eaefcf8..b0820ef7 100644 --- a/packages/opentelemetry-node/lib/metrics/host.js +++ b/packages/opentelemetry-node/lib/metrics/host.js @@ -29,26 +29,14 @@ function enableHostMetrics() { hostMetricsInstance.start(); } -// It is known that host metrics sends a lot of data so for now we drop some -// instruments that are not handled by Kibana and doing aggregations -// for others that we want to include shorly (CPU metrics) -// Ref (data amount issue): https://github.com/elastic/elastic-otel-node/issues/51 -// Ref (metrics in Kibana): https://github.com/elastic/kibana/pull/174700 +// Dropping system metrics because: +// - sends a lot of data. Ref: https://github.com/elastic/elastic-otel-node/issues/51 +// - not displayed by Kibana in metrics dashboard. Ref: https://github.com/elastic/kibana/pull/199353 +// - recommendation is to use OTEL collector to get and export them /** @type {metrics.View[]} */ const HOST_METRICS_VIEWS = [ - // drop `system.network.*` (not in Kibana) new View({ - instrumentName: 'system.network.*', - aggregation: Aggregation.Drop(), - }), - // drop `system.cpu.time` (not in Kibana) - new View({ - instrumentName: 'system.cpu.time', - aggregation: Aggregation.Drop(), - }), - // drop `process.*` (not in Kibana) - new View({ - instrumentName: 'process.*', + instrumentName: 'system.*', aggregation: Aggregation.Drop(), }), ]; diff --git a/packages/opentelemetry-node/package-lock.json b/packages/opentelemetry-node/package-lock.json index e04030b5..6f92a135 100644 --- a/packages/opentelemetry-node/package-lock.json +++ b/packages/opentelemetry-node/package-lock.json @@ -43,6 +43,7 @@ "@opentelemetry/instrumentation-redis-4": "^0.43.0", "@opentelemetry/instrumentation-restify": "^0.42.0", "@opentelemetry/instrumentation-router": "^0.41.0", + "@opentelemetry/instrumentation-runtime-node": "^0.9.0", "@opentelemetry/instrumentation-socket.io": "^0.43.0", "@opentelemetry/instrumentation-tedious": "^0.15.0", "@opentelemetry/instrumentation-undici": "^0.7.0", @@ -2717,6 +2718,50 @@ "@opentelemetry/api": "^1.3.0" } }, + "node_modules/@opentelemetry/instrumentation-runtime-node": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-runtime-node/-/instrumentation-runtime-node-0.9.0.tgz", + "integrity": "sha512-D20X1Uz13exU70dpws4/Sc+zLU5F9MzfYrUt0AXK3yOt/BTXL7vsArQybWTaf2rnGFd35Gicfa/jRgFftoC0vw==", + "dependencies": { + "@opentelemetry/instrumentation": "^0.54.0" + }, + "engines": { + "node": ">=17.4.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-runtime-node/node_modules/@opentelemetry/api-logs": { + "version": "0.54.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.54.2.tgz", + "integrity": "sha512-4MTVwwmLgUh5QrJnZpYo6YRO5IBLAggf2h8gWDblwRagDStY13aEvt7gGk3jewrMaPlHiF83fENhIx0HO97/cQ==", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/instrumentation-runtime-node/node_modules/@opentelemetry/instrumentation": { + "version": "0.54.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.54.2.tgz", + "integrity": "sha512-go6zpOVoZVztT9r1aPd79Fr3OWiD4N24bCPJsIKkBses8oyFo12F/Ew3UBTdIu6hsW4HC4MVEJygG6TEyJI/lg==", + "dependencies": { + "@opentelemetry/api-logs": "0.54.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, "node_modules/@opentelemetry/instrumentation-socket.io": { "version": "0.43.0", "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-socket.io/-/instrumentation-socket.io-0.43.0.tgz", @@ -10393,6 +10438,37 @@ "@opentelemetry/semantic-conventions": "^1.27.0" } }, + "@opentelemetry/instrumentation-runtime-node": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-runtime-node/-/instrumentation-runtime-node-0.9.0.tgz", + "integrity": "sha512-D20X1Uz13exU70dpws4/Sc+zLU5F9MzfYrUt0AXK3yOt/BTXL7vsArQybWTaf2rnGFd35Gicfa/jRgFftoC0vw==", + "requires": { + "@opentelemetry/instrumentation": "^0.54.0" + }, + "dependencies": { + "@opentelemetry/api-logs": { + "version": "0.54.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.54.2.tgz", + "integrity": "sha512-4MTVwwmLgUh5QrJnZpYo6YRO5IBLAggf2h8gWDblwRagDStY13aEvt7gGk3jewrMaPlHiF83fENhIx0HO97/cQ==", + "requires": { + "@opentelemetry/api": "^1.3.0" + } + }, + "@opentelemetry/instrumentation": { + "version": "0.54.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.54.2.tgz", + "integrity": "sha512-go6zpOVoZVztT9r1aPd79Fr3OWiD4N24bCPJsIKkBses8oyFo12F/Ew3UBTdIu6hsW4HC4MVEJygG6TEyJI/lg==", + "requires": { + "@opentelemetry/api-logs": "0.54.2", + "@types/shimmer": "^1.2.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + } + } + } + }, "@opentelemetry/instrumentation-socket.io": { "version": "0.43.0", "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-socket.io/-/instrumentation-socket.io-0.43.0.tgz", diff --git a/packages/opentelemetry-node/package.json b/packages/opentelemetry-node/package.json index e60a402a..f4395e78 100644 --- a/packages/opentelemetry-node/package.json +++ b/packages/opentelemetry-node/package.json @@ -98,6 +98,7 @@ "@opentelemetry/instrumentation-redis-4": "^0.43.0", "@opentelemetry/instrumentation-restify": "^0.42.0", "@opentelemetry/instrumentation-router": "^0.41.0", + "@opentelemetry/instrumentation-runtime-node": "^0.9.0", "@opentelemetry/instrumentation-socket.io": "^0.43.0", "@opentelemetry/instrumentation-tedious": "^0.15.0", "@opentelemetry/instrumentation-undici": "^0.7.0", diff --git a/packages/opentelemetry-node/test/host-metrics.test.js b/packages/opentelemetry-node/test/host-metrics.test.js index 90bcc16d..b7f7e683 100644 --- a/packages/opentelemetry-node/test/host-metrics.test.js +++ b/packages/opentelemetry-node/test/host-metrics.test.js @@ -18,9 +18,10 @@ */ // Test that the view set by ElasticNodeSdk work as expected -// - dropping data points for `system.network.*` metrics -// - dropping data points for `system.cpu.time` metric -// - agreggating data points for `system.cpu.utilization` metric +// - dropping data points for `system.*` metrics +// - exporting data points for `process.*` metrics +// - exporting data points for `nodejs.*` metrics +// - exporting data points for `v8js.*` metrics const {test} = require('tape'); const {runTestFixtures} = require('./testutils'); @@ -43,68 +44,38 @@ const testFixtures = [ // verbose: true, checkTelemetry: (t, collector) => { const metrics = collector.metrics; - const networkMetrics = metrics.filter((metric) => - metric.name.startsWith('system.network') + const systemMetrics = metrics.filter((metric) => + metric.name.startsWith('system.') ); const processMetrics = metrics.filter((metric) => metric.name.startsWith('process.') ); - const cpuTimeMetrics = metrics.filter( - (metric) => metric.name === 'system.cpu.time' + const nodejsMetrics = metrics.filter((metric) => + metric.name.startsWith('nodejs.') ); - const cpuUtilizationMetrics = metrics.filter( - (metric) => metric.name === 'system.cpu.utilization' + const v8jsMetrics = metrics.filter((metric) => + metric.name.startsWith('v8js.') ); - t.ok( - networkMetrics.length === 0, - 'system.network.* metrics are dropped' - ); - t.ok(processMetrics.length === 0, 'process.* metrics are dropped'); - t.ok( - cpuTimeMetrics.length === 0, - 'system.cpu.time metric is dropped' - ); - cpuUtilizationMetrics.forEach((metric) => { - t.ok( - metric.gauge?.dataPoints, - 'data points are present in system.cpu.utilization metric' - ); - - // Note: Skip this too-frequently flaky test for now. See https://github.com/elastic/elastic-otel-node/issues/73 - // { - // "startTimeUnixNano": "1713354074349000000", - // "timeUnixNano": "1713354074349000000", - // "asDouble": 1.005859375, - // "attributes": - // { - // "system.cpu.state": "idle", - // "system.cpu.logical_number": "11" - // } - // }, - // const allInRange = metric.gauge?.dataPoints?.every( - // (dp) => 0 <= dp.asDouble && dp.asDouble <= 1 - // ); - // t.ok( - // allInRange, - // '"system.cpu.utilization" data points are in the range [0,1]' - // ); - // if (!allInRange) { - // // Note: extra output to debug flaky test (https://github.com/elastic/elastic-otel-node/issues/73). - // t.comment( - // 'cpuUtilizationMetrics: ' + - // JSON.stringify(cpuUtilizationMetrics) - // ); - // } + t.ok(systemMetrics.length === 0, 'system.* metrics are dropped'); + t.ok(processMetrics.length > 0, 'process metrics are collected'); + t.ok(nodejsMetrics.length > 0, 'Node.js metrics are collected'); + t.ok(v8jsMetrics.length > 0, 'V8 metrics are collected'); + // Check that, at least, we send the data which is going to be plotted + // in Kibana dashboard (mentioned in the docs). + [ + 'process.cpu.utilization', + 'process.memory.usage', + 'nodejs.eventloop.delay.p50', + 'nodejs.eventloop.delay.p90', + 'nodejs.eventloop.delay.max', + 'nodejs.eventloop.utilization', + // TODO: check for v8js specific ones when adding the to dashboards + ].forEach((name) => { t.ok( - metric.gauge?.dataPoints?.every( - (dp) => - dp.attributes && - dp.attributes['system.cpu.state'] && - dp.attributes['system.cpu.logical_number'] - ), - 'data points have "system.cpu.state" and "system.cpu.logical_number" attributes' + metrics.find((m) => m.name === name), + `metric "${name}" is collected` ); }); }, diff --git a/packages/opentelemetry-node/types/instrumentations.d.ts b/packages/opentelemetry-node/types/instrumentations.d.ts index 96db6cd7..2df1d694 100644 --- a/packages/opentelemetry-node/types/instrumentations.d.ts +++ b/packages/opentelemetry-node/types/instrumentations.d.ts @@ -27,6 +27,7 @@ export type InstrumentaionsMap = { "@opentelemetry/instrumentation-redis-4": import('@opentelemetry/instrumentation-redis-4').RedisInstrumentationConfig | InstrumentationFactory; "@opentelemetry/instrumentation-restify": import('@opentelemetry/instrumentation-restify').RestifyInstrumentationConfig | InstrumentationFactory; "@opentelemetry/instrumentation-router": import('@opentelemetry/instrumentation').InstrumentationConfig | InstrumentationFactory; + "@opentelemetry/instrumentation-runtime-node": import('@opentelemetry/instrumentation-runtime-node').RuntimeNodeInstrumentationConfig | InstrumentationFactory; "@opentelemetry/instrumentation-socket.io": import('@opentelemetry/instrumentation-socket.io').SocketIoInstrumentationConfig | InstrumentationFactory; "@opentelemetry/instrumentation-tedious": import('@opentelemetry/instrumentation-tedious').TediousInstrumentationConfig | InstrumentationFactory; "@opentelemetry/instrumentation-undici": import('@opentelemetry/instrumentation-undici').UndiciInstrumentationConfig | InstrumentationFactory;