@saidsef/tracing-node 6.1.0 → 7.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CONTRIBUTING.md CHANGED
@@ -1,15 +1,16 @@
1
1
  # Contributing
2
2
 
3
- When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change.
3
+ Please open an issue to discuss a change before you make it, or reach the owners of this repository by email or whatever other route you prefer. Agreeing the shape of a change first saves rework on both sides.
4
4
 
5
- Please note we have a code of conduct, please follow it in all your interactions with the project.
5
+ This project has a code of conduct. It applies to every interaction with the project, so please follow it.
6
6
 
7
7
  ## Pull Request Process
8
8
 
9
- 1. Ensure any install or build dependencies are removed before the end of the layer when doing a build.
10
- 2. Update the `package.json`, run `npm run rebuild` and add commit message with details of changes, this includes new environment variables, useful file locations and parameters.
11
- 3. Increase the version numbers is managed by the GitHub Actions CI workflow via `tagging.yml` and `release.yml`
12
- 4. You may merge the Pull Request in once you have the sign-off of from the project team, or if you do not have permission to do that, you may request a reviewer to merge it for you.
9
+ 1. Run `npm run lint` and `npm test` locally. Both need to pass before you open the pull request.
10
+ 2. Bump the version in `package.json`, with the increment matching the scope of your change. Run `npm run rebuild` where you have changed a dependency, which refreshes `package-lock.json`.
11
+ 3. Describe the change in the commit message. Name any new environment variable, option or file path that a user of the library will need to know about.
12
+ 4. The `Release` workflow reads the version from `package.json`, tags `v<version>`, publishes the GitHub release and pushes the package to npm. You do not need to create a tag yourself.
13
+ 5. A member of the project team signs the pull request off before it merges. Ask a reviewer to merge it for you where you do not have permission to do it yourself.
13
14
 
14
15
  ## Code of Conduct
15
16
 
