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.
- package/package.json +1 -1
- package/tracing.js +66 -73
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,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
|
-
//
|
|
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.
|
|
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
|
-
//
|
|
103
|
+
// -------------------- start (sync/async safe) --------------------
|
|
108
104
|
(async () => {
|
|
109
105
|
try {
|
|
110
|
-
|
|
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
|
-
|
|
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:',
|
|
118
|
+
console.error('[securenow] OTel start failed:', err && err.stack || err);
|
|
125
119
|
}
|
|
126
120
|
})();
|
|
127
121
|
|
|
128
|
-
//
|
|
122
|
+
// -------------------- graceful shutdown --------------------
|
|
129
123
|
async function safeShutdown(sig) {
|
|
130
124
|
try {
|
|
131
|
-
|
|
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);
|