@saidsef/tracing-node 3.22.6 → 4.1.0
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/README.md +28 -0
- package/libs/index.mjs +64 -87
- package/libs/index.test.mjs +23 -21
- package/package.json +18 -17
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@ Effortlessly supercharge your applications with world-class distributed tracing!
|
|
|
15
15
|
| Feature | Description |
|
|
16
16
|
|---------|-------------|
|
|
17
17
|
| HTTP/HTTPS instrumentation | Automatic service detection |
|
|
18
|
+
| fetch/undici instrumentation | Outgoing `globalThis.fetch` calls |
|
|
18
19
|
| Express.js support | Framework instrumentation |
|
|
19
20
|
| Elasticsearch client | Database instrumentation |
|
|
20
21
|
| IORedis client | Cache instrumentation |
|
|
@@ -36,6 +37,33 @@ Effortlessly supercharge your applications with world-class distributed tracing!
|
|
|
36
37
|
npm install @saidsef/tracing-node --save
|
|
37
38
|
```
|
|
38
39
|
|
|
40
|
+
## Upgrading to 4.0.0
|
|
41
|
+
|
|
42
|
+
**Breaking change: spans now carry the stable OpenTelemetry semantic conventions.**
|
|
43
|
+
|
|
44
|
+
The upstream instrumentations ([open-telemetry/opentelemetry-js-contrib#3585](https://github.com/open-telemetry/opentelemetry-js-contrib/pull/3585)) dropped the legacy attributes and removed the `OTEL_SEMCONV_STABILITY_OPT_IN` escape hatch, so there is no way to keep the old names. The public API of `setupTracing` / `stopTracing` is unchanged - no code changes are required - but any dashboard, alert or processor keyed on the old attribute names must be updated.
|
|
45
|
+
|
|
46
|
+
| Removed | Replacement | Affected spans |
|
|
47
|
+
|---------|-------------|----------------|
|
|
48
|
+
| `http.method` | `http.request.method` | HTTP |
|
|
49
|
+
| `http.status_code` | `http.response.status_code` | HTTP, AWS SDK |
|
|
50
|
+
| `http.url` | `url.full` | HTTP |
|
|
51
|
+
| `http.target` | `url.path` + `url.query` | HTTP |
|
|
52
|
+
| `http.scheme` | `url.scheme` | HTTP |
|
|
53
|
+
| `http.user_agent` | `user_agent.original` | HTTP |
|
|
54
|
+
| `http.client_ip` | `client.address` | HTTP |
|
|
55
|
+
| `http.flavor` | `network.protocol.version` | HTTP |
|
|
56
|
+
| `net.peer.name` | `server.address` | HTTP, IORedis |
|
|
57
|
+
| `net.peer.port` | `server.port` | HTTP, IORedis |
|
|
58
|
+
| `db.system` | `db.system.name` | IORedis, DynamoDB |
|
|
59
|
+
| `db.statement` | `db.query.text` | IORedis, DynamoDB |
|
|
60
|
+
| `db.operation` | `db.operation.name` | IORedis, DynamoDB |
|
|
61
|
+
| `db.connection_string` | none | IORedis |
|
|
62
|
+
|
|
63
|
+
Server-side HTTP metrics also move from `http.server.duration` (milliseconds) to `http.server.request.duration` (seconds), and the client equivalents likewise.
|
|
64
|
+
|
|
65
|
+
`peer.service` is unchanged, so Tempo/Grafana service graphs keep working as before. IORedis spans also gain `db.operation.name`, which distinguishes `MULTI`/`PIPELINE` commands.
|
|
66
|
+
|
|
39
67
|
## Usage
|
|
40
68
|
|
|
41
69
|
You can set required params via env variables or function:
|
package/libs/index.mjs
CHANGED
|
@@ -25,6 +25,7 @@ import {ExpressInstrumentation} from '@opentelemetry/instrumentation-express';
|
|
|
25
25
|
import {NodeTracerProvider} from '@opentelemetry/sdk-trace-node';
|
|
26
26
|
import {OTLPTraceExporter} from '@opentelemetry/exporter-trace-otlp-grpc';
|
|
27
27
|
import {PinoInstrumentation} from '@opentelemetry/instrumentation-pino';
|
|
28
|
+
import {UndiciInstrumentation} from '@opentelemetry/instrumentation-undici';
|
|
28
29
|
import {IORedisInstrumentation} from '@opentelemetry/instrumentation-ioredis';
|
|
29
30
|
import {registerInstrumentations} from '@opentelemetry/instrumentation';
|
|
30
31
|
import {FsInstrumentation} from '@opentelemetry/instrumentation-fs';
|
|
@@ -43,6 +44,30 @@ const setIntAttribute = (span, name, value) => {
|
|
|
43
44
|
}
|
|
44
45
|
};
|
|
45
46
|
|
|
47
|
+
// Slice before converting: String(buf) decodes a whole 1MB Buffer only to throw
|
|
48
|
+
// it away. 4 bytes per UTF-16 unit plus slack keeps the result byte-identical.
|
|
49
|
+
const truncateArg = (value, limit) => {
|
|
50
|
+
const str = Buffer.isBuffer(value) ? value.subarray(0, limit * 4 + 8).toString() : String(value);
|
|
51
|
+
return str.length > limit ? `${str.substring(0, limit)}...` : str;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// Tempo names a service-graph node from peer.service, which no instrumentation
|
|
55
|
+
// emits, so both the http and undici hooks below derive it from the remote host.
|
|
56
|
+
const PEER_SERVICES = ['elasticsearch', 'redis'];
|
|
57
|
+
|
|
58
|
+
const setPeerService = (span, host) => {
|
|
59
|
+
if (!host) return;
|
|
60
|
+
for (const service of PEER_SERVICES) {
|
|
61
|
+
if (host.includes(service)) {
|
|
62
|
+
span.setAttribute('peer.service', service);
|
|
63
|
+
span.setAttribute('db.system.name', service);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
let tracerProvider = null; // Declare provider in module scope for access in stopTracing
|
|
70
|
+
|
|
46
71
|
/**
|
|
47
72
|
* Sets up tracing for the application using OpenTelemetry.
|
|
48
73
|
*
|
|
@@ -53,7 +78,7 @@ const setIntAttribute = (span, name, value) => {
|
|
|
53
78
|
* service map visualization in distributed tracing tools like Tempo.
|
|
54
79
|
*
|
|
55
80
|
* @param {Object} options - Configuration options for tracing.
|
|
56
|
-
* @param {string} [options.hostname=process.env.HOSTNAME] - The hostname of the service.
|
|
81
|
+
* @param {string} [options.hostname=process.env.CONTAINER_NAME || process.env.HOSTNAME] - The hostname of the service.
|
|
57
82
|
* @param {string} [options.serviceName=process.env.SERVICE_NAME] - The name of the service.
|
|
58
83
|
* @param {string} [options.url=process.env.ENDPOINT] - The endpoint URL for the tracing collector.
|
|
59
84
|
* @param {number} [options.concurrencyLimit=10] - The concurrency limit for the exporter.
|
|
@@ -62,12 +87,10 @@ const setIntAttribute = (span, name, value) => {
|
|
|
62
87
|
*
|
|
63
88
|
* @returns {Tracer} - The tracer for the service.
|
|
64
89
|
*/
|
|
65
|
-
let tracerProvider = null; // Declare provider in module scope for access in stopTracing
|
|
66
|
-
|
|
67
90
|
export function setupTracing(options = {}) {
|
|
68
91
|
// Prevent multiple initializations - return existing provider if already set up
|
|
69
92
|
if (tracerProvider) {
|
|
70
|
-
|
|
93
|
+
diag.warn('Tracing is already initialized. Returning existing tracer.');
|
|
71
94
|
return tracerProvider.getTracer(options.serviceName || process.env.SERVICE_NAME);
|
|
72
95
|
}
|
|
73
96
|
|
|
@@ -95,10 +118,8 @@ export function setupTracing(options = {}) {
|
|
|
95
118
|
timeoutMillis: 10000,
|
|
96
119
|
};
|
|
97
120
|
|
|
98
|
-
// Register the span processor with the tracer provider
|
|
99
121
|
const exporter = new OTLPTraceExporter(exportOptions);
|
|
100
122
|
|
|
101
|
-
// Configure BatchSpanProcessor for production workloads
|
|
102
123
|
const spanProcessor = new BatchSpanProcessor(exporter, {
|
|
103
124
|
maxQueueSize: 4096,
|
|
104
125
|
maxExportBatchSize: 1024,
|
|
@@ -127,72 +148,49 @@ export function setupTracing(options = {}) {
|
|
|
127
148
|
// explicit config, with the recommended context manager.
|
|
128
149
|
tracerProvider.register();
|
|
129
150
|
|
|
130
|
-
//
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const hostname = request?.hostname || request?.host || '';
|
|
134
|
-
|
|
135
|
-
// Detect Elasticsearch endpoints
|
|
136
|
-
if (hostname.includes('elasticsearch') || url.includes('elasticsearch') ||
|
|
137
|
-
hostname.includes(':9200') || url.includes(':9200')) {
|
|
138
|
-
span.setAttribute('peer.service', 'elasticsearch');
|
|
139
|
-
span.setAttribute('db.system', 'elasticsearch');
|
|
140
|
-
}
|
|
151
|
+
// Only an outgoing ClientRequest carries .host, so bailing without it keeps
|
|
152
|
+
// server spans out: peer.service must name the remote service being called.
|
|
153
|
+
const applyCustomAttributesOnSpan = (span, request) => setPeerService(span, request?.host);
|
|
141
154
|
|
|
142
|
-
// Detect Redis endpoints
|
|
143
|
-
if (hostname.includes('redis') || url.includes('redis') ||
|
|
144
|
-
hostname.includes(':6379') || url.includes(':6379')) {
|
|
145
|
-
span.setAttribute('peer.service', 'redis');
|
|
146
|
-
span.setAttribute('db.system', 'redis');
|
|
147
|
-
}
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
// Register instrumentations
|
|
151
155
|
const instrumentations = [
|
|
152
156
|
new HttpInstrumentation({
|
|
153
|
-
serverName: serviceName,
|
|
154
157
|
// Ignore spans from static assets (metrics/health probes).
|
|
155
158
|
ignoreIncomingRequestHook: (req) => req.url.startsWith('/metrics') || req.url.startsWith('/healthz'),
|
|
156
159
|
applyCustomAttributesOnSpan,
|
|
157
160
|
requestHook: (span, request) => {
|
|
158
|
-
//
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const headers = request.headers;
|
|
161
|
+
// Outgoing ClientRequest exposes getHeaders(); incoming IncomingMessage has .headers.
|
|
162
|
+
const headers = request.getHeaders?.() ?? request.headers;
|
|
163
|
+
if (!headers) return;
|
|
162
164
|
|
|
163
|
-
|
|
164
|
-
const
|
|
165
|
-
const
|
|
166
|
-
const contentLength = headers['content-length'] || headers['Content-Length'];
|
|
167
|
-
const requestId = headers['x-request-id'] || headers['X-Request-ID'];
|
|
168
|
-
const correlationId = headers['x-correlation-id'] || headers['X-Correlation-ID'];
|
|
165
|
+
const contentType = headers['content-type'];
|
|
166
|
+
const requestId = headers['x-request-id'];
|
|
167
|
+
const correlationId = headers['x-correlation-id'];
|
|
169
168
|
|
|
170
|
-
// Only set attributes if values exist
|
|
171
|
-
if (userAgent) span.setAttribute('http.user_agent', userAgent);
|
|
172
169
|
if (contentType) span.setAttribute('http.request.content_type', contentType);
|
|
173
|
-
|
|
174
|
-
setIntAttribute(span, 'http.request.content_length', contentLength);
|
|
175
|
-
|
|
176
|
-
// Correlation headers for distributed tracing
|
|
170
|
+
setIntAttribute(span, 'http.request.content_length', headers['content-length']);
|
|
177
171
|
if (requestId) span.setAttribute('http.request_id', requestId);
|
|
178
172
|
if (correlationId) span.setAttribute('http.correlation_id', correlationId);
|
|
179
173
|
},
|
|
180
174
|
responseHook: (span, response) => {
|
|
181
|
-
// Add response attributes for better observability
|
|
182
175
|
if (!response.headers) return;
|
|
183
176
|
|
|
184
177
|
const headers = response.headers;
|
|
185
|
-
const contentType = headers['content-type']
|
|
186
|
-
const
|
|
187
|
-
const requestId = headers['x-request-id'] || headers['X-Request-ID'];
|
|
178
|
+
const contentType = headers['content-type'];
|
|
179
|
+
const requestId = headers['x-request-id'];
|
|
188
180
|
|
|
189
181
|
if (contentType) span.setAttribute('http.response.content_type', contentType);
|
|
190
|
-
|
|
191
|
-
setIntAttribute(span, 'http.response.content_length', contentLength);
|
|
192
|
-
|
|
182
|
+
setIntAttribute(span, 'http.response.content_length', headers['content-length']);
|
|
193
183
|
if (requestId) span.setAttribute('http.request_id', requestId);
|
|
194
184
|
},
|
|
195
185
|
}),
|
|
186
|
+
// globalThis.fetch runs on undici, which never touches the http/https
|
|
187
|
+
// modules HttpInstrumentation patches. Without this, fetch calls produce no
|
|
188
|
+
// client span and inject no traceparent, so the callee starts a new trace
|
|
189
|
+
// and the two services can never be paired into a service-graph edge.
|
|
190
|
+
new UndiciInstrumentation({
|
|
191
|
+
// UndiciRequest exposes origin, not the .host the http hook reads.
|
|
192
|
+
requestHook: (span, request) => setPeerService(span, request?.origin),
|
|
193
|
+
}),
|
|
196
194
|
new ExpressInstrumentation({
|
|
197
195
|
requestHook: (span, info) => {
|
|
198
196
|
// info is ExpressRequestInfo: { request, route, layerType }
|
|
@@ -249,17 +247,12 @@ export function setupTracing(options = {}) {
|
|
|
249
247
|
new IORedisInstrumentation({
|
|
250
248
|
requireParentSpan: false,
|
|
251
249
|
requestHook: (span, {cmdName, cmdArgs}) => {
|
|
252
|
-
//
|
|
253
|
-
//
|
|
254
|
-
//
|
|
255
|
-
// already set to the real host by the instrumentation, so we do not
|
|
256
|
-
// override those here.
|
|
250
|
+
// peer.service drives the Tempo service graph and is never emitted by
|
|
251
|
+
// the instrumentation, so it has to be set here. db.system.name,
|
|
252
|
+
// db.operation.name and server.* already come from the instrumentation.
|
|
257
253
|
span.setAttribute('peer.service', 'redis');
|
|
258
|
-
span.setAttribute('db.system', 'redis');
|
|
259
254
|
|
|
260
|
-
// Add command details for better observability
|
|
261
255
|
if (cmdName) {
|
|
262
|
-
span.setAttribute('db.operation', cmdName.toUpperCase());
|
|
263
256
|
span.updateName(`redis.${cmdName.toUpperCase()}`);
|
|
264
257
|
}
|
|
265
258
|
|
|
@@ -274,9 +267,8 @@ export function setupTracing(options = {}) {
|
|
|
274
267
|
}
|
|
275
268
|
},
|
|
276
269
|
responseHook: (span, cmdName, cmdArgs, response) => {
|
|
277
|
-
// peer.service
|
|
278
|
-
//
|
|
279
|
-
// re-set here. Record only the response shape for observability.
|
|
270
|
+
// peer.service is already set by requestHook and persists for the
|
|
271
|
+
// span's lifetime, so only the response shape is recorded here.
|
|
280
272
|
if (response !== undefined && response !== null) {
|
|
281
273
|
span.setAttribute('db.response.type', typeof response);
|
|
282
274
|
if (Array.isArray(response)) {
|
|
@@ -285,37 +277,22 @@ export function setupTracing(options = {}) {
|
|
|
285
277
|
}
|
|
286
278
|
},
|
|
287
279
|
dbStatementSerializer: (cmdName, cmdArgs) => {
|
|
288
|
-
|
|
289
|
-
const args = cmdArgs.map(arg => {
|
|
290
|
-
const str = String(arg);
|
|
291
|
-
return str.length > 100 ? `${str.substring(0, 100)}...` : str;
|
|
292
|
-
});
|
|
280
|
+
const args = cmdArgs.map(arg => truncateArg(arg, 100));
|
|
293
281
|
return `${cmdName} ${args.join(' ')}`;
|
|
294
282
|
},
|
|
295
283
|
}),
|
|
296
284
|
new ElasticsearchInstrumentation(),
|
|
285
|
+
// Spread so the optional instrumentations are constructed only when enabled:
|
|
286
|
+
// FsInstrumentation patches fs on construction.
|
|
287
|
+
...(enableFsInstrumentation ? [new FsInstrumentation()] : []),
|
|
288
|
+
// DnsInstrumentationConfig accepts only ignoreHostnames; it has no hooks.
|
|
289
|
+
...(enableDnsInstrumentation ? [new DnsInstrumentation({ignoreHostnames: ['localhost', '127.0.0.1', '::1']})] : []),
|
|
297
290
|
];
|
|
298
291
|
|
|
299
|
-
if (enableFsInstrumentation) {
|
|
300
|
-
// Enable fs instrumentation if specified
|
|
301
|
-
// This instrumentation is useful for tracing file system operations.
|
|
302
|
-
instrumentations.push(new FsInstrumentation());
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
if (enableDnsInstrumentation) {
|
|
306
|
-
// Enable DNS instrumentation if specified
|
|
307
|
-
// This instrumentation is useful for tracing DNS operations.
|
|
308
|
-
// DnsInstrumentationConfig only supports ignoreHostnames; it has no
|
|
309
|
-
// request/response/error hooks.
|
|
310
|
-
instrumentations.push(new DnsInstrumentation({
|
|
311
|
-
ignoreHostnames: ['localhost', '127.0.0.1', '::1'],
|
|
312
|
-
}));
|
|
313
|
-
}
|
|
314
|
-
|
|
315
292
|
// Register instrumentations
|
|
316
293
|
registerInstrumentations({
|
|
317
|
-
tracerProvider
|
|
318
|
-
instrumentations
|
|
294
|
+
tracerProvider,
|
|
295
|
+
instrumentations,
|
|
319
296
|
});
|
|
320
297
|
|
|
321
298
|
// Return the tracer for the service
|
|
@@ -336,12 +313,12 @@ export async function stopTracing() {
|
|
|
336
313
|
try {
|
|
337
314
|
await tracerProvider.shutdown();
|
|
338
315
|
tracerProvider = null;
|
|
339
|
-
|
|
316
|
+
diag.info('Tracing has been successfully shut down.');
|
|
340
317
|
} catch (error) {
|
|
341
|
-
|
|
318
|
+
diag.error('Error during tracing shutdown:', error);
|
|
342
319
|
}
|
|
343
320
|
} else {
|
|
344
|
-
|
|
321
|
+
diag.warn('Tracer provider is not initialized.');
|
|
345
322
|
}
|
|
346
323
|
}
|
|
347
324
|
|
package/libs/index.test.mjs
CHANGED
|
@@ -1,48 +1,38 @@
|
|
|
1
1
|
// index.test.mjs
|
|
2
2
|
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
3
3
|
import assert from 'node:assert';
|
|
4
|
+
import { setupTracing, stopTracing, __resetTracingForTesting } from './index.mjs';
|
|
4
5
|
|
|
5
6
|
describe('setupTracing', () => {
|
|
6
|
-
let stopTracing;
|
|
7
|
-
|
|
8
7
|
// Clear environment and reset tracing state before each test
|
|
9
|
-
beforeEach(
|
|
8
|
+
beforeEach(() => {
|
|
10
9
|
delete process.env.SERVICE_NAME;
|
|
11
10
|
delete process.env.ENDPOINT;
|
|
12
11
|
delete process.env.HOSTNAME;
|
|
13
12
|
delete process.env.CONTAINER_NAME;
|
|
14
13
|
|
|
15
|
-
// Import and store stopTracing for cleanup
|
|
16
|
-
const tracing = await import('./index.mjs');
|
|
17
|
-
stopTracing = tracing.stopTracing;
|
|
18
|
-
|
|
19
14
|
// Reset singleton for test isolation
|
|
20
|
-
|
|
15
|
+
__resetTracingForTesting();
|
|
21
16
|
});
|
|
22
17
|
|
|
23
18
|
// Clean up tracing after each test
|
|
24
19
|
afterEach(async () => {
|
|
25
|
-
|
|
26
|
-
await stopTracing();
|
|
27
|
-
}
|
|
20
|
+
await stopTracing();
|
|
28
21
|
});
|
|
29
22
|
|
|
30
|
-
it('should throw error when serviceName is not provided',
|
|
31
|
-
const { setupTracing } = await import('./index.mjs');
|
|
23
|
+
it('should throw error when serviceName is not provided', () => {
|
|
32
24
|
assert.throws(() => {
|
|
33
25
|
setupTracing({ url: 'http://localhost:4317' });
|
|
34
26
|
}, /serviceName is required/);
|
|
35
27
|
});
|
|
36
28
|
|
|
37
|
-
it('should throw error when url is not provided',
|
|
38
|
-
const { setupTracing } = await import('./index.mjs');
|
|
29
|
+
it('should throw error when url is not provided', () => {
|
|
39
30
|
assert.throws(() => {
|
|
40
31
|
setupTracing({ serviceName: 'test-service' });
|
|
41
32
|
}, /url is required/);
|
|
42
33
|
});
|
|
43
34
|
|
|
44
|
-
it('should create a tracer with required parameters',
|
|
45
|
-
const { setupTracing } = await import('./index.mjs');
|
|
35
|
+
it('should create a tracer with required parameters', () => {
|
|
46
36
|
const tracer = setupTracing({
|
|
47
37
|
serviceName: 'test-service',
|
|
48
38
|
url: 'http://localhost:4317',
|
|
@@ -50,8 +40,7 @@ describe('setupTracing', () => {
|
|
|
50
40
|
assert.ok(tracer, 'tracer should be defined');
|
|
51
41
|
});
|
|
52
42
|
|
|
53
|
-
it('should accept hostname parameter',
|
|
54
|
-
const { setupTracing } = await import('./index.mjs');
|
|
43
|
+
it('should accept hostname parameter', () => {
|
|
55
44
|
const tracer = setupTracing({
|
|
56
45
|
serviceName: 'test-service',
|
|
57
46
|
url: 'http://localhost:4317',
|
|
@@ -60,8 +49,21 @@ describe('setupTracing', () => {
|
|
|
60
49
|
assert.ok(tracer, 'tracer should be defined');
|
|
61
50
|
});
|
|
62
51
|
|
|
63
|
-
|
|
64
|
-
|
|
52
|
+
// globalThis.fetch runs on undici, so it is invisible to HttpInstrumentation.
|
|
53
|
+
// Registering it must not disturb setup, and the patch has to land on the
|
|
54
|
+
// global fetch itself - otherwise outgoing calls carry no traceparent.
|
|
55
|
+
it('should instrument global fetch', () => {
|
|
56
|
+
const before = globalThis.fetch;
|
|
57
|
+
const tracer = setupTracing({
|
|
58
|
+
serviceName: 'test-service',
|
|
59
|
+
url: 'http://localhost:4317',
|
|
60
|
+
});
|
|
61
|
+
assert.ok(tracer, 'tracer should be defined');
|
|
62
|
+
assert.strictEqual(typeof globalThis.fetch, 'function', 'global fetch should still be callable');
|
|
63
|
+
assert.ok(before, 'global fetch should exist on a supported runtime');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should accept optional instrumentations', () => {
|
|
65
67
|
const tracer = setupTracing({
|
|
66
68
|
serviceName: 'test-service',
|
|
67
69
|
url: 'http://localhost:4317',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saidsef/tracing-node",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "tracing NodeJS - Wrapper for OpenTelemetry instrumentation packages",
|
|
5
5
|
"main": "libs/index.mjs",
|
|
6
6
|
"scripts": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"author": "Said Sef <saidsef@gmail.com>",
|
|
24
24
|
"license": "Apache-2.0",
|
|
25
25
|
"engines": {
|
|
26
|
-
"node": ">= 20"
|
|
26
|
+
"node": ">= 20.6.0"
|
|
27
27
|
},
|
|
28
28
|
"bugs": {
|
|
29
29
|
"url": "https://github.com/saidsef/tracing-node/issues"
|
|
@@ -31,30 +31,31 @@
|
|
|
31
31
|
"homepage": "https://github.com/saidsef/tracing-node#readme",
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@opentelemetry/api": "^1.9.0",
|
|
34
|
-
"@opentelemetry/exporter-trace-otlp-grpc": "^0.
|
|
35
|
-
"@opentelemetry/instrumentation": "^0.
|
|
36
|
-
"@opentelemetry/instrumentation-aws-sdk": "^0.
|
|
37
|
-
"@opentelemetry/instrumentation-connect": "^0.
|
|
34
|
+
"@opentelemetry/exporter-trace-otlp-grpc": "^0.221.0",
|
|
35
|
+
"@opentelemetry/instrumentation": "^0.221.0",
|
|
36
|
+
"@opentelemetry/instrumentation-aws-sdk": "^0.76.0",
|
|
37
|
+
"@opentelemetry/instrumentation-connect": "^0.64.0",
|
|
38
38
|
"@opentelemetry/instrumentation-dns": "^0.64.0",
|
|
39
|
-
"@opentelemetry/instrumentation-express": "^0.
|
|
39
|
+
"@opentelemetry/instrumentation-express": "^0.69.0",
|
|
40
40
|
"@opentelemetry/instrumentation-fs": "^0.40.0",
|
|
41
|
-
"@opentelemetry/instrumentation-http": "^0.
|
|
42
|
-
"@opentelemetry/instrumentation-ioredis": "^0.
|
|
43
|
-
"@opentelemetry/instrumentation-pino": "^0.
|
|
44
|
-
"@opentelemetry/
|
|
45
|
-
"@opentelemetry/
|
|
46
|
-
"@opentelemetry/sdk-trace-
|
|
47
|
-
"@opentelemetry/
|
|
41
|
+
"@opentelemetry/instrumentation-http": "^0.221.0",
|
|
42
|
+
"@opentelemetry/instrumentation-ioredis": "^0.69.0",
|
|
43
|
+
"@opentelemetry/instrumentation-pino": "^0.67.0",
|
|
44
|
+
"@opentelemetry/instrumentation-undici": "^0.31.0",
|
|
45
|
+
"@opentelemetry/resources": "^2.10.0",
|
|
46
|
+
"@opentelemetry/sdk-trace-base": "^2.10.0",
|
|
47
|
+
"@opentelemetry/sdk-trace-node": "^2.10.0",
|
|
48
|
+
"@opentelemetry/semantic-conventions": "^1.43.0",
|
|
48
49
|
"opentelemetry-instrumentation-elasticsearch": "^0.41.0"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
|
-
"eslint": "^10.
|
|
52
|
+
"eslint": "^10.8.0"
|
|
52
53
|
},
|
|
53
54
|
"overrides": {
|
|
54
55
|
"protobufjs": "^7.5.3",
|
|
55
|
-
"@opentelemetry/core": "^2.
|
|
56
|
+
"@opentelemetry/core": "^2.10.0"
|
|
56
57
|
},
|
|
57
58
|
"allowScripts": {
|
|
58
|
-
"protobufjs@7.6.
|
|
59
|
+
"protobufjs@7.6.5": true
|
|
59
60
|
}
|
|
60
61
|
}
|