unnbound-logger-sdk 2.0.6 → 2.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -6
- package/dist/types.d.ts +1 -0
- package/dist/unnbound-logger.d.ts +2 -0
- package/dist/unnbound-logger.js +27 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -52,7 +52,8 @@ interface Log<T extends LogType = 'general'> {
|
|
|
52
52
|
level: LogLevel; // "info" | "debug" | "error" | "warn"
|
|
53
53
|
type: T; // "general" | "httpRequest" | "httpResponse" | "sftpTransaction" | "dbQueryTransaction"
|
|
54
54
|
message: string;
|
|
55
|
-
workflowId: string;
|
|
55
|
+
workflowId: string;
|
|
56
|
+
serviceId: string;
|
|
56
57
|
traceId: string;
|
|
57
58
|
requestId: string;
|
|
58
59
|
deploymentId: string; // Automatically populated from UNNBOUND_DEPLOYMENT_ID
|
|
@@ -73,15 +74,18 @@ The logger includes a `workflowId` field in all log entries for tracking operati
|
|
|
73
74
|
```bash
|
|
74
75
|
# Set the workflow ID in your environment
|
|
75
76
|
export UNNBOUND_WORKFLOW_ID="order-processing-12345"
|
|
77
|
+
export UNNBOUND_WORKFLOW_URL="https://workflows.example.com/order-processing-12345"
|
|
78
|
+
export UNNBOUND_SERVICE_ID="order-service"
|
|
76
79
|
|
|
77
80
|
# Or in your deployment configuration
|
|
78
81
|
UNNBOUND_WORKFLOW_ID=order-processing-12345
|
|
82
|
+
UNNBOUND_WORKFLOW_URL=https://workflows.example.com/order-processing-12345
|
|
83
|
+
UNNBOUND_SERVICE_ID=order-service
|
|
79
84
|
```
|
|
80
85
|
|
|
81
86
|
```typescript
|
|
82
|
-
// Create a logger - workflowId
|
|
87
|
+
// Create a logger - workflowId and serviceId are automatically set from environment
|
|
83
88
|
const logger = new UnnboundLogger();
|
|
84
|
-
// All logs will include the workflowId from UNNBOUND_WORKFLOW_ID environment variable
|
|
85
89
|
```
|
|
86
90
|
|
|
87
91
|
### Deployment Tracking
|
|
@@ -98,8 +102,10 @@ UNNBOUND_DEPLOYMENT_ID=v1.2.3-prod-20231201
|
|
|
98
102
|
|
|
99
103
|
If the environment variables are not set, the fields will be empty strings. These fields help with:
|
|
100
104
|
|
|
101
|
-
- **Workflow ID**: Unique identifier for the workflow
|
|
102
|
-
- **
|
|
105
|
+
- **Workflow ID**: Unique identifier for the workflow (logged in each entry)
|
|
106
|
+
- **Workflow URL**: Used internally for URL construction in webhook endpoints (not logged as a field)
|
|
107
|
+
- **Service ID**: Identifier for the specific service/component (logged in each entry)
|
|
108
|
+
- **Deployment ID**: Tracking logs across different application deployments (logged in each entry)
|
|
103
109
|
- **Correlating issues**: Link problems to specific workflows and releases
|
|
104
110
|
- **Monitoring**: Track health and performance across workflows and deployments
|
|
105
111
|
|
|
@@ -146,6 +152,46 @@ The logger automatically captures:
|
|
|
146
152
|
- Request duration
|
|
147
153
|
- Trace ID and request ID for correlation
|
|
148
154
|
|
|
155
|
+
### Full URL Logging for Webhook Endpoints
|
|
156
|
+
|
|
157
|
+
When webhook endpoints receive incoming requests, the logger automatically constructs and logs the full URL using a smart fallback strategy:
|
|
158
|
+
|
|
159
|
+
1. **Preferred: Uses `UNNBOUND_WORKFLOW_URL`** - If set, this becomes the base URL for all logged requests
|
|
160
|
+
2. **Fallback: Constructs from request headers** - Uses protocol, host, and forwarded headers from the incoming request
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
# Set your workflow URL to ensure full URLs in logs
|
|
164
|
+
export UNNBOUND_WORKFLOW_URL="https://api.yourservice.com"
|
|
165
|
+
|
|
166
|
+
# Example webhook endpoints will be logged as:
|
|
167
|
+
# POST https://api.yourservice.com/webhooks/stripe
|
|
168
|
+
# POST https://api.yourservice.com/webhooks/github
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
import express from 'express';
|
|
173
|
+
import { UnnboundLogger } from 'unnbound-logger';
|
|
174
|
+
|
|
175
|
+
const app = express();
|
|
176
|
+
const logger = new UnnboundLogger();
|
|
177
|
+
|
|
178
|
+
// Apply trace middleware for automatic logging
|
|
179
|
+
app.use(logger.traceMiddleware);
|
|
180
|
+
|
|
181
|
+
// Webhook endpoints - URLs automatically logged with full domain
|
|
182
|
+
app.post('/webhooks/stripe', (req, res) => {
|
|
183
|
+
// Request logged as: https://api.yourservice.com/webhooks/stripe
|
|
184
|
+
res.status(200).send('OK');
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
app.post('/webhooks/github', (req, res) => {
|
|
188
|
+
// Request logged as: https://api.yourservice.com/webhooks/github
|
|
189
|
+
res.status(200).send('OK');
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
This ensures webhook logs contain the complete URL for easy debugging and monitoring.
|
|
194
|
+
|
|
149
195
|
## SFTP Transaction Logging
|
|
150
196
|
|
|
151
197
|
For logging SFTP operations:
|
|
@@ -353,7 +399,7 @@ new UnnboundLogger(options?: LoggerOptions)
|
|
|
353
399
|
- `ignoreTraceRoutes?: string[]` - Routes to ignore in Express middleware
|
|
354
400
|
- `ignoreAxiosTraceRoutes?: string[]` - Routes to ignore in Axios middleware
|
|
355
401
|
|
|
356
|
-
**Note:** `workflowId` and `deploymentId` are configured via environment variables (`UNNBOUND_WORKFLOW_ID`, `UNNBOUND_DEPLOYMENT_ID`).
|
|
402
|
+
**Note:** `workflowId`, `serviceId`, and `deploymentId` are configured via environment variables (`UNNBOUND_WORKFLOW_ID`, `UNNBOUND_SERVICE_ID`, `UNNBOUND_DEPLOYMENT_ID`). The `UNNBOUND_WORKFLOW_URL` is used for URL construction in webhook endpoints.
|
|
357
403
|
|
|
358
404
|
#### Methods
|
|
359
405
|
|
package/dist/types.d.ts
CHANGED
package/dist/unnbound-logger.js
CHANGED
|
@@ -169,6 +169,8 @@ class UnnboundLogger {
|
|
|
169
169
|
}
|
|
170
170
|
};
|
|
171
171
|
this.workflowId = process.env.UNNBOUND_WORKFLOW_ID || '';
|
|
172
|
+
this.workflowUrl = process.env.UNNBOUND_WORKFLOW_URL || '';
|
|
173
|
+
this.serviceId = process.env.UNNBOUND_SERVICE_ID || '';
|
|
172
174
|
this.deploymentId = process.env.UNNBOUND_DEPLOYMENT_ID || '';
|
|
173
175
|
this.traceHeaderKey = options.traceHeaderKey || 'unnbound-trace-id';
|
|
174
176
|
this.ignoreTraceRoutes = options.ignoreTraceRoutes || [];
|
|
@@ -178,6 +180,7 @@ class UnnboundLogger {
|
|
|
178
180
|
level: 'info',
|
|
179
181
|
base: {}, // Disable all default base fields (pid, hostname)
|
|
180
182
|
timestamp: false, // Let CloudWatch handle timestamps
|
|
183
|
+
messageKey: 'messages', // Change message field from 'msg' to 'messages'
|
|
181
184
|
formatters: {
|
|
182
185
|
level: (label) => {
|
|
183
186
|
return { level: label };
|
|
@@ -218,6 +221,7 @@ class UnnboundLogger {
|
|
|
218
221
|
logId,
|
|
219
222
|
type: 'general',
|
|
220
223
|
workflowId: this.workflowId,
|
|
224
|
+
serviceId: this.serviceId,
|
|
221
225
|
traceId,
|
|
222
226
|
requestId,
|
|
223
227
|
deploymentId: this.deploymentId,
|
|
@@ -299,11 +303,10 @@ class UnnboundLogger {
|
|
|
299
303
|
if (reqUrl?.startsWith('http://') || reqUrl?.startsWith('https://')) {
|
|
300
304
|
return reqUrl;
|
|
301
305
|
}
|
|
302
|
-
// Check if we have a
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
return `${serviceBaseUrl.replace(/\/$/, '')}${reqUrl}`;
|
|
306
|
+
// Check if we have a workflow URL configured (preferred method)
|
|
307
|
+
if (this.workflowUrl) {
|
|
308
|
+
// Use workflow URL as the base URL
|
|
309
|
+
return `${this.workflowUrl.replace(/\/$/, '')}${reqUrl}`;
|
|
307
310
|
}
|
|
308
311
|
// Fallback to constructing from request info for incoming requests
|
|
309
312
|
const protocol = req.protocol || (req.secure ? 'https' : 'http');
|
|
@@ -327,12 +330,15 @@ class UnnboundLogger {
|
|
|
327
330
|
req.res.locals.startTime = startTime;
|
|
328
331
|
req.res.locals.traceId = traceId;
|
|
329
332
|
req.res.locals.workflowId = this.workflowId;
|
|
333
|
+
req.res.locals.workflowUrl = this.workflowUrl;
|
|
334
|
+
req.res.locals.serviceId = this.serviceId;
|
|
330
335
|
}
|
|
331
336
|
const logEntry = {
|
|
332
337
|
logId,
|
|
333
338
|
type: 'httpRequest',
|
|
334
339
|
message: req.ip === 'outgoing' ? 'Outgoing HTTP Request' : 'Incoming HTTP Request',
|
|
335
340
|
workflowId: this.workflowId,
|
|
341
|
+
serviceId: this.serviceId,
|
|
336
342
|
traceId,
|
|
337
343
|
requestId,
|
|
338
344
|
deploymentId: this.deploymentId,
|
|
@@ -345,8 +351,9 @@ class UnnboundLogger {
|
|
|
345
351
|
body: (0, logger_utils_1.safeJsonParse)(req.body),
|
|
346
352
|
},
|
|
347
353
|
};
|
|
348
|
-
const
|
|
349
|
-
|
|
354
|
+
const { message: logMessage, ...logData } = logEntry;
|
|
355
|
+
this.logger[options.level || 'info'](logData, logMessage);
|
|
356
|
+
return logEntry;
|
|
350
357
|
}
|
|
351
358
|
/**
|
|
352
359
|
* Logs an HTTP response
|
|
@@ -359,6 +366,7 @@ class UnnboundLogger {
|
|
|
359
366
|
const requestId = res.locals.requestId || options.requestId || (0, uuid_1.v4)();
|
|
360
367
|
const startTime = res.locals.startTime || options.startTime || Date.now();
|
|
361
368
|
const workflowId = res.locals.workflowId || this.workflowId;
|
|
369
|
+
const serviceId = res.locals.serviceId || this.serviceId;
|
|
362
370
|
const traceId = res.locals.traceId || options.traceId || trace_context_1.traceContext.getTraceId() || (0, uuid_1.v4)();
|
|
363
371
|
const duration = options.duration || (Date.now() - startTime);
|
|
364
372
|
// Determine log level based on status code
|
|
@@ -376,6 +384,7 @@ class UnnboundLogger {
|
|
|
376
384
|
type: 'httpResponse',
|
|
377
385
|
message: (0, http_status_messages_1.getStatusMessage)(res.statusCode),
|
|
378
386
|
workflowId: workflowId || '',
|
|
387
|
+
serviceId: serviceId || '',
|
|
379
388
|
traceId,
|
|
380
389
|
requestId,
|
|
381
390
|
deploymentId: this.deploymentId,
|
|
@@ -389,8 +398,9 @@ class UnnboundLogger {
|
|
|
389
398
|
body: (0, logger_utils_1.safeJsonParse)(res.locals.body),
|
|
390
399
|
},
|
|
391
400
|
};
|
|
392
|
-
const
|
|
393
|
-
|
|
401
|
+
const { message: logMessage, ...logData } = logEntry;
|
|
402
|
+
this.logger[level](logData, logMessage);
|
|
403
|
+
return logEntry;
|
|
394
404
|
}
|
|
395
405
|
/**
|
|
396
406
|
* Logs an SFTP transaction
|
|
@@ -408,14 +418,16 @@ class UnnboundLogger {
|
|
|
408
418
|
type: 'sftpTransaction',
|
|
409
419
|
message: `SFTP ${operation.operation} ${operation.status} - ${operation.path}`,
|
|
410
420
|
workflowId: this.workflowId,
|
|
421
|
+
serviceId: this.serviceId,
|
|
411
422
|
traceId,
|
|
412
423
|
requestId,
|
|
413
424
|
deploymentId: this.deploymentId,
|
|
414
425
|
duration,
|
|
415
426
|
sftp: operation,
|
|
416
427
|
};
|
|
417
|
-
const
|
|
418
|
-
|
|
428
|
+
const { message: logMessage, ...logData } = logEntry;
|
|
429
|
+
this.logger[level](logData, logMessage);
|
|
430
|
+
return logEntry;
|
|
419
431
|
}
|
|
420
432
|
/**
|
|
421
433
|
* Logs a database query transaction
|
|
@@ -433,14 +445,16 @@ class UnnboundLogger {
|
|
|
433
445
|
type: 'dbQueryTransaction',
|
|
434
446
|
message: `DB Query ${query.status} - ${query.vendor}`,
|
|
435
447
|
workflowId: this.workflowId,
|
|
448
|
+
serviceId: this.serviceId,
|
|
436
449
|
traceId,
|
|
437
450
|
requestId,
|
|
438
451
|
deploymentId: this.deploymentId,
|
|
439
452
|
duration,
|
|
440
453
|
db: query,
|
|
441
454
|
};
|
|
442
|
-
const
|
|
443
|
-
|
|
455
|
+
const { message: logMessage, ...logData } = logEntry;
|
|
456
|
+
this.logger[level](logData, logMessage);
|
|
457
|
+
return logEntry;
|
|
444
458
|
}
|
|
445
459
|
}
|
|
446
460
|
exports.UnnboundLogger = UnnboundLogger;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unnbound-logger-sdk",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.8",
|
|
4
4
|
"description": "A structured logging library with TypeScript support using Pino. Provides consistent, well-typed logging with automatic logId, workflowId, traceId, and deploymentId tracking across operational contexts.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|