securenow 3.0.5 → 3.0.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/tracing.js +66 -73
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securenow",
3
- "version": "3.0.5",
3
+ "version": "3.0.6",
4
4
  "type": "commonjs",
5
5
  "main": "register.js",
6
6
  "exports": { ".": "./register.js", "./register": "./register.js", "./tracing": "./tracing.js" },
package/tracing.js CHANGED
@@ -1,84 +1,84 @@
1
1
  'use strict';
2
2
 
3
3
  /**
4
- * securenow/tracing.js
5
- * Preload with: NODE_OPTIONS="--require securenow/register" (or -r securenow/register via PM2)
6
- * Env you can use:
7
- * - SECURENOW_INSTANCE=http://host:4318 # base OTLP/HTTP endpoint (defaults to http://46.62.173.237:4318)
8
- * - OTEL_EXPORTER_OTLP_ENDPOINT=... # alt base (will be used if securenow_instance not set)
9
- * - OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=... # full traces URL (overrides base)
10
- * - OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer abc123,foo=bar"
11
- * - OTEL_SERVICE_NAME=your-service # logical name (UUID suffix auto-appended)
12
- * - SECURENOW_APPID=your-appid # fallback logical name (UUID suffix auto-appended)
13
- * - SECURENOW_NO_UUID=1 # disable UUID suffix
14
- * - SECURENOW_DISABLE_INSTRUMENTATIONS="@opentelemetry/instrumentation-mongodb,@opentelemetry/instrumentation-redis"
15
- * - OTEL_LOG_LEVEL=info|debug # OTel internal diagnostics
16
- * - SECURENOW_TEST_SPAN=1 # emit a smoke-test span on startup
4
+ * Preload with: NODE_OPTIONS="-r securenow/register"
5
+ *
6
+ * Env:
7
+ * SECURENOW_INSTANCE=http://host:4318
8
+ * OTEL_EXPORTER_OTLP_ENDPOINT=...
9
+ * OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=...
10
+ * OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer abc123,foo=bar"
11
+ * OTEL_SERVICE_NAME=logical-name
12
+ * SECURENOW_APPID=logical-name
13
+ * SECURENOW_NO_UUID=1 # one service.name across all workers
14
+ * SECURENOW_DISABLE_INSTRUMENTATIONS="@opentelemetry/instrumentation-mongodb,@opentelemetry/instrumentation-redis"
15
+ * OTEL_LOG_LEVEL=info|debug
16
+ * SECURENOW_TEST_SPAN=1 # emit a smoke test span on startup
17
17
  */
18
18
 
19
19
  const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api');
20
+ const { NodeSDK } = require('@opentelemetry/sdk-node');
21
+ const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
22
+ const { Resource } = require('@opentelemetry/resources');
23
+ const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
24
+ const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
25
+ const { v4: uuidv4 } = require('uuid');
26
+
27
+ // -------------------- helpers --------------------
20
28
  const env = k => process.env[k] ?? process.env[k.toUpperCase()] ?? process.env[k.toLowerCase()];
29
+ const parseHeaders = (str) => {
30
+ const out = {};
31
+ if (!str) return out;
32
+ for (const raw of str.split(',')) {
33
+ const s = raw.trim();
34
+ if (!s) continue;
35
+ const i = s.indexOf('=');
36
+ if (i === -1) continue;
37
+ out[s.slice(0, i).trim().toLowerCase()] = s.slice(i + 1).trim();
38
+ }
39
+ return out;
40
+ };
21
41
 
