@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 +7 -6
- package/README.md +13 -5
- package/libs/index.mjs +20 -5
- package/package.json +11 -5
package/CONTRIBUTING.md
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
# Contributing
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
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.
|
|
10
|
-
2.
|
|
11
|
-
3.
|
|
12
|
-
4.
|
|
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
|

|
|
9
9
|

|
|
10
10
|
|
|
11
|
-
**Traces, metrics and logs from one function call.** Add two lines to a service
|
|
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
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
120
|
-
*
|
|
121
|
-
*
|
|
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": "
|
|
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
|