securenow 6.0.0 → 6.0.1
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/docs/CHANGELOG-NEXTJS.md +34 -0
- package/docs/LOGGING-QUICKSTART.md +18 -2
- package/nextjs.js +67 -0
- package/package.json +3 -3
- package/tracing.js +7 -2
package/docs/CHANGELOG-NEXTJS.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# Changelog - Next.js Support
|
|
2
2
|
|
|
3
|
+
## Version 6.0.1 (Logging hotfix)
|
|
4
|
+
|
|
5
|
+
### 🐛 Bug Fixes
|
|
6
|
+
|
|
7
|
+
- **Fixed: `logger.emit()` silently dropped every log record in 6.0.0.**
|
|
8
|
+
`tracing.js` constructed the `LoggerProvider` with `{ processors: [new
|
|
9
|
+
BatchLogRecordProcessor(...)] }`, but that constructor option was only added
|
|
10
|
+
in `@opentelemetry/sdk-logs` 0.52 — the pinned 0.47.x silently ignores it,
|
|
11
|
+
leaving the provider with a `NoopLogRecordProcessor`. Every `logger.emit()`
|
|
12
|
+
(and every auto-captured `console.*`) was dropped, and `forceFlush()`
|
|
13
|
+
resolved with nothing to export. No HTTP POST ever reached `/v1/logs`.
|
|
14
|
+
Traces were unaffected (separate pipeline). Fixed by calling
|
|
15
|
+
`loggerProvider.addLogRecordProcessor(...)` after construction, matching the
|
|
16
|
+
0.47.x API.
|
|
17
|
+
|
|
18
|
+
### ✨ Improvements
|
|
19
|
+
|
|
20
|
+
- **`registerSecureNow()` (Next.js) now wires the OTLP logs pipeline.** In
|
|
21
|
+
6.0.0, `securenow/nextjs` only set up traces — calling `registerSecureNow()`
|
|
22
|
+
with `SECURENOW_LOGGING_ENABLED=1` would log the "ENABLED" banner but emit
|
|
23
|
+
nothing. 6.0.1 creates a `LoggerProvider`, registers a
|
|
24
|
+
`BatchLogRecordProcessor(OTLPLogExporter)`, publishes it via
|
|
25
|
+
`logs.setGlobalLoggerProvider()`, and auto-patches
|
|
26
|
+
`console.log/info/warn/error/debug` to emit OTLP log records. Works on both
|
|
27
|
+
the Vercel (`@vercel/otel`) and self-hosted (`NodeSDK`) code paths. Graceful
|
|
28
|
+
flush + shutdown registered on SIGINT/SIGTERM/beforeExit.
|
|
29
|
+
- **`tracing.js` now calls `logs.setGlobalLoggerProvider()`** so consumers can
|
|
30
|
+
retrieve the logger via `@opentelemetry/api-logs` without depending on the
|
|
31
|
+
module export.
|
|
32
|
+
- **Docs updated** (`NPM_README.md`, `docs/LOGGING-QUICKSTART.md`) to
|
|
33
|
+
recommend `registerSecureNow` from `securenow/nextjs` for Next.js apps
|
|
34
|
+
instead of `securenow/register` + `securenow/console-instrumentation`
|
|
35
|
+
(which boots a full `NodeSDK` and conflicts with Next.js / `@vercel/otel`).
|
|
36
|
+
|
|
3
37
|
## Version 3.1.0 (Next.js Support Added)
|
|
4
38
|
|
|
5
39
|
### 🎉 New Features
|
|
@@ -101,13 +101,21 @@ app.listen(3000);
|
|
|
101
101
|
|
|
102
102
|
### Next.js
|
|
103
103
|
|
|
104
|
+
Next.js apps must use `securenow/nextjs` (not `securenow/register`, which
|
|
105
|
+
boots a full NodeSDK and conflicts with Next.js / `@vercel/otel`). Since
|
|
106
|
+
**6.0.1**, `registerSecureNow()` sets up the OTLP logs pipeline and auto-
|
|
107
|
+
patches `console.*` whenever `SECURENOW_LOGGING_ENABLED=1` is set — on both
|
|
108
|
+
Vercel and self-hosted (EC2, PM2, Docker) environments.
|
|
109
|
+
|
|
104
110
|
```typescript
|
|
105
111
|
// instrumentation.ts (in project root)
|
|
106
112
|
export async function register() {
|
|
107
113
|
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
|
114
|
+
// Must be set BEFORE loading securenow/nextjs
|
|
108
115
|
process.env.SECURENOW_LOGGING_ENABLED = '1';
|
|
109
|
-
|
|
110
|
-
await import('securenow/
|
|
116
|
+
|
|
117
|
+
const { registerSecureNow } = await import('securenow/nextjs');
|
|
118
|
+
registerSecureNow({ captureBody: true });
|
|
111
119
|
}
|
|
112
120
|
}
|
|
113
121
|
```
|
|
@@ -119,6 +127,14 @@ SECURENOW_APPID=my-nextjs-app
|
|
|
119
127
|
SECURENOW_INSTANCE=http://localhost:4318
|
|
120
128
|
```
|
|
121
129
|
|
|
130
|
+
Enable the instrumentation hook in `next.config.js`:
|
|
131
|
+
|
|
132
|
+
```javascript
|
|
133
|
+
module.exports = {
|
|
134
|
+
experimental: { instrumentationHook: true },
|
|
135
|
+
};
|
|
136
|
+
```
|
|
137
|
+
|
|
122
138
|
### Fastify
|
|
123
139
|
|
|
124
140
|
```javascript
|
package/nextjs.js
CHANGED
|
@@ -261,12 +261,18 @@ function registerSecureNow(options = {}) {
|
|
|
261
261
|
).replace(/\/$/, '');
|
|
262
262
|
|
|
263
263
|
const tracesUrl = env('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT') || `${endpointBase}/v1/traces`;
|
|
264
|
+
const logsUrl = env('OTEL_EXPORTER_OTLP_LOGS_ENDPOINT') || `${endpointBase}/v1/logs`;
|
|
264
265
|
|
|
265
266
|
// Set environment variables for @vercel/otel to pick up
|
|
266
267
|
process.env.OTEL_SERVICE_NAME = serviceName;
|
|
267
268
|
process.env.OTEL_EXPORTER_OTLP_ENDPOINT = endpointBase;
|
|
268
269
|
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = tracesUrl;
|
|
269
270
|
|
|
271
|
+
// -------- Logging Configuration --------
|
|
272
|
+
// Opt-in: SECURENOW_LOGGING_ENABLED=1 (or "true").
|
|
273
|
+
const loggingEnabled = String(env('SECURENOW_LOGGING_ENABLED')) === '1' ||
|
|
274
|
+
String(env('SECURENOW_LOGGING_ENABLED')).toLowerCase() === 'true';
|
|
275
|
+
|
|
270
276
|
console.log('[securenow] 🚀 Next.js App → service.name=%s', serviceName);
|
|
271
277
|
|
|
272
278
|
// -------- Body Capture Configuration --------
|
|
@@ -506,6 +512,67 @@ function registerSecureNow(options = {}) {
|
|
|
506
512
|
console.log('[securenow] 🎯 Vanilla SDK initialized for self-hosted environment');
|
|
507
513
|
}
|
|
508
514
|
|
|
515
|
+
// -------- Logging pipeline (both Vercel and self-hosted) --------
|
|
516
|
+
// Neither @vercel/otel nor NodeSDK 0.47.x wires OTLP logs for us, so we
|
|
517
|
+
// create the LoggerProvider ourselves, register a BatchLogRecordProcessor
|
|
518
|
+
// (addLogRecordProcessor — the `processors` constructor option was only
|
|
519
|
+
// added in sdk-logs 0.52 and is silently ignored in 0.47), publish it as
|
|
520
|
+
// the global logger provider, and auto-patch console.* to emit records.
|
|
521
|
+
if (loggingEnabled) {
|
|
522
|
+
const { LoggerProvider, BatchLogRecordProcessor } = require('@opentelemetry/sdk-logs');
|
|
523
|
+
const { OTLPLogExporter } = require('@opentelemetry/exporter-logs-otlp-http');
|
|
524
|
+
const { logs } = require('@opentelemetry/api-logs');
|
|
525
|
+
const { Resource } = require('@opentelemetry/resources');
|
|
526
|
+
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
|
|
527
|
+
|
|
528
|
+
const logResource = new Resource({
|
|
529
|
+
[SemanticResourceAttributes.SERVICE_NAME]: serviceName,
|
|
530
|
+
[SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]: env('NODE_ENV') || env('VERCEL_ENV') || 'production',
|
|
531
|
+
[SemanticResourceAttributes.SERVICE_VERSION]: process.env.npm_package_version || process.env.VERCEL_GIT_COMMIT_SHA || undefined,
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
const logExporter = new OTLPLogExporter({
|
|
535
|
+
url: logsUrl,
|
|
536
|
+
headers: parseHeaders(env('OTEL_EXPORTER_OTLP_HEADERS')),
|
|
537
|
+
});
|
|
538
|
+
const loggerProvider = new LoggerProvider({ resource: logResource });
|
|
539
|
+
loggerProvider.addLogRecordProcessor(new BatchLogRecordProcessor(logExporter));
|
|
540
|
+
logs.setGlobalLoggerProvider(loggerProvider);
|
|
541
|
+
|
|
542
|
+
const _logger = loggerProvider.getLogger('console', '1.0.0');
|
|
543
|
+
const _orig = { log: console.log, info: console.info, warn: console.warn, error: console.error, debug: console.debug };
|
|
544
|
+
const SEV = { DEBUG: 5, INFO: 9, WARN: 13, ERROR: 17 };
|
|
545
|
+
const _emit = (sn, st, args) => {
|
|
546
|
+
try {
|
|
547
|
+
_logger.emit({
|
|
548
|
+
severityNumber: sn,
|
|
549
|
+
severityText: st,
|
|
550
|
+
body: args.map(a => (typeof a === 'object' && a !== null)
|
|
551
|
+
? (() => { try { return JSON.stringify(a); } catch { return String(a); } })()
|
|
552
|
+
: String(a)).join(' '),
|
|
553
|
+
attributes: { 'log.source': 'console', 'log.method': st.toLowerCase() },
|
|
554
|
+
});
|
|
555
|
+
} catch (_) {}
|
|
556
|
+
};
|
|
557
|
+
console.log = function (...a) { _emit(SEV.INFO, 'INFO', a); _orig.log.apply(console, a); };
|
|
558
|
+
console.info = function (...a) { _emit(SEV.INFO, 'INFO', a); _orig.info.apply(console, a); };
|
|
559
|
+
console.warn = function (...a) { _emit(SEV.WARN, 'WARN', a); _orig.warn.apply(console, a); };
|
|
560
|
+
console.error = function (...a) { _emit(SEV.ERROR, 'ERROR', a); _orig.error.apply(console, a); };
|
|
561
|
+
console.debug = function (...a) { _emit(SEV.DEBUG, 'DEBUG', a); _orig.debug.apply(console, a); };
|
|
562
|
+
|
|
563
|
+
const _shutdownLogs = async () => {
|
|
564
|
+
try { await Promise.resolve(loggerProvider.forceFlush?.()); } catch (_) {}
|
|
565
|
+
try { await Promise.resolve(loggerProvider.shutdown?.()); } catch (_) {}
|
|
566
|
+
};
|
|
567
|
+
process.on('SIGINT', _shutdownLogs);
|
|
568
|
+
process.on('SIGTERM', _shutdownLogs);
|
|
569
|
+
process.on('beforeExit', _shutdownLogs);
|
|
570
|
+
|
|
571
|
+
console.log('[securenow] 📋 Logging: ENABLED → %s', logsUrl);
|
|
572
|
+
} else {
|
|
573
|
+
console.log('[securenow] 📋 Logging: DISABLED (set SECURENOW_LOGGING_ENABLED=1 to enable)');
|
|
574
|
+
}
|
|
575
|
+
|
|
509
576
|
isRegistered = true;
|
|
510
577
|
console.log('[securenow] ✅ OpenTelemetry started for Next.js → %s', tracesUrl);
|
|
511
578
|
console.log('[securenow] 📊 Auto-capturing comprehensive request metadata:');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "securenow",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.1",
|
|
4
4
|
"description": "OpenTelemetry instrumentation for Node.js and Next.js - Send traces and logs to SigNoz or any OTLP backend",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "register.js",
|
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
},
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
16
|
-
"url": "git+https://github.com/securenow/securenow-npm.git"
|
|
16
|
+
"url": "git+https://github.com/securenow-ai/securenow-npm.git"
|
|
17
17
|
},
|
|
18
18
|
"homepage": "https://securenow.ai",
|
|
19
19
|
"bugs": {
|
|
20
|
-
"url": "https://github.com/securenow/securenow-npm/issues",
|
|
20
|
+
"url": "https://github.com/securenow-ai/securenow-npm/issues",
|
|
21
21
|
"email": "support@securenow.ai"
|
|
22
22
|
},
|
|
23
23
|
"author": "SecureNow <support@securenow.ai> (https://securenow.ai)",
|
package/tracing.js
CHANGED
|
@@ -23,6 +23,7 @@ const { NodeSDK } = require('@opentelemetry/sdk-node');
|
|
|
23
23
|
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
|
|
24
24
|
const { OTLPLogExporter } = require('@opentelemetry/exporter-logs-otlp-http');
|
|
25
25
|
const { LoggerProvider, BatchLogRecordProcessor } = require('@opentelemetry/sdk-logs');
|
|
26
|
+
const { logs: apiLogs } = require('@opentelemetry/api-logs');
|
|
26
27
|
const { Resource } = require('@opentelemetry/resources');
|
|
27
28
|
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
|
|
28
29
|
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
|
|
@@ -267,9 +268,13 @@ if (loggingEnabled) {
|
|
|
267
268
|
|
|
268
269
|
loggerProvider = new LoggerProvider({
|
|
269
270
|
resource: sharedResource,
|
|
270
|
-
processors: [new BatchLogRecordProcessor(logExporter)],
|
|
271
271
|
});
|
|
272
|
-
|
|
272
|
+
// sdk-logs 0.47.x ignores the `processors` constructor option (added in 0.52),
|
|
273
|
+
// so the provider would silently keep a NoopLogRecordProcessor and drop every
|
|
274
|
+
// emit(). Register the processor explicitly instead.
|
|
275
|
+
loggerProvider.addLogRecordProcessor(new BatchLogRecordProcessor(logExporter));
|
|
276
|
+
apiLogs.setGlobalLoggerProvider(loggerProvider);
|
|
277
|
+
|
|
273
278
|
globalLogger = loggerProvider.getLogger('securenow', '1.0.0');
|
|
274
279
|
}
|
|
275
280
|
|