package/README.md CHANGED
@@ -8,9 +8,9 @@
8
8
  ![GitHub release(latest by date)](https://img.shields.io/github/v/release/saidsef/tracing-node)
9
9
  ![Commits](https://img.shields.io/github/commits-since/saidsef/tracing-node/latest.svg)
10
10
 
11
- **Traces, metrics and logs from one function call.** Add two lines to a service, and its requests, its calls to Redis, Elasticsearch, AWS and other services, its runtime counters and its Pino log records all arrive at your collector, already correlated by trace id and stitched into a service graph.
11
+ **Traces, metrics and logs from one function call.** Add two lines to a service and everything it does arrives at your collector: its requests, its calls to Redis, Elasticsearch and AWS, its runtime counters, its Pino log records. All of it correlated by trace id and stitched into a service graph.
12
12
 
13
- `@saidsef/tracing-node` wraps the OpenTelemetry Node SDK. One call to `setupTracing` builds the tracer, meter and logger providers, registers them globally, and turns on a fixed set of instrumentations, so an application gets all three signals without assembling exporters, span processors, resource detectors and instrumentation packages itself. A second call logs a warning and returns the tracer that already exists, which makes initialisation idempotent.
13
+ `@saidsef/tracing-node` wraps the OpenTelemetry Node SDK. One call to `setupTracing` builds the tracer, meter and logger providers, registers them globally, and turns on a fixed set of instrumentations. An application gets all three signals without assembling exporters, span processors, resource detectors and instrumentation packages itself. A second call logs a warning and returns the tracer that already exists, which makes initialisation idempotent.
14
14
 
15
15
  Full documentation: [tracing-node.readthedocs.io](https://tracing-node.readthedocs.io/).
16
16
 
@@ -26,6 +26,14 @@ Full documentation: [tracing-node.readthedocs.io](https://tracing-node.readthedo
26
26
  npm install @saidsef/tracing-node --save
27
27
  ```
28
28
 
29
+ Elasticsearch spans carrying the query, the operation and the index name need an optional peer dependency:
30
+
31
+ ```shell
32
+ npm install opentelemetry-instrumentation-elasticsearch --save
33
+ ```
34
+
35
+ That package pins `@opentelemetry/core` to the 1.x line, so installing it brings [GHSA-8988-4f7v-96qf](https://github.com/advisories/GHSA-8988-4f7v-96qf) into the dependency tree. Leave it out and an Elasticsearch call is still traced as an HTTP client span, still on the service graph. See [Instrumentation](https://tracing-node.readthedocs.io/en/latest/instrumentation/) for what each option records.
36
+
29
37
  ## Usage
30
38
 
31
39
  ```javascript
@@ -41,11 +49,11 @@ node --import ./instrument.mjs ./app.mjs
41
49
 
42
50
  `serviceName` and `url` are required, and both fall back to the `SERVICE_NAME` and `ENDPOINT` environment variables.
43
51
 
44
- `setupTracing` has to run before the application imports the libraries being traced, which is what the `--import` preload guarantees. The library registers the `import-in-the-middle` loader hook on import, so ES modules and CommonJS modules are both patched. Importing an instrumented package statically in the same file as the library loads it too early to be patched, so the preload is the form to reach for. [Initialisation order](https://tracing-node.readthedocs.io/en/latest/usage/#initialisation-order) covers the alternatives.
52
+ `setupTracing` has to run before the application imports the libraries being traced, and the `--import` preload guarantees it. The library registers the `import-in-the-middle` loader hook on import, which covers ES modules and CommonJS modules alike. Importing an instrumented package statically in the same file as the library loads it too early to patch, so reach for the preload. [Initialisation order](https://tracing-node.readthedocs.io/en/latest/usage/#initialisation-order) covers the alternatives.
45
53
 
46
54
  ## Collector and backend
47
55
 
48
- The exporter speaks OTLP over gRPC, so any OpenTelemetry-compatible collector accepts all three signals. Point `url` at yours.
56
+ The exporter speaks OTLP over gRPC, which any OpenTelemetry-compatible collector accepts for all three signals. Point `url` at yours.
49
57
 
50
58
  [**grafana-loki-on-k8s**](https://github.com/saidsef/grafana-loki-on-k8s) is the companion stack, and the one the end to end harness in [`test/e2e/`](./test/e2e) targets. It deploys Grafana, Prometheus, Mimir, Loki, Tempo, Pyroscope, Alloy and Beyla to Kubernetes as small composable manifests.
51
59
 
@@ -54,7 +62,7 @@ git clone https://github.com/saidsef/grafana-loki-on-k8s
54
62
  kubectl apply -k grafana-loki-on-k8s/deployment
55
63
  ```
56
64
 
57
- Traces sent to its Alloy OTLP receiver on port 4317 land in Tempo, log records in Loki and metrics in Mimir. Tempo's metrics generator turns the spans into RED and service graph metrics, which is what the `peer.service` attribute this library sets exists to feed.
65
+ Traces sent to its Alloy OTLP receiver on port 4317 land in Tempo, log records in Loki and metrics in Mimir. Tempo's metrics generator turns the spans into RED and service graph metrics. Feeding those is why this library sets the `peer.service` attribute.
58
66
 
59
67
  ## Documentation
60
68
 
package/libs/index.mjs CHANGED
@@ -23,7 +23,6 @@ import {ConnectInstrumentation} from '@opentelemetry/instrumentation-connect';
23
23
  import {diag, DiagConsoleLogger, DiagLogLevel, metrics} from '@opentelemetry/api';
24
24
  import {HttpInstrumentation} from '@opentelemetry/instrumentation-http';
25
25
  import {DnsInstrumentation} from '@opentelemetry/instrumentation-dns';
26
- import {ElasticsearchInstrumentation} from 'opentelemetry-instrumentation-elasticsearch';
27
26
  import {ExpressInstrumentation, ExpressLayerType} from '@opentelemetry/instrumentation-express';
28
27
  import {logs} from '@opentelemetry/api-logs';
29
28
  import {NodeTracerProvider} from '@opentelemetry/sdk-trace-node';
@@ -50,6 +49,21 @@ if (esmHookFailure) {
50
49
  diag.warn(`ESM loader hook not registered, so ES module imports are not instrumented: ${esmHookFailure.message}`);
51
50
  }
52
51
 
52
+ // An optional peer dependency: it pins @opentelemetry/core 1.x, which carries a
53
+ // published advisory. Absent, an Elasticsearch call still gets a client span from
54
+ // the http or undici instrumentation. See #576.
55
+ let ElasticsearchInstrumentation = null;
56
+ try {
57
+ ({ElasticsearchInstrumentation} = await import('opentelemetry-instrumentation-elasticsearch'));
58
+ } catch (error) {
59
+ // Absence is the expected case. An installed but unloadable package would
60
+ // otherwise vanish silently, and tracing must not take the application down.
61
+ if (error?.code !== 'ERR_MODULE_NOT_FOUND') {
62
+ diag.warn('opentelemetry-instrumentation-elasticsearch failed to load:', error);
63
+ }
64
+ }
65
+
66
+
53
67
  // Set a non-negative integer span attribute from a header value; ignore invalid input.
54
68
  const setIntAttribute = (span, name, value) => {
55
69
  if (!value) return;
@@ -116,9 +130,10 @@ let loggerProvider = null;
116
130
  *
117
131
  * This function configures a NodeTracerProvider with various instrumentations
118
132
  * and span processors to enable tracing for the application. It supports
119
- * tracing for HTTP, Express, AWS, Pino, DNS, Elasticsearch, and IORedis.
120
- * The IORedis instrumentation includes peer.service attributes for proper
121
- * service map visualization in distributed tracing tools like Tempo.
133
+ * tracing for HTTP, Express, AWS, Pino, DNS, and IORedis, and for Elasticsearch
134
+ * when the optional opentelemetry-instrumentation-elasticsearch package is
135
+ * installed. The IORedis instrumentation includes peer.service attributes for
136
+ * proper service map visualization in distributed tracing tools like Tempo.
122
137
  *
123
138
  * A MeterProvider is registered alongside it, which is what makes the
124
139
  * instrumentations record the request duration histograms they already
@@ -356,7 +371,7 @@ export function setupTracing(options = {}) {
356
371
  return `${cmdName} ${args.join(' ')}`;
357
372
  },
358
373
  }),
359
- new ElasticsearchInstrumentation(),
374
+ ...(ElasticsearchInstrumentation ? [new ElasticsearchInstrumentation()] : []),
360
375
  // Event loop delay, GC pauses and heap occupancy are metric-only, and they
361
376
  // are what explains a whole service slowing at once. Constructed only with
362
377
  // metrics on, since the collectors start sampling on construction.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saidsef/tracing-node",
3
- "version": "6.1.0",
3
+ "version": "7.0.1",
4
4
  "description": "tracing NodeJS - Wrapper for OpenTelemetry instrumentation packages",
5
5
  "main": "libs/index.mjs",
6
6
  "scripts": {
@@ -54,15 +54,21 @@
54
54
  "@opentelemetry/sdk-trace-base": "^2.11.0",
55
55
  "@opentelemetry/sdk-trace-node": "^2.11.0",
56
56
  "@opentelemetry/semantic-conventions": "^1.43.0",
57
- "import-in-the-middle": "^3.0.0",
58
- "opentelemetry-instrumentation-elasticsearch": "^0.41.0"
57
+ "import-in-the-middle": "^3.0.0"
59
58
  },
60
59
  "devDependencies": {
61
60
  "eslint": "^10.10.0"
62
61
  },
62
+ "peerDependencies": {
63
+ "opentelemetry-instrumentation-elasticsearch": "^0.41.0"
64
+ },
65
+ "peerDependenciesMeta": {
66
+ "opentelemetry-instrumentation-elasticsearch": {
67
+ "optional": true
68
+ }
69
+ },
63
70
  "overrides": {
64
- "protobufjs": "^7.5.3",
65
- "@opentelemetry/core": "^2.11.0"
71
+ "protobufjs": "^7.5.3"
66
72
  },
67
73
  "allowScripts": {
68
74
  "protobufjs@7.6.6": true