22
- // ---------- Diagnostics level ----------
42
+ // -------------------- diagnostics --------------------
23
43
  (() => {
24
44
  const L = (env('OTEL_LOG_LEVEL') || '').toLowerCase();
25
45
  const level =
26
46
  L === 'debug' ? DiagLogLevel.DEBUG :
27
47
  L === 'info' ? DiagLogLevel.INFO :
28
48
  L === 'warn' ? DiagLogLevel.WARN :
29
- L === 'error' ? DiagLogLevel.ERROR :
30
- DiagLogLevel.NONE;
49
+ L === 'error' ? DiagLogLevel.ERROR : DiagLogLevel.NONE;
31
50
  diag.setLogger(new DiagConsoleLogger(), level);
32
- console.log('[securenow] preload loaded');
51
+ console.log('[securenow] preload loaded pid=', process.pid);
33
52
  })();
34
53
 
35
- const { NodeSDK } = require('@opentelemetry/sdk-node');
36
- const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
37
- const { Resource } = require('@opentelemetry/resources');
38
- const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
39
- const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
40
- const { v4: uuidv4 } = require('uuid');
54
+ // -------------------- endpoints --------------------
55
+ const endpointBase = (env('SECURENOW_INSTANCE') || env('OTEL_EXPORTER_OTLP_ENDPOINT') || 'http://46.62.173.237:4318').replace(/\/$/, '');
56
+ const tracesUrl = env('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT') || `${endpointBase}/v1/traces`;
57
+ const headers = parseHeaders(env('OTEL_EXPORTER_OTLP_HEADERS'));
41
58
 
