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.
- package/package.json +1 -1
- package/tracing.js +66 -71
package/package.json
CHANGED
package/tracing.js
CHANGED
|
@@ -1,84 +1,84 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* securenow/
|
|
5
|
-
*
|
|
6
|
-
* Env
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
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
|
-
//
|
|
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
|
-
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const
|
|
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
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
//
|
|
52
|
-
const
|
|
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 (
|
|
75
|
-
serviceName =
|
|
68
|
+
if (baseName) {
|
|
69
|
+
serviceName = noUuid ? baseName : `${baseName}-${uuidv4()}`;
|
|
76
70
|
} else {
|
|
77
|
-
//
|
|
71
|
+
// No provided name: safe fallback, unique per process
|
|
78
72
|
serviceName = `securenow-free-${uuidv4()}`;
|
|
79
73
|
}
|
|
80
74
|
|
|
81
|
-
//
|
|
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
|
-
//
|
|
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
|
|
99
|
+
[SemanticResourceAttributes.SERVICE_VERSION]: process.env.npm_package_version || undefined,
|
|
102
100
|
}),
|
|
103
101
|
});
|
|
104
102
|
|
|
105
|
-
//
|
|
103
|
+
// -------------------- start (sync/async safe) --------------------
|
|
106
104
|
(async () => {
|
|
107
105
|
try {
|
|
108
|
-
|
|
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
|
-
|
|
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:',
|
|
118
|
+
console.error('[securenow] OTel start failed:', err && err.stack || err);
|
|
123
119
|
}
|
|
124
120
|
})();
|
|
125
121
|
|
|
126
|
-
//
|
|
122
|
+
// -------------------- graceful shutdown --------------------
|
|
127
123
|
async function safeShutdown(sig) {
|
|
128
124
|
try {
|
|
129
|
-
|
|
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);
|