unnbound-logger-sdk 2.0.7 → 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 +26 -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 || [];
|
|
@@ -219,6 +221,7 @@ class UnnboundLogger {
|
|
|
219
221
|
logId,
|
|
220
222
|
type: 'general',
|
|
221
223
|
workflowId: this.workflowId,
|
|
224
|
+
serviceId: this.serviceId,
|
|
222
225
|
traceId,
|
|
223
226
|
requestId,
|
|
224
227
|
deploymentId: this.deploymentId,
|
|
@@ -300,11 +303,10 @@ class UnnboundLogger {
|
|
|
300
303
|
if (reqUrl?.startsWith('http://') || reqUrl?.startsWith('https://')) {
|
|
301
304
|
return reqUrl;
|
|
302
305
|
}
|
|
303
|
-
// Check if we have a
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
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}`;
|
|
308
310
|
}
|
|
309
311
|
// Fallback to constructing from request info for incoming requests
|
|
310
312
|
const protocol = req.protocol || (req.secure ? 'https' : 'http');
|
|
@@ -328,12 +330,15 @@ class UnnboundLogger {
|
|
|
328
330
|
req.res.locals.startTime = startTime;
|
|
329
331
|
req.res.locals.traceId = traceId;
|
|
330
332
|
req.res.locals.workflowId = this.workflowId;
|
|
333
|
+
req.res.locals.workflowUrl = this.workflowUrl;
|
|
334
|
+
req.res.locals.serviceId = this.serviceId;
|
|
331
335
|
}
|
|
332
336
|
const logEntry = {
|
|
333
337
|
logId,
|
|
334
338
|
type: 'httpRequest',
|
|
335
339
|
message: req.ip === 'outgoing' ? 'Outgoing HTTP Request' : 'Incoming HTTP Request',
|
|
336
340
|
workflowId: this.workflowId,
|
|
341
|
+
serviceId: this.serviceId,
|
|
337
342
|
traceId,
|
|
338
343
|
requestId,
|
|
339
344
|
deploymentId: this.deploymentId,
|
|
@@ -346,8 +351,9 @@ class UnnboundLogger {
|
|
|
346
351
|
body: (0, logger_utils_1.safeJsonParse)(req.body),
|
|
347
352
|
},
|
|
348
353
|
};
|
|
349
|
-
const
|
|
350
|
-
|
|
354
|
+
const { message: logMessage, ...logData } = logEntry;
|
|
355
|
+
this.logger[options.level || 'info'](logData, logMessage);
|
|
356
|
+
return logEntry;
|
|
351
357
|
}
|
|
352
358
|
/**
|
|
353
359
|
* Logs an HTTP response
|
|
@@ -360,6 +366,7 @@ class UnnboundLogger {
|
|
|
360
366
|
const requestId = res.locals.requestId || options.requestId || (0, uuid_1.v4)();
|
|
361
367
|
const startTime = res.locals.startTime || options.startTime || Date.now();
|
|
362
368
|
const workflowId = res.locals.workflowId || this.workflowId;
|
|
369
|
+
const serviceId = res.locals.serviceId || this.serviceId;
|
|
363
370
|
const traceId = res.locals.traceId || options.traceId || trace_context_1.traceContext.getTraceId() || (0, uuid_1.v4)();
|
|
364
371
|
const duration = options.duration || (Date.now() - startTime);
|
|
365
372
|
// Determine log level based on status code
|
|
@@ -377,6 +384,7 @@ class UnnboundLogger {
|
|
|
377
384
|
type: 'httpResponse',
|
|
378
385
|
message: (0, http_status_messages_1.getStatusMessage)(res.statusCode),
|
|
379
386
|
workflowId: workflowId || '',
|
|
387
|
+
serviceId: serviceId || '',
|
|
380
388
|
traceId,
|
|
381
389
|
requestId,
|
|
382
390
|
deploymentId: this.deploymentId,
|
|
@@ -390,8 +398,9 @@ class UnnboundLogger {
|
|
|
390
398
|
body: (0, logger_utils_1.safeJsonParse)(res.locals.body),
|
|
391
399
|
},
|
|
392
400
|
};
|
|
393
|
-
const
|
|
394
|
-
|
|
401
|
+
const { message: logMessage, ...logData } = logEntry;
|
|
402
|
+
this.logger[level](logData, logMessage);
|
|
403
|
+
return logEntry;
|
|
395
404
|
}
|
|
396
405
|
/**
|
|
397
406
|
* Logs an SFTP transaction
|
|
@@ -409,14 +418,16 @@ class UnnboundLogger {
|
|
|
409
418
|
type: 'sftpTransaction',
|
|
410
419
|
message: `SFTP ${operation.operation} ${operation.status} - ${operation.path}`,
|
|
411
420
|
workflowId: this.workflowId,
|
|
421
|
+
serviceId: this.serviceId,
|
|
412
422
|
traceId,
|
|
413
423
|
requestId,
|
|
414
424
|
deploymentId: this.deploymentId,
|
|
415
425
|
duration,
|
|
416
426
|
sftp: operation,
|
|
417
427
|
};
|
|
418
|
-
const
|
|
419
|
-
|
|
428
|
+
const { message: logMessage, ...logData } = logEntry;
|
|
429
|
+
this.logger[level](logData, logMessage);
|
|
430
|
+
return logEntry;
|
|
420
431
|
}
|
|
421
432
|
/**
|
|
422
433
|
* Logs a database query transaction
|
|
@@ -434,14 +445,16 @@ class UnnboundLogger {
|
|
|
434
445
|
type: 'dbQueryTransaction',
|
|
435
446
|
message: `DB Query ${query.status} - ${query.vendor}`,
|
|
436
447
|
workflowId: this.workflowId,
|
|
448
|
+
serviceId: this.serviceId,
|
|
437
449
|
traceId,
|
|
438
450
|
requestId,
|
|
439
451
|
deploymentId: this.deploymentId,
|
|
440
452
|
duration,
|
|
441
453
|
db: query,
|
|
442
454
|
};
|
|
443
|
-
const
|
|
444
|
-
|
|
455
|
+
const { message: logMessage, ...logData } = logEntry;
|
|
456
|
+
this.logger[level](logData, logMessage);
|
|
457
|
+
return logEntry;
|
|
445
458
|
}
|
|
446
459
|
}
|
|
447
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",
|