securenow 5.0.0 → 5.0.2

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.
@@ -0,0 +1,720 @@
1
+ # Express.js Setup Guide - SecureNow Observability
2
+
3
+ Complete guide to add distributed tracing and logging to your Express.js application using SecureNow.
4
+
5
+ ---
6
+
7
+ ## Prerequisites
8
+
9
+ - Node.js 18 or higher
10
+ - An existing Express.js application
11
+ - An OTLP-compatible observability backend
12
+
13
+ ---
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install securenow express
19
+ ```
20
+
21
+ ---
22
+
23
+ ## Quick Start (5 Minutes)
24
+
25
+ ### Step 1: Install Package
26
+
27
+ ```bash
28
+ npm install securenow
29
+ ```
30
+
31
+ ### Step 2: Create Environment Variables
32
+
33
+ Create a `.env` file in your project root:
34
+
35
+ ```env
36
+ SECURENOW_APPID=my-express-app
37
+ SECURENOW_INSTANCE=http://localhost:4318
38
+ SECURENOW_LOGGING_ENABLED=1
39
+ SECURENOW_CAPTURE_BODY=1
40
+ ```
41
+
42
+ ### Step 3: Initialize SecureNow
43
+
44
+ Add these lines at the **very top** of your main file (before any other requires):
45
+
46
+ ```javascript
47
+ // app.js or server.js
48
+ require('securenow/register');
49
+ require('securenow/console-instrumentation');
50
+
51
+ // Now your Express app
52
+ const express = require('express');
53
+ const app = express();
54
+
55
+ app.use(express.json());
56
+
57
+ app.get('/', (req, res) => {
58
+ console.log('Home page accessed');
59
+ res.send('Hello World');
60
+ });
61
+
62
+ const PORT = process.env.PORT || 3000;
63
+ app.listen(PORT, () => {
64
+ console.log(`Server running on port ${PORT}`);
65
+ });
66
+ ```
67
+
68
+ ### Step 4: Run Your Application
69
+
70
+ ```bash
71
+ node app.js
72
+ ```
73
+
74
+ You should see:
75
+
76
+ ```
77
+ [securenow] OTel SDK started → http://localhost:4318/v1/traces
78
+ [securenow] 📋 Logging: ENABLED → http://localhost:4318/v1/logs
79
+ [securenow] Console instrumentation installed
80
+ Server running on port 3000
81
+ ```
82
+
83
+ **Done!** Your Express app is now sending traces and logs.
84
+
85
+ ---
86
+
87
+ ## Complete Example
88
+
89
+ ```javascript
90
+ // app.js
91
+ require('securenow/register');
92
+ require('securenow/console-instrumentation');
93
+
94
+ const express = require('express');
95
+ const app = express();
96
+
97
+ // Middleware
98
+ app.use(express.json());
99
+ app.use(express.urlencoded({ extended: true }));
100
+
101
+ // Logging middleware
102
+ app.use((req, res, next) => {
103
+ console.info('Incoming request', {
104
+ method: req.method,
105
+ path: req.path,
106
+ query: req.query,
107
+ ip: req.ip,
108
+ userAgent: req.get('user-agent'),
109
+ });
110
+ next();
111
+ });
112
+
113
+ // Routes
114
+ app.get('/', (req, res) => {
115
+ console.log('Home page accessed');
116
+ res.json({
117
+ message: 'Express with SecureNow',
118
+ timestamp: new Date().toISOString(),
119
+ });
120
+ });
121
+
122
+ app.get('/api/users', async (req, res) => {
123
+ console.log('Fetching users');
124
+
125
+ try {
126
+ // Your database logic
127
+ const users = await getUsersFromDatabase();
128
+
129
+ console.info('Users fetched successfully', {
130
+ count: users.length,
131
+ });
132
+
133
+ res.json(users);
134
+ } catch (error) {
135
+ console.error('Failed to fetch users', {
136
+ error: error.message,
137
+ stack: error.stack,
138
+ });
139
+ res.status(500).json({ error: 'Internal server error' });
140
+ }
141
+ });
142
+
143
+ app.post('/api/users', async (req, res) => {
144
+ console.info('Creating new user', {
145
+ email: req.body.email,
146
+ name: req.body.name,
147
+ });
148
+
149
+ try {
150
+ // Validation
151
+ if (!req.body.email || !req.body.name) {
152
+ console.warn('Validation failed', {
153
+ body: req.body,
154
+ });
155
+ return res.status(400).json({ error: 'Email and name required' });
156
+ }
157
+
158
+ // Your database logic
159
+ const user = await createUserInDatabase(req.body);
160
+
161
+ console.log('User created successfully', {
162
+ userId: user.id,
163
+ email: user.email,
164
+ });
165
+
166
+ res.status(201).json(user);
167
+ } catch (error) {
168
+ console.error('Failed to create user', {
169
+ error: error.message,
170
+ stack: error.stack,
171
+ body: req.body,
172
+ });
173
+ res.status(500).json({ error: 'Internal server error' });
174
+ }
175
+ });
176
+
177
+ // Error handling middleware
178
+ app.use((err, req, res, next) => {
179
+ console.error('Express error handler', {
180
+ error: err.message,
181
+ stack: err.stack,
182
+ path: req.path,
183
+ method: req.method,
184
+ });
185
+
186
+ res.status(500).json({
187
+ error: 'Internal server error',
188
+ message: err.message,
189
+ });
190
+ });
191
+
192
+ // Start server
193
+ const PORT = process.env.PORT || 3000;
194
+ app.listen(PORT, () => {
195
+ console.log('Express server started', {
196
+ port: PORT,
197
+ nodeVersion: process.version,
198
+ env: process.env.NODE_ENV || 'development',
199
+ });
200
+ });
201
+ ```
202
+
203
+ ---
204
+
205
+ ## Using NODE_OPTIONS (No Code Changes)
206
+
207
+ If you don't want to modify your code, use `NODE_OPTIONS`:
208
+
209
+ ```bash
210
+ NODE_OPTIONS="-r securenow/register -r securenow/console-instrumentation" \
211
+ SECURENOW_APPID=my-express-app \
212
+ SECURENOW_INSTANCE=http://localhost:4318 \
213
+ SECURENOW_LOGGING_ENABLED=1 \
214
+ node app.js
215
+ ```
216
+
217
+ This works with npm scripts too:
218
+
219
+ ```json
220
+ {
221
+ "scripts": {
222
+ "start": "node app.js",
223
+ "start:instrumented": "NODE_OPTIONS='-r securenow/register -r securenow/console-instrumentation' node app.js"
224
+ }
225
+ }
226
+ ```
227
+
228
+ Then run:
229
+
230
+ ```bash
231
+ npm run start:instrumented
232
+ ```
233
+
234
+ ---
235
+
236
+ ## Environment Variables
237
+
238
+ ### Required
239
+
240
+ ```env
241
+ # Your application identifier
242
+ SECURENOW_APPID=my-express-app
243
+
244
+ # Your OTLP collector endpoint
245
+ SECURENOW_INSTANCE=http://localhost:4318
246
+ ```
247
+
248
+ ### Recommended
249
+
250
+ ```env
251
+ # Enable logging
252
+ SECURENOW_LOGGING_ENABLED=1
253
+
254
+ # Enable request body capture (for debugging)
255
+ SECURENOW_CAPTURE_BODY=1
256
+
257
+ # Max body size (default: 10KB)
258
+ SECURENOW_MAX_BODY_SIZE=10240
259
+
260
+ # Environment name
261
+ NODE_ENV=production
262
+ ```
263
+
264
+ ### Optional
265
+
266
+ ```env
267
+ # Authentication headers for your observability backend
268
+ OTEL_EXPORTER_OTLP_HEADERS=x-api-key=your-key
269
+
270
+ # Disable UUID suffix on service name
271
+ SECURENOW_NO_UUID=1
272
+
273
+ # Enable debug logging
274
+ OTEL_LOG_LEVEL=debug
275
+
276
+ # Additional sensitive fields to redact
277
+ SECURENOW_SENSITIVE_FIELDS=internal_token,session_key
278
+ ```
279
+
280
+ ---
281
+
282
+ ## PM2 Setup
283
+
284
+ ### Basic PM2 Configuration
285
+
286
+ ```javascript
287
+ // ecosystem.config.js
288
+ module.exports = {
289
+ apps: [{
290
+ name: 'my-express-app',
291
+ script: './app.js',
292
+ instances: 4,
293
+ exec_mode: 'cluster',
294
+ node_args: '-r securenow/register -r securenow/console-instrumentation',
295
+ env: {
296
+ SECURENOW_APPID: 'my-express-app',
297
+ SECURENOW_INSTANCE: 'http://localhost:4318',
298
+ SECURENOW_LOGGING_ENABLED: '1',
299
+ SECURENOW_NO_UUID: '1', // Same service name for all instances
300
+ SECURENOW_CAPTURE_BODY: '1',
301
+ NODE_ENV: 'production',
302
+ }
303
+ }]
304
+ };
305
+ ```
306
+
307
+ Start with PM2:
308
+
309
+ ```bash
310
+ pm2 start ecosystem.config.js
311
+ ```
312
+
313
+ ### PM2 with Environment-Specific Config
314
+
315
+ ```javascript
316
+ // ecosystem.config.js
317
+ module.exports = {
318
+ apps: [{
319
+ name: 'my-app',
320
+ script: './app.js',
321
+ instances: 4,
322
+ exec_mode: 'cluster',
323
+ node_args: '-r securenow/register -r securenow/console-instrumentation',
324
+ env_development: {
325
+ SECURENOW_APPID: 'my-app-dev',
326
+ SECURENOW_INSTANCE: 'http://localhost:4318',
327
+ SECURENOW_LOGGING_ENABLED: '1',
328
+ SECURENOW_CAPTURE_BODY: '1',
329
+ OTEL_LOG_LEVEL: 'debug',
330
+ NODE_ENV: 'development',
331
+ },
332
+ env_production: {
333
+ SECURENOW_APPID: 'my-app-prod',
334
+ SECURENOW_INSTANCE: 'http://collector.prod:4318',
335
+ SECURENOW_LOGGING_ENABLED: '1',
336
+ SECURENOW_CAPTURE_BODY: '0', // Disable in production
337
+ SECURENOW_NO_UUID: '1',
338
+ NODE_ENV: 'production',
339
+ }
340
+ }]
341
+ };
342
+ ```
343
+
344
+ Run with specific environment:
345
+
346
+ ```bash
347
+ # Development
348
+ pm2 start ecosystem.config.js
349
+
350
+ # Production
351
+ pm2 start ecosystem.config.js --env production
352
+ ```
353
+
354
+ ---
355
+
356
+ ## TypeScript Setup
357
+
358
+ ### Step 1: Install
359
+
360
+ ```bash
361
+ npm install securenow typescript @types/node @types/express ts-node
362
+ ```
363
+
364
+ ### Step 2: Initialize SecureNow
365
+
366
+ ```typescript
367
+ // app.ts
368
+ require('securenow/register');
369
+ require('securenow/console-instrumentation');
370
+
371
+ import express, { Request, Response, NextFunction } from 'express';
372
+
373
+ const app = express();
374
+
375
+ app.use(express.json());
376
+
377
+ app.get('/', (req: Request, res: Response) => {
378
+ console.log('Home page accessed');
379
+ res.json({ message: 'Hello World' });
380
+ });
381
+
382
+ app.post('/api/users', async (req: Request, res: Response) => {
383
+ console.info('Creating user', { body: req.body });
384
+
385
+ try {
386
+ // Your logic
387
+ const user = await createUser(req.body);
388
+ console.log('User created', { userId: user.id });
389
+ res.status(201).json(user);
390
+ } catch (error) {
391
+ console.error('Failed to create user', { error });
392
+ res.status(500).json({ error: 'Internal server error' });
393
+ }
394
+ });
395
+
396
+ // Error handler
397
+ app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
398
+ console.error('Express error', {
399
+ error: err.message,
400
+ stack: err.stack,
401
+ path: req.path,
402
+ });
403
+ res.status(500).json({ error: 'Internal server error' });
404
+ });
405
+
406
+ const PORT = process.env.PORT || 3000;
407
+ app.listen(PORT, () => {
408
+ console.log(`Server running on port ${PORT}`);
409
+ });
410
+ ```
411
+
412
+ ### Step 3: Run with ts-node
413
+
414
+ ```bash
415
+ npx ts-node app.ts
416
+ ```
417
+
418
+ Or compile and run:
419
+
420
+ ```bash
421
+ npx tsc
422
+ node dist/app.js
423
+ ```
424
+
425
+ ---
426
+
427
+ ## Advanced Features
428
+
429
+ ### Request Body Capture
430
+
431
+ Enable to see request bodies in your traces:
432
+
433
+ ```env
434
+ SECURENOW_CAPTURE_BODY=1
435
+ SECURENOW_MAX_BODY_SIZE=10240
436
+ ```
437
+
438
+ **Automatically redacted fields:** passwords, tokens, api_keys, card numbers, etc.
439
+
440
+ **Add custom redaction:**
441
+
442
+ ```env
443
+ SECURENOW_SENSITIVE_FIELDS=internal_token,session_key
444
+ ```
445
+
446
+ ### Custom Logger
447
+
448
+ For more control, use the direct logger API:
449
+
450
+ ```javascript
451
+ const { getLogger } = require('securenow/tracing');
452
+
453
+ const logger = getLogger('express-app', '1.0.0');
454
+
455
+ app.post('/api/users', async (req, res) => {
456
+ logger.emit({
457
+ severityNumber: 9,
458
+ severityText: 'INFO',
459
+ body: 'User creation started',
460
+ attributes: {
461
+ email: req.body.email,
462
+ ip: req.ip,
463
+ timestamp: Date.now(),
464
+ },
465
+ });
466
+
467
+ // Your logic...
468
+ });
469
+ ```
470
+
471
+ ### Disable Specific Instrumentations
472
+
473
+ If you don't need certain instrumentations:
474
+
475
+ ```env
476
+ SECURENOW_DISABLE_INSTRUMENTATIONS=fs,dns,net
477
+ ```
478
+
479
+ ---
480
+
481
+ ## Docker Setup
482
+
483
+ ### Dockerfile
484
+
485
+ ```dockerfile
486
+ FROM node:20-alpine
487
+
488
+ WORKDIR /app
489
+
490
+ # Copy package files
491
+ COPY package*.json ./
492
+
493
+ # Install dependencies
494
+ RUN npm install
495
+
496
+ # Copy application code
497
+ COPY . .
498
+
499
+ # Set environment variables
500
+ ENV SECURENOW_APPID=my-express-app
501
+ ENV SECURENOW_INSTANCE=http://collector:4318
502
+ ENV SECURENOW_LOGGING_ENABLED=1
503
+ ENV NODE_ENV=production
504
+
505
+ # Expose port
506
+ EXPOSE 3000
507
+
508
+ # Start application
509
+ CMD ["node", "app.js"]
510
+ ```
511
+
512
+ ### docker-compose.yml
513
+
514
+ ```yaml
515
+ version: '3.8'
516
+
517
+ services:
518
+ app:
519
+ build: .
520
+ ports:
521
+ - "3000:3000"
522
+ environment:
523
+ - SECURENOW_APPID=my-express-app
524
+ - SECURENOW_INSTANCE=http://collector:4318
525
+ - SECURENOW_LOGGING_ENABLED=1
526
+ - SECURENOW_CAPTURE_BODY=1
527
+ - NODE_ENV=production
528
+ depends_on:
529
+ - collector
530
+
531
+ collector:
532
+ image: otel/opentelemetry-collector:latest
533
+ ports:
534
+ - "4318:4318"
535
+ volumes:
536
+ - ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
537
+ command: ["--config=/etc/otel-collector-config.yaml"]
538
+ ```
539
+
540
+ Run:
541
+
542
+ ```bash
543
+ docker-compose up
544
+ ```
545
+
546
+ ---
547
+
548
+ ## Troubleshooting
549
+
550
+ ### Traces Not Appearing
551
+
552
+ **Check initialization order:**
553
+
554
+ ```javascript
555
+ // ✅ Correct
556
+ require('securenow/register');
557
+ require('securenow/console-instrumentation');
558
+ const express = require('express');
559
+
560
+ // ❌ Wrong
561
+ const express = require('express');
562
+ require('securenow/register');
563
+ ```
564
+
565
+ **Enable debug logging:**
566
+
567
+ ```bash
568
+ export OTEL_LOG_LEVEL=debug
569
+ node app.js
570
+ ```
571
+
572
+ **Verify collector is running:**
573
+
574
+ ```bash
575
+ curl http://localhost:4318/v1/traces
576
+ # Should return 200 or 405
577
+ ```
578
+
579
+ ### Logs Not Appearing
580
+
581
+ **Check logging is enabled:**
582
+
583
+ ```bash
584
+ echo $SECURENOW_LOGGING_ENABLED
585
+ # Should output: 1
586
+ ```
587
+
588
+ **Verify console instrumentation:**
589
+
590
+ Look for this in the output:
591
+ ```
592
+ [securenow] Console instrumentation installed
593
+ ```
594
+
595
+ ### PM2 Issues
596
+
597
+ **Different service names for each worker:**
598
+
599
+ ```env
600
+ # Add this to use same service name
601
+ SECURENOW_NO_UUID=1
602
+ ```
603
+
604
+ **Workers not instrumented:**
605
+
606
+ Use `node_args` in PM2 config:
607
+
608
+ ```javascript
609
+ {
610
+ node_args: '-r securenow/register -r securenow/console-instrumentation'
611
+ }
612
+ ```
613
+
614
+ ---
615
+
616
+ ## Best Practices
617
+
618
+ ### 1. Use Structured Logging
619
+
620
+ ```javascript
621
+ // ❌ Bad
622
+ console.log('User 123 logged in');
623
+
624
+ // ✅ Good
625
+ console.log('User logged in', {
626
+ userId: 123,
627
+ email: 'user@example.com',
628
+ timestamp: Date.now(),
629
+ });
630
+ ```
631
+
632
+ ### 2. Log at Appropriate Levels
633
+
634
+ ```javascript
635
+ // Normal operations
636
+ console.info('Request processed', { userId: 123 });
637
+
638
+ // Warnings
639
+ console.warn('API rate limit approaching', { remaining: 10 });
640
+
641
+ // Errors
642
+ console.error('Database error', { error: err.message });
643
+ ```
644
+
645
+ ### 3. Use Middleware for Request Logging
646
+
647
+ ```javascript
648
+ app.use((req, res, next) => {
649
+ console.info('Request received', {
650
+ method: req.method,
651
+ path: req.path,
652
+ ip: req.ip,
653
+ });
654
+ next();
655
+ });
656
+ ```
657
+
658
+ ### 4. Don't Enable Body Capture in Production
659
+
660
+ ```env
661
+ # .env.development
662
+ SECURENOW_CAPTURE_BODY=1
663
+
664
+ # .env.production
665
+ SECURENOW_CAPTURE_BODY=0
666
+ ```
667
+
668
+ ---
669
+
670
+ ## Complete Environment Variables Reference
671
+
672
+ ```env
673
+ # === Required ===
674
+ SECURENOW_APPID=my-express-app
675
+ SECURENOW_INSTANCE=http://localhost:4318
676
+
677
+ # === Logging ===
678
+ SECURENOW_LOGGING_ENABLED=1
679
+
680
+ # === Request Body Capture ===
681
+ SECURENOW_CAPTURE_BODY=1
682
+ SECURENOW_MAX_BODY_SIZE=10240
683
+ SECURENOW_SENSITIVE_FIELDS=custom_field1,custom_field2
684
+
685
+ # === Service Naming ===
686
+ SECURENOW_NO_UUID=1
687
+ OTEL_SERVICE_NAME=my-express-app
688
+
689
+ # === Connection ===
690
+ OTEL_EXPORTER_OTLP_HEADERS=x-api-key=your-key
691
+ OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces
692
+ OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://localhost:4318/v1/logs
693
+
694
+ # === Debugging ===
695
+ OTEL_LOG_LEVEL=debug
696
+ SECURENOW_TEST_SPAN=1
697
+
698
+ # === Environment ===
699
+ NODE_ENV=production
700
+ ```
701
+
702
+ ---
703
+
704
+ ## Next Steps
705
+
706
+ - Check your observability backend to see traces and logs
707
+ - Set up dashboards and alerts
708
+ - Explore the captured data to understand your application behavior
709
+
710
+ ---
711
+
712
+ ## Support
713
+
714
+ - **Documentation:** [Main Docs](../README.md)
715
+ - **Examples:** [Express Examples](../examples/)
716
+ - **Issues:** GitHub Issues
717
+
718
+ ---
719
+
720
+ **Your Express app is now fully observable!** 🎉