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.
package/NPM_README.md ADDED
@@ -0,0 +1,1328 @@
1
+ # SecureNow - Complete OpenTelemetry Observability for Node.js
2
+
3
+ OpenTelemetry instrumentation library for Node.js applications. Send distributed traces and logs to any OTLP-compatible observability backend.
4
+
5
+ **Features:**
6
+ - 🚀 Zero-config automatic instrumentation
7
+ - 📊 Distributed tracing for all popular frameworks
8
+ - 📋 Automatic logging with console instrumentation
9
+ - 🔐 Built-in sensitive data redaction
10
+ - 🎯 Request body capture for debugging
11
+ - 🔧 Fully configurable via environment variables
12
+
13
+ ---
14
+
15
+ ## Table of Contents
16
+
17
+ - [Installation](#installation)
18
+ - [Quick Start](#quick-start)
19
+ - [Framework-Specific Setup](#framework-specific-setup)
20
+ - [Express.js](#expressjs)
21
+ - [Next.js](#nextjs)
22
+ - [Fastify](#fastify)
23
+ - [NestJS](#nestjs)
24
+ - [Koa](#koa)
25
+ - [Hapi](#hapi)
26
+ - [Environment Variables Reference](#environment-variables-reference)
27
+ - [Logging Setup](#logging-setup)
28
+ - [Request Body Capture](#request-body-capture)
29
+ - [Advanced Configuration](#advanced-configuration)
30
+ - [TypeScript Support](#typescript-support)
31
+ - [Troubleshooting](#troubleshooting)
32
+
33
+ ---
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ npm install securenow
39
+ ```
40
+
41
+ Or with yarn:
42
+
43
+ ```bash
44
+ yarn add securenow
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Quick Start
50
+
51
+ ### 1. Set Environment Variables
52
+
53
+ ```bash
54
+ # Required: Your application identifier
55
+ export SECURENOW_APPID=my-app
56
+
57
+ # Required: Your OTLP collector endpoint
58
+ export SECURENOW_INSTANCE=http://your-otlp-collector:4318
59
+
60
+ # Optional: Enable logging
61
+ export SECURENOW_LOGGING_ENABLED=1
62
+ ```
63
+
64
+ ### 2. Initialize in Your Application
65
+
66
+ **Option A: Using NODE_OPTIONS (Recommended)**
67
+
68
+ ```bash
69
+ NODE_OPTIONS="-r securenow/register" node app.js
70
+ ```
71
+
72
+ **Option B: Code-based initialization**
73
+
74
+ ```javascript
75
+ // At the very top of your main file
76
+ require('securenow/register');
77
+
78
+ // Your application code
79
+ const express = require('express');
80
+ const app = express();
81
+ // ...
82
+ ```
83
+
84
+ ### 3. Run Your Application
85
+
86
+ ```bash
87
+ node app.js
88
+ ```
89
+
90
+ You'll see confirmation in the console:
91
+
92
+ ```
93
+ [securenow] OTel SDK started → http://your-otlp-collector:4318/v1/traces
94
+ [securenow] 📝 Request body capture: ENABLED
95
+ ```
96
+
97
+ ---
98
+
99
+ ## Framework-Specific Setup
100
+
101
+ ### Express.js
102
+
103
+ #### Basic Tracing Setup
104
+
105
+ **Step 1: Install**
106
+
107
+ ```bash
108
+ npm install securenow express
109
+ ```
110
+
111
+ **Step 2: Create `.env` file**
112
+
113
+ ```env
114
+ SECURENOW_APPID=my-express-app
115
+ SECURENOW_INSTANCE=http://localhost:4318
116
+ SECURENOW_LOGGING_ENABLED=1
117
+ ```
118
+
119
+ **Step 3: Initialize at the top of your main file**
120
+
121
+ ```javascript
122
+ // app.js or server.js
123
+ require('securenow/register');
124
+ require('securenow/console-instrumentation'); // Optional: for automatic logging
125
+
126
+ const express = require('express');
127
+ const app = express();
128
+
129
+ app.use(express.json());
130
+
131
+ app.get('/', (req, res) => {
132
+ console.log('Home page accessed'); // Automatically logged if console-instrumentation is enabled
133
+ res.send('Hello World');
134
+ });
135
+
136
+ app.post('/api/users', (req, res) => {
137
+ console.info('User created', { userId: 123 });
138
+ res.json({ success: true });
139
+ });
140
+
141
+ const PORT = process.env.PORT || 3000;
142
+ app.listen(PORT, () => {
143
+ console.log(`Server running on port ${PORT}`);
144
+ });
145
+ ```
146
+
147
+ **Step 4: Run**
148
+
149
+ ```bash
150
+ # With NODE_OPTIONS
151
+ NODE_OPTIONS="-r securenow/register -r securenow/console-instrumentation" node app.js
152
+
153
+ # Or directly (if you added require statements)
154
+ node app.js
155
+ ```
156
+
157
+ #### With PM2
158
+
159
+ ```javascript
160
+ // ecosystem.config.js
161
+ module.exports = {
162
+ apps: [{
163
+ name: 'my-app',
164
+ script: './app.js',
165
+ instances: 4,
166
+ exec_mode: 'cluster',
167
+ node_args: '-r securenow/register -r securenow/console-instrumentation',
168
+ env: {
169
+ SECURENOW_APPID: 'my-express-app',
170
+ SECURENOW_INSTANCE: 'http://localhost:4318',
171
+ SECURENOW_LOGGING_ENABLED: '1',
172
+ SECURENOW_NO_UUID: '1', // Use same service name across all instances
173
+ SECURENOW_CAPTURE_BODY: '1' // Enable request body capture
174
+ }
175
+ }]
176
+ };
177
+ ```
178
+
179
+ ```bash
180
+ pm2 start ecosystem.config.js
181
+ ```
182
+
183
+ ---
184
+
185
+ ### Next.js
186
+
187
+ #### App Router (Next.js 13+)
188
+
189
+ **Step 1: Install**
190
+
191
+ ```bash
192
+ npm install securenow
193
+ ```
194
+
195
+ **Step 2: Create `instrumentation.ts` (or `.js`) in your project root**
196
+
197
+ ```typescript
198
+ // instrumentation.ts
199
+ export async function register() {
200
+ if (process.env.NEXT_RUNTIME === 'nodejs') {
201
+ // Enable logging
202
+ process.env.SECURENOW_LOGGING_ENABLED = '1';
203
+
204
+ // Initialize tracing and logging
205
+ await import('securenow/register');
206
+ await import('securenow/console-instrumentation');
207
+
208
+ console.log('SecureNow observability initialized');
209
+ }
210
+ }
211
+ ```
212
+
213
+ **Step 3: Enable instrumentation hook in `next.config.js`**
214
+
215
+ ```javascript
216
+ // next.config.js
217
+ /** @type {import('next').NextConfig} */
218
+ const nextConfig = {
219
+ experimental: {
220
+ instrumentationHook: true,
221
+ },
222
+ };
223
+
224
+ module.exports = nextConfig;
225
+ ```
226
+
227
+ **Step 4: Create `.env.local`**
228
+
229
+ ```env
230
+ SECURENOW_APPID=my-nextjs-app
231
+ SECURENOW_INSTANCE=http://localhost:4318
232
+ SECURENOW_LOGGING_ENABLED=1
233
+ SECURENOW_CAPTURE_BODY=1
234
+ ```
235
+
236
+ **Step 5: Use in your application**
237
+
238
+ ```typescript
239
+ // app/api/users/route.ts
240
+ import { NextRequest, NextResponse } from 'next/server';
241
+
242
+ export async function GET(request: NextRequest) {
243
+ console.log('GET /api/users called');
244
+
245
+ // Your logic here
246
+ const users = await fetchUsers();
247
+
248
+ console.info('Users fetched', { count: users.length });
249
+ return NextResponse.json(users);
250
+ }
251
+
252
+ export async function POST(request: NextRequest) {
253
+ const body = await request.json();
254
+ console.info('Creating user', { email: body.email });
255
+
256
+ try {
257
+ const user = await createUser(body);
258
+ console.log('User created successfully', { userId: user.id });
259
+ return NextResponse.json(user, { status: 201 });
260
+ } catch (error) {
261
+ console.error('Failed to create user', { error: error.message });
262
+ return NextResponse.json({ error: 'Failed' }, { status: 500 });
263
+ }
264
+ }
265
+ ```
266
+
267
+ **Step 6: Run**
268
+
269
+ ```bash
270
+ npm run dev
271
+ ```
272
+
273
+ #### Pages Router (Next.js 12 and below)
274
+
275
+ **Step 1: Create `_app.js` or `_app.tsx`**
276
+
277
+ ```javascript
278
+ // pages/_app.js
279
+ if (typeof window === 'undefined') {
280
+ require('securenow/register');
281
+ require('securenow/console-instrumentation');
282
+ }
283
+
284
+ function MyApp({ Component, pageProps }) {
285
+ return <Component {...pageProps} />;
286
+ }
287
+
288
+ export default MyApp;
289
+ ```
290
+
291
+ **Step 2: Same `.env.local` as above**
292
+
293
+ **Step 3: Run**
294
+
295
+ ```bash
296
+ npm run dev
297
+ ```
298
+
299
+ ---
300
+
301
+ ### Fastify
302
+
303
+ **Step 1: Install**
304
+
305
+ ```bash
306
+ npm install securenow fastify
307
+ ```
308
+
309
+ **Step 2: Create `.env`**
310
+
311
+ ```env
312
+ SECURENOW_APPID=my-fastify-app
313
+ SECURENOW_INSTANCE=http://localhost:4318
314
+ SECURENOW_LOGGING_ENABLED=1
315
+ ```
316
+
317
+ **Step 3: Initialize at the top**
318
+
319
+ ```javascript
320
+ // server.js
321
+ require('securenow/register');
322
+ require('securenow/console-instrumentation');
323
+
324
+ const fastify = require('fastify')({ logger: false });
325
+
326
+ // Logging hook
327
+ fastify.addHook('onRequest', async (request, reply) => {
328
+ console.info('Request received', {
329
+ method: request.method,
330
+ url: request.url,
331
+ });
332
+ });
333
+
334
+ fastify.get('/', async (request, reply) => {
335
+ console.log('Root endpoint called');
336
+ return { hello: 'world' };
337
+ });
338
+
339
+ fastify.post('/users', async (request, reply) => {
340
+ console.info('Creating user', { body: request.body });
341
+ // Your logic
342
+ return { success: true };
343
+ });
344
+
345
+ // Error handler
346
+ fastify.setErrorHandler((error, request, reply) => {
347
+ console.error('Fastify error', {
348
+ error: error.message,
349
+ stack: error.stack,
350
+ url: request.url,
351
+ });
352
+ reply.status(500).send({ error: 'Internal server error' });
353
+ });
354
+
355
+ const start = async () => {
356
+ try {
357
+ await fastify.listen({ port: 3000 });
358
+ console.log('Fastify server running on port 3000');
359
+ } catch (err) {
360
+ console.error('Server start failed', { error: err });
361
+ process.exit(1);
362
+ }
363
+ };
364
+
365
+ start();
366
+ ```
367
+
368
+ **Step 4: Run**
369
+
370
+ ```bash
371
+ node server.js
372
+ ```
373
+
374
+ ---
375
+
376
+ ### NestJS
377
+
378
+ **Step 1: Install**
379
+
380
+ ```bash
381
+ npm install securenow
382
+ ```
383
+
384
+ **Step 2: Create `.env`**
385
+
386
+ ```env
387
+ SECURENOW_APPID=my-nestjs-app
388
+ SECURENOW_INSTANCE=http://localhost:4318
389
+ SECURENOW_LOGGING_ENABLED=1
390
+ ```
391
+
392
+ **Step 3: Initialize in `main.ts`**
393
+
394
+ ```typescript
395
+ // src/main.ts
396
+ require('securenow/register');
397
+ require('securenow/console-instrumentation');
398
+
399
+ import { NestFactory } from '@nestjs/core';
400
+ import { AppModule } from './app.module';
401
+
402
+ async function bootstrap() {
403
+ const app = await NestFactory.create(AppModule);
404
+
405
+ console.log('NestJS application starting');
406
+
407
+ await app.listen(3000);
408
+ console.log('Application is running on: http://localhost:3000');
409
+ }
410
+
411
+ bootstrap();
412
+ ```
413
+
414
+ **Step 4: Use in services**
415
+
416
+ ```typescript
417
+ // src/users/users.service.ts
418
+ import { Injectable } from '@nestjs/common';
419
+
420
+ @Injectable()
421
+ export class UsersService {
422
+ async findAll() {
423
+ console.log('Fetching all users');
424
+ const users = await this.fetchFromDatabase();
425
+ console.info('Users retrieved', { count: users.length });
426
+ return users;
427
+ }
428
+
429
+ async create(userData: any) {
430
+ console.info('Creating user', { email: userData.email });
431
+
432
+ try {
433
+ const user = await this.saveToDatabase(userData);
434
+ console.log('User created', { userId: user.id });
435
+ return user;
436
+ } catch (error) {
437
+ console.error('Failed to create user', {
438
+ error: error.message,
439
+ email: userData.email,
440
+ });
441
+ throw error;
442
+ }
443
+ }
444
+ }
445
+ ```
446
+
447
+ **Step 5: Run**
448
+
449
+ ```bash
450
+ npm run start
451
+ ```
452
+
453
+ ---
454
+
455
+ ### Koa
456
+
457
+ **Step 1: Install**
458
+
459
+ ```bash
460
+ npm install securenow koa
461
+ ```
462
+
463
+ **Step 2: Create `.env`**
464
+
465
+ ```env
466
+ SECURENOW_APPID=my-koa-app
467
+ SECURENOW_INSTANCE=http://localhost:4318
468
+ SECURENOW_LOGGING_ENABLED=1
469
+ ```
470
+
471
+ **Step 3: Initialize**
472
+
473
+ ```javascript
474
+ // app.js
475
+ require('securenow/register');
476
+ require('securenow/console-instrumentation');
477
+
478
+ const Koa = require('koa');
479
+ const Router = require('@koa/router');
480
+
481
+ const app = new Koa();
482
+ const router = new Router();
483
+
484
+ // Logging middleware
485
+ app.use(async (ctx, next) => {
486
+ console.info('Request received', {
487
+ method: ctx.method,
488
+ path: ctx.path,
489
+ });
490
+ await next();
491
+ });
492
+
493
+ router.get('/', (ctx) => {
494
+ console.log('Home page accessed');
495
+ ctx.body = { message: 'Hello World' };
496
+ });
497
+
498
+ router.post('/users', (ctx) => {
499
+ console.info('Creating user', { body: ctx.request.body });
500
+ ctx.body = { success: true };
501
+ });
502
+
503
+ app.use(router.routes());
504
+
505
+ const PORT = 3000;
506
+ app.listen(PORT, () => {
507
+ console.log(`Koa server running on port ${PORT}`);
508
+ });
509
+ ```
510
+
511
+ **Step 4: Run**
512
+
513
+ ```bash
514
+ node app.js
515
+ ```
516
+
517
+ ---
518
+
519
+ ### Hapi
520
+
521
+ **Step 1: Install**
522
+
523
+ ```bash
524
+ npm install securenow @hapi/hapi
525
+ ```
526
+
527
+ **Step 2: Create `.env`**
528
+
529
+ ```env
530
+ SECURENOW_APPID=my-hapi-app
531
+ SECURENOW_INSTANCE=http://localhost:4318
532
+ SECURENOW_LOGGING_ENABLED=1
533
+ ```
534
+
535
+ **Step 3: Initialize**
536
+
537
+ ```javascript
538
+ // server.js
539
+ require('securenow/register');
540
+ require('securenow/console-instrumentation');
541
+
542
+ const Hapi = require('@hapi/hapi');
543
+
544
+ const init = async () => {
545
+ const server = Hapi.server({
546
+ port: 3000,
547
+ host: 'localhost'
548
+ });
549
+
550
+ // Logging extension
551
+ server.ext('onRequest', (request, h) => {
552
+ console.info('Request received', {
553
+ method: request.method,
554
+ path: request.path,
555
+ });
556
+ return h.continue;
557
+ });
558
+
559
+ server.route({
560
+ method: 'GET',
561
+ path: '/',
562
+ handler: (request, h) => {
563
+ console.log('Home page accessed');
564
+ return { message: 'Hello World' };
565
+ }
566
+ });
567
+
568
+ server.route({
569
+ method: 'POST',
570
+ path: '/users',
571
+ handler: (request, h) => {
572
+ console.info('Creating user', { payload: request.payload });
573
+ return { success: true };
574
+ }
575
+ });
576
+
577
+ await server.start();
578
+ console.log('Hapi server running on:', server.info.uri);
579
+ };
580
+
581
+ init();
582
+ ```
583
+
584
+ **Step 4: Run**
585
+
586
+ ```bash
587
+ node server.js
588
+ ```
589
+
590
+ ---
591
+
592
+ ## Environment Variables Reference
593
+
594
+ ### Required Variables
595
+
596
+ | Variable | Description | Example |
597
+ |----------|-------------|---------|
598
+ | `SECURENOW_APPID` | Your application identifier. Used as the service name in traces. | `my-app` |
599
+ | `SECURENOW_INSTANCE` | Base URL of your OTLP collector endpoint. | `http://localhost:4318` |
600
+
601
+ ### Optional Configuration
602
+
603
+ #### Service Naming
604
+
605
+ | Variable | Description | Default |
606
+ |----------|-------------|---------|
607
+ | `OTEL_SERVICE_NAME` | Alternative to SECURENOW_APPID. Standard OpenTelemetry variable. | - |
608
+ | `SECURENOW_NO_UUID` | Set to `1` to disable UUID suffix on service name. Useful for clustered apps. | `0` |
609
+ | `SECURENOW_STRICT` | Set to `1` to exit process if SECURENOW_APPID is not set in cluster mode. | `0` |
610
+
611
+ #### Connection Settings
612
+
613
+ | Variable | Description | Default |
614
+ |----------|-------------|---------|
615
+ | `OTEL_EXPORTER_OTLP_ENDPOINT` | Alternative to SECURENOW_INSTANCE. Standard OpenTelemetry variable. | - |
616
+ | `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | Override traces endpoint specifically. | `{SECURENOW_INSTANCE}/v1/traces` |
617
+ | `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` | Override logs endpoint specifically. | `{SECURENOW_INSTANCE}/v1/logs` |
618
+ | `OTEL_EXPORTER_OTLP_HEADERS` | Headers to send with OTLP exports. Format: `key1=value1,key2=value2` | - |
619
+
620
+ #### Logging
621
+
622
+ | Variable | Description | Default |
623
+ |----------|-------------|---------|
624
+ | `SECURENOW_LOGGING_ENABLED` | Enable automatic logging to OTLP backend. Set to `1` to enable, `0` to disable. | `1` |
625
+
626
+ #### Request Body Capture
627
+
628
+ | Variable | Description | Default |
629
+ |----------|-------------|---------|
630
+ | `SECURENOW_CAPTURE_BODY` | Enable request body capture in traces. Set to `1` to enable. | `0` |
631
+ | `SECURENOW_MAX_BODY_SIZE` | Maximum body size to capture in bytes. Bodies larger than this are truncated. | `10240` (10KB) |
632
+ | `SECURENOW_SENSITIVE_FIELDS` | Comma-separated list of additional field names to redact. | - |
633
+
634
+ **Default sensitive fields (auto-redacted):** `password`, `passwd`, `pwd`, `secret`, `token`, `api_key`, `apikey`, `access_token`, `auth`, `credentials`, `mysql_pwd`, `stripeToken`, `card`, `cardnumber`, `ccv`, `cvc`, `cvv`, `ssn`, `pin`
635
+
636
+ #### Instrumentation Control
637
+
638
+ | Variable | Description | Default |
639
+ |----------|-------------|---------|
640
+ | `SECURENOW_DISABLE_INSTRUMENTATIONS` | Comma-separated list of instrumentation packages to disable. | - |
641
+
642
+ **Example:** `SECURENOW_DISABLE_INSTRUMENTATIONS=fs,dns` disables filesystem and DNS instrumentations.
643
+
644
+ #### Debugging
645
+
646
+ | Variable | Description | Default |
647
+ |----------|-------------|---------|
648
+ | `OTEL_LOG_LEVEL` | OpenTelemetry SDK log level. Options: `debug`, `info`, `warn`, `error` | `none` |
649
+ | `SECURENOW_TEST_SPAN` | Set to `1` to emit a test span on startup. | `0` |
650
+
651
+ #### Environment
652
+
653
+ | Variable | Description | Default |
654
+ |----------|-------------|---------|
655
+ | `NODE_ENV` | Deployment environment name. Sent as `deployment.environment` attribute. | `production` |
656
+
657
+ ---
658
+
659
+ ## Logging Setup
660
+
661
+ ### Automatic Console Logging
662
+
663
+ The easiest way to send logs is to use the console instrumentation wrapper:
664
+
665
+ ```javascript
666
+ // At the top of your main file
667
+ require('securenow/register');
668
+ require('securenow/console-instrumentation');
669
+
670
+ // Now all console logs are automatically sent
671
+ console.log('Application started');
672
+ console.info('User action', { userId: 123, action: 'login' });
673
+ console.warn('Deprecation warning');
674
+ console.error('Error occurred', { error: 'Something failed' });
675
+ console.debug('Debug info');
676
+ ```
677
+
678
+ **Severity mapping:**
679
+ - `console.log()` → INFO
680
+ - `console.info()` → INFO
681
+ - `console.warn()` → WARN
682
+ - `console.error()` → ERROR
683
+ - `console.debug()` → DEBUG
684
+
685
+ **Environment variable:**
686
+ ```bash
687
+ SECURENOW_LOGGING_ENABLED=1
688
+ ```
689
+
690
+ ### Direct Logger API
691
+
692
+ For more control, use the OpenTelemetry logger API:
693
+
694
+ ```javascript
695
+ require('securenow/register');
696
+ const { getLogger } = require('securenow/tracing');
697
+
698
+ // Get a logger instance
699
+ const logger = getLogger('my-module', '1.0.0');
700
+
701
+ // Emit structured logs
702
+ logger.emit({
703
+ severityNumber: 9, // INFO
704
+ severityText: 'INFO',
705
+ body: 'User logged in',
706
+ attributes: {
707
+ userId: 123,
708
+ username: 'john',
709
+ sessionId: 'abc123',
710
+ },
711
+ });
712
+ ```
713
+
714
+ **Severity numbers:**
715
+ - `5` - DEBUG
716
+ - `9` - INFO
717
+ - `13` - WARN
718
+ - `17` - ERROR
719
+
720
+ ### Using with NODE_OPTIONS
721
+
722
+ ```bash
723
+ # Enable both tracing and logging
724
+ NODE_OPTIONS="-r securenow/register -r securenow/console-instrumentation" \
725
+ SECURENOW_APPID=my-app \
726
+ SECURENOW_INSTANCE=http://localhost:4318 \
727
+ SECURENOW_LOGGING_ENABLED=1 \
728
+ node app.js
729
+ ```
730
+
731
+ ---
732
+
733
+ ## Request Body Capture
734
+
735
+ SecureNow can capture HTTP request bodies in traces for debugging purposes. This is disabled by default.
736
+
737
+ ### Enable Body Capture
738
+
739
+ ```bash
740
+ export SECURENOW_CAPTURE_BODY=1
741
+ export SECURENOW_MAX_BODY_SIZE=10240 # 10KB (optional)
742
+ ```
743
+
744
+ ### Supported Content Types
745
+
746
+ - `application/json`
747
+ - `application/x-www-form-urlencoded`
748
+ - `application/graphql`
749
+
750
+ **Note:** Multipart form data (file uploads) are NOT captured by design.
751
+
752
+ ### Sensitive Data Redaction
753
+
754
+ All request bodies are automatically scanned and sensitive fields are redacted:
755
+
756
+ **Automatically redacted fields:** `password`, `secret`, `token`, `api_key`, `card`, `cvv`, `ssn`, and more.
757
+
758
+ **Add custom fields to redact:**
759
+
760
+ ```bash
761
+ export SECURENOW_SENSITIVE_FIELDS="custom_secret,internal_token"
762
+ ```
763
+
764
+ ### Example
765
+
766
+ ```javascript
767
+ // POST /api/users with body:
768
+ {
769
+ "email": "user@example.com",
770
+ "password": "secret123",
771
+ "name": "John Doe"
772
+ }
773
+
774
+ // Captured in trace as:
775
+ {
776
+ "email": "user@example.com",
777
+ "password": "[REDACTED]",
778
+ "name": "John Doe"
779
+ }
780
+ ```
781
+
782
+ ---
783
+
784
+ ## Advanced Configuration
785
+
786
+ ### Complete Example with All Options
787
+
788
+ ```bash
789
+ # Service identification
790
+ export SECURENOW_APPID=my-production-app
791
+ export SECURENOW_NO_UUID=1
792
+ export SECURENOW_STRICT=1
793
+
794
+ # OTLP backend
795
+ export SECURENOW_INSTANCE=http://collector.example.com:4318
796
+ export OTEL_EXPORTER_OTLP_HEADERS="x-api-key=your-api-key"
797
+
798
+ # Logging
799
+ export SECURENOW_LOGGING_ENABLED=1
800
+
801
+ # Request body capture
802
+ export SECURENOW_CAPTURE_BODY=1
803
+ export SECURENOW_MAX_BODY_SIZE=20480
804
+ export SECURENOW_SENSITIVE_FIELDS="internal_id,session_key"
805
+
806
+ # Environment
807
+ export NODE_ENV=production
808
+
809
+ # Debugging
810
+ export OTEL_LOG_LEVEL=info
811
+
812
+ # Disable specific instrumentations
813
+ export SECURENOW_DISABLE_INSTRUMENTATIONS=fs,dns
814
+
815
+ # Run application
816
+ NODE_OPTIONS="-r securenow/register -r securenow/console-instrumentation" node app.js
817
+ ```
818
+
819
+ ### Using Multiple Logger Instances
820
+
821
+ ```javascript
822
+ const { getLogger } = require('securenow/tracing');
823
+
824
+ const authLogger = getLogger('auth-service', '1.0.0');
825
+ const dbLogger = getLogger('database', '1.0.0');
826
+ const apiLogger = getLogger('api-handler', '1.0.0');
827
+
828
+ authLogger.emit({
829
+ severityNumber: 9,
830
+ severityText: 'INFO',
831
+ body: 'User authenticated',
832
+ attributes: { userId: 123 },
833
+ });
834
+
835
+ dbLogger.emit({
836
+ severityNumber: 13,
837
+ severityText: 'WARN',
838
+ body: 'Slow query detected',
839
+ attributes: { queryTime: 5000 },
840
+ });
841
+ ```
842
+
843
+ ### Check if Logging is Enabled
844
+
845
+ ```javascript
846
+ const { isLoggingEnabled } = require('securenow/tracing');
847
+
848
+ if (isLoggingEnabled()) {
849
+ console.log('Logging is enabled');
850
+ } else {
851
+ console.log('Logging is disabled');
852
+ }
853
+ ```
854
+
855
+ ### Programmatic Configuration
856
+
857
+ While environment variables are recommended, you can also configure programmatically:
858
+
859
+ ```javascript
860
+ // Set environment variables before requiring securenow
861
+ process.env.SECURENOW_APPID = 'my-app';
862
+ process.env.SECURENOW_INSTANCE = 'http://localhost:4318';
863
+ process.env.SECURENOW_LOGGING_ENABLED = '1';
864
+
865
+ // Then initialize
866
+ require('securenow/register');
867
+ require('securenow/console-instrumentation');
868
+ ```
869
+
870
+ ---
871
+
872
+ ## TypeScript Support
873
+
874
+ SecureNow includes full TypeScript definitions.
875
+
876
+ ### Type Definitions
877
+
878
+ ```typescript
879
+ import { getLogger, isLoggingEnabled, Logger, LogRecord } from 'securenow/tracing';
880
+
881
+ // Get a typed logger
882
+ const logger: Logger | null = getLogger('my-service', '1.0.0');
883
+
884
+ // Emit a log with type checking
885
+ if (logger) {
886
+ const logRecord: LogRecord = {
887
+ severityNumber: 9,
888
+ severityText: 'INFO',
889
+ body: 'User action',
890
+ attributes: {
891
+ userId: 123,
892
+ action: 'login',
893
+ },
894
+ };
895
+
896
+ logger.emit(logRecord);
897
+ }
898
+
899
+ // Check if enabled
900
+ const enabled: boolean = isLoggingEnabled();
901
+ ```
902
+
903
+ ### Next.js with TypeScript
904
+
905
+ ```typescript
906
+ // instrumentation.ts
907
+ export async function register() {
908
+ if (process.env.NEXT_RUNTIME === 'nodejs') {
909
+ process.env.SECURENOW_LOGGING_ENABLED = '1';
910
+
911
+ await import('securenow/register');
912
+ await import('securenow/console-instrumentation');
913
+ }
914
+ }
915
+ ```
916
+
917
+ ### NestJS with TypeScript
918
+
919
+ ```typescript
920
+ // main.ts
921
+ require('securenow/register');
922
+ require('securenow/console-instrumentation');
923
+
924
+ import { NestFactory } from '@nestjs/core';
925
+ import { AppModule } from './app.module';
926
+
927
+ async function bootstrap() {
928
+ const app = await NestFactory.create(AppModule);
929
+ await app.listen(3000);
930
+ }
931
+
932
+ bootstrap();
933
+ ```
934
+
935
+ ---
936
+
937
+ ## Troubleshooting
938
+
939
+ ### Traces Not Appearing
940
+
941
+ **Check 1: Verify environment variables**
942
+
943
+ ```bash
944
+ echo $SECURENOW_APPID
945
+ echo $SECURENOW_INSTANCE
946
+ ```
947
+
948
+ Both should output values.
949
+
950
+ **Check 2: Verify OTLP collector is running**
951
+
952
+ ```bash
953
+ curl http://localhost:4318/v1/traces
954
+ # Should return 200 or 405 (method not allowed)
955
+ ```
956
+
957
+ **Check 3: Enable debug logging**
958
+
959
+ ```bash
960
+ export OTEL_LOG_LEVEL=debug
961
+ node app.js
962
+ ```
963
+
964
+ Look for lines like:
965
+ ```
966
+ [securenow] OTel SDK started → http://localhost:4318/v1/traces
967
+ ```
968
+
969
+ **Check 4: Verify initialization order**
970
+
971
+ SecureNow must be required BEFORE any other modules:
972
+
973
+ ```javascript
974
+ // ✅ Correct
975
+ require('securenow/register');
976
+ const express = require('express');
977
+
978
+ // ❌ Wrong - too late!
979
+ const express = require('express');
980
+ require('securenow/register');
981
+ ```
982
+
983
+ ### Logs Not Appearing
984
+
985
+ **Check 1: Is logging enabled?**
986
+
987
+ ```bash
988
+ echo $SECURENOW_LOGGING_ENABLED
989
+ # Should output: 1
990
+ ```
991
+
992
+ **Check 2: Verify console instrumentation is loaded**
993
+
994
+ ```javascript
995
+ // Must load after register
996
+ require('securenow/register');
997
+ require('securenow/console-instrumentation');
998
+ ```
999
+
1000
+ **Check 3: Check console output**
1001
+
1002
+ You should see:
1003
+ ```
1004
+ [securenow] 📋 Logging: ENABLED → http://localhost:4318/v1/logs
1005
+ [securenow] Console instrumentation installed
1006
+ ```
1007
+
1008
+ **Check 4: Verify OTLP logs endpoint**
1009
+
1010
+ ```bash
1011
+ curl http://localhost:4318/v1/logs
1012
+ # Should return 200 or 405
1013
+ ```
1014
+
1015
+ ### Request Body Not Captured
1016
+
1017
+ **Check 1: Is body capture enabled?**
1018
+
1019
+ ```bash
1020
+ export SECURENOW_CAPTURE_BODY=1
1021
+ ```
1022
+
1023
+ **Check 2: Verify content type**
1024
+
1025
+ Body capture only works for:
1026
+ - `application/json`
1027
+ - `application/x-www-form-urlencoded`
1028
+ - `application/graphql`
1029
+
1030
+ **Check 3: Check body size**
1031
+
1032
+ Bodies larger than `SECURENOW_MAX_BODY_SIZE` are truncated:
1033
+
1034
+ ```bash
1035
+ export SECURENOW_MAX_BODY_SIZE=20480 # Increase to 20KB
1036
+ ```
1037
+
1038
+ ### High Memory Usage
1039
+
1040
+ **Option 1: Disable body capture**
1041
+
1042
+ ```bash
1043
+ export SECURENOW_CAPTURE_BODY=0
1044
+ ```
1045
+
1046
+ **Option 2: Reduce body size limit**
1047
+
1048
+ ```bash
1049
+ export SECURENOW_MAX_BODY_SIZE=5120 # 5KB
1050
+ ```
1051
+
1052
+ **Option 3: Disable specific instrumentations**
1053
+
1054
+ ```bash
1055
+ export SECURENOW_DISABLE_INSTRUMENTATIONS=fs,dns,net
1056
+ ```
1057
+
1058
+ ### Next.js Instrumentation Not Working
1059
+
1060
+ **Check 1: Verify instrumentation file location**
1061
+
1062
+ `instrumentation.ts` or `instrumentation.js` must be in the project root (same level as `app/` or `pages/`).
1063
+
1064
+ **Check 2: Enable instrumentation hook**
1065
+
1066
+ ```javascript
1067
+ // next.config.js
1068
+ module.exports = {
1069
+ experimental: {
1070
+ instrumentationHook: true,
1071
+ },
1072
+ };
1073
+ ```
1074
+
1075
+ **Check 3: Restart dev server**
1076
+
1077
+ ```bash
1078
+ # Kill the server and restart
1079
+ npm run dev
1080
+ ```
1081
+
1082
+ ### PM2 Cluster Issues
1083
+
1084
+ **Problem: Different service names for each worker**
1085
+
1086
+ **Solution: Use SECURENOW_NO_UUID**
1087
+
1088
+ ```bash
1089
+ export SECURENOW_NO_UUID=1
1090
+ ```
1091
+
1092
+ This uses the same service name for all workers.
1093
+
1094
+ **Problem: Workers not instrumented**
1095
+
1096
+ **Solution: Use node_args in PM2 config**
1097
+
1098
+ ```javascript
1099
+ // ecosystem.config.js
1100
+ module.exports = {
1101
+ apps: [{
1102
+ name: 'my-app',
1103
+ script: './app.js',
1104
+ instances: 4,
1105
+ node_args: '-r securenow/register',
1106
+ env: {
1107
+ SECURENOW_APPID: 'my-app',
1108
+ SECURENOW_INSTANCE: 'http://localhost:4318',
1109
+ }
1110
+ }]
1111
+ };
1112
+ ```
1113
+
1114
+ ---
1115
+
1116
+ ## Best Practices
1117
+
1118
+ ### 1. Use Environment Variables
1119
+
1120
+ Don't hardcode configuration. Use environment variables:
1121
+
1122
+ ```javascript
1123
+ // ❌ Bad
1124
+ process.env.SECURENOW_APPID = 'hardcoded-value';
1125
+
1126
+ // ✅ Good - use .env file or export
1127
+ // .env
1128
+ SECURENOW_APPID=my-app
1129
+ SECURENOW_INSTANCE=http://localhost:4318
1130
+ ```
1131
+
1132
+ ### 2. Use Structured Logging
1133
+
1134
+ Pass objects to console methods for better filtering:
1135
+
1136
+ ```javascript
1137
+ // ❌ Less useful
1138
+ console.log('User 123 logged in');
1139
+
1140
+ // ✅ Better - structured attributes
1141
+ console.log('User logged in', {
1142
+ userId: 123,
1143
+ email: 'user@example.com',
1144
+ timestamp: new Date().toISOString(),
1145
+ });
1146
+ ```
1147
+
1148
+ ### 3. Choose Appropriate Severity Levels
1149
+
1150
+ ```javascript
1151
+ // Normal operations
1152
+ console.log('Request processed');
1153
+ console.info('User created', { userId: 123 });
1154
+
1155
+ // Warnings
1156
+ console.warn('API rate limit approaching', { remaining: 10 });
1157
+
1158
+ // Errors
1159
+ console.error('Database connection failed', { error: err.message });
1160
+
1161
+ // Debug (only in development)
1162
+ console.debug('Cache hit', { key: 'user:123' });
1163
+ ```
1164
+
1165
+ ### 4. Don't Log Sensitive Data
1166
+
1167
+ Even though SecureNow automatically redacts common sensitive fields, avoid logging:
1168
+
1169
+ ```javascript
1170
+ // ❌ Bad
1171
+ console.log('Login attempt', {
1172
+ email: 'user@example.com',
1173
+ password: 'secret123', // Will be redacted, but don't log it!
1174
+ });
1175
+
1176
+ // ✅ Good
1177
+ console.log('Login attempt', {
1178
+ email: 'user@example.com',
1179
+ timestamp: Date.now(),
1180
+ });
1181
+ ```
1182
+
1183
+ ### 5. Use Different Logger Instances for Different Modules
1184
+
1185
+ ```javascript
1186
+ // auth-service.js
1187
+ const authLogger = getLogger('auth-service', '1.0.0');
1188
+
1189
+ // database.js
1190
+ const dbLogger = getLogger('database', '1.0.0');
1191
+
1192
+ // api.js
1193
+ const apiLogger = getLogger('api', '1.0.0');
1194
+ ```
1195
+
1196
+ ### 6. Enable Body Capture Only in Development
1197
+
1198
+ ```bash
1199
+ # .env.development
1200
+ SECURENOW_CAPTURE_BODY=1
1201
+
1202
+ # .env.production
1203
+ SECURENOW_CAPTURE_BODY=0
1204
+ ```
1205
+
1206
+ ---
1207
+
1208
+ ## Supported Runtimes
1209
+
1210
+ - **Node.js:** 18+
1211
+ - **Frameworks:** Express, Next.js, Fastify, NestJS, Koa, Hapi, and more
1212
+ - **Databases:** PostgreSQL, MySQL, MongoDB, Redis
1213
+ - **HTTP Clients:** axios, fetch, node-fetch, got, request
1214
+ - **GraphQL:** Apollo Server, GraphQL.js
1215
+ - **Message Queues:** Redis, BullMQ
1216
+ - **And many more via OpenTelemetry auto-instrumentation**
1217
+
1218
+ ---
1219
+
1220
+ ## Automatic Instrumentations
1221
+
1222
+ SecureNow automatically instruments:
1223
+
1224
+ - HTTP/HTTPS (incoming and outgoing)
1225
+ - Express.js
1226
+ - Fastify
1227
+ - Koa
1228
+ - Hapi
1229
+ - Next.js
1230
+ - PostgreSQL
1231
+ - MySQL/MySQL2
1232
+ - MongoDB
1233
+ - Redis
1234
+ - GraphQL
1235
+ - gRPC
1236
+ - DNS
1237
+ - File System
1238
+ - And 50+ more libraries
1239
+
1240
+ No code changes needed!
1241
+
1242
+ ---
1243
+
1244
+ ## Architecture
1245
+
1246
+ ```
1247
+ ┌─────────────────────────────────┐
1248
+ │ Your Application │
1249
+ │ (Express/Next.js/etc) │
1250
+ └───────────────┬─────────────────┘
1251
+
1252
+
1253
+ ┌─────────────────────────────────┐
1254
+ │ SecureNow Library │
1255
+ │ - Auto-instrumentation │
1256
+ │ - Console wrapper (optional) │
1257
+ │ - Body capture (optional) │
1258
+ └───────────────┬─────────────────┘
1259
+
1260
+
1261
+ ┌─────────────────────────────────┐
1262
+ │ OpenTelemetry SDK │
1263
+ │ - Trace/Log processors │
1264
+ │ - OTLP exporters │
1265
+ └───────────────┬─────────────────┘
1266
+
1267
+
1268
+ ┌─────────────────────────────────┐
1269
+ │ OTLP Collector/Backend │
1270
+ │ (Your observability platform) │
1271
+ └─────────────────────────────────┘
1272
+ ```
1273
+
1274
+ ---
1275
+
1276
+ ## Performance
1277
+
1278
+ - **Minimal overhead:** < 1% CPU and memory impact
1279
+ - **Batch export:** Traces and logs are batched before sending
1280
+ - **Async processing:** No blocking of application threads
1281
+ - **Configurable:** Disable instrumentations you don't need
1282
+
1283
+ ---
1284
+
1285
+ ## Security
1286
+
1287
+ - **Automatic redaction** of sensitive fields (passwords, tokens, keys)
1288
+ - **Configurable** sensitive field patterns
1289
+ - **No data stored** locally - everything sent to your OTLP backend
1290
+ - **Open source** - audit the code yourself
1291
+
1292
+ ---
1293
+
1294
+ ## License
1295
+
1296
+ ISC
1297
+
1298
+ ---
1299
+
1300
+ ## Support
1301
+
1302
+ - **Documentation:** [GitHub Docs](https://github.com/your-repo/securenow-npm/tree/main/docs)
1303
+ - **Issues:** [GitHub Issues](https://github.com/your-repo/securenow-npm/issues)
1304
+ - **Examples:** [GitHub Examples](https://github.com/your-repo/securenow-npm/tree/main/examples)
1305
+
1306
+ ---
1307
+
1308
+ ## Changelog
1309
+
1310
+ See [CHANGELOG.md](CHANGELOG.md) for version history.
1311
+
1312
+ ---
1313
+
1314
+ ## Contributing
1315
+
1316
+ Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
1317
+
1318
+ ---
1319
+
1320
+ ## Related Packages
1321
+
1322
+ - [@opentelemetry/sdk-node](https://www.npmjs.com/package/@opentelemetry/sdk-node) - Core OpenTelemetry SDK
1323
+ - [@opentelemetry/auto-instrumentations-node](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node) - Auto-instrumentation
1324
+ - [@opentelemetry/exporter-trace-otlp-http](https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-http) - OTLP exporter
1325
+
1326
+ ---
1327
+
1328
+ **Made with ❤️ for the Node.js community**