42
- // ---------- Show actual loaded OTel versions (helpful for debugging) ----------
43
- try {
44
- const vApi = require('@opentelemetry/api/package.json').version;
45
- const vSdk = require('@opentelemetry/sdk-node/package.json').version;
46
- console.log('[securenow] otel versions → api:', vApi, 'sdk-node:', vSdk);
47
- } catch (e) {
48
- console.log('[securenow] could not read otel versions', e && e.message);
49
- }
59
+ // -------------------- naming rules --------------------
60
+ const rawBase =
61
+ (env('OTEL_SERVICE_NAME') || env('SECURENOW_APPID') || '').trim().replace(/^['"]|['"]$/g, '');
62
+ const baseName = rawBase || null;
50
63
 
51
- // ---------- Endpoint config (HTTP/4318) ----------
52
- const endpointBase = (env('SECURENOW_INSTANCE') || env('OTEL_EXPORTER_OTLP_ENDPOINT') || 'http://46.62.173.237:4318').replace(/\/$/, '');
53
- const tracesUrl = (env('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT') || `${endpointBase}/v1/traces`);
64
+ // SECURENOW_NO_UUID=1 -> keep one service.name for all workers (baseName), but unique instance ids
65
+ const noUuid = String(env('SECURENOW_NO_UUID')) === '1' || String(env('SECURENOW_NO_UUID')).toLowerCase() === 'true';
54
66
 
55
- // ---------- Headers parsing ----------
56
- function parseOtelHeaders(str) {
57
- const headers = {};
58
- if (!str) return headers;
59
- // split on comma; tolerate spaces
60
- for (const raw of str.split(',')) {
61
- const piece = raw.trim();
62
- if (!piece) continue;
63
- const eq = piece.indexOf('=');
64
- if (eq === -1) continue;
65
- const k = piece.slice(0, eq).trim();
66
- const v = piece.slice(eq + 1).trim();
67
- if (k) headers[k.toLowerCase()] = v;
68
- }
69
- return headers;
70
- }
71
- const headers = parseOtelHeaders(env('OTEL_EXPORTER_OTLP_HEADERS'));
72
- // ---------- Service name with UUID rules ----------
73
67
  let serviceName;
74
- if (env('SECURENOW_APPID')) {
75
- serviceName = env('SECURENOW_APPID');
68
+ if (baseName) {
69
+ serviceName = noUuid ? baseName : `${baseName}-${uuidv4()}`;
76
70
  } else {
77
- // default can also be unique to avoid collisions
71
+ // No provided name: safe fallback, unique per process
78
72
  serviceName = `securenow-free-${uuidv4()}`;
79
73
  }
80
74
 
81
- // ---------- Disable instrumentations via env ----------
75
+ // Always make a unique instance id (appID + uuid if available; else “securenow” + uuid)
76
+ const instancePrefix = baseName || 'securenow';
77
+ const serviceInstanceId = `${instancePrefix}-${uuidv4()}`;
78
+
79
+ console.log('[securenow] resolved names →', { serviceName, serviceInstanceId });
80
+
81
+ // -------------------- instrumentations --------------------
82
82
  const disabledList = (env('SECURENOW_DISABLE_INSTRUMENTATIONS') || '')
83
83
  .split(',')
84
84
  .map(s => s.trim())
@@ -86,33 +86,27 @@ const disabledList = (env('SECURENOW_DISABLE_INSTRUMENTATIONS') || '')
86
86
  const disabledMap = {};
87
87
  for (const name of disabledList) disabledMap[name] = { enabled: false };
88
88
 
89
- // ---------- Build exporter & SDK ----------
89
+ // -------------------- SDK --------------------
90
90
  const traceExporter = new OTLPTraceExporter({ url: tracesUrl, headers });
91
- const serviceInstanceId = `${serviceName}-${uuidv4()}`;
92
91
 
93
92
  const sdk = new NodeSDK({
94
93
  traceExporter,
95
- instrumentations: getNodeAutoInstrumentations({
96
- // Merge disabled flags (keys must match package names)
97
- ...disabledMap,
98
- }),
94
+ instrumentations: getNodeAutoInstrumentations({ ...disabledMap }),
99
95
  resource: new Resource({
100
96
  [SemanticResourceAttributes.SERVICE_NAME]: serviceName,
101
- [SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]: env('NODE_ENV') || 'development',
102
97
  [SemanticResourceAttributes.SERVICE_INSTANCE_ID]: serviceInstanceId,
103
- [SemanticResourceAttributes.SERVICE_VERSION]: env('npm_package_version') || undefined,
98
+ [SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]: env('NODE_ENV') || 'development',
99
+ [SemanticResourceAttributes.SERVICE_VERSION]: process.env.npm_package_version || undefined,
104
100
  }),
105
101
  });
106
102
 
107
- // ---------- Start (supports both sync/async start()) ----------
103
+ // -------------------- start (sync/async safe) --------------------
108
104
  (async () => {
109
105
  try {
110
- const res = sdk.start?.(); // may be undefined or a Promise
111
- await Promise.resolve(res); // normalize to Promise
106
+ await Promise.resolve(sdk.start?.());
112
107
  console.log('[securenow] OTel SDK started →', tracesUrl);
113
108
 
114
- // Optional smoke test to verify export path
115
- if ((env('SECURENOW_TEST_SPAN') || '') === '1') {
109
+ if (String(env('SECURENOW_TEST_SPAN')) === '1') {
116
110
  const api = require('@opentelemetry/api');
117
111
  const tracer = api.trace.getTracer('securenow-smoke');
118
112
  const span = tracer.startSpan('securenow.startup.smoke');
@@ -121,15 +115,14 @@ const sdk = new NodeSDK({
121
115
  console.log('[securenow] emitted startup smoke span');
122
116
  }
123
117
  } catch (err) {
124
- console.error('[securenow] OTel start failed:', (err && err.stack) || err);
118
+ console.error('[securenow] OTel start failed:', err && err.stack || err);
125
119
  }
126
120
  })();
127
121
 
128
- // ---------- Graceful shutdown (supports both sync/async shutdown()) ----------
122
+ // -------------------- graceful shutdown --------------------
129
123
  async function safeShutdown(sig) {
130
124
  try {
131
- const r = sdk.shutdown?.(); // may be undefined or a Promise
132
- await Promise.resolve(r);
125
+ await Promise.resolve(sdk.shutdown?.());
133
126
  console.log(`[securenow] Tracing terminated on ${sig}`);
134
127
  } catch (err) {
135
128
  console.error('[securenow] Tracing shutdown error:', err);