securenow 3.0.4 → 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 -71
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securenow",
3
- "version": "3.0.4",
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,31 +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
91
 
92
92
  const sdk = new NodeSDK({
93
93
  traceExporter,
94
- instrumentations: getNodeAutoInstrumentations({
95
- // Merge disabled flags (keys must match package names)
96
- ...disabledMap,
97
- }),
94
+ instrumentations: getNodeAutoInstrumentations({ ...disabledMap }),
98
95
  resource: new Resource({
99
96
  [SemanticResourceAttributes.SERVICE_NAME]: serviceName,
97
+ [SemanticResourceAttributes.SERVICE_INSTANCE_ID]: serviceInstanceId,
100
98
  [SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]: env('NODE_ENV') || 'development',
101
- [SemanticResourceAttributes.SERVICE_VERSION]: env('npm_package_version') || undefined,
99
+ [SemanticResourceAttributes.SERVICE_VERSION]: process.env.npm_package_version || undefined,
102
100
  }),
103
101
  });
104
102
 
105
- // ---------- Start (supports both sync/async start()) ----------
103
+ // -------------------- start (sync/async safe) --------------------
106
104
  (async () => {
107
105
  try {
108
- const res = sdk.start?.(); // may be undefined or a Promise
109
- await Promise.resolve(res); // normalize to Promise
106
+ await Promise.resolve(sdk.start?.());
110
107
  console.log('[securenow] OTel SDK started →', tracesUrl);
111
108
 
112
- // Optional smoke test to verify export path
113
- if ((env('SECURENOW_TEST_SPAN') || '') === '1') {
109
+ if (String(env('SECURENOW_TEST_SPAN')) === '1') {
114
110
  const api = require('@opentelemetry/api');
115
111
  const tracer = api.trace.getTracer('securenow-smoke');
116
112
  const span = tracer.startSpan('securenow.startup.smoke');
@@ -119,15 +115,14 @@ const sdk = new NodeSDK({
119
115
  console.log('[securenow] emitted startup smoke span');
120
116
  }
121
117
  } catch (err) {
122
- console.error('[securenow] OTel start failed:', (err && err.stack) || err);
118
+ console.error('[securenow] OTel start failed:', err && err.stack || err);
123
119
  }
124
120
  })();
125
121
 
126
- // ---------- Graceful shutdown (supports both sync/async shutdown()) ----------
122
+ // -------------------- graceful shutdown --------------------
127
123
  async function safeShutdown(sig) {
128
124
  try {
129
- const r = sdk.shutdown?.(); // may be undefined or a Promise
130
- await Promise.resolve(r);
125
+ await Promise.resolve(sdk.shutdown?.());
131
126
  console.log(`[securenow] Tracing terminated on ${sig}`);
132
127
  } catch (err) {
133
128
  console.error('[securenow] Tracing shutdown error:', err);