securenow 2.0.3 → 3.0.0

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 (3) hide show
  1. package/package.json +26 -28
  2. package/register.js +2 -0
  3. package/tracing.js +130 -83
package/package.json CHANGED
@@ -1,30 +1,28 @@
1
1
  {
2
- "name": "securenow",
3
- "version": "2.0.3",
4
- "description": "Securenow for nodejs apps",
5
- "main": "tracing.js",
6
- "dependencies": {
7
- "@opentelemetry/auto-instrumentations-node": "^0.40.3",
8
- "@opentelemetry/exporter-trace-otlp-http": "^0.47.0",
9
- "@opentelemetry/instrumentation-express": "^0.38.0",
10
- "@opentelemetry/instrumentation-fastify": "^0.44.2",
11
- "@opentelemetry/instrumentation-graphql": "^0.47.1",
12
- "@opentelemetry/instrumentation-hapi": "^0.45.2",
13
- "@opentelemetry/instrumentation-http": "^0.51.1",
14
- "@opentelemetry/instrumentation-koa": "^0.47.1",
15
- "@opentelemetry/instrumentation-mongodb": "^0.43.0",
16
- "@opentelemetry/instrumentation-mysql": "^0.45.1",
17
- "@opentelemetry/instrumentation-mysql2": "^0.45.2",
18
- "@opentelemetry/instrumentation-nestjs-core": "^0.44.1",
19
- "@opentelemetry/instrumentation-pg": "^0.51.1",
20
- "@opentelemetry/instrumentation-redis": "^0.46.1",
21
- "@opentelemetry/resources": "^1.30.1",
22
- "@opentelemetry/sdk-node": "^0.47.0",
23
- "@opentelemetry/semantic-conventions": "^1.30.0",
24
- "uuid": "^9.0.1"
25
- },
26
- "scripts": {},
27
- "keywords": [],
28
- "author": "",
29
- "license": "ISC"
2
+ "name": "securenow",
3
+ "version": "3.0.0",
4
+ "description": "Zero-config OpenTelemetry auto-instrumentation for Node",
5
+ "type": "commonjs",
6
+ "main": "register.js",
7
+ "exports": {
8
+ ".": "./register.js",
9
+ "./register": "./register.js",
10
+ "./tracing": "./tracing.js"
11
+ },
12
+ "files": [
13
+ "register.js",
14
+ "tracing.js",
15
+ "README.md"
16
+ ],
17
+ "dependencies": {
18
+ "@opentelemetry/api": "1.9.0",
19
+ "@opentelemetry/auto-instrumentations-node": "0.47.0",
20
+ "@opentelemetry/exporter-trace-otlp-http": "0.47.0",
21
+ "@opentelemetry/resources": "1.30.1",
22
+ "@opentelemetry/sdk-node": "0.47.0",
23
+ "@opentelemetry/semantic-conventions": "1.30.0",
24
+ "uuid": "^11.1.0"
25
+ },
26
+ "sideEffects": true,
27
+ "license": "ISC"
30
28
  }
package/register.js ADDED
@@ -0,0 +1,2 @@
1
+ // tiny entry so users can always do: --require securenow/register
2
+ require('./tracing');
package/tracing.js CHANGED
@@ -1,92 +1,139 @@
1
- // tracing.js
2
- 'use strict'
3
- const process = require('process');
4
- //OpenTelemetry
5
- const opentelemetry = require('@opentelemetry/sdk-node');
6
- const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
7
- //instrumentations
8
- const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
9
- const { ExpressInstrumentation } = require("@opentelemetry/instrumentation-express");
10
- const { HttpInstrumentation } = require("@opentelemetry/instrumentation-http");
1
+ 'use strict';
11
2
 
