securenow 5.5.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/cli.js +1 -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.d.ts +1 -0
- package/tracing.js +87 -1
package/NPM_README.md
CHANGED
|
@@ -1,1609 +1,1544 @@
|
|
|
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
|
-
- [CLI — Command Line Interface](#cli--command-line-interface)
|
|
20
|
-
- [Framework-Specific Setup](#framework-specific-setup)
|
|
21
|
-
- [Express.js](#expressjs)
|
|
22
|
-
- [Next.js](#nextjs)
|
|
23
|
-
- [Fastify](#fastify)
|
|
24
|
-
- [NestJS](#nestjs)
|
|
25
|
-
- [Koa](#koa)
|
|
26
|
-
- [Hapi](#hapi)
|
|
27
|
-
- [Environment Variables Reference](#environment-variables-reference)
|
|
28
|
-
- [Logging Setup](#logging-setup)
|
|
29
|
-
- [Request Body Capture](#request-body-capture)
|
|
30
|
-
- [Advanced Configuration](#advanced-configuration)
|
|
31
|
-
- [TypeScript Support](#typescript-support)
|
|
32
|
-
- [Troubleshooting](#troubleshooting)
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## Installation
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
npm install securenow
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
Or with yarn:
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
yarn add securenow
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## Quick Start
|
|
51
|
-
|
|
52
|
-
### 1. Set Environment Variables
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
# Required: Your application identifier
|
|
56
|
-
export SECURENOW_APPID=my-app
|
|
57
|
-
|
|
58
|
-
# Required: Your OTLP collector endpoint
|
|
59
|
-
export SECURENOW_INSTANCE=http://your-otlp-collector:4318
|
|
60
|
-
|
|
61
|
-
# Optional: Enable logging
|
|
62
|
-
export SECURENOW_LOGGING_ENABLED=1
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### 2. Initialize in Your Application
|
|
66
|
-
|
|
67
|
-
**Option A: Using NODE_OPTIONS (Recommended)**
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
NODE_OPTIONS="-r securenow/register" node app.js
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
**Option B: Code-based initialization**
|
|
74
|
-
|
|
75
|
-
```javascript
|
|
76
|
-
// At the very top of your main file
|
|
77
|
-
require('securenow/register');
|
|
78
|
-
|
|
79
|
-
// Your application code
|
|
80
|
-
const express = require('express');
|
|
81
|
-
const app = express();
|
|
82
|
-
// ...
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### 3. Run Your Application
|
|
86
|
-
|
|
87
|
-
```bash
|
|
88
|
-
node app.js
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
You'll see confirmation in the console:
|
|
92
|
-
|
|
93
|
-
```
|
|
94
|
-
[securenow] OTel SDK started → http://your-otlp-collector:4318/v1/traces
|
|
95
|
-
[securenow] 📝 Request body capture: ENABLED
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
## CLI — Command Line Interface
|
|
101
|
-
|
|
102
|
-
The `securenow` CLI gives you full access to the SecureNow platform from the terminal — no browser required for day-to-day workflows. Zero additional dependencies.
|
|
103
|
-
|
|
104
|
-
### Getting Started
|
|
105
|
-
|
|
106
|
-
```bash
|
|
107
|
-
# Log in (opens browser for OAuth)
|
|
108
|
-
npx securenow login
|
|
109
|
-
|
|
110
|
-
# Or use a token for CI/headless environments
|
|
111
|
-
npx securenow login --token <YOUR_JWT>
|
|
112
|
-
|
|
113
|
-
# Check who you're logged in as
|
|
114
|
-
npx securenow whoami
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### Managing Applications
|
|
118
|
-
|
|
119
|
-
```bash
|
|
120
|
-
# List all applications
|
|
121
|
-
npx securenow apps
|
|
122
|
-
|
|
123
|
-
# Create a new application
|
|
124
|
-
npx securenow apps create my-production-app --hosts api.example.com,app.example.com
|
|
125
|
-
|
|
126
|
-
# Get application details (including the app key)
|
|
127
|
-
npx securenow apps info <app-id>
|
|
128
|
-
|
|
129
|
-
# Set a default app so you don't need --app on every command
|
|
130
|
-
npx securenow apps default <app-key>
|
|
131
|
-
|
|
132
|
-
# Delete an application
|
|
133
|
-
npx securenow apps delete <app-id> --force
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
### Viewing Traces
|
|
137
|
-
|
|
138
|
-
```bash
|
|
139
|
-
# List recent traces (uses default app, or specify --app)
|
|
140
|
-
npx securenow traces
|
|
141
|
-
npx securenow traces --app <key> --limit 50
|
|
142
|
-
|
|
143
|
-
# Show detailed spans for a trace
|
|
144
|
-
npx securenow traces show <traceId>
|
|
145
|
-
|
|
146
|
-
# AI-powered security analysis of a trace
|
|
147
|
-
npx securenow traces analyze <traceId>
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### Viewing Logs
|
|
151
|
-
|
|
152
|
-
```bash
|
|
153
|
-
# List recent logs
|
|
154
|
-
npx securenow logs
|
|
155
|
-
npx securenow logs --app <key> --minutes 30 --level error
|
|
156
|
-
|
|
157
|
-
# Show logs for a specific trace
|
|
158
|
-
npx securenow logs trace <traceId>
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
### Security Issues
|
|
162
|
-
|
|
163
|
-
```bash
|
|
164
|
-
# List all issues
|
|
165
|
-
npx securenow issues
|
|
166
|
-
npx securenow issues --status open
|
|
167
|
-
|
|
168
|
-
# Show issue details with AI analysis
|
|
169
|
-
npx securenow issues show <issue-id>
|
|
170
|
-
|
|
171
|
-
# Resolve an issue
|
|
172
|
-
npx securenow issues resolve <issue-id>
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
### Notifications
|
|
176
|
-
|
|
177
|
-
```bash
|
|
178
|
-
# List notifications
|
|
179
|
-
npx securenow notifications
|
|
180
|
-
|
|
181
|
-
# Check unread count
|
|
182
|
-
npx securenow notifications unread
|
|
183
|
-
|
|
184
|
-
# Mark as read
|
|
185
|
-
npx securenow notifications read <id>
|
|
186
|
-
npx securenow notifications read-all
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### Alerting
|
|
190
|
-
|
|
191
|
-
```bash
|
|
192
|
-
# View alert rules, channels, and history
|
|
193
|
-
npx securenow alerts rules
|
|
194
|
-
npx securenow alerts channels
|
|
195
|
-
npx securenow alerts history --limit 20
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### IP Intelligence & Blocklist
|
|
199
|
-
|
|
200
|
-
```bash
|
|
201
|
-
# Look up any IP — geo, abuse score, verdict, risk factors
|
|
202
|
-
npx securenow ip 203.0.113.42
|
|
203
|
-
|
|
204
|
-
# Show traces from a specific IP
|
|
205
|
-
npx securenow ip traces 203.0.113.42
|
|
206
|
-
|
|
207
|
-
# Manage the blocklist
|
|
208
|
-
npx securenow blocklist
|
|
209
|
-
npx securenow blocklist add 203.0.113.42 --reason "Brute force scanner"
|
|
210
|
-
npx securenow blocklist remove <id>
|
|
211
|
-
npx securenow blocklist stats
|
|
212
|
-
|
|
213
|
-
# Manage trusted IPs
|
|
214
|
-
npx securenow trusted
|
|
215
|
-
npx securenow trusted add 10.0.0.1 --label "Office VPN"
|
|
216
|
-
npx securenow trusted remove <id>
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
### Forensic Queries
|
|
220
|
-
|
|
221
|
-
Ask questions in plain English — the AI translates them to SQL and runs them against your data.
|
|
222
|
-
|
|
223
|
-
```bash
|
|
224
|
-
# Run a forensic query
|
|
225
|
-
npx securenow forensics "show top 10 attacking IPs in the last hour"
|
|
226
|
-
npx securenow forensics "which endpoints had 5xx errors today"
|
|
227
|
-
|
|
228
|
-
# Browse the saved query library
|
|
229
|
-
npx securenow forensics library
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
### API Map
|
|
233
|
-
|
|
234
|
-
```bash
|
|
235
|
-
# View all discovered API endpoints
|
|
236
|
-
npx securenow api-map
|
|
237
|
-
|
|
238
|
-
# API map statistics
|
|
239
|
-
npx securenow api-map stats
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
### Analytics & Dashboard
|
|
243
|
-
|
|
244
|
-
```bash
|
|
245
|
-
# Response code analytics
|
|
246
|
-
npx securenow analytics --app <key>
|
|
247
|
-
|
|
248
|
-
# Full dashboard overview (apps, protection status, unread alerts)
|
|
249
|
-
npx securenow status
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
### Instances
|
|
253
|
-
|
|
254
|
-
```bash
|
|
255
|
-
# List ClickHouse instances
|
|
256
|
-
npx securenow instances
|
|
257
|
-
|
|
258
|
-
# Test an instance connection
|
|
259
|
-
npx securenow instances test <id>
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
### Configuration
|
|
263
|
-
|
|
264
|
-
```bash
|
|
265
|
-
# View all config
|
|
266
|
-
npx securenow config get
|
|
267
|
-
|
|
268
|
-
# Set values
|
|
269
|
-
npx securenow config set apiUrl https://custom-api.example.com
|
|
270
|
-
npx securenow config set defaultApp <app-key>
|
|
271
|
-
npx securenow config set format json
|
|
272
|
-
|
|
273
|
-
# Show config file paths
|
|
274
|
-
npx securenow config path
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
Config files are stored in `~/.securenow/`:
|
|
278
|
-
|
|
279
|
-
| File | Description |
|
|
280
|
-
|------|-------------|
|
|
281
|
-
| `config.json` | API URL, default app, output format |
|
|
282
|
-
| `credentials.json` | Auth token (file permissions: 0600) |
|
|
283
|
-
|
|
284
|
-
### Initialize Instrumentation
|
|
285
|
-
|
|
286
|
-
```bash
|
|
287
|
-
# Interactive setup — creates instrumentation files for Next.js
|
|
288
|
-
npx securenow init
|
|
289
|
-
npx securenow init --ts --src --force
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
### Global Flags
|
|
293
|
-
|
|
294
|
-
Every command supports these flags:
|
|
295
|
-
|
|
296
|
-
| Flag | Short | Description |
|
|
297
|
-
|------|-------|-------------|
|
|
298
|
-
| `--json` | `-j` | Output as JSON for scripting and CI/CD |
|
|
299
|
-
| `--help` | | Show help for the command |
|
|
300
|
-
| `--app <key>` | | Override the default application key |
|
|
301
|
-
|
|
302
|
-
### Environment Variables
|
|
303
|
-
|
|
304
|
-
| Variable | Description |
|
|
305
|
-
|----------|-------------|
|
|
306
|
-
| `SECURENOW_API_URL` | Override the API base URL |
|
|
307
|
-
| `SECURENOW_DEBUG` | Show stack traces on errors |
|
|
308
|
-
| `NO_COLOR` | Disable colored output |
|
|
309
|
-
|
|
310
|
-
### CI/CD Integration
|
|
311
|
-
|
|
312
|
-
```bash
|
|
313
|
-
# Authenticate with a token in CI
|
|
314
|
-
npx securenow login --token $SECURENOW_TOKEN
|
|
315
|
-
|
|
316
|
-
# Use --json for machine-readable output
|
|
317
|
-
npx securenow issues --json | jq '.[] | select(.severity == "critical")'
|
|
318
|
-
|
|
319
|
-
# Check for critical issues in a pipeline
|
|
320
|
-
ISSUES=$(npx securenow issues --json --status open)
|
|
321
|
-
CRITICAL=$(echo "$ISSUES" | jq '[.[] | select(.severity == "critical")] | length')
|
|
322
|
-
if [ "$CRITICAL" -gt "0" ]; then
|
|
323
|
-
echo "Found $CRITICAL critical issues!"
|
|
324
|
-
exit 1
|
|
325
|
-
fi
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
### Complete Command Reference
|
|
329
|
-
|
|
330
|
-
| Category | Command | Description |
|
|
331
|
-
|----------|---------|-------------|
|
|
332
|
-
| **Auth** | `login` | Authenticate via browser or `--token` |
|
|
333
|
-
| | `logout` | Clear credentials |
|
|
334
|
-
| | `whoami` | Show session info |
|
|
335
|
-
| **Apps** | `apps` | List applications |
|
|
336
|
-
| | `apps create <name>` | Create application |
|
|
337
|
-
| | `apps info <id>` | Application details |
|
|
338
|
-
| | `apps delete <id>` | Delete application |
|
|
339
|
-
| | `apps default <key>` | Set default app |
|
|
340
|
-
| **Observe** | `traces` | List traces |
|
|
341
|
-
| | `traces show <id>` | Trace details |
|
|
342
|
-
| | `traces analyze <id>` | AI trace analysis |
|
|
343
|
-
| | `logs` | List logs |
|
|
344
|
-
| | `logs trace <id>` | Logs for a trace |
|
|
345
|
-
| | `analytics` | Response analytics |
|
|
346
|
-
| | `status` | Dashboard overview |
|
|
347
|
-
| **Detect** | `issues` | List issues |
|
|
348
|
-
| | `issues show <id>` | Issue details |
|
|
349
|
-
| | `issues resolve <id>` | Resolve issue |
|
|
350
|
-
| | `notifications` | List notifications |
|
|
351
|
-
| | `notifications unread` | Unread count |
|
|
352
|
-
| | `notifications read <id>` | Mark read |
|
|
353
|
-
| | `notifications read-all` | Mark all read |
|
|
354
|
-
| | `alerts rules` | Alert rules |
|
|
355
|
-
| | `alerts channels` | Alert channels |
|
|
356
|
-
| | `alerts history` | Alert history |
|
|
357
|
-
| **Investigate** | `ip <addr>` | IP intelligence |
|
|
358
|
-
| | `ip traces <addr>` | Traces from IP |
|
|
359
|
-
| | `forensics "<query>"` | NL forensic query |
|
|
360
|
-
| | `forensics library` | Saved queries |
|
|
361
|
-
| | `api-map` | API endpoints |
|
|
362
|
-
| | `api-map stats` | API stats |
|
|
363
|
-
| **Remediate** | `blocklist` | Blocked IPs |
|
|
364
|
-
| | `blocklist add <ip>` | Block IP |
|
|
365
|
-
| | `blocklist remove <id>` | Unblock IP |
|
|
366
|
-
| | `blocklist stats` | Block stats |
|
|
367
|
-
| | `trusted` | Trusted IPs |
|
|
368
|
-
| | `trusted add <ip>` | Add trusted IP |
|
|
369
|
-
| | `trusted remove <id>` | Remove trusted |
|
|
370
|
-
| **Settings** | `instances` | List instances |
|
|
371
|
-
| | `instances test <id>` | Test connection |
|
|
372
|
-
| | `config get` | Show config |
|
|
373
|
-
| | `config set <k> <v>` | Set config value |
|
|
374
|
-
| | `config path` | Config file paths |
|
|
375
|
-
| | `init` | Setup instrumentation |
|
|
376
|
-
| | `version` | Show version |
|
|
377
|
-
|
|
378
|
-
---
|
|
379
|
-
|
|
380
|
-
## Framework-Specific Setup
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
app.
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
app
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
---
|
|
465
|
-
|
|
466
|
-
###
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
```
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
console.log('
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
```
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
```
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
async function
|
|
684
|
-
const
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
const
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
**
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
**
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
###
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
```
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
export
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
```
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
const
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
const
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
```
|
|
1123
|
-
|
|
1124
|
-
###
|
|
1125
|
-
|
|
1126
|
-
```
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
if (
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
}
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
```
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
```
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
```
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
###
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
// .
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
```
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
- **
|
|
1495
|
-
- **
|
|
1496
|
-
- **
|
|
1497
|
-
- **
|
|
1498
|
-
|
|
1499
|
-
---
|
|
1500
|
-
|
|
1501
|
-
##
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
-
|
|
1506
|
-
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
-
|
|
1519
|
-
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
│ - OTLP exporters │
|
|
1546
|
-
└───────────────┬─────────────────┘
|
|
1547
|
-
│
|
|
1548
|
-
▼
|
|
1549
|
-
┌─────────────────────────────────┐
|
|
1550
|
-
│ OTLP Collector/Backend │
|
|
1551
|
-
│ (Your observability platform) │
|
|
1552
|
-
└─────────────────────────────────┘
|
|
1553
|
-
```
|
|
1554
|
-
|
|
1555
|
-
---
|
|
1556
|
-
|
|
1557
|
-
## Performance
|
|
1558
|
-
|
|
1559
|
-
- **Minimal overhead:** < 1% CPU and memory impact
|
|
1560
|
-
- **Batch export:** Traces and logs are batched before sending
|
|
1561
|
-
- **Async processing:** No blocking of application threads
|
|
1562
|
-
- **Configurable:** Disable instrumentations you don't need
|
|
1563
|
-
|
|
1564
|
-
---
|
|
1565
|
-
|
|
1566
|
-
## Security
|
|
1567
|
-
|
|
1568
|
-
- **Automatic redaction** of sensitive fields (passwords, tokens, keys)
|
|
1569
|
-
- **Configurable** sensitive field patterns
|
|
1570
|
-
- **No data stored** locally - everything sent to your OTLP backend
|
|
1571
|
-
- **Open source** - audit the code yourself
|
|
1572
|
-
|
|
1573
|
-
---
|
|
1574
|
-
|
|
1575
|
-
## License
|
|
1576
|
-
|
|
1577
|
-
ISC
|
|
1578
|
-
|
|
1579
|
-
---
|
|
1580
|
-
|
|
1581
|
-
## Support
|
|
1582
|
-
|
|
1583
|
-
- **Documentation:** [GitHub Docs](https://github.com/your-repo/securenow-npm/tree/main/docs)
|
|
1584
|
-
- **Issues:** [GitHub Issues](https://github.com/your-repo/securenow-npm/issues)
|
|
1585
|
-
- **Examples:** [GitHub Examples](https://github.com/your-repo/securenow-npm/tree/main/examples)
|
|
1586
|
-
|
|
1587
|
-
---
|
|
1588
|
-
|
|
1589
|
-
## Changelog
|
|
1590
|
-
|
|
1591
|
-
See [CHANGELOG.md](CHANGELOG.md) for version history.
|
|
1592
|
-
|
|
1593
|
-
---
|
|
1594
|
-
|
|
1595
|
-
## Contributing
|
|
1596
|
-
|
|
1597
|
-
Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
1598
|
-
|
|
1599
|
-
---
|
|
1600
|
-
|
|
1601
|
-
## Related Packages
|
|
1602
|
-
|
|
1603
|
-
- [@opentelemetry/sdk-node](https://www.npmjs.com/package/@opentelemetry/sdk-node) - Core OpenTelemetry SDK
|
|
1604
|
-
- [@opentelemetry/auto-instrumentations-node](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node) - Auto-instrumentation
|
|
1605
|
-
- [@opentelemetry/exporter-trace-otlp-http](https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-http) - OTLP exporter
|
|
1606
|
-
|
|
1607
|
-
---
|
|
1608
|
-
|
|
1609
|
-
**Made with ❤️ for the Node.js community**
|
|
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
|
+
- [CLI — Command Line Interface](#cli--command-line-interface)
|
|
20
|
+
- [Framework-Specific Setup](#framework-specific-setup)
|
|
21
|
+
- [Express.js](#expressjs)
|
|
22
|
+
- [Next.js](#nextjs)
|
|
23
|
+
- [Fastify](#fastify)
|
|
24
|
+
- [NestJS](#nestjs)
|
|
25
|
+
- [Koa](#koa)
|
|
26
|
+
- [Hapi](#hapi)
|
|
27
|
+
- [Environment Variables Reference](#environment-variables-reference)
|
|
28
|
+
- [Logging Setup](#logging-setup)
|
|
29
|
+
- [Request Body Capture](#request-body-capture)
|
|
30
|
+
- [Advanced Configuration](#advanced-configuration)
|
|
31
|
+
- [TypeScript Support](#typescript-support)
|
|
32
|
+
- [Troubleshooting](#troubleshooting)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install securenow
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Or with yarn:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
yarn add securenow
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
### 1. Set Environment Variables
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Required: Your application identifier
|
|
56
|
+
export SECURENOW_APPID=my-app
|
|
57
|
+
|
|
58
|
+
# Required: Your OTLP collector endpoint
|
|
59
|
+
export SECURENOW_INSTANCE=http://your-otlp-collector:4318
|
|
60
|
+
|
|
61
|
+
# Optional: Enable logging
|
|
62
|
+
export SECURENOW_LOGGING_ENABLED=1
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 2. Initialize in Your Application
|
|
66
|
+
|
|
67
|
+
**Option A: Using NODE_OPTIONS (Recommended)**
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
NODE_OPTIONS="-r securenow/register" node app.js
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Option B: Code-based initialization**
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
// At the very top of your main file
|
|
77
|
+
require('securenow/register');
|
|
78
|
+
|
|
79
|
+
// Your application code
|
|
80
|
+
const express = require('express');
|
|
81
|
+
const app = express();
|
|
82
|
+
// ...
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 3. Run Your Application
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
node app.js
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
You'll see confirmation in the console:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
[securenow] OTel SDK started → http://your-otlp-collector:4318/v1/traces
|
|
95
|
+
[securenow] 📝 Request body capture: ENABLED
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## CLI — Command Line Interface
|
|
101
|
+
|
|
102
|
+
The `securenow` CLI gives you full access to the SecureNow platform from the terminal — no browser required for day-to-day workflows. Zero additional dependencies.
|
|
103
|
+
|
|
104
|
+
### Getting Started
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Log in (opens browser for OAuth)
|
|
108
|
+
npx securenow login
|
|
109
|
+
|
|
110
|
+
# Or use a token for CI/headless environments
|
|
111
|
+
npx securenow login --token <YOUR_JWT>
|
|
112
|
+
|
|
113
|
+
# Check who you're logged in as
|
|
114
|
+
npx securenow whoami
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Managing Applications
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# List all applications
|
|
121
|
+
npx securenow apps
|
|
122
|
+
|
|
123
|
+
# Create a new application
|
|
124
|
+
npx securenow apps create my-production-app --hosts api.example.com,app.example.com
|
|
125
|
+
|
|
126
|
+
# Get application details (including the app key)
|
|
127
|
+
npx securenow apps info <app-id>
|
|
128
|
+
|
|
129
|
+
# Set a default app so you don't need --app on every command
|
|
130
|
+
npx securenow apps default <app-key>
|
|
131
|
+
|
|
132
|
+
# Delete an application
|
|
133
|
+
npx securenow apps delete <app-id> --force
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Viewing Traces
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# List recent traces (uses default app, or specify --app)
|
|
140
|
+
npx securenow traces
|
|
141
|
+
npx securenow traces --app <key> --limit 50
|
|
142
|
+
|
|
143
|
+
# Show detailed spans for a trace
|
|
144
|
+
npx securenow traces show <traceId>
|
|
145
|
+
|
|
146
|
+
# AI-powered security analysis of a trace
|
|
147
|
+
npx securenow traces analyze <traceId>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Viewing Logs
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# List recent logs
|
|
154
|
+
npx securenow logs
|
|
155
|
+
npx securenow logs --app <key> --minutes 30 --level error
|
|
156
|
+
|
|
157
|
+
# Show logs for a specific trace
|
|
158
|
+
npx securenow logs trace <traceId>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Security Issues
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
# List all issues
|
|
165
|
+
npx securenow issues
|
|
166
|
+
npx securenow issues --status open
|
|
167
|
+
|
|
168
|
+
# Show issue details with AI analysis
|
|
169
|
+
npx securenow issues show <issue-id>
|
|
170
|
+
|
|
171
|
+
# Resolve an issue
|
|
172
|
+
npx securenow issues resolve <issue-id>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Notifications
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
# List notifications
|
|
179
|
+
npx securenow notifications
|
|
180
|
+
|
|
181
|
+
# Check unread count
|
|
182
|
+
npx securenow notifications unread
|
|
183
|
+
|
|
184
|
+
# Mark as read
|
|
185
|
+
npx securenow notifications read <id>
|
|
186
|
+
npx securenow notifications read-all
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Alerting
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
# View alert rules, channels, and history
|
|
193
|
+
npx securenow alerts rules
|
|
194
|
+
npx securenow alerts channels
|
|
195
|
+
npx securenow alerts history --limit 20
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### IP Intelligence & Blocklist
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
# Look up any IP — geo, abuse score, verdict, risk factors
|
|
202
|
+
npx securenow ip 203.0.113.42
|
|
203
|
+
|
|
204
|
+
# Show traces from a specific IP
|
|
205
|
+
npx securenow ip traces 203.0.113.42
|
|
206
|
+
|
|
207
|
+
# Manage the blocklist
|
|
208
|
+
npx securenow blocklist
|
|
209
|
+
npx securenow blocklist add 203.0.113.42 --reason "Brute force scanner"
|
|
210
|
+
npx securenow blocklist remove <id>
|
|
211
|
+
npx securenow blocklist stats
|
|
212
|
+
|
|
213
|
+
# Manage trusted IPs
|
|
214
|
+
npx securenow trusted
|
|
215
|
+
npx securenow trusted add 10.0.0.1 --label "Office VPN"
|
|
216
|
+
npx securenow trusted remove <id>
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Forensic Queries
|
|
220
|
+
|
|
221
|
+
Ask questions in plain English — the AI translates them to SQL and runs them against your data.
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
# Run a forensic query
|
|
225
|
+
npx securenow forensics "show top 10 attacking IPs in the last hour"
|
|
226
|
+
npx securenow forensics "which endpoints had 5xx errors today"
|
|
227
|
+
|
|
228
|
+
# Browse the saved query library
|
|
229
|
+
npx securenow forensics library
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### API Map
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
# View all discovered API endpoints
|
|
236
|
+
npx securenow api-map
|
|
237
|
+
|
|
238
|
+
# API map statistics
|
|
239
|
+
npx securenow api-map stats
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Analytics & Dashboard
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
# Response code analytics
|
|
246
|
+
npx securenow analytics --app <key>
|
|
247
|
+
|
|
248
|
+
# Full dashboard overview (apps, protection status, unread alerts)
|
|
249
|
+
npx securenow status
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Instances
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
# List ClickHouse instances
|
|
256
|
+
npx securenow instances
|
|
257
|
+
|
|
258
|
+
# Test an instance connection
|
|
259
|
+
npx securenow instances test <id>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Configuration
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
# View all config
|
|
266
|
+
npx securenow config get
|
|
267
|
+
|
|
268
|
+
# Set values
|
|
269
|
+
npx securenow config set apiUrl https://custom-api.example.com
|
|
270
|
+
npx securenow config set defaultApp <app-key>
|
|
271
|
+
npx securenow config set format json
|
|
272
|
+
|
|
273
|
+
# Show config file paths
|
|
274
|
+
npx securenow config path
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Config files are stored in `~/.securenow/`:
|
|
278
|
+
|
|
279
|
+
| File | Description |
|
|
280
|
+
|------|-------------|
|
|
281
|
+
| `config.json` | API URL, default app, output format |
|
|
282
|
+
| `credentials.json` | Auth token (file permissions: 0600) |
|
|
283
|
+
|
|
284
|
+
### Initialize Instrumentation
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
# Interactive setup — creates instrumentation files for Next.js
|
|
288
|
+
npx securenow init
|
|
289
|
+
npx securenow init --ts --src --force
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Global Flags
|
|
293
|
+
|
|
294
|
+
Every command supports these flags:
|
|
295
|
+
|
|
296
|
+
| Flag | Short | Description |
|
|
297
|
+
|------|-------|-------------|
|
|
298
|
+
| `--json` | `-j` | Output as JSON for scripting and CI/CD |
|
|
299
|
+
| `--help` | | Show help for the command |
|
|
300
|
+
| `--app <key>` | | Override the default application key |
|
|
301
|
+
|
|
302
|
+
### Environment Variables
|
|
303
|
+
|
|
304
|
+
| Variable | Description |
|
|
305
|
+
|----------|-------------|
|
|
306
|
+
| `SECURENOW_API_URL` | Override the API base URL |
|
|
307
|
+
| `SECURENOW_DEBUG` | Show stack traces on errors |
|
|
308
|
+
| `NO_COLOR` | Disable colored output |
|
|
309
|
+
|
|
310
|
+
### CI/CD Integration
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
# Authenticate with a token in CI
|
|
314
|
+
npx securenow login --token $SECURENOW_TOKEN
|
|
315
|
+
|
|
316
|
+
# Use --json for machine-readable output
|
|
317
|
+
npx securenow issues --json | jq '.[] | select(.severity == "critical")'
|
|
318
|
+
|
|
319
|
+
# Check for critical issues in a pipeline
|
|
320
|
+
ISSUES=$(npx securenow issues --json --status open)
|
|
321
|
+
CRITICAL=$(echo "$ISSUES" | jq '[.[] | select(.severity == "critical")] | length')
|
|
322
|
+
if [ "$CRITICAL" -gt "0" ]; then
|
|
323
|
+
echo "Found $CRITICAL critical issues!"
|
|
324
|
+
exit 1
|
|
325
|
+
fi
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Complete Command Reference
|
|
329
|
+
|
|
330
|
+
| Category | Command | Description |
|
|
331
|
+
|----------|---------|-------------|
|
|
332
|
+
| **Auth** | `login` | Authenticate via browser or `--token` |
|
|
333
|
+
| | `logout` | Clear credentials |
|
|
334
|
+
| | `whoami` | Show session info |
|
|
335
|
+
| **Apps** | `apps` | List applications |
|
|
336
|
+
| | `apps create <name>` | Create application |
|
|
337
|
+
| | `apps info <id>` | Application details |
|
|
338
|
+
| | `apps delete <id>` | Delete application |
|
|
339
|
+
| | `apps default <key>` | Set default app |
|
|
340
|
+
| **Observe** | `traces` | List traces |
|
|
341
|
+
| | `traces show <id>` | Trace details |
|
|
342
|
+
| | `traces analyze <id>` | AI trace analysis |
|
|
343
|
+
| | `logs` | List logs |
|
|
344
|
+
| | `logs trace <id>` | Logs for a trace |
|
|
345
|
+
| | `analytics` | Response analytics |
|
|
346
|
+
| | `status` | Dashboard overview |
|
|
347
|
+
| **Detect** | `issues` | List issues |
|
|
348
|
+
| | `issues show <id>` | Issue details |
|
|
349
|
+
| | `issues resolve <id>` | Resolve issue |
|
|
350
|
+
| | `notifications` | List notifications |
|
|
351
|
+
| | `notifications unread` | Unread count |
|
|
352
|
+
| | `notifications read <id>` | Mark read |
|
|
353
|
+
| | `notifications read-all` | Mark all read |
|
|
354
|
+
| | `alerts rules` | Alert rules |
|
|
355
|
+
| | `alerts channels` | Alert channels |
|
|
356
|
+
| | `alerts history` | Alert history |
|
|
357
|
+
| **Investigate** | `ip <addr>` | IP intelligence |
|
|
358
|
+
| | `ip traces <addr>` | Traces from IP |
|
|
359
|
+
| | `forensics "<query>"` | NL forensic query |
|
|
360
|
+
| | `forensics library` | Saved queries |
|
|
361
|
+
| | `api-map` | API endpoints |
|
|
362
|
+
| | `api-map stats` | API stats |
|
|
363
|
+
| **Remediate** | `blocklist` | Blocked IPs |
|
|
364
|
+
| | `blocklist add <ip>` | Block IP |
|
|
365
|
+
| | `blocklist remove <id>` | Unblock IP |
|
|
366
|
+
| | `blocklist stats` | Block stats |
|
|
367
|
+
| | `trusted` | Trusted IPs |
|
|
368
|
+
| | `trusted add <ip>` | Add trusted IP |
|
|
369
|
+
| | `trusted remove <id>` | Remove trusted |
|
|
370
|
+
| **Settings** | `instances` | List instances |
|
|
371
|
+
| | `instances test <id>` | Test connection |
|
|
372
|
+
| | `config get` | Show config |
|
|
373
|
+
| | `config set <k> <v>` | Set config value |
|
|
374
|
+
| | `config path` | Config file paths |
|
|
375
|
+
| | `init` | Setup instrumentation |
|
|
376
|
+
| | `version` | Show version |
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
## Framework-Specific Setup
|
|
381
|
+
|
|
382
|
+
> **v5.6.0+:** When `SECURENOW_LOGGING_ENABLED=1`, all `console.log`/`warn`/`error`/`info`/`debug` calls
|
|
383
|
+
> are **automatically** forwarded as OTLP log records. The separate `require('securenow/console-instrumentation')` is no longer needed (but still available for backward compat).
|
|
384
|
+
|
|
385
|
+
### Express.js
|
|
386
|
+
|
|
387
|
+
```bash
|
|
388
|
+
npm install securenow express
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
```javascript
|
|
392
|
+
// app.js
|
|
393
|
+
require('securenow/register');
|
|
394
|
+
const express = require('express');
|
|
395
|
+
|
|
396
|
+
const app = express();
|
|
397
|
+
app.use(express.json());
|
|
398
|
+
|
|
399
|
+
app.get('/health', (req, res) => res.json({ status: 'ok' }));
|
|
400
|
+
|
|
401
|
+
app.post('/tasks', (req, res) => {
|
|
402
|
+
console.log('Created task:', req.body.title);
|
|
403
|
+
res.status(201).json({ id: '1', title: req.body.title });
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
app.listen(3000, () => console.log('Express running on port 3000'));
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
```bash
|
|
410
|
+
node app.js
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
#### With PM2
|
|
414
|
+
|
|
415
|
+
```javascript
|
|
416
|
+
// ecosystem.config.cjs
|
|
417
|
+
module.exports = {
|
|
418
|
+
apps: [{
|
|
419
|
+
name: 'my-app',
|
|
420
|
+
script: './app.js',
|
|
421
|
+
node_args: '-r securenow/register',
|
|
422
|
+
env: {
|
|
423
|
+
SECURENOW_APPID: 'your-app-key',
|
|
424
|
+
SECURENOW_INSTANCE: 'https://freetrial.securenow.ai:4318',
|
|
425
|
+
SECURENOW_LOGGING_ENABLED: '1',
|
|
426
|
+
SECURENOW_NO_UUID: '1',
|
|
427
|
+
SECURENOW_CAPTURE_BODY: '1',
|
|
428
|
+
}
|
|
429
|
+
}]
|
|
430
|
+
};
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
### Fastify
|
|
436
|
+
|
|
437
|
+
```bash
|
|
438
|
+
npm install securenow fastify
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
```javascript
|
|
442
|
+
// app.js
|
|
443
|
+
require('securenow/register');
|
|
444
|
+
const Fastify = require('fastify');
|
|
445
|
+
const fastify = Fastify({ logger: true });
|
|
446
|
+
|
|
447
|
+
fastify.get('/health', async () => ({ status: 'ok' }));
|
|
448
|
+
|
|
449
|
+
fastify.post('/tasks', {
|
|
450
|
+
schema: { body: { type: 'object', required: ['title'], properties: { title: { type: 'string' } } } }
|
|
451
|
+
}, async (request) => {
|
|
452
|
+
console.log('Created task:', request.body.title);
|
|
453
|
+
return { id: '1', title: request.body.title };
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
fastify.listen({ port: 3000 }, (err) => {
|
|
457
|
+
if (err) { fastify.log.error(err); process.exit(1); }
|
|
458
|
+
console.log('Fastify running on port 3000');
|
|
459
|
+
});
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
> **Important:** Set `SECURENOW_CAPTURE_BODY=0` with Fastify — the body capture hook conflicts with Fastify's internal stream handling.
|
|
463
|
+
|
|
464
|
+
---
|
|
465
|
+
|
|
466
|
+
### Koa
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
npm install securenow koa @koa/router koa-bodyparser
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
```javascript
|
|
473
|
+
// app.js
|
|
474
|
+
require('securenow/register');
|
|
475
|
+
const Koa = require('koa');
|
|
476
|
+
const Router = require('@koa/router');
|
|
477
|
+
const bodyParser = require('koa-bodyparser');
|
|
478
|
+
|
|
479
|
+
const app = new Koa();
|
|
480
|
+
const router = new Router();
|
|
481
|
+
|
|
482
|
+
router.get('/health', (ctx) => { ctx.body = { status: 'ok' }; });
|
|
483
|
+
|
|
484
|
+
router.post('/tasks', (ctx) => {
|
|
485
|
+
console.log('Created task:', ctx.request.body.title);
|
|
486
|
+
ctx.status = 201;
|
|
487
|
+
ctx.body = { id: '1', title: ctx.request.body.title };
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
app.use(bodyParser());
|
|
491
|
+
app.use(router.routes());
|
|
492
|
+
app.use(router.allowedMethods());
|
|
493
|
+
|
|
494
|
+
app.listen(3000, () => console.log('Koa running on port 3000'));
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
---
|
|
498
|
+
|
|
499
|
+
### NestJS
|
|
500
|
+
|
|
501
|
+
```bash
|
|
502
|
+
npm install securenow @nestjs/core @nestjs/common reflect-metadata ts-node typescript
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
NestJS uses TypeScript — securenow is loaded via `-r` flags instead of in-code `require()`:
|
|
506
|
+
|
|
507
|
+
```typescript
|
|
508
|
+
// app.ts
|
|
509
|
+
import 'reflect-metadata';
|
|
510
|
+
import { NestFactory } from '@nestjs/core';
|
|
511
|
+
import { Module, Controller, Get, Post, Body } from '@nestjs/common';
|
|
512
|
+
|
|
513
|
+
@Controller()
|
|
514
|
+
class AppController {
|
|
515
|
+
@Get('health')
|
|
516
|
+
health() { return { status: 'ok' }; }
|
|
517
|
+
|
|
518
|
+
@Post('tasks')
|
|
519
|
+
create(@Body() body: { title: string }) {
|
|
520
|
+
console.log('Created task:', body.title);
|
|
521
|
+
return { id: '1', title: body.title };
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
@Module({ controllers: [AppController] })
|
|
526
|
+
class AppModule {}
|
|
527
|
+
|
|
528
|
+
async function bootstrap() {
|
|
529
|
+
const app = await NestFactory.create(AppModule);
|
|
530
|
+
await app.listen(3000);
|
|
531
|
+
console.log('NestJS running on port 3000');
|
|
532
|
+
}
|
|
533
|
+
bootstrap();
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
```bash
|
|
537
|
+
node -r securenow/register -r ts-node/register app.ts
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
PM2 config:
|
|
541
|
+
|
|
542
|
+
```javascript
|
|
543
|
+
{
|
|
544
|
+
name: 'my-nestjs-app',
|
|
545
|
+
script: 'app.ts',
|
|
546
|
+
interpreter: 'node',
|
|
547
|
+
node_args: '-r securenow/register -r ts-node/register',
|
|
548
|
+
}
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
---
|
|
552
|
+
|
|
553
|
+
### Hapi
|
|
554
|
+
|
|
555
|
+
```bash
|
|
556
|
+
npm install securenow @hapi/hapi
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
```javascript
|
|
560
|
+
// app.js
|
|
561
|
+
require('securenow/register');
|
|
562
|
+
const Hapi = require('@hapi/hapi');
|
|
563
|
+
|
|
564
|
+
const init = async () => {
|
|
565
|
+
const server = Hapi.server({ port: 3000, host: '0.0.0.0' });
|
|
566
|
+
|
|
567
|
+
server.route({ method: 'GET', path: '/health', handler: () => ({ status: 'ok' }) });
|
|
568
|
+
|
|
569
|
+
server.route({
|
|
570
|
+
method: 'POST', path: '/tasks',
|
|
571
|
+
options: { payload: { parse: true, allow: 'application/json' } },
|
|
572
|
+
handler: (request, h) => {
|
|
573
|
+
console.log('Created task:', request.payload.title);
|
|
574
|
+
return h.response({ id: '1', title: request.payload.title }).code(201);
|
|
575
|
+
}
|
|
576
|
+
});
|
|
577
|
+
|
|
578
|
+
await server.start();
|
|
579
|
+
console.log('Hapi running on port 3000');
|
|
580
|
+
};
|
|
581
|
+
|
|
582
|
+
init().catch((err) => { console.error(err); process.exit(1); });
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
> **Important:** Set `SECURENOW_CAPTURE_BODY=0` with Hapi — the body capture hook consumes the request stream before Hapi's payload parser.
|
|
586
|
+
|
|
587
|
+
---
|
|
588
|
+
|
|
589
|
+
### h3 (UnJS / Nitro)
|
|
590
|
+
|
|
591
|
+
```bash
|
|
592
|
+
npm install securenow h3
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
```javascript
|
|
596
|
+
// app.js
|
|
597
|
+
require('securenow/register');
|
|
598
|
+
const { createApp, createRouter, defineEventHandler, readBody, setResponseStatus, toNodeListener } = require('h3');
|
|
599
|
+
const http = require('http');
|
|
600
|
+
|
|
601
|
+
const app = createApp();
|
|
602
|
+
const router = createRouter();
|
|
603
|
+
|
|
604
|
+
router.get('/health', defineEventHandler(() => ({ status: 'ok' })));
|
|
605
|
+
|
|
606
|
+
router.post('/tasks', defineEventHandler(async (event) => {
|
|
607
|
+
const body = await readBody(event);
|
|
608
|
+
console.log('Created task:', body.title);
|
|
609
|
+
setResponseStatus(event, 201);
|
|
610
|
+
return { id: '1', title: body.title };
|
|
611
|
+
}));
|
|
612
|
+
|
|
613
|
+
app.use(router);
|
|
614
|
+
|
|
615
|
+
http.createServer(toNodeListener(app)).listen(3000, () => {
|
|
616
|
+
console.log('h3 running on port 3000');
|
|
617
|
+
});
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
---
|
|
621
|
+
|
|
622
|
+
### Polka
|
|
623
|
+
|
|
624
|
+
```bash
|
|
625
|
+
npm install securenow polka
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
Polka is minimalist — no built-in body parser:
|
|
629
|
+
|
|
630
|
+
```javascript
|
|
631
|
+
// app.js
|
|
632
|
+
require('securenow/register');
|
|
633
|
+
const polka = require('polka');
|
|
634
|
+
|
|
635
|
+
function jsonBody(req, res, next) {
|
|
636
|
+
if (req.method === 'GET' || req.method === 'DELETE') return next();
|
|
637
|
+
let data = '';
|
|
638
|
+
req.on('data', chunk => { data += chunk; });
|
|
639
|
+
req.on('end', () => { try { req.body = JSON.parse(data); } catch { req.body = {}; } next(); });
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
function sendJson(res, status, body) {
|
|
643
|
+
res.writeHead(status, { 'Content-Type': 'application/json' });
|
|
644
|
+
res.end(JSON.stringify(body));
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
polka()
|
|
648
|
+
.use(jsonBody)
|
|
649
|
+
.get('/health', (req, res) => sendJson(res, 200, { status: 'ok' }))
|
|
650
|
+
.post('/tasks', (req, res) => {
|
|
651
|
+
console.log('Created task:', req.body.title);
|
|
652
|
+
sendJson(res, 201, { id: '1', title: req.body.title });
|
|
653
|
+
})
|
|
654
|
+
.listen(3000, () => console.log('Polka running on port 3000'));
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
---
|
|
658
|
+
|
|
659
|
+
### Micro / Raw HTTP
|
|
660
|
+
|
|
661
|
+
For apps using Node's bare `http` module:
|
|
662
|
+
|
|
663
|
+
```bash
|
|
664
|
+
npm install securenow
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
```javascript
|
|
668
|
+
// app.js
|
|
669
|
+
require('securenow/register');
|
|
670
|
+
const http = require('http');
|
|
671
|
+
|
|
672
|
+
function sendJson(res, status, body) {
|
|
673
|
+
res.writeHead(status, { 'Content-Type': 'application/json' });
|
|
674
|
+
res.end(JSON.stringify(body));
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
function readBody(req) {
|
|
678
|
+
return new Promise((resolve) => {
|
|
679
|
+
let d = ''; req.on('data', c => { d += c; }); req.on('end', () => { try { resolve(JSON.parse(d)); } catch { resolve({}); } });
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
async function handler(req, res) {
|
|
684
|
+
const url = new URL(req.url, `http://${req.headers.host}`);
|
|
685
|
+
if (url.pathname === '/health') return sendJson(res, 200, { status: 'ok' });
|
|
686
|
+
if (url.pathname === '/tasks' && req.method === 'POST') {
|
|
687
|
+
const body = await readBody(req);
|
|
688
|
+
console.log('Created task:', body.title);
|
|
689
|
+
return sendJson(res, 201, { id: '1', title: body.title });
|
|
690
|
+
}
|
|
691
|
+
sendJson(res, 404, { error: 'Not found' });
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
http.createServer(handler).listen(3000, () => console.log('HTTP running on port 3000'));
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
---
|
|
698
|
+
|
|
699
|
+
### Hono (ESM)
|
|
700
|
+
|
|
701
|
+
```bash
|
|
702
|
+
npm install securenow hono @hono/node-server
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
Hono uses ESM — securenow must be preloaded via `-r` flag:
|
|
706
|
+
|
|
707
|
+
```javascript
|
|
708
|
+
// app.mjs
|
|
709
|
+
import { serve } from '@hono/node-server';
|
|
710
|
+
import { Hono } from 'hono';
|
|
711
|
+
|
|
712
|
+
const app = new Hono();
|
|
713
|
+
|
|
714
|
+
app.get('/health', (c) => c.json({ status: 'ok' }));
|
|
715
|
+
|
|
716
|
+
app.post('/tasks', async (c) => {
|
|
717
|
+
const body = await c.req.json();
|
|
718
|
+
console.log('Created task:', body.title);
|
|
719
|
+
return c.json({ id: '1', title: body.title }, 201);
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
serve({ fetch: app.fetch, port: 3000 }, () => console.log('Hono running on port 3000'));
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
```bash
|
|
726
|
+
node -r securenow/register app.mjs
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
> **Important:** Set `SECURENOW_CAPTURE_BODY=0` with Hono. Do **not** add `require('securenow/register')` inside `.mjs` files.
|
|
730
|
+
|
|
731
|
+
---
|
|
732
|
+
|
|
733
|
+
### Feathers
|
|
734
|
+
|
|
735
|
+
```bash
|
|
736
|
+
npm install securenow @feathersjs/feathers @feathersjs/express @feathersjs/errors
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
Feathers uses Express transport — same setup as Express:
|
|
740
|
+
|
|
741
|
+
```javascript
|
|
742
|
+
// app.js
|
|
743
|
+
require('securenow/register');
|
|
744
|
+
const feathers = require('@feathersjs/feathers');
|
|
745
|
+
const express = require('@feathersjs/express');
|
|
746
|
+
const errors = require('@feathersjs/errors');
|
|
747
|
+
|
|
748
|
+
class TaskService {
|
|
749
|
+
constructor() { this.tasks = []; this.nextId = 1; }
|
|
750
|
+
async find() { return this.tasks; }
|
|
751
|
+
async create(data) {
|
|
752
|
+
if (!data.title) throw new errors.BadRequest('title is required');
|
|
753
|
+
const task = { id: String(this.nextId++), title: data.title };
|
|
754
|
+
this.tasks.push(task);
|
|
755
|
+
console.log('Created task:', task.id);
|
|
756
|
+
return task;
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
const app = express(feathers());
|
|
761
|
+
app.use(express.json());
|
|
762
|
+
app.configure(express.rest());
|
|
763
|
+
app.get('/health', (req, res) => res.json({ status: 'ok' }));
|
|
764
|
+
app.use('/tasks', new TaskService());
|
|
765
|
+
app.use(express.errorHandler());
|
|
766
|
+
|
|
767
|
+
app.listen(3000, () => console.log('Feathers running on port 3000'));
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
---
|
|
771
|
+
|
|
772
|
+
### Next.js
|
|
773
|
+
|
|
774
|
+
See [Next.js Complete Guide →](./docs/NEXTJS-SETUP-COMPLETE.md)
|
|
775
|
+
|
|
776
|
+
Create `instrumentation.ts` in your project root:
|
|
777
|
+
|
|
778
|
+
```typescript
|
|
779
|
+
export async function register() {
|
|
780
|
+
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
|
781
|
+
await import('securenow/register');
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
```
|
|
785
|
+
|
|
786
|
+
`.env.local`:
|
|
787
|
+
|
|
788
|
+
```env
|
|
789
|
+
SECURENOW_APPID=my-nextjs-app
|
|
790
|
+
SECURENOW_INSTANCE=https://freetrial.securenow.ai:4318
|
|
791
|
+
SECURENOW_LOGGING_ENABLED=1
|
|
792
|
+
SECURENOW_NO_UUID=1
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
---
|
|
796
|
+
|
|
797
|
+
### Compatibility Matrix
|
|
798
|
+
|
|
799
|
+
| Framework | Traces | Logs | Body Capture | Notes |
|
|
800
|
+
|-----------|--------|------|--------------|-------|
|
|
801
|
+
| Express | Yes | Yes | Yes | Fully compatible |
|
|
802
|
+
| Fastify | Yes | Yes | **No** | `SECURENOW_CAPTURE_BODY=0` required |
|
|
803
|
+
| Koa | Yes | Yes | Yes | Needs `koa-bodyparser` |
|
|
804
|
+
| NestJS | Yes | Yes | Yes | Use `-r ts-node/register` |
|
|
805
|
+
| Hapi | Yes | Yes | **No** | `SECURENOW_CAPTURE_BODY=0` required |
|
|
806
|
+
| h3 | Yes | Yes | Yes | Uses `toNodeListener()` |
|
|
807
|
+
| Polka | Yes | Yes | Yes | Needs manual body parser |
|
|
808
|
+
| Micro/HTTP | Yes | Yes | Yes | Full control |
|
|
809
|
+
| Hono | Yes | Yes | **No** | `SECURENOW_CAPTURE_BODY=0`; ESM `-r` flag |
|
|
810
|
+
| Feathers | Yes | Yes | Yes | Uses Express transport |
|
|
811
|
+
| Next.js | Yes | Yes | Yes | Use `instrumentation.ts` |
|
|
812
|
+
|
|
813
|
+
---
|
|
814
|
+
|
|
815
|
+
## Environment Variables Reference
|
|
816
|
+
|
|
817
|
+
### Required Variables
|
|
818
|
+
|
|
819
|
+
| Variable | Description | Example |
|
|
820
|
+
|----------|-------------|---------|
|
|
821
|
+
| `SECURENOW_APPID` | Your application identifier. Used as the service name in traces. | `my-app` |
|
|
822
|
+
| `SECURENOW_INSTANCE` | Base URL of your OTLP collector endpoint. | `http://localhost:4318` |
|
|
823
|
+
|
|
824
|
+
### Optional Configuration
|
|
825
|
+
|
|
826
|
+
#### Service Naming
|
|
827
|
+
|
|
828
|
+
| Variable | Description | Default |
|
|
829
|
+
|----------|-------------|---------|
|
|
830
|
+
| `OTEL_SERVICE_NAME` | Alternative to SECURENOW_APPID. Standard OpenTelemetry variable. | - |
|
|
831
|
+
| `SECURENOW_NO_UUID` | Set to `1` to disable UUID suffix on service name. Useful for clustered apps. | `0` |
|
|
832
|
+
| `SECURENOW_STRICT` | Set to `1` to exit process if SECURENOW_APPID is not set in cluster mode. | `0` |
|
|
833
|
+
|
|
834
|
+
#### Connection Settings
|
|
835
|
+
|
|
836
|
+
| Variable | Description | Default |
|
|
837
|
+
|----------|-------------|---------|
|
|
838
|
+
| `OTEL_EXPORTER_OTLP_ENDPOINT` | Alternative to SECURENOW_INSTANCE. Standard OpenTelemetry variable. | - |
|
|
839
|
+
| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | Override traces endpoint specifically. | `{SECURENOW_INSTANCE}/v1/traces` |
|
|
840
|
+
| `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` | Override logs endpoint specifically. | `{SECURENOW_INSTANCE}/v1/logs` |
|
|
841
|
+
| `OTEL_EXPORTER_OTLP_HEADERS` | Headers to send with OTLP exports. Format: `key1=value1,key2=value2` | - |
|
|
842
|
+
|
|
843
|
+
#### Logging
|
|
844
|
+
|
|
845
|
+
| Variable | Description | Default |
|
|
846
|
+
|----------|-------------|---------|
|
|
847
|
+
| `SECURENOW_LOGGING_ENABLED` | Enable automatic logging to OTLP backend. Set to `1` to enable, `0` to disable. | `1` |
|
|
848
|
+
|
|
849
|
+
#### Request Body Capture
|
|
850
|
+
|
|
851
|
+
| Variable | Description | Default |
|
|
852
|
+
|----------|-------------|---------|
|
|
853
|
+
| `SECURENOW_CAPTURE_BODY` | Enable request body capture in traces. Set to `1` to enable. | `0` |
|
|
854
|
+
| `SECURENOW_MAX_BODY_SIZE` | Maximum body size to capture in bytes. Bodies larger than this are truncated. | `10240` (10KB) |
|
|
855
|
+
| `SECURENOW_SENSITIVE_FIELDS` | Comma-separated list of additional field names to redact. | - |
|
|
856
|
+
|
|
857
|
+
**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`
|
|
858
|
+
|
|
859
|
+
#### Instrumentation Control
|
|
860
|
+
|
|
861
|
+
| Variable | Description | Default |
|
|
862
|
+
|----------|-------------|---------|
|
|
863
|
+
| `SECURENOW_DISABLE_INSTRUMENTATIONS` | Comma-separated list of instrumentation packages to disable. | - |
|
|
864
|
+
|
|
865
|
+
**Example:** `SECURENOW_DISABLE_INSTRUMENTATIONS=fs,dns` disables filesystem and DNS instrumentations.
|
|
866
|
+
|
|
867
|
+
#### Debugging
|
|
868
|
+
|
|
869
|
+
| Variable | Description | Default |
|
|
870
|
+
|----------|-------------|---------|
|
|
871
|
+
| `OTEL_LOG_LEVEL` | OpenTelemetry SDK log level. Options: `debug`, `info`, `warn`, `error` | `none` |
|
|
872
|
+
| `SECURENOW_TEST_SPAN` | Set to `1` to emit a test span on startup. | `0` |
|
|
873
|
+
|
|
874
|
+
#### Environment
|
|
875
|
+
|
|
876
|
+
| Variable | Description | Default |
|
|
877
|
+
|----------|-------------|---------|
|
|
878
|
+
| `NODE_ENV` | Deployment environment name. Sent as `deployment.environment` attribute. | `production` |
|
|
879
|
+
|
|
880
|
+
---
|
|
881
|
+
|
|
882
|
+
## Logging Setup
|
|
883
|
+
|
|
884
|
+
### Automatic Console Logging
|
|
885
|
+
|
|
886
|
+
Since **v5.6.0**, when `SECURENOW_LOGGING_ENABLED=1`, all console calls are automatically forwarded as OTLP log records:
|
|
887
|
+
|
|
888
|
+
```javascript
|
|
889
|
+
// At the top of your main file
|
|
890
|
+
require('securenow/register');
|
|
891
|
+
|
|
892
|
+
// With SECURENOW_LOGGING_ENABLED=1, all console logs are automatically sent
|
|
893
|
+
console.log('Application started');
|
|
894
|
+
console.info('User action', { userId: 123, action: 'login' });
|
|
895
|
+
console.warn('Deprecation warning');
|
|
896
|
+
console.error('Error occurred', { error: 'Something failed' });
|
|
897
|
+
console.debug('Debug info');
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
**Severity mapping:**
|
|
901
|
+
- `console.log()` → INFO
|
|
902
|
+
- `console.info()` → INFO
|
|
903
|
+
- `console.warn()` → WARN
|
|
904
|
+
- `console.error()` → ERROR
|
|
905
|
+
- `console.debug()` → DEBUG
|
|
906
|
+
|
|
907
|
+
**Environment variable:**
|
|
908
|
+
```bash
|
|
909
|
+
SECURENOW_LOGGING_ENABLED=1
|
|
910
|
+
```
|
|
911
|
+
|
|
912
|
+
### Direct Logger API
|
|
913
|
+
|
|
914
|
+
For more control, use the OpenTelemetry logger API:
|
|
915
|
+
|
|
916
|
+
```javascript
|
|
917
|
+
require('securenow/register');
|
|
918
|
+
const { getLogger } = require('securenow/tracing');
|
|
919
|
+
|
|
920
|
+
// Get a logger instance
|
|
921
|
+
const logger = getLogger('my-module', '1.0.0');
|
|
922
|
+
|
|
923
|
+
// Emit structured logs
|
|
924
|
+
logger.emit({
|
|
925
|
+
severityNumber: 9, // INFO
|
|
926
|
+
severityText: 'INFO',
|
|
927
|
+
body: 'User logged in',
|
|
928
|
+
attributes: {
|
|
929
|
+
userId: 123,
|
|
930
|
+
username: 'john',
|
|
931
|
+
sessionId: 'abc123',
|
|
932
|
+
},
|
|
933
|
+
});
|
|
934
|
+
```
|
|
935
|
+
|
|
936
|
+
**Severity numbers:**
|
|
937
|
+
- `5` - DEBUG
|
|
938
|
+
- `9` - INFO
|
|
939
|
+
- `13` - WARN
|
|
940
|
+
- `17` - ERROR
|
|
941
|
+
|
|
942
|
+
### Using with NODE_OPTIONS
|
|
943
|
+
|
|
944
|
+
```bash
|
|
945
|
+
# Enable tracing + logging (console auto-forwarding is built-in since v5.6.0)
|
|
946
|
+
NODE_OPTIONS="-r securenow/register" \
|
|
947
|
+
SECURENOW_APPID=my-app \
|
|
948
|
+
SECURENOW_INSTANCE=https://freetrial.securenow.ai:4318 \
|
|
949
|
+
SECURENOW_LOGGING_ENABLED=1 \
|
|
950
|
+
node app.js
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
---
|
|
954
|
+
|
|
955
|
+
## Request Body Capture
|
|
956
|
+
|
|
957
|
+
SecureNow can capture HTTP request bodies in traces for debugging purposes. This is disabled by default.
|
|
958
|
+
|
|
959
|
+
### Enable Body Capture
|
|
960
|
+
|
|
961
|
+
```bash
|
|
962
|
+
export SECURENOW_CAPTURE_BODY=1
|
|
963
|
+
export SECURENOW_MAX_BODY_SIZE=10240 # 10KB (optional)
|
|
964
|
+
```
|
|
965
|
+
|
|
966
|
+
### Supported Content Types
|
|
967
|
+
|
|
968
|
+
- `application/json`
|
|
969
|
+
- `application/x-www-form-urlencoded`
|
|
970
|
+
- `application/graphql`
|
|
971
|
+
|
|
972
|
+
**Note:** Multipart form data (file uploads) are NOT captured by design.
|
|
973
|
+
|
|
974
|
+
### Sensitive Data Redaction
|
|
975
|
+
|
|
976
|
+
All request bodies are automatically scanned and sensitive fields are redacted:
|
|
977
|
+
|
|
978
|
+
**Automatically redacted fields:** `password`, `secret`, `token`, `api_key`, `card`, `cvv`, `ssn`, and more.
|
|
979
|
+
|
|
980
|
+
**Add custom fields to redact:**
|
|
981
|
+
|
|
982
|
+
```bash
|
|
983
|
+
export SECURENOW_SENSITIVE_FIELDS="custom_secret,internal_token"
|
|
984
|
+
```
|
|
985
|
+
|
|
986
|
+
### Example
|
|
987
|
+
|
|
988
|
+
```javascript
|
|
989
|
+
// POST /api/users with body:
|
|
990
|
+
{
|
|
991
|
+
"email": "user@example.com",
|
|
992
|
+
"password": "secret123",
|
|
993
|
+
"name": "John Doe"
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
// Captured in trace as:
|
|
997
|
+
{
|
|
998
|
+
"email": "user@example.com",
|
|
999
|
+
"password": "[REDACTED]",
|
|
1000
|
+
"name": "John Doe"
|
|
1001
|
+
}
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
---
|
|
1005
|
+
|
|
1006
|
+
## Advanced Configuration
|
|
1007
|
+
|
|
1008
|
+
### Complete Example with All Options
|
|
1009
|
+
|
|
1010
|
+
```bash
|
|
1011
|
+
# Service identification
|
|
1012
|
+
export SECURENOW_APPID=my-production-app
|
|
1013
|
+
export SECURENOW_NO_UUID=1
|
|
1014
|
+
export SECURENOW_STRICT=1
|
|
1015
|
+
|
|
1016
|
+
# OTLP backend
|
|
1017
|
+
export SECURENOW_INSTANCE=http://collector.example.com:4318
|
|
1018
|
+
export OTEL_EXPORTER_OTLP_HEADERS="x-api-key=your-api-key"
|
|
1019
|
+
|
|
1020
|
+
# Logging
|
|
1021
|
+
export SECURENOW_LOGGING_ENABLED=1
|
|
1022
|
+
|
|
1023
|
+
# Request body capture
|
|
1024
|
+
export SECURENOW_CAPTURE_BODY=1
|
|
1025
|
+
export SECURENOW_MAX_BODY_SIZE=20480
|
|
1026
|
+
export SECURENOW_SENSITIVE_FIELDS="internal_id,session_key"
|
|
1027
|
+
|
|
1028
|
+
# Environment
|
|
1029
|
+
export NODE_ENV=production
|
|
1030
|
+
|
|
1031
|
+
# Debugging
|
|
1032
|
+
export OTEL_LOG_LEVEL=info
|
|
1033
|
+
|
|
1034
|
+
# Disable specific instrumentations
|
|
1035
|
+
export SECURENOW_DISABLE_INSTRUMENTATIONS=fs,dns
|
|
1036
|
+
|
|
1037
|
+
# Run application
|
|
1038
|
+
NODE_OPTIONS="-r securenow/register" node app.js
|
|
1039
|
+
```
|
|
1040
|
+
|
|
1041
|
+
### Using Multiple Logger Instances
|
|
1042
|
+
|
|
1043
|
+
```javascript
|
|
1044
|
+
const { getLogger } = require('securenow/tracing');
|
|
1045
|
+
|
|
1046
|
+
const authLogger = getLogger('auth-service', '1.0.0');
|
|
1047
|
+
const dbLogger = getLogger('database', '1.0.0');
|
|
1048
|
+
const apiLogger = getLogger('api-handler', '1.0.0');
|
|
1049
|
+
|
|
1050
|
+
authLogger.emit({
|
|
1051
|
+
severityNumber: 9,
|
|
1052
|
+
severityText: 'INFO',
|
|
1053
|
+
body: 'User authenticated',
|
|
1054
|
+
attributes: { userId: 123 },
|
|
1055
|
+
});
|
|
1056
|
+
|
|
1057
|
+
dbLogger.emit({
|
|
1058
|
+
severityNumber: 13,
|
|
1059
|
+
severityText: 'WARN',
|
|
1060
|
+
body: 'Slow query detected',
|
|
1061
|
+
attributes: { queryTime: 5000 },
|
|
1062
|
+
});
|
|
1063
|
+
```
|
|
1064
|
+
|
|
1065
|
+
### Check if Logging is Enabled
|
|
1066
|
+
|
|
1067
|
+
```javascript
|
|
1068
|
+
const { isLoggingEnabled } = require('securenow/tracing');
|
|
1069
|
+
|
|
1070
|
+
if (isLoggingEnabled()) {
|
|
1071
|
+
console.log('Logging is enabled');
|
|
1072
|
+
} else {
|
|
1073
|
+
console.log('Logging is disabled');
|
|
1074
|
+
}
|
|
1075
|
+
```
|
|
1076
|
+
|
|
1077
|
+
### Programmatic Configuration
|
|
1078
|
+
|
|
1079
|
+
While environment variables are recommended, you can also configure programmatically:
|
|
1080
|
+
|
|
1081
|
+
```javascript
|
|
1082
|
+
// Set environment variables before requiring securenow
|
|
1083
|
+
process.env.SECURENOW_APPID = 'my-app';
|
|
1084
|
+
process.env.SECURENOW_INSTANCE = 'http://localhost:4318';
|
|
1085
|
+
process.env.SECURENOW_LOGGING_ENABLED = '1';
|
|
1086
|
+
|
|
1087
|
+
// Then initialize (console log forwarding is automatic since v5.6.0)
|
|
1088
|
+
require('securenow/register');
|
|
1089
|
+
```
|
|
1090
|
+
|
|
1091
|
+
---
|
|
1092
|
+
|
|
1093
|
+
## TypeScript Support
|
|
1094
|
+
|
|
1095
|
+
SecureNow includes full TypeScript definitions.
|
|
1096
|
+
|
|
1097
|
+
### Type Definitions
|
|
1098
|
+
|
|
1099
|
+
```typescript
|
|
1100
|
+
import { getLogger, isLoggingEnabled, Logger, LogRecord } from 'securenow/tracing';
|
|
1101
|
+
|
|
1102
|
+
// Get a typed logger
|
|
1103
|
+
const logger: Logger | null = getLogger('my-service', '1.0.0');
|
|
1104
|
+
|
|
1105
|
+
// Emit a log with type checking
|
|
1106
|
+
if (logger) {
|
|
1107
|
+
const logRecord: LogRecord = {
|
|
1108
|
+
severityNumber: 9,
|
|
1109
|
+
severityText: 'INFO',
|
|
1110
|
+
body: 'User action',
|
|
1111
|
+
attributes: {
|
|
1112
|
+
userId: 123,
|
|
1113
|
+
action: 'login',
|
|
1114
|
+
},
|
|
1115
|
+
};
|
|
1116
|
+
|
|
1117
|
+
logger.emit(logRecord);
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
// Check if enabled
|
|
1121
|
+
const enabled: boolean = isLoggingEnabled();
|
|
1122
|
+
```
|
|
1123
|
+
|
|
1124
|
+
### Next.js with TypeScript
|
|
1125
|
+
|
|
1126
|
+
```typescript
|
|
1127
|
+
// instrumentation.ts
|
|
1128
|
+
export async function register() {
|
|
1129
|
+
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
|
1130
|
+
process.env.SECURENOW_LOGGING_ENABLED = '1';
|
|
1131
|
+
|
|
1132
|
+
await import('securenow/register');
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
```
|
|
1136
|
+
|
|
1137
|
+
### NestJS with TypeScript
|
|
1138
|
+
|
|
1139
|
+
Use `-r securenow/register -r ts-node/register` flags instead of in-code require:
|
|
1140
|
+
|
|
1141
|
+
```typescript
|
|
1142
|
+
// main.ts (run with: node -r securenow/register -r ts-node/register main.ts)
|
|
1143
|
+
import { NestFactory } from '@nestjs/core';
|
|
1144
|
+
import { AppModule } from './app.module';
|
|
1145
|
+
|
|
1146
|
+
async function bootstrap() {
|
|
1147
|
+
const app = await NestFactory.create(AppModule);
|
|
1148
|
+
await app.listen(3000);
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
bootstrap();
|
|
1152
|
+
```
|
|
1153
|
+
|
|
1154
|
+
---
|
|
1155
|
+
|
|
1156
|
+
## Troubleshooting
|
|
1157
|
+
|
|
1158
|
+
### Traces Not Appearing
|
|
1159
|
+
|
|
1160
|
+
**Check 1: Verify environment variables**
|
|
1161
|
+
|
|
1162
|
+
```bash
|
|
1163
|
+
echo $SECURENOW_APPID
|
|
1164
|
+
echo $SECURENOW_INSTANCE
|
|
1165
|
+
```
|
|
1166
|
+
|
|
1167
|
+
Both should output values.
|
|
1168
|
+
|
|
1169
|
+
**Check 2: Verify OTLP collector is running**
|
|
1170
|
+
|
|
1171
|
+
```bash
|
|
1172
|
+
curl http://localhost:4318/v1/traces
|
|
1173
|
+
# Should return 200 or 405 (method not allowed)
|
|
1174
|
+
```
|
|
1175
|
+
|
|
1176
|
+
**Check 3: Enable debug logging**
|
|
1177
|
+
|
|
1178
|
+
```bash
|
|
1179
|
+
export OTEL_LOG_LEVEL=debug
|
|
1180
|
+
node app.js
|
|
1181
|
+
```
|
|
1182
|
+
|
|
1183
|
+
Look for lines like:
|
|
1184
|
+
```
|
|
1185
|
+
[securenow] OTel SDK started → http://localhost:4318/v1/traces
|
|
1186
|
+
```
|
|
1187
|
+
|
|
1188
|
+
**Check 4: Verify initialization order**
|
|
1189
|
+
|
|
1190
|
+
SecureNow must be required BEFORE any other modules:
|
|
1191
|
+
|
|
1192
|
+
```javascript
|
|
1193
|
+
// ✅ Correct
|
|
1194
|
+
require('securenow/register');
|
|
1195
|
+
const express = require('express');
|
|
1196
|
+
|
|
1197
|
+
// ❌ Wrong - too late!
|
|
1198
|
+
const express = require('express');
|
|
1199
|
+
require('securenow/register');
|
|
1200
|
+
```
|
|
1201
|
+
|
|
1202
|
+
### Logs Not Appearing
|
|
1203
|
+
|
|
1204
|
+
**Check 1: Is logging enabled?**
|
|
1205
|
+
|
|
1206
|
+
```bash
|
|
1207
|
+
echo $SECURENOW_LOGGING_ENABLED
|
|
1208
|
+
# Should output: 1
|
|
1209
|
+
```
|
|
1210
|
+
|
|
1211
|
+
**Check 2: Verify console instrumentation is loaded**
|
|
1212
|
+
|
|
1213
|
+
```javascript
|
|
1214
|
+
require('securenow/register');
|
|
1215
|
+
```
|
|
1216
|
+
|
|
1217
|
+
**Check 3: Check console output**
|
|
1218
|
+
|
|
1219
|
+
You should see:
|
|
1220
|
+
```
|
|
1221
|
+
[securenow] 📋 Logging: ENABLED → http://localhost:4318/v1/logs
|
|
1222
|
+
```
|
|
1223
|
+
|
|
1224
|
+
**Check 4: Verify OTLP logs endpoint**
|
|
1225
|
+
|
|
1226
|
+
```bash
|
|
1227
|
+
curl http://localhost:4318/v1/logs
|
|
1228
|
+
# Should return 200 or 405
|
|
1229
|
+
```
|
|
1230
|
+
|
|
1231
|
+
### Request Body Not Captured
|
|
1232
|
+
|
|
1233
|
+
**Check 1: Is body capture enabled?**
|
|
1234
|
+
|
|
1235
|
+
```bash
|
|
1236
|
+
export SECURENOW_CAPTURE_BODY=1
|
|
1237
|
+
```
|
|
1238
|
+
|
|
1239
|
+
**Check 2: Verify content type**
|
|
1240
|
+
|
|
1241
|
+
Body capture only works for:
|
|
1242
|
+
- `application/json`
|
|
1243
|
+
- `application/x-www-form-urlencoded`
|
|
1244
|
+
- `application/graphql`
|
|
1245
|
+
|
|
1246
|
+
**Check 3: Check body size**
|
|
1247
|
+
|
|
1248
|
+
Bodies larger than `SECURENOW_MAX_BODY_SIZE` are truncated:
|
|
1249
|
+
|
|
1250
|
+
```bash
|
|
1251
|
+
export SECURENOW_MAX_BODY_SIZE=20480 # Increase to 20KB
|
|
1252
|
+
```
|
|
1253
|
+
|
|
1254
|
+
### High Memory Usage
|
|
1255
|
+
|
|
1256
|
+
**Option 1: Disable body capture**
|
|
1257
|
+
|
|
1258
|
+
```bash
|
|
1259
|
+
export SECURENOW_CAPTURE_BODY=0
|
|
1260
|
+
```
|
|
1261
|
+
|
|
1262
|
+
**Option 2: Reduce body size limit**
|
|
1263
|
+
|
|
1264
|
+
```bash
|
|
1265
|
+
export SECURENOW_MAX_BODY_SIZE=5120 # 5KB
|
|
1266
|
+
```
|
|
1267
|
+
|
|
1268
|
+
**Option 3: Disable specific instrumentations**
|
|
1269
|
+
|
|
1270
|
+
```bash
|
|
1271
|
+
export SECURENOW_DISABLE_INSTRUMENTATIONS=fs,dns,net
|
|
1272
|
+
```
|
|
1273
|
+
|
|
1274
|
+
### Next.js Instrumentation Not Working
|
|
1275
|
+
|
|
1276
|
+
**Check 1: Verify instrumentation file location**
|
|
1277
|
+
|
|
1278
|
+
`instrumentation.ts` or `instrumentation.js` must be in the project root (same level as `app/` or `pages/`).
|
|
1279
|
+
|
|
1280
|
+
**Check 2: Enable instrumentation hook**
|
|
1281
|
+
|
|
1282
|
+
```javascript
|
|
1283
|
+
// next.config.js
|
|
1284
|
+
module.exports = {
|
|
1285
|
+
experimental: {
|
|
1286
|
+
instrumentationHook: true,
|
|
1287
|
+
},
|
|
1288
|
+
};
|
|
1289
|
+
```
|
|
1290
|
+
|
|
1291
|
+
**Check 3: Restart dev server**
|
|
1292
|
+
|
|
1293
|
+
```bash
|
|
1294
|
+
# Kill the server and restart
|
|
1295
|
+
npm run dev
|
|
1296
|
+
```
|
|
1297
|
+
|
|
1298
|
+
### PM2 Cluster Issues
|
|
1299
|
+
|
|
1300
|
+
**Problem: Different service names for each worker**
|
|
1301
|
+
|
|
1302
|
+
**Solution: Use SECURENOW_NO_UUID**
|
|
1303
|
+
|
|
1304
|
+
```bash
|
|
1305
|
+
export SECURENOW_NO_UUID=1
|
|
1306
|
+
```
|
|
1307
|
+
|
|
1308
|
+
This uses the same service name for all workers.
|
|
1309
|
+
|
|
1310
|
+
**Problem: Workers not instrumented**
|
|
1311
|
+
|
|
1312
|
+
**Solution: Use node_args in PM2 config**
|
|
1313
|
+
|
|
1314
|
+
```javascript
|
|
1315
|
+
// ecosystem.config.js
|
|
1316
|
+
module.exports = {
|
|
1317
|
+
apps: [{
|
|
1318
|
+
name: 'my-app',
|
|
1319
|
+
script: './app.js',
|
|
1320
|
+
instances: 4,
|
|
1321
|
+
node_args: '-r securenow/register',
|
|
1322
|
+
env: {
|
|
1323
|
+
SECURENOW_APPID: 'my-app',
|
|
1324
|
+
SECURENOW_INSTANCE: 'http://localhost:4318',
|
|
1325
|
+
}
|
|
1326
|
+
}]
|
|
1327
|
+
};
|
|
1328
|
+
```
|
|
1329
|
+
|
|
1330
|
+
---
|
|
1331
|
+
|
|
1332
|
+
## Best Practices
|
|
1333
|
+
|
|
1334
|
+
### 1. Use Environment Variables
|
|
1335
|
+
|
|
1336
|
+
Don't hardcode configuration. Use environment variables:
|
|
1337
|
+
|
|
1338
|
+
```javascript
|
|
1339
|
+
// ❌ Bad
|
|
1340
|
+
process.env.SECURENOW_APPID = 'hardcoded-value';
|
|
1341
|
+
|
|
1342
|
+
// ✅ Good - use .env file or export
|
|
1343
|
+
// .env
|
|
1344
|
+
SECURENOW_APPID=my-app
|
|
1345
|
+
SECURENOW_INSTANCE=http://localhost:4318
|
|
1346
|
+
```
|
|
1347
|
+
|
|
1348
|
+
### 2. Use Structured Logging
|
|
1349
|
+
|
|
1350
|
+
Pass objects to console methods for better filtering:
|
|
1351
|
+
|
|
1352
|
+
```javascript
|
|
1353
|
+
// ❌ Less useful
|
|
1354
|
+
console.log('User 123 logged in');
|
|
1355
|
+
|
|
1356
|
+
// ✅ Better - structured attributes
|
|
1357
|
+
console.log('User logged in', {
|
|
1358
|
+
userId: 123,
|
|
1359
|
+
email: 'user@example.com',
|
|
1360
|
+
timestamp: new Date().toISOString(),
|
|
1361
|
+
});
|
|
1362
|
+
```
|
|
1363
|
+
|
|
1364
|
+
### 3. Choose Appropriate Severity Levels
|
|
1365
|
+
|
|
1366
|
+
```javascript
|
|
1367
|
+
// Normal operations
|
|
1368
|
+
console.log('Request processed');
|
|
1369
|
+
console.info('User created', { userId: 123 });
|
|
1370
|
+
|
|
1371
|
+
// Warnings
|
|
1372
|
+
console.warn('API rate limit approaching', { remaining: 10 });
|
|
1373
|
+
|
|
1374
|
+
// Errors
|
|
1375
|
+
console.error('Database connection failed', { error: err.message });
|
|
1376
|
+
|
|
1377
|
+
// Debug (only in development)
|
|
1378
|
+
console.debug('Cache hit', { key: 'user:123' });
|
|
1379
|
+
```
|
|
1380
|
+
|
|
1381
|
+
### 4. Don't Log Sensitive Data
|
|
1382
|
+
|
|
1383
|
+
Even though SecureNow automatically redacts common sensitive fields, avoid logging:
|
|
1384
|
+
|
|
1385
|
+
```javascript
|
|
1386
|
+
// ❌ Bad
|
|
1387
|
+
console.log('Login attempt', {
|
|
1388
|
+
email: 'user@example.com',
|
|
1389
|
+
password: 'secret123', // Will be redacted, but don't log it!
|
|
1390
|
+
});
|
|
1391
|
+
|
|
1392
|
+
// ✅ Good
|
|
1393
|
+
console.log('Login attempt', {
|
|
1394
|
+
email: 'user@example.com',
|
|
1395
|
+
timestamp: Date.now(),
|
|
1396
|
+
});
|
|
1397
|
+
```
|
|
1398
|
+
|
|
1399
|
+
### 5. Use Different Logger Instances for Different Modules
|
|
1400
|
+
|
|
1401
|
+
```javascript
|
|
1402
|
+
// auth-service.js
|
|
1403
|
+
const authLogger = getLogger('auth-service', '1.0.0');
|
|
1404
|
+
|
|
1405
|
+
// database.js
|
|
1406
|
+
const dbLogger = getLogger('database', '1.0.0');
|
|
1407
|
+
|
|
1408
|
+
// api.js
|
|
1409
|
+
const apiLogger = getLogger('api', '1.0.0');
|
|
1410
|
+
```
|
|
1411
|
+
|
|
1412
|
+
### 6. Enable Body Capture Only in Development
|
|
1413
|
+
|
|
1414
|
+
```bash
|
|
1415
|
+
# .env.development
|
|
1416
|
+
SECURENOW_CAPTURE_BODY=1
|
|
1417
|
+
|
|
1418
|
+
# .env.production
|
|
1419
|
+
SECURENOW_CAPTURE_BODY=0
|
|
1420
|
+
```
|
|
1421
|
+
|
|
1422
|
+
---
|
|
1423
|
+
|
|
1424
|
+
## Supported Runtimes
|
|
1425
|
+
|
|
1426
|
+
- **Node.js:** 18+
|
|
1427
|
+
- **Frameworks:** Express, Next.js, Fastify, NestJS, Koa, Hapi, and more
|
|
1428
|
+
- **Databases:** PostgreSQL, MySQL, MongoDB, Redis
|
|
1429
|
+
- **HTTP Clients:** axios, fetch, node-fetch, got, request
|
|
1430
|
+
- **GraphQL:** Apollo Server, GraphQL.js
|
|
1431
|
+
- **Message Queues:** Redis, BullMQ
|
|
1432
|
+
- **And many more via OpenTelemetry auto-instrumentation**
|
|
1433
|
+
|
|
1434
|
+
---
|
|
1435
|
+
|
|
1436
|
+
## Automatic Instrumentations
|
|
1437
|
+
|
|
1438
|
+
SecureNow automatically instruments:
|
|
1439
|
+
|
|
1440
|
+
- HTTP/HTTPS (incoming and outgoing)
|
|
1441
|
+
- Express.js
|
|
1442
|
+
- Fastify
|
|
1443
|
+
- Koa
|
|
1444
|
+
- Hapi
|
|
1445
|
+
- Next.js
|
|
1446
|
+
- PostgreSQL
|
|
1447
|
+
- MySQL/MySQL2
|
|
1448
|
+
- MongoDB
|
|
1449
|
+
- Redis
|
|
1450
|
+
- GraphQL
|
|
1451
|
+
- gRPC
|
|
1452
|
+
- DNS
|
|
1453
|
+
- File System
|
|
1454
|
+
- And 50+ more libraries
|
|
1455
|
+
|
|
1456
|
+
No code changes needed!
|
|
1457
|
+
|
|
1458
|
+
---
|
|
1459
|
+
|
|
1460
|
+
## Architecture
|
|
1461
|
+
|
|
1462
|
+
```
|
|
1463
|
+
┌─────────────────────────────────┐
|
|
1464
|
+
│ Your Application │
|
|
1465
|
+
│ (Express/Next.js/etc) │
|
|
1466
|
+
└───────────────┬─────────────────┘
|
|
1467
|
+
│
|
|
1468
|
+
▼
|
|
1469
|
+
┌─────────────────────────────────┐
|
|
1470
|
+
│ SecureNow Library │
|
|
1471
|
+
│ - Auto-instrumentation │
|
|
1472
|
+
│ - Console wrapper (optional) │
|
|
1473
|
+
│ - Body capture (optional) │
|
|
1474
|
+
└───────────────┬─────────────────┘
|
|
1475
|
+
│
|
|
1476
|
+
▼
|
|
1477
|
+
┌─────────────────────────────────┐
|
|
1478
|
+
│ OpenTelemetry SDK │
|
|
1479
|
+
│ - Trace/Log processors │
|
|
1480
|
+
│ - OTLP exporters │
|
|
1481
|
+
└───────────────┬─────────────────┘
|
|
1482
|
+
│
|
|
1483
|
+
▼
|
|
1484
|
+
┌─────────────────────────────────┐
|
|
1485
|
+
│ OTLP Collector/Backend │
|
|
1486
|
+
│ (Your observability platform) │
|
|
1487
|
+
└─────────────────────────────────┘
|
|
1488
|
+
```
|
|
1489
|
+
|
|
1490
|
+
---
|
|
1491
|
+
|
|
1492
|
+
## Performance
|
|
1493
|
+
|
|
1494
|
+
- **Minimal overhead:** < 1% CPU and memory impact
|
|
1495
|
+
- **Batch export:** Traces and logs are batched before sending
|
|
1496
|
+
- **Async processing:** No blocking of application threads
|
|
1497
|
+
- **Configurable:** Disable instrumentations you don't need
|
|
1498
|
+
|
|
1499
|
+
---
|
|
1500
|
+
|
|
1501
|
+
## Security
|
|
1502
|
+
|
|
1503
|
+
- **Automatic redaction** of sensitive fields (passwords, tokens, keys)
|
|
1504
|
+
- **Configurable** sensitive field patterns
|
|
1505
|
+
- **No data stored** locally - everything sent to your OTLP backend
|
|
1506
|
+
- **Open source** - audit the code yourself
|
|
1507
|
+
|
|
1508
|
+
---
|
|
1509
|
+
|
|
1510
|
+
## License
|
|
1511
|
+
|
|
1512
|
+
ISC
|
|
1513
|
+
|
|
1514
|
+
---
|
|
1515
|
+
|
|
1516
|
+
## Support
|
|
1517
|
+
|
|
1518
|
+
- **Documentation:** [GitHub Docs](https://github.com/your-repo/securenow-npm/tree/main/docs)
|
|
1519
|
+
- **Issues:** [GitHub Issues](https://github.com/your-repo/securenow-npm/issues)
|
|
1520
|
+
- **Examples:** [GitHub Examples](https://github.com/your-repo/securenow-npm/tree/main/examples)
|
|
1521
|
+
|
|
1522
|
+
---
|
|
1523
|
+
|
|
1524
|
+
## Changelog
|
|
1525
|
+
|
|
1526
|
+
See [CHANGELOG.md](CHANGELOG.md) for version history.
|
|
1527
|
+
|
|
1528
|
+
---
|
|
1529
|
+
|
|
1530
|
+
## Contributing
|
|
1531
|
+
|
|
1532
|
+
Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
1533
|
+
|
|
1534
|
+
---
|
|
1535
|
+
|
|
1536
|
+
## Related Packages
|
|
1537
|
+
|
|
1538
|
+
- [@opentelemetry/sdk-node](https://www.npmjs.com/package/@opentelemetry/sdk-node) - Core OpenTelemetry SDK
|
|
1539
|
+
- [@opentelemetry/auto-instrumentations-node](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node) - Auto-instrumentation
|
|
1540
|
+
- [@opentelemetry/exporter-trace-otlp-http](https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-http) - OTLP exporter
|
|
1541
|
+
|
|
1542
|
+
---
|
|
1543
|
+
|
|
1544
|
+
**Made with ❤️ for the Node.js community**
|