@saidsef/tracing-node 3.13.4 → 3.13.6

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/libs/index.mjs CHANGED
@@ -60,6 +60,12 @@ diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);
60
60
  let tracerProvider = null; // Declare provider in module scope for access in stopTracing
61
61
 
62
62
  export function setupTracing(options = {}) {
63
+ // Prevent multiple initializations - return existing provider if already set up
64
+ if (tracerProvider) {
65
+ console.warn('Tracing is already initialized. Returning existing tracer.');
66
+ return tracerProvider.getTracer(options.serviceName || process.env.SERVICE_NAME);
67
+ }
68
+
63
69
  const {
64
70
  hostname = process.env.CONTAINER_NAME || process.env.HOSTNAME,
65
71
  serviceName = process.env.SERVICE_NAME,
@@ -69,6 +75,14 @@ export function setupTracing(options = {}) {
69
75
  enableDnsInstrumentation = false,
70
76
  } = options;
71
77
 
78
+ // Validate required parameters
79
+ if (!serviceName) {
80
+ throw new Error('serviceName is required');
81
+ }
82
+ if (!url) {
83
+ throw new Error('url is required');
84
+ }
85
+
72
86
  // Configure exporter with the Collector endpoint - uses gRPC
73
87
  const exportOptions = {
74
88
  concurrencyLimit: parseInt(concurrencyLimit, 10),
@@ -386,6 +400,7 @@ export async function stopTracing() {
386
400
  if (tracerProvider) {
387
401
  try {
388
402
  await tracerProvider.shutdown();
403
+ tracerProvider = null;
389
404
  console.info('Tracing has been successfully shut down.');
390
405
  } catch (error) {
391
406
  console.error('Error during tracing shutdown:', error);
@@ -1,62 +1,57 @@
1
- // tracing.test.mjs
2
- import { setupTracing } from './index.mjs';
3
- import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
4
- import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
5
- import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
6
-
7
- // Mocking external dependencies
8
- jest.mock('@opentelemetry/sdk-trace-node', () => {
9
- const originalModule = jest.requireActual('@opentelemetry/sdk-trace-node');
10
- return {
11
- ...originalModule,
12
- NodeTracerProvider: jest.fn().mockImplementation(() => ({
13
- addSpanProcessor: jest.fn(),
14
- register: jest.fn(),
15
- getTracer: jest.fn().mockReturnValue({}),
16
- resource: {
17
- attributes: {},
18
- },
19
- })),
20
- };
21
- });
22
-
23
- jest.mock('@opentelemetry/sdk-trace-base', () => ({
24
- BatchSpanProcessor: jest.fn(),
25
- SpanProcessor: jest.fn(),
26
- }));
27
-
28
- jest.mock('@opentelemetry/exporter-trace-otlp-grpc', () => ({
29
- OTLPTraceExporter: jest.fn(),
30
- }));
1
+ // index.test.mjs
2
+ import { describe, it, beforeEach } from 'node:test';
3
+ import assert from 'node:assert';
31
4
 
32
5
  describe('setupTracing', () => {
6
+ // Clear environment before each test
33
7
  beforeEach(() => {
34
- // Clear all instances and calls to constructor and all methods:
35
- NodeTracerProvider.mockClear();
36
- BatchSpanProcessor.mockClear();
37
- OTLPTraceExporter.mockClear();
8
+ delete process.env.SERVICE_NAME;
9
+ delete process.env.ENDPOINT;
10
+ delete process.env.HOSTNAME;
11
+ delete process.env.CONTAINER_NAME;
12
+ });
13
+
14
+ it('should throw error when serviceName is not provided', async () => {
15
+ const { setupTracing } = await import('./index.mjs');
16
+ assert.throws(() => {
17
+ setupTracing({ url: 'http://localhost:4317' });
18
+ }, /serviceName is required/);
38
19
  });
39
20
 
40
- it('should create a tracer with default parameters', () => {
41
- const tracer = setupTracing('test-service');
42
- expect(NodeTracerProvider).toHaveBeenCalledTimes(1);
43
- expect(BatchSpanProcessor).toHaveBeenCalledTimes(1);
44
- expect(OTLPTraceExporter).toHaveBeenCalledWith({
21
+ it('should throw error when url is not provided', async () => {
22
+ const { setupTracing } = await import('./index.mjs');
23
+ assert.throws(() => {
24
+ setupTracing({ serviceName: 'test-service' });
25
+ }, /url is required/);
26
+ });
27
+
28
+ it('should create a tracer with required parameters', async () => {
29
+ const { setupTracing } = await import('./index.mjs');
30
+ const tracer = setupTracing({
45
31
  serviceName: 'test-service',
46
- url: null,
32
+ url: 'http://localhost:4317',
47
33
  });
48
- expect(tracer).toBeDefined();
34
+ assert.ok(tracer, 'tracer should be defined');
49
35
  });
50
36
 
51
- it('should create a tracer with custom application name and endpoint', () => {
52
- const tracer = setupTracing('test-service', 'custom-app', 'custom-endpoint');
53
- expect(NodeTracerProvider).toHaveBeenCalledTimes(1);
54
- expect(BatchSpanProcessor).toHaveBeenCalledTimes(1);
55
- expect(OTLPTraceExporter).toHaveBeenCalledWith({
37
+ it('should accept hostname parameter', async () => {
38
+ const { setupTracing } = await import('./index.mjs');
39
+ const tracer = setupTracing({
56
40
  serviceName: 'test-service',
57
- url: 'custom-endpoint',
41
+ url: 'http://localhost:4317',
42
+ hostname: 'test-host',
58
43
  });
59
- expect(tracer).toBeDefined();
44
+ assert.ok(tracer, 'tracer should be defined');
60
45
  });
61
46
 
47
+ it('should accept optional instrumentations', async () => {
48
+ const { setupTracing } = await import('./index.mjs');
49
+ const tracer = setupTracing({
50
+ serviceName: 'test-service',
51
+ url: 'http://localhost:4317',
52
+ enableFsInstrumentation: true,
53
+ enableDnsInstrumentation: true,
54
+ });
55
+ assert.ok(tracer, 'tracer should be defined');
56
+ });
62
57
  });
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@saidsef/tracing-node",
3
- "version": "3.13.4",
3
+ "version": "3.13.6",
4
4
  "description": "tracing NodeJS - Wrapper for OpenTelemetry instrumentation packages",
5
5
  "main": "libs/index.mjs",
6
6
  "scripts": {
7
- "test": "node --trace-warnings --test --report-uncaught-exception --heap-prof --cpu-prof --track-heap-objects --report-dir=test/ --diagnostic-dir=test/ --heap-prof-dir=test/ libs/index.mjs",
7
+ "test": "node --trace-warnings --test --report-uncaught-exception --heap-prof --cpu-prof --track-heap-objects --report-dir=test/ --diagnostic-dir=test/ --heap-prof-dir=test/ libs/index.test.mjs",
8
8
  "lint": "eslint .",
9
9
  "rebuild": "rm -rfv node_modules/ package-lock.json && npm install --prod --omit=dev"
10
10
  },
@@ -32,16 +32,16 @@
32
32
  "dependencies": {
33
33
  "@opentelemetry/api": "^1.9.0",
34
34
  "@opentelemetry/context-async-hooks": "^2.0.1",
35
- "@opentelemetry/exporter-trace-otlp-grpc": "^0.208.0",
36
- "@opentelemetry/instrumentation": "^0.208.0",
37
- "@opentelemetry/instrumentation-aws-sdk": "^0.64.0",
38
- "@opentelemetry/instrumentation-connect": "^0.52.0",
39
- "@opentelemetry/instrumentation-dns": "^0.52.0",
40
- "@opentelemetry/instrumentation-express": "^0.57.0",
41
- "@opentelemetry/instrumentation-fs": "^0.28.0",
42
- "@opentelemetry/instrumentation-http": "^0.208.0",
43
- "@opentelemetry/instrumentation-ioredis": "^0.57.0",
44
- "@opentelemetry/instrumentation-pino": "^0.55.0",
35
+ "@opentelemetry/exporter-trace-otlp-grpc": "^0.213.0",
36
+ "@opentelemetry/instrumentation": "^0.213.0",
37
+ "@opentelemetry/instrumentation-aws-sdk": "^0.67.0",
38
+ "@opentelemetry/instrumentation-connect": "^0.55.0",
39
+ "@opentelemetry/instrumentation-dns": "^0.55.0",
40
+ "@opentelemetry/instrumentation-express": "^0.60.0",
41
+ "@opentelemetry/instrumentation-fs": "^0.31.0",
42
+ "@opentelemetry/instrumentation-http": "^0.213.0",
43
+ "@opentelemetry/instrumentation-ioredis": "^0.60.0",
44
+ "@opentelemetry/instrumentation-pino": "^0.58.0",
45
45
  "@opentelemetry/resources": "^2.0.1",
46
46
  "@opentelemetry/sdk-trace-base": "^2.0.0",
47
47
  "@opentelemetry/sdk-trace-node": "^2.0.0",