securenow 4.0.12 → 5.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.
- package/README.md +42 -2
- package/console-instrumentation.js +136 -0
- package/docs/INDEX.md +21 -3
- package/docs/LOGGING-GUIDE.md +708 -0
- package/docs/LOGGING-QUICKSTART.md +239 -0
- package/examples/express-with-logging.js +137 -0
- package/examples/nextjs-with-logging-example.md +301 -0
- package/package.json +11 -2
- package/tracing.d.ts +93 -0
- package/tracing.js +59 -8
|
@@ -0,0 +1,708 @@
|
|
|
1
|
+
# SecureNow Logging Guide
|
|
2
|
+
|
|
3
|
+
Complete guide for sending logs from your Node.js applications to SigNoz using the SecureNow library.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Quick Start](#quick-start)
|
|
8
|
+
- [Configuration](#configuration)
|
|
9
|
+
- [Usage Methods](#usage-methods)
|
|
10
|
+
- [Method 1: Automatic Console Instrumentation](#method-1-automatic-console-instrumentation-easiest)
|
|
11
|
+
- [Method 2: Direct Logger API](#method-2-direct-logger-api)
|
|
12
|
+
- [Method 3: Custom Logger Integration](#method-3-custom-logger-integration)
|
|
13
|
+
- [Framework-Specific Examples](#framework-specific-examples)
|
|
14
|
+
- [Express.js](#expressjs)
|
|
15
|
+
- [Next.js](#nextjs)
|
|
16
|
+
- [Fastify](#fastify)
|
|
17
|
+
- [NestJS](#nestjs)
|
|
18
|
+
- [Advanced Configuration](#advanced-configuration)
|
|
19
|
+
- [Troubleshooting](#troubleshooting)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### 1. Install SecureNow
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install securenow
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 2. Enable Logging
|
|
32
|
+
|
|
33
|
+
Set environment variables:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Required: Enable logging
|
|
37
|
+
export SECURENOW_LOGGING_ENABLED=1
|
|
38
|
+
|
|
39
|
+
# Required: Your app identifier
|
|
40
|
+
export SECURENOW_APPID=my-app
|
|
41
|
+
|
|
42
|
+
# Optional: Your SigNoz endpoint (defaults to http://46.62.173.237:4318)
|
|
43
|
+
export SECURENOW_INSTANCE=http://your-signoz-server:4318
|
|
44
|
+
|
|
45
|
+
# Optional: SigNoz Cloud authentication
|
|
46
|
+
export OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=your-key-here"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 3. Choose Your Usage Method
|
|
50
|
+
|
|
51
|
+
**Option A: Automatic Console Logging (Easiest)**
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
// At the top of your main file (app.js, index.js, server.js)
|
|
55
|
+
require('securenow/register');
|
|
56
|
+
require('securenow/console-instrumentation');
|
|
57
|
+
|
|
58
|
+
// Now all console logs are automatically sent to SigNoz
|
|
59
|
+
console.log('Application started');
|
|
60
|
+
console.error('An error occurred', { userId: 123 });
|
|
61
|
+
console.warn('Warning message');
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Option B: Direct Logger API**
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
require('securenow/register');
|
|
68
|
+
const { getLogger } = require('securenow/tracing');
|
|
69
|
+
|
|
70
|
+
const logger = getLogger('my-module', '1.0.0');
|
|
71
|
+
|
|
72
|
+
logger.emit({
|
|
73
|
+
severityNumber: 9, // INFO
|
|
74
|
+
severityText: 'INFO',
|
|
75
|
+
body: 'User logged in',
|
|
76
|
+
attributes: {
|
|
77
|
+
userId: 123,
|
|
78
|
+
username: 'john',
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Configuration
|
|
86
|
+
|
|
87
|
+
### Environment Variables
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Logging Control
|
|
91
|
+
SECURENOW_LOGGING_ENABLED=1 # Enable logging (default: 1)
|
|
92
|
+
|
|
93
|
+
# Connection Settings
|
|
94
|
+
SECURENOW_INSTANCE=http://localhost:4318 # Base OTLP endpoint
|
|
95
|
+
OTEL_EXPORTER_OTLP_ENDPOINT=... # Alternative to SECURENOW_INSTANCE
|
|
96
|
+
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=... # Specific logs endpoint (overrides base)
|
|
97
|
+
|
|
98
|
+
# Authentication (for SigNoz Cloud)
|
|
99
|
+
OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=YOUR_KEY"
|
|
100
|
+
|
|
101
|
+
# Service Identification
|
|
102
|
+
SECURENOW_APPID=my-app # Your application name
|
|
103
|
+
OTEL_SERVICE_NAME=my-app # Alternative to SECURENOW_APPID
|
|
104
|
+
|
|
105
|
+
# Additional Options
|
|
106
|
+
OTEL_LOG_LEVEL=info # debug|info|warn|error
|
|
107
|
+
NODE_ENV=production # Environment name
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### SigNoz Cloud Configuration
|
|
111
|
+
|
|
112
|
+
For SigNoz Cloud:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
export SECURENOW_LOGGING_ENABLED=1
|
|
116
|
+
export SECURENOW_APPID=my-app
|
|
117
|
+
export SECURENOW_INSTANCE=https://ingest.<region>.signoz.cloud:443
|
|
118
|
+
export OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=<your-ingestion-key>"
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Replace:
|
|
122
|
+
- `<region>`: Your SigNoz Cloud region (us, eu, in)
|
|
123
|
+
- `<your-ingestion-key>`: Your ingestion key from SigNoz Cloud
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Usage Methods
|
|
128
|
+
|
|
129
|
+
### Method 1: Automatic Console Instrumentation (Easiest)
|
|
130
|
+
|
|
131
|
+
This method wraps the default `console` methods to automatically send logs to SigNoz while still printing to the console.
|
|
132
|
+
|
|
133
|
+
**Setup:**
|
|
134
|
+
|
|
135
|
+
```javascript
|
|
136
|
+
// app.js or index.js
|
|
137
|
+
require('securenow/register');
|
|
138
|
+
require('securenow/console-instrumentation');
|
|
139
|
+
|
|
140
|
+
const express = require('express');
|
|
141
|
+
const app = express();
|
|
142
|
+
|
|
143
|
+
// Use console as normal - all logs are captured
|
|
144
|
+
console.log('Server starting...');
|
|
145
|
+
|
|
146
|
+
app.get('/', (req, res) => {
|
|
147
|
+
console.info('Request received', { path: req.path });
|
|
148
|
+
res.send('Hello World');
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
app.listen(3000, () => {
|
|
152
|
+
console.log('Server running on port 3000');
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Supported Methods:**
|
|
157
|
+
- `console.log()` → INFO level
|
|
158
|
+
- `console.info()` → INFO level
|
|
159
|
+
- `console.warn()` → WARN level
|
|
160
|
+
- `console.error()` → ERROR level
|
|
161
|
+
- `console.debug()` → DEBUG level
|
|
162
|
+
|
|
163
|
+
**Benefits:**
|
|
164
|
+
- ✅ Zero code changes needed
|
|
165
|
+
- ✅ Works with existing console logging
|
|
166
|
+
- ✅ Automatic severity mapping
|
|
167
|
+
- ✅ Works with all frameworks
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
### Method 2: Direct Logger API
|
|
172
|
+
|
|
173
|
+
Use the OpenTelemetry logger API directly for more control.
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
require('securenow/register');
|
|
177
|
+
const { getLogger } = require('securenow/tracing');
|
|
178
|
+
|
|
179
|
+
// Get a logger instance
|
|
180
|
+
const logger = getLogger('my-service', '1.0.0');
|
|
181
|
+
|
|
182
|
+
// Emit structured logs
|
|
183
|
+
logger.emit({
|
|
184
|
+
severityNumber: 9, // OpenTelemetry severity number
|
|
185
|
+
severityText: 'INFO', // Human-readable severity
|
|
186
|
+
body: 'User login', // Log message
|
|
187
|
+
attributes: { // Structured attributes
|
|
188
|
+
userId: 123,
|
|
189
|
+
username: 'john',
|
|
190
|
+
ip: '192.168.1.1',
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Severity Numbers:**
|
|
196
|
+
- `5` - DEBUG
|
|
197
|
+
- `9` - INFO
|
|
198
|
+
- `13` - WARN
|
|
199
|
+
- `17` - ERROR
|
|
200
|
+
|
|
201
|
+
**Example with Error:**
|
|
202
|
+
|
|
203
|
+
```javascript
|
|
204
|
+
try {
|
|
205
|
+
// Some operation
|
|
206
|
+
} catch (error) {
|
|
207
|
+
logger.emit({
|
|
208
|
+
severityNumber: 17,
|
|
209
|
+
severityText: 'ERROR',
|
|
210
|
+
body: 'Database connection failed',
|
|
211
|
+
attributes: {
|
|
212
|
+
error: error.message,
|
|
213
|
+
stack: error.stack,
|
|
214
|
+
database: 'postgres',
|
|
215
|
+
},
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
### Method 3: Custom Logger Integration
|
|
223
|
+
|
|
224
|
+
Create a wrapper for your preferred logging style.
|
|
225
|
+
|
|
226
|
+
```javascript
|
|
227
|
+
// logger.js
|
|
228
|
+
require('securenow/register');
|
|
229
|
+
const { getLogger } = require('securenow/tracing');
|
|
230
|
+
|
|
231
|
+
const logger = getLogger('app-logger', '1.0.0');
|
|
232
|
+
|
|
233
|
+
const SeverityNumber = {
|
|
234
|
+
DEBUG: 5,
|
|
235
|
+
INFO: 9,
|
|
236
|
+
WARN: 13,
|
|
237
|
+
ERROR: 17,
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
function log(level, message, attributes = {}) {
|
|
241
|
+
if (!logger) {
|
|
242
|
+
console.log(message, attributes);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
logger.emit({
|
|
247
|
+
severityNumber: SeverityNumber[level],
|
|
248
|
+
severityText: level,
|
|
249
|
+
body: message,
|
|
250
|
+
attributes,
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
// Also log to console
|
|
254
|
+
console.log(`[${level}] ${message}`, attributes);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
module.exports = {
|
|
258
|
+
debug: (msg, attrs) => log('DEBUG', msg, attrs),
|
|
259
|
+
info: (msg, attrs) => log('INFO', msg, attrs),
|
|
260
|
+
warn: (msg, attrs) => log('WARN', msg, attrs),
|
|
261
|
+
error: (msg, attrs) => log('ERROR', msg, attrs),
|
|
262
|
+
};
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**Usage:**
|
|
266
|
+
|
|
267
|
+
```javascript
|
|
268
|
+
const logger = require('./logger');
|
|
269
|
+
|
|
270
|
+
logger.info('User signed up', { userId: 456, email: 'user@example.com' });
|
|
271
|
+
logger.error('Payment failed', { orderId: 789, amount: 99.99 });
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## Framework-Specific Examples
|
|
277
|
+
|
|
278
|
+
### Express.js
|
|
279
|
+
|
|
280
|
+
```javascript
|
|
281
|
+
// app.js
|
|
282
|
+
require('securenow/register');
|
|
283
|
+
require('securenow/console-instrumentation');
|
|
284
|
+
|
|
285
|
+
const express = require('express');
|
|
286
|
+
const app = express();
|
|
287
|
+
|
|
288
|
+
app.use(express.json());
|
|
289
|
+
|
|
290
|
+
// Logging middleware
|
|
291
|
+
app.use((req, res, next) => {
|
|
292
|
+
console.info('Request received', {
|
|
293
|
+
method: req.method,
|
|
294
|
+
path: req.path,
|
|
295
|
+
ip: req.ip,
|
|
296
|
+
});
|
|
297
|
+
next();
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
app.get('/', (req, res) => {
|
|
301
|
+
console.log('Home page accessed');
|
|
302
|
+
res.send('Hello World');
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
app.post('/api/users', (req, res) => {
|
|
306
|
+
console.info('User created', { userData: req.body });
|
|
307
|
+
res.json({ success: true });
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// Error handler with logging
|
|
311
|
+
app.use((err, req, res, next) => {
|
|
312
|
+
console.error('Express error', {
|
|
313
|
+
error: err.message,
|
|
314
|
+
stack: err.stack,
|
|
315
|
+
path: req.path,
|
|
316
|
+
});
|
|
317
|
+
res.status(500).json({ error: 'Internal server error' });
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
app.listen(3000, () => {
|
|
321
|
+
console.log('Express server running on port 3000');
|
|
322
|
+
});
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**Run with:**
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
SECURENOW_LOGGING_ENABLED=1 \
|
|
329
|
+
SECURENOW_APPID=express-app \
|
|
330
|
+
NODE_OPTIONS="-r securenow/register -r securenow/console-instrumentation" \
|
|
331
|
+
node app.js
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
### Next.js
|
|
337
|
+
|
|
338
|
+
#### App Router (Next.js 13+)
|
|
339
|
+
|
|
340
|
+
**instrumentation.ts:**
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
// instrumentation.ts (in root directory)
|
|
344
|
+
export async function register() {
|
|
345
|
+
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
|
346
|
+
// Enable tracing and logging
|
|
347
|
+
process.env.SECURENOW_LOGGING_ENABLED = '1';
|
|
348
|
+
|
|
349
|
+
await import('securenow/register');
|
|
350
|
+
await import('securenow/console-instrumentation');
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**Environment Variables (.env.local):**
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
SECURENOW_LOGGING_ENABLED=1
|
|
359
|
+
SECURENOW_APPID=nextjs-app
|
|
360
|
+
SECURENOW_INSTANCE=http://your-signoz-server:4318
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
**Usage in API Routes:**
|
|
364
|
+
|
|
365
|
+
```typescript
|
|
366
|
+
// app/api/users/route.ts
|
|
367
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
368
|
+
|
|
369
|
+
export async function GET(request: NextRequest) {
|
|
370
|
+
console.log('GET /api/users called');
|
|
371
|
+
|
|
372
|
+
const users = await fetchUsers();
|
|
373
|
+
console.info('Users fetched', { count: users.length });
|
|
374
|
+
|
|
375
|
+
return NextResponse.json(users);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
export async function POST(request: NextRequest) {
|
|
379
|
+
const data = await request.json();
|
|
380
|
+
console.info('Creating user', { email: data.email });
|
|
381
|
+
|
|
382
|
+
try {
|
|
383
|
+
const user = await createUser(data);
|
|
384
|
+
console.log('User created successfully', { userId: user.id });
|
|
385
|
+
return NextResponse.json(user);
|
|
386
|
+
} catch (error) {
|
|
387
|
+
console.error('Failed to create user', { error: error.message });
|
|
388
|
+
return NextResponse.json({ error: 'Failed' }, { status: 500 });
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
**Usage in Server Components:**
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
// app/dashboard/page.tsx
|
|
397
|
+
export default async function DashboardPage() {
|
|
398
|
+
console.log('Dashboard page rendering');
|
|
399
|
+
|
|
400
|
+
const data = await fetchDashboardData();
|
|
401
|
+
console.info('Dashboard data loaded', { items: data.length });
|
|
402
|
+
|
|
403
|
+
return <div>{/* your component */}</div>;
|
|
404
|
+
}
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
### Fastify
|
|
410
|
+
|
|
411
|
+
```javascript
|
|
412
|
+
// server.js
|
|
413
|
+
require('securenow/register');
|
|
414
|
+
require('securenow/console-instrumentation');
|
|
415
|
+
|
|
416
|
+
const fastify = require('fastify')({ logger: false });
|
|
417
|
+
|
|
418
|
+
// Logging hook
|
|
419
|
+
fastify.addHook('onRequest', async (request, reply) => {
|
|
420
|
+
console.info('Request received', {
|
|
421
|
+
method: request.method,
|
|
422
|
+
url: request.url,
|
|
423
|
+
});
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
fastify.get('/', async (request, reply) => {
|
|
427
|
+
console.log('Root endpoint called');
|
|
428
|
+
return { hello: 'world' };
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
fastify.post('/users', async (request, reply) => {
|
|
432
|
+
console.info('Creating user', { body: request.body });
|
|
433
|
+
return { success: true };
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
// Error handler
|
|
437
|
+
fastify.setErrorHandler((error, request, reply) => {
|
|
438
|
+
console.error('Fastify error', {
|
|
439
|
+
error: error.message,
|
|
440
|
+
stack: error.stack,
|
|
441
|
+
url: request.url,
|
|
442
|
+
});
|
|
443
|
+
reply.status(500).send({ error: 'Internal server error' });
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
const start = async () => {
|
|
447
|
+
try {
|
|
448
|
+
await fastify.listen({ port: 3000 });
|
|
449
|
+
console.log('Fastify server running on port 3000');
|
|
450
|
+
} catch (err) {
|
|
451
|
+
console.error('Server start failed', { error: err });
|
|
452
|
+
process.exit(1);
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
start();
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
### NestJS
|
|
462
|
+
|
|
463
|
+
**main.ts:**
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
// main.ts
|
|
467
|
+
require('securenow/register');
|
|
468
|
+
require('securenow/console-instrumentation');
|
|
469
|
+
|
|
470
|
+
import { NestFactory } from '@nestjs/core';
|
|
471
|
+
import { AppModule } from './app.module';
|
|
472
|
+
|
|
473
|
+
async function bootstrap() {
|
|
474
|
+
const app = await NestFactory.create(AppModule);
|
|
475
|
+
|
|
476
|
+
console.log('NestJS application starting...');
|
|
477
|
+
|
|
478
|
+
await app.listen(3000);
|
|
479
|
+
console.log('NestJS application running on port 3000');
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
bootstrap();
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
**Service with logging:**
|
|
486
|
+
|
|
487
|
+
```typescript
|
|
488
|
+
// users.service.ts
|
|
489
|
+
import { Injectable } from '@nestjs/common';
|
|
490
|
+
|
|
491
|
+
@Injectable()
|
|
492
|
+
export class UsersService {
|
|
493
|
+
async findAll() {
|
|
494
|
+
console.log('Fetching all users');
|
|
495
|
+
const users = await this.fetchFromDatabase();
|
|
496
|
+
console.info('Users retrieved', { count: users.length });
|
|
497
|
+
return users;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
async create(userData: any) {
|
|
501
|
+
console.info('Creating user', { email: userData.email });
|
|
502
|
+
|
|
503
|
+
try {
|
|
504
|
+
const user = await this.saveToDatabase(userData);
|
|
505
|
+
console.log('User created', { userId: user.id });
|
|
506
|
+
return user;
|
|
507
|
+
} catch (error) {
|
|
508
|
+
console.error('Failed to create user', {
|
|
509
|
+
error: error.message,
|
|
510
|
+
email: userData.email,
|
|
511
|
+
});
|
|
512
|
+
throw error;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
**Run with environment variables:**
|
|
519
|
+
|
|
520
|
+
```bash
|
|
521
|
+
SECURENOW_LOGGING_ENABLED=1 \
|
|
522
|
+
SECURENOW_APPID=nestjs-app \
|
|
523
|
+
npm run start
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
---
|
|
527
|
+
|
|
528
|
+
## Advanced Configuration
|
|
529
|
+
|
|
530
|
+
### Disable Logging Temporarily
|
|
531
|
+
|
|
532
|
+
```bash
|
|
533
|
+
SECURENOW_LOGGING_ENABLED=0 node app.js
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### Custom Logs Endpoint
|
|
537
|
+
|
|
538
|
+
```bash
|
|
539
|
+
export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://custom-collector:4318/v1/logs
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### Check if Logging is Enabled
|
|
543
|
+
|
|
544
|
+
```javascript
|
|
545
|
+
const { isLoggingEnabled } = require('securenow/tracing');
|
|
546
|
+
|
|
547
|
+
if (isLoggingEnabled()) {
|
|
548
|
+
console.log('Logging is enabled');
|
|
549
|
+
}
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
### Multiple Logger Instances
|
|
553
|
+
|
|
554
|
+
```javascript
|
|
555
|
+
const { getLogger } = require('securenow/tracing');
|
|
556
|
+
|
|
557
|
+
const authLogger = getLogger('auth-service', '1.0.0');
|
|
558
|
+
const dbLogger = getLogger('database', '2.0.0');
|
|
559
|
+
const apiLogger = getLogger('api', '1.0.0');
|
|
560
|
+
|
|
561
|
+
authLogger.emit({
|
|
562
|
+
severityNumber: 9,
|
|
563
|
+
severityText: 'INFO',
|
|
564
|
+
body: 'User logged in',
|
|
565
|
+
attributes: { userId: 123 },
|
|
566
|
+
});
|
|
567
|
+
|
|
568
|
+
dbLogger.emit({
|
|
569
|
+
severityNumber: 13,
|
|
570
|
+
severityText: 'WARN',
|
|
571
|
+
body: 'Slow query detected',
|
|
572
|
+
attributes: { queryTime: 5000, query: 'SELECT ...' },
|
|
573
|
+
});
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
---
|
|
577
|
+
|
|
578
|
+
## Troubleshooting
|
|
579
|
+
|
|
580
|
+
### Logs not appearing in SigNoz
|
|
581
|
+
|
|
582
|
+
**Check 1: Is logging enabled?**
|
|
583
|
+
|
|
584
|
+
```bash
|
|
585
|
+
SECURENOW_LOGGING_ENABLED=1
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
**Check 2: Verify endpoint**
|
|
589
|
+
|
|
590
|
+
```bash
|
|
591
|
+
# For self-hosted SigNoz
|
|
592
|
+
export SECURENOW_INSTANCE=http://your-signoz-server:4318
|
|
593
|
+
|
|
594
|
+
# For SigNoz Cloud
|
|
595
|
+
export SECURENOW_INSTANCE=https://ingest.<region>.signoz.cloud:443
|
|
596
|
+
export OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=<your-key>"
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
**Check 3: Enable debug logging**
|
|
600
|
+
|
|
601
|
+
```bash
|
|
602
|
+
export OTEL_LOG_LEVEL=debug
|
|
603
|
+
node app.js
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
Look for messages like:
|
|
607
|
+
```
|
|
608
|
+
[securenow] 📋 Logging: ENABLED → http://localhost:4318/v1/logs
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
**Check 4: Verify initialization order**
|
|
612
|
+
|
|
613
|
+
Make sure `securenow/register` is required BEFORE any other code:
|
|
614
|
+
|
|
615
|
+
```javascript
|
|
616
|
+
// ✅ Correct
|
|
617
|
+
require('securenow/register');
|
|
618
|
+
require('securenow/console-instrumentation');
|
|
619
|
+
const express = require('express');
|
|
620
|
+
|
|
621
|
+
// ❌ Wrong
|
|
622
|
+
const express = require('express');
|
|
623
|
+
require('securenow/register');
|
|
624
|
+
require('securenow/console-instrumentation');
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
### Console instrumentation not working
|
|
628
|
+
|
|
629
|
+
**Check load order:**
|
|
630
|
+
|
|
631
|
+
```javascript
|
|
632
|
+
// console-instrumentation MUST come AFTER register
|
|
633
|
+
require('securenow/register');
|
|
634
|
+
require('securenow/console-instrumentation'); // This wraps console
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
**Verify in output:**
|
|
638
|
+
|
|
639
|
+
You should see:
|
|
640
|
+
```
|
|
641
|
+
[securenow] Console instrumentation installed - all console logs will be sent to SigNoz
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
### Logger returns null
|
|
645
|
+
|
|
646
|
+
This happens when logging is not enabled:
|
|
647
|
+
|
|
648
|
+
```javascript
|
|
649
|
+
const { getLogger } = require('securenow/tracing');
|
|
650
|
+
const logger = getLogger('test');
|
|
651
|
+
|
|
652
|
+
if (!logger) {
|
|
653
|
+
console.log('Logging not enabled - set SECURENOW_LOGGING_ENABLED=1');
|
|
654
|
+
}
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
### Logs in SigNoz but missing attributes
|
|
658
|
+
|
|
659
|
+
Make sure you're passing attributes correctly:
|
|
660
|
+
|
|
661
|
+
```javascript
|
|
662
|
+
// ✅ Correct
|
|
663
|
+
console.log('User action', { userId: 123, action: 'login' });
|
|
664
|
+
|
|
665
|
+
// ❌ Won't capture structured data
|
|
666
|
+
console.log('User action userId=123 action=login');
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
Or use direct logger API:
|
|
670
|
+
|
|
671
|
+
```javascript
|
|
672
|
+
logger.emit({
|
|
673
|
+
severityNumber: 9,
|
|
674
|
+
severityText: 'INFO',
|
|
675
|
+
body: 'User action',
|
|
676
|
+
attributes: {
|
|
677
|
+
userId: 123,
|
|
678
|
+
action: 'login',
|
|
679
|
+
},
|
|
680
|
+
});
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
---
|
|
684
|
+
|
|
685
|
+
## Best Practices
|
|
686
|
+
|
|
687
|
+
1. **Always enable logging via environment variable** - don't hardcode it
|
|
688
|
+
2. **Use structured logging** - pass objects with meaningful attributes
|
|
689
|
+
3. **Include context** - userId, requestId, etc. in log attributes
|
|
690
|
+
4. **Use appropriate severity levels** - INFO for normal flow, ERROR for exceptions
|
|
691
|
+
5. **Don't log sensitive data** - passwords, tokens, credit cards
|
|
692
|
+
6. **Use different loggers for different modules** - easier filtering in SigNoz
|
|
693
|
+
|
|
694
|
+
---
|
|
695
|
+
|
|
696
|
+
## Next Steps
|
|
697
|
+
|
|
698
|
+
- [View logs in SigNoz](https://signoz.io/docs/logs-management/overview/)
|
|
699
|
+
- [Set up log-based alerts](https://signoz.io/docs/alerts-management/log-based-alerts/)
|
|
700
|
+
- [Combine with tracing](../README.md) for full observability
|
|
701
|
+
|
|
702
|
+
---
|
|
703
|
+
|
|
704
|
+
## Support
|
|
705
|
+
|
|
706
|
+
- **Issues**: [GitHub Issues](https://github.com/your-repo/securenow-npm)
|
|
707
|
+
- **Documentation**: [Full Docs](./INDEX.md)
|
|
708
|
+
- **Website**: [securenow.ai](http://securenow.ai/)
|