securenow 5.6.0 → 5.6.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/CONSUMING-APPS-GUIDE.md +411 -415
- package/NPM_README.md +1544 -1609
- package/README.md +9 -21
- package/cli/monitor.js +13 -1
- package/console-instrumentation.js +6 -1
- package/docs/ALL-FRAMEWORKS-QUICKSTART.md +1282 -455
- package/docs/EXPRESS-SETUP-GUIDE.md +719 -720
- package/docs/LOGGING-GUIDE.md +701 -708
- package/docs/LOGGING-QUICKSTART.md +234 -239
- package/nextjs.js +19 -3
- package/package.json +1 -1
- package/tracing.js +4 -1
|
@@ -1,239 +1,234 @@
|
|
|
1
|
-
# SecureNow Logging - Quick Start
|
|
2
|
-
|
|
3
|
-
Get logging set up in your Node.js app in under 2 minutes!
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
#
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
console.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
[securenow]
|
|
68
|
-
[securenow]
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## 5. View Logs in SecureNow
|
|
74
|
-
|
|
75
|
-
1. Open your SecureNow dashboard
|
|
76
|
-
2. Go to **Logs** section
|
|
77
|
-
3. Filter by `service.name = my-app`
|
|
78
|
-
4. See all your logs with automatic trace correlation!
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
## Framework-Specific Examples
|
|
83
|
-
|
|
84
|
-
### Express.js
|
|
85
|
-
|
|
86
|
-
```javascript
|
|
87
|
-
// app.js
|
|
88
|
-
require('securenow/register');
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
require('
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
require('securenow/register');
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
---
|
|
236
|
-
|
|
237
|
-
**That's it!** 🎉 Your app is now sending logs to SecureNow.
|
|
238
|
-
|
|
239
|
-
Need help? Check the [full documentation](./LOGGING-GUIDE.md) or open an issue.
|
|
1
|
+
# SecureNow Logging - Quick Start
|
|
2
|
+
|
|
3
|
+
Get logging set up in your Node.js app in under 2 minutes!
|
|
4
|
+
|
|
5
|
+
**Since v5.6.0:** When `SECURENOW_LOGGING_ENABLED=1` is set, all `console.log` / `warn` / `error` / `info` / `debug` calls are automatically forwarded as OTLP log records. You only need `require('securenow/register')`—a separate `console-instrumentation` preload is no longer required.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install securenow
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 2. Configure Environment
|
|
18
|
+
|
|
19
|
+
Create `.env` file or export variables:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
SECURENOW_LOGGING_ENABLED=1
|
|
23
|
+
SECURENOW_APPID=my-app
|
|
24
|
+
SECURENOW_INSTANCE=http://your-otlp-backend:4318
|
|
25
|
+
|
|
26
|
+
# For SecureNow / hosted OTLP (example):
|
|
27
|
+
# SECURENOW_INSTANCE=https://freetrial.securenow.ai:4318
|
|
28
|
+
# OTEL_EXPORTER_OTLP_HEADERS="x-api-key=<your-key>"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 3. Add to Your App
|
|
34
|
+
|
|
35
|
+
**Option A: Automatic Console Logging (Easiest)**
|
|
36
|
+
|
|
37
|
+
Add this line at the top of your main file:
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
// app.js, index.js, server.js, or main.ts
|
|
41
|
+
require('securenow/register');
|
|
42
|
+
|
|
43
|
+
// That's it! Now use console normally
|
|
44
|
+
console.log('App started');
|
|
45
|
+
console.error('An error occurred', { userId: 123 });
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Option B: Use NODE_OPTIONS (No code changes)**
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
NODE_OPTIONS="-r securenow/register" node app.js
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 4. Run Your App
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
node app.js
|
|
60
|
+
# or
|
|
61
|
+
npm start
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
You should see:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
[securenow] OTel SDK started → http://your-otlp-backend:4318/v1/traces
|
|
68
|
+
[securenow] 📋 Logging: ENABLED → http://your-otlp-backend:4318/v1/logs
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 5. View Logs in SecureNow
|
|
74
|
+
|
|
75
|
+
1. Open your SecureNow dashboard
|
|
76
|
+
2. Go to **Logs** section
|
|
77
|
+
3. Filter by `service.name = my-app`
|
|
78
|
+
4. See all your logs with automatic trace correlation!
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Framework-Specific Examples
|
|
83
|
+
|
|
84
|
+
### Express.js
|
|
85
|
+
|
|
86
|
+
```javascript
|
|
87
|
+
// app.js
|
|
88
|
+
require('securenow/register');
|
|
89
|
+
|
|
90
|
+
const express = require('express');
|
|
91
|
+
const app = express();
|
|
92
|
+
|
|
93
|
+
app.get('/', (req, res) => {
|
|
94
|
+
console.log('Request received');
|
|
95
|
+
res.send('Hello World');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
app.listen(3000);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Next.js
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
// instrumentation.ts (in project root)
|
|
105
|
+
export async function register() {
|
|
106
|
+
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
|
107
|
+
process.env.SECURENOW_LOGGING_ENABLED = '1';
|
|
108
|
+
await import('securenow/register');
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# .env.local
|
|
115
|
+
SECURENOW_LOGGING_ENABLED=1
|
|
116
|
+
SECURENOW_APPID=my-nextjs-app
|
|
117
|
+
SECURENOW_INSTANCE=http://localhost:4318
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Fastify
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
// server.js
|
|
124
|
+
require('securenow/register');
|
|
125
|
+
|
|
126
|
+
const fastify = require('fastify')();
|
|
127
|
+
|
|
128
|
+
fastify.get('/', async () => {
|
|
129
|
+
console.log('Route called');
|
|
130
|
+
return { hello: 'world' };
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
fastify.listen({ port: 3000 });
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### NestJS
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
// main.ts
|
|
140
|
+
require('securenow/register');
|
|
141
|
+
|
|
142
|
+
import { NestFactory } from '@nestjs/core';
|
|
143
|
+
import { AppModule } from './app.module';
|
|
144
|
+
|
|
145
|
+
async function bootstrap() {
|
|
146
|
+
const app = await NestFactory.create(AppModule);
|
|
147
|
+
console.log('App starting');
|
|
148
|
+
await app.listen(3000);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
bootstrap();
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Troubleshooting
|
|
157
|
+
|
|
158
|
+
**Logs not appearing?**
|
|
159
|
+
|
|
160
|
+
1. Check `SECURENOW_LOGGING_ENABLED=1` is set
|
|
161
|
+
2. Verify your OTLP / SecureNow endpoint is correct
|
|
162
|
+
3. Enable debug: `OTEL_LOG_LEVEL=debug`
|
|
163
|
+
|
|
164
|
+
**Console logs not forwarding?**
|
|
165
|
+
|
|
166
|
+
Load `securenow/register` before other app code so logging hooks run first:
|
|
167
|
+
|
|
168
|
+
```javascript
|
|
169
|
+
// ✅ Correct
|
|
170
|
+
require('securenow/register'); // First
|
|
171
|
+
|
|
172
|
+
// ❌ Wrong
|
|
173
|
+
require('express');
|
|
174
|
+
require('securenow/register'); // Too late!
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## What Gets Logged?
|
|
180
|
+
|
|
181
|
+
All standard console methods:
|
|
182
|
+
|
|
183
|
+
- `console.log()` → INFO
|
|
184
|
+
- `console.info()` → INFO
|
|
185
|
+
- `console.warn()` → WARN
|
|
186
|
+
- `console.error()` → ERROR
|
|
187
|
+
- `console.debug()` → DEBUG
|
|
188
|
+
|
|
189
|
+
**Structured logging example:**
|
|
190
|
+
|
|
191
|
+
```javascript
|
|
192
|
+
console.log('User logged in', {
|
|
193
|
+
userId: 123,
|
|
194
|
+
email: 'user@example.com',
|
|
195
|
+
ip: '192.168.1.1'
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
This creates a log with attributes you can filter/search in SecureNow!
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Advanced Usage
|
|
204
|
+
|
|
205
|
+
**Direct Logger API:**
|
|
206
|
+
|
|
207
|
+
```javascript
|
|
208
|
+
const { getLogger } = require('securenow/tracing');
|
|
209
|
+
const logger = getLogger('my-module', '1.0.0');
|
|
210
|
+
|
|
211
|
+
logger.emit({
|
|
212
|
+
severityNumber: 9,
|
|
213
|
+
severityText: 'INFO',
|
|
214
|
+
body: 'Custom log message',
|
|
215
|
+
attributes: {
|
|
216
|
+
customField: 'value',
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Next Steps
|
|
224
|
+
|
|
225
|
+
- [Complete Logging Guide](./LOGGING-GUIDE.md) - All features and options
|
|
226
|
+
- [SecureNow](https://securenow.ai/)
|
|
227
|
+
- [Documentation](./INDEX.md)
|
|
228
|
+
- [Combine with Tracing](../README.md) - Full observability
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
**That's it!** 🎉 Your app is now sending logs to SecureNow.
|
|
233
|
+
|
|
234
|
+
Need help? Check the [full documentation](./LOGGING-GUIDE.md) or open an issue.
|
package/nextjs.js
CHANGED
|
@@ -551,17 +551,30 @@ function registerSecureNow(options = {}) {
|
|
|
551
551
|
const origWarn = console.warn;
|
|
552
552
|
const origError = console.error;
|
|
553
553
|
|
|
554
|
+
const { context: otelContext, trace: otelTrace } = require('@opentelemetry/api');
|
|
555
|
+
function _emitLog(sn, st, args) {
|
|
556
|
+
try {
|
|
557
|
+
const activeCtx = otelContext.active();
|
|
558
|
+
const spanCtx = otelTrace.getSpanContext(activeCtx);
|
|
559
|
+
logger.emit({
|
|
560
|
+
severityNumber: sn,
|
|
561
|
+
severityText: st,
|
|
562
|
+
body: args.map(String).join(' '),
|
|
563
|
+
...(spanCtx && { context: activeCtx }),
|
|
564
|
+
});
|
|
565
|
+
} catch (_) {}
|
|
566
|
+
}
|
|
554
567
|
console.log = (...args) => {
|
|
555
568
|
origLog.apply(console, args);
|
|
556
|
-
|
|
569
|
+
_emitLog(SeverityNumber.INFO, 'INFO', args);
|
|
557
570
|
};
|
|
558
571
|
console.warn = (...args) => {
|
|
559
572
|
origWarn.apply(console, args);
|
|
560
|
-
|
|
573
|
+
_emitLog(SeverityNumber.WARN, 'WARN', args);
|
|
561
574
|
};
|
|
562
575
|
console.error = (...args) => {
|
|
563
576
|
origError.apply(console, args);
|
|
564
|
-
|
|
577
|
+
_emitLog(SeverityNumber.ERROR, 'ERROR', args);
|
|
565
578
|
};
|
|
566
579
|
|
|
567
580
|
console.log('[securenow] 📋 Logging: ENABLED → %s', logsUrl);
|
|
@@ -575,6 +588,8 @@ function registerSecureNow(options = {}) {
|
|
|
575
588
|
const start = Date.now();
|
|
576
589
|
const method = req.method;
|
|
577
590
|
const url = req.url;
|
|
591
|
+
const reqCtx = otelContext.active();
|
|
592
|
+
const reqSpanCtx = otelTrace.getSpanContext(reqCtx);
|
|
578
593
|
|
|
579
594
|
res.on('finish', () => {
|
|
580
595
|
const duration = Date.now() - start;
|
|
@@ -598,6 +613,7 @@ function registerSecureNow(options = {}) {
|
|
|
598
613
|
'http.client_ip': String(ip).split(',')[0].trim(),
|
|
599
614
|
'http.user_agent': ua,
|
|
600
615
|
},
|
|
616
|
+
...(reqSpanCtx && { context: reqCtx }),
|
|
601
617
|
});
|
|
602
618
|
} catch (_) {}
|
|
603
619
|
});
|
package/package.json
CHANGED
package/tracing.js
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* SECURENOW_STRICT=1 -> if no appid/name is provided in cluster, exit(1) so PM2 restarts the worker
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api');
|
|
24
|
+
const { diag, DiagConsoleLogger, DiagLogLevel, context, trace } = require('@opentelemetry/api');
|
|
25
25
|
const { NodeSDK } = require('@opentelemetry/sdk-node');
|
|
26
26
|
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
|
|
27
27
|
const { OTLPLogExporter } = require('@opentelemetry/exporter-logs-otlp-http');
|
|
@@ -363,11 +363,14 @@ if (loggingEnabled) {
|
|
|
363
363
|
const SEV = { DEBUG: 5, INFO: 9, WARN: 13, ERROR: 17 };
|
|
364
364
|
function _emit(sn, st, args) {
|
|
365
365
|
try {
|
|
366
|
+
const activeCtx = context.active();
|
|
367
|
+
const spanCtx = trace.getSpanContext(activeCtx);
|
|
366
368
|
_logger.emit({
|
|
367
369
|
severityNumber: sn,
|
|
368
370
|
severityText: st,
|
|
369
371
|
body: args.map(a => (typeof a === 'object' && a !== null) ? JSON.stringify(a) : String(a)).join(' '),
|
|
370
372
|
attributes: { 'log.source': 'console', 'log.method': st.toLowerCase() },
|
|
373
|
+
...(spanCtx && { context: activeCtx }),
|
|
371
374
|
});
|
|
372
375
|
} catch (_) {}
|
|
373
376
|
}
|