12
- const { v4: uuidv4 } = require('uuid');
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
17
+ */
18
+
19
+ const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api');
20
+
21
+ // ---------- Diagnostics level ----------
22
+ (() => {
23
+ const L = (process.env.OTEL_LOG_LEVEL || '').toLowerCase();
24
+ const level =
25
+ L === 'debug' ? DiagLogLevel.DEBUG :
26
+ L === 'info' ? DiagLogLevel.INFO :
27
+ L === 'warn' ? DiagLogLevel.WARN :
28
+ L === 'error' ? DiagLogLevel.ERROR :
29
+ DiagLogLevel.NONE;
30
+ diag.setLogger(new DiagConsoleLogger(), level);
31
+ console.log('[securenow] preload loaded');
32
+ })();
33
+
34
+ const { NodeSDK } = require('@opentelemetry/sdk-node');
35
+ const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
13
36
  const { Resource } = require('@opentelemetry/resources');
14
37
  const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
38
+ const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
39
+ const { v4: uuidv4 } = require('uuid');
40
+
41
+ // ---------- Show actual loaded OTel versions (helpful for debugging) ----------
42
+ try {
43
+ const vApi = require('@opentelemetry/api/package.json').version;
44
+ const vSdk = require('@opentelemetry/sdk-node/package.json').version;
45
+ console.log('[securenow] otel versions → api:', vApi, 'sdk-node:', vSdk);
46
+ } catch (e) {
47
+ console.log('[securenow] could not read otel versions', e && e.message);
48
+ }
49
+
50
+ // ---------- Endpoint config (HTTP/4318) ----------
51
+ const endpointBase = (process.env.securenow_instance || process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://46.62.173.237:4318').replace(/\/$/, '');
52
+ const tracesUrl = (process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT || `${endpointBase}/v1/traces`);
15
53
 
16
- const securenow_instance = process.env.securenow_instance|| 'http://46.62.173.237:4318';
17
- const exporterOptions = {
18
- url: securenow_instance+'/v1/traces'
54
+ // ---------- Headers parsing ----------
55
+ function parseOtelHeaders(str) {
56
+ const headers = {};
57
+ if (!str) return headers;
58
+ // split on comma; tolerate spaces
59
+ for (const raw of str.split(',')) {
60
+ const piece = raw.trim();
61
+ if (!piece) continue;
62
+ const eq = piece.indexOf('=');
63
+ if (eq === -1) continue;
64
+ const k = piece.slice(0, eq).trim();
65
+ const v = piece.slice(eq + 1).trim();
66
+ if (k) headers[k.toLowerCase()] = v;
67
+ }
68
+ return headers;
19
69
  }
70
+ const headers = parseOtelHeaders(process.env.OTEL_EXPORTER_OTLP_HEADERS);
71
+
72
+ // ---------- Service name with UUID rules ----------
73
+ let serviceName;
74
+ if (process.env.securenow_appid) {
75
+ serviceName = process.env.securenow_appid;
76
+ } else {
77
+ // default can also be unique to avoid collisions
78
+ serviceName = `securenow-free-${uuidv4()}`;
79
+ }
80
+
81
+ // ---------- Disable instrumentations via env ----------
82
+ const disabledList = (process.env.SECURENOW_DISABLE_INSTRUMENTATIONS || '')
83
+ .split(',')
84
+ .map(s => s.trim())
85
+ .filter(Boolean);
86
+ const disabledMap = {};
87
+ for (const name of disabledList) disabledMap[name] = { enabled: false };
20
88
 
21
- const traceExporter = new OTLPTraceExporter(exporterOptions);
22
- const sdk = new opentelemetry.NodeSDK({
89
+ // ---------- Build exporter & SDK ----------
90
+ const traceExporter = new OTLPTraceExporter({ url: tracesUrl, headers });
91
+
92
+ const sdk = new NodeSDK({
23
93
  traceExporter,
24
- instrumentations: [
25
- // Auto-instrument many Node.js libraries and frameworks
26
- getNodeAutoInstrumentations({
27
- // You can customize specific instrumentations if needed
28
- '@opentelemetry/instrumentation-fs': {
29
- enabled: true,
30
- },
31
- '@opentelemetry/instrumentation-dns': {
32
- enabled: true,
33
- },
34
- '@opentelemetry/instrumentation-net': {
35
- enabled: true,
36
- },
37
- // Next.js support through auto-instrumentation
38
- '@opentelemetry/instrumentation-http': {
39
- enabled: true,
40
- },
41
- '@opentelemetry/instrumentation-express': {
42
- enabled: true,
43
- },
44
- '@opentelemetry/instrumentation-graphql': {
45
- enabled: true,
46
- },
47
- // Add more framework instrumentations
48
- '@opentelemetry/instrumentation-koa': {
49
- enabled: true,
50
- },
51
- '@opentelemetry/instrumentation-redis': {
52
- enabled: true,
53
- },
54
- '@opentelemetry/instrumentation-pg': {
55
- enabled: true,
56
- },
57
- '@opentelemetry/instrumentation-mysql': {
58
- enabled: true,
59
- },
60
- '@opentelemetry/instrumentation-mysql2': {
61
- enabled: true,
62
- },
63
- '@opentelemetry/instrumentation-nestjs-core': {
64
- enabled: true,
65
- },
66
- '@opentelemetry/instrumentation-fastify': {
67
- enabled: true,
68
- },
69
- '@opentelemetry/instrumentation-hapi': {
70
- enabled: true,
71
- },
72
- }),
73
- // Add specific instrumentations that might not be covered by auto-instrumentation
74
- new ExpressInstrumentation(),
75
- new HttpInstrumentation(),
76
- ],
94
+ instrumentations: getNodeAutoInstrumentations({
95
+ // Merge disabled flags (keys must match package names)
96
+ ...disabledMap,
97
+ }),
77
98
  resource: new Resource({
78
- [SemanticResourceAttributes.SERVICE_NAME]: process.env.securenow_appid || 'securenow-free-'+uuidv4()
79
- })
99
+ [SemanticResourceAttributes.SERVICE_NAME]: serviceName,
100
+ [SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]: process.env.NODE_ENV || 'development',
101
+ [SemanticResourceAttributes.SERVICE_VERSION]: process.env.npm_package_version || undefined,
102
+ }),
80
103
  });
81
-
82
- // initialize the SDK and register with the OpenTelemetry API
83
- // this enables the API to record telemetry
84
- sdk.start()
85
-
86
- // gracefully shut down the SDK on process exit
87
- process.on('SIGTERM', () => {
88
- sdk.shutdown()
89
- .then(() => console.log('Tracing terminated'))
90
- .catch((error) => console.log('Error terminating tracing', error))
91
- .finally(() => process.exit(0));
92
- });
104
+
105
+ // ---------- Start (supports both sync/async start()) ----------
106
+ (async () => {
107
+ try {
108
+ const res = sdk.start?.(); // may be undefined or a Promise
109
+ await Promise.resolve(res); // normalize to Promise
110
+ console.log('[securenow] OTel SDK started →', tracesUrl);
111
+
112
+ // Optional smoke test to verify export path
113
+ if ((process.env.SECURENOW_TEST_SPAN || '') === '1') {
114
+ const api = require('@opentelemetry/api');
115
+ const tracer = api.trace.getTracer('securenow-smoke');
116
+ const span = tracer.startSpan('securenow.startup.smoke');
117
+ span.setAttribute('securenow.test', true);
118
+ span.end();
119
+ console.log('[securenow] emitted startup smoke span');
120
+ }
121
+ } catch (err) {
122
+ console.error('[securenow] OTel start failed:', (err && err.stack) || err);
123
+ }
124
+ })();
125
+
126
+ // ---------- Graceful shutdown (supports both sync/async shutdown()) ----------
127
+ async function safeShutdown(sig) {
128
+ try {
129
+ const r = sdk.shutdown?.(); // may be undefined or a Promise
130
+ await Promise.resolve(r);
131
+ console.log(`[securenow] Tracing terminated on ${sig}`);
132
+ } catch (err) {
133
+ console.error('[securenow] Tracing shutdown error:', err);
134
+ } finally {
135
+ process.exit(0);
136
+ }
137
+ }
138
+ process.on('SIGINT', () => safeShutdown('SIGINT'));
139
+ process.on('SIGTERM', () => safeShutdown('SIGTERM'));