unnbound-logger-sdk 2.0.3 → 2.0.5
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 +39 -10
- package/dist/types.d.ts +2 -6
- package/dist/unnbound-logger.d.ts +1 -3
- package/dist/unnbound-logger.js +35 -26
- package/dist/utils/http-status-messages.js +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -48,12 +48,14 @@ All logs follow a standardized format:
|
|
|
48
48
|
|
|
49
49
|
```typescript
|
|
50
50
|
interface Log<T extends LogType = 'general'> {
|
|
51
|
+
logId: string; // Unique identifier for each log entry
|
|
51
52
|
level: LogLevel; // "info" | "debug" | "error" | "warn"
|
|
52
53
|
type: T; // "general" | "httpRequest" | "httpResponse" | "sftpTransaction" | "dbQueryTransaction"
|
|
53
54
|
message: string;
|
|
55
|
+
workflowId: string; // Workflow tracking (empty string if not set)
|
|
54
56
|
traceId: string;
|
|
55
57
|
requestId: string;
|
|
56
|
-
deploymentId: string; // Automatically populated from
|
|
58
|
+
deploymentId: string; // Automatically populated from UNNBOUND_DEPLOYMENT_ID
|
|
57
59
|
error?: SerializableError; // Only present for Error objects
|
|
58
60
|
}
|
|
59
61
|
|
|
@@ -62,24 +64,44 @@ interface LogTransaction<T extends LogType> extends Log<T> {
|
|
|
62
64
|
}
|
|
63
65
|
```
|
|
64
66
|
|
|
65
|
-
## Deployment Tracking
|
|
67
|
+
## Workflow and Deployment Tracking
|
|
66
68
|
|
|
67
|
-
|
|
69
|
+
### Workflow Tracking
|
|
70
|
+
|
|
71
|
+
The logger includes a `workflowId` field in all log entries for tracking operations across services:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Set the workflow ID in your environment
|
|
75
|
+
export UNNBOUND_WORKFLOW_ID="order-processing-12345"
|
|
76
|
+
|
|
77
|
+
# Or in your deployment configuration
|
|
78
|
+
UNNBOUND_WORKFLOW_ID=order-processing-12345
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// Create a logger - workflowId is automatically set from environment
|
|
83
|
+
const logger = new UnnboundLogger();
|
|
84
|
+
// All logs will include the workflowId from UNNBOUND_WORKFLOW_ID environment variable
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Deployment Tracking
|
|
88
|
+
|
|
89
|
+
The logger automatically includes a `deploymentId` field in all log entries. This field is populated from the `UNNBOUND_DEPLOYMENT_ID` environment variable, allowing you to track logs per deployment.
|
|
68
90
|
|
|
69
91
|
```bash
|
|
70
92
|
# Set the deployment ID in your environment
|
|
71
|
-
export
|
|
93
|
+
export UNNBOUND_DEPLOYMENT_ID="v1.2.3-prod-20231201"
|
|
72
94
|
|
|
73
95
|
# Or in your deployment configuration
|
|
74
|
-
|
|
96
|
+
UNNBOUND_DEPLOYMENT_ID=v1.2.3-prod-20231201
|
|
75
97
|
```
|
|
76
98
|
|
|
77
|
-
If the
|
|
99
|
+
If the environment variables are not set, the fields will be empty strings. These fields help with:
|
|
78
100
|
|
|
79
|
-
-
|
|
80
|
-
-
|
|
81
|
-
-
|
|
82
|
-
-
|
|
101
|
+
- **Workflow ID**: Unique identifier for the workflow
|
|
102
|
+
- **Deployment ID**: Tracking logs across different application deployments
|
|
103
|
+
- **Correlating issues**: Link problems to specific workflows and releases
|
|
104
|
+
- **Monitoring**: Track health and performance across workflows and deployments
|
|
83
105
|
|
|
84
106
|
## HTTP Request/Response Logging
|
|
85
107
|
|
|
@@ -326,6 +348,13 @@ The main logger class that provides all logging functionality using Pino.
|
|
|
326
348
|
new UnnboundLogger(options?: LoggerOptions)
|
|
327
349
|
```
|
|
328
350
|
|
|
351
|
+
**LoggerOptions:**
|
|
352
|
+
- `traceHeaderKey?: string` - Custom trace header name (default: 'unnbound-trace-id')
|
|
353
|
+
- `ignoreTraceRoutes?: string[]` - Routes to ignore in Express middleware
|
|
354
|
+
- `ignoreAxiosTraceRoutes?: string[]` - Routes to ignore in Axios middleware
|
|
355
|
+
|
|
356
|
+
**Note:** `workflowId` and `deploymentId` are configured via environment variables (`UNNBOUND_WORKFLOW_ID`, `UNNBOUND_DEPLOYMENT_ID`).
|
|
357
|
+
|
|
329
358
|
#### Methods
|
|
330
359
|
|
|
331
360
|
- `log(level: LogLevel, message: string | Error | Record<string, unknown>, options?: GeneralLogOptions): void`
|
package/dist/types.d.ts
CHANGED
|
@@ -19,10 +19,12 @@ export interface SerializableError {
|
|
|
19
19
|
stack?: string;
|
|
20
20
|
}
|
|
21
21
|
export interface Log<T extends LogType = 'general'> {
|
|
22
|
+
logId: string;
|
|
22
23
|
level: LogLevel;
|
|
23
24
|
type: T;
|
|
24
25
|
message: string;
|
|
25
26
|
deploymentId: string;
|
|
27
|
+
workflowId: string;
|
|
26
28
|
traceId: string;
|
|
27
29
|
requestId: string;
|
|
28
30
|
error?: SerializableError;
|
|
@@ -75,12 +77,6 @@ export interface DbQueryTransactionLog extends LogTransaction<'dbQueryTransactio
|
|
|
75
77
|
* Configuration options for the logger
|
|
76
78
|
*/
|
|
77
79
|
export interface LoggerOptions {
|
|
78
|
-
/** Default log level */
|
|
79
|
-
defaultLevel?: LogLevel;
|
|
80
|
-
/** Optional service name to include in logs */
|
|
81
|
-
serviceName?: string;
|
|
82
|
-
/** Optional environment name to include in logs */
|
|
83
|
-
environment?: string;
|
|
84
80
|
/** Optional trace header key */
|
|
85
81
|
traceHeaderKey?: string;
|
|
86
82
|
/** Routes to ignore in trace middleware (supports glob patterns) */
|
|
@@ -14,9 +14,7 @@ declare module 'axios' {
|
|
|
14
14
|
*/
|
|
15
15
|
export declare class UnnboundLogger {
|
|
16
16
|
private logger;
|
|
17
|
-
private
|
|
18
|
-
private serviceName?;
|
|
19
|
-
private environment?;
|
|
17
|
+
private workflowId;
|
|
20
18
|
private deploymentId;
|
|
21
19
|
private traceHeaderKey;
|
|
22
20
|
private ignoreTraceRoutes;
|
package/dist/unnbound-logger.js
CHANGED
|
@@ -168,20 +168,15 @@ class UnnboundLogger {
|
|
|
168
168
|
return Promise.reject(error);
|
|
169
169
|
}
|
|
170
170
|
};
|
|
171
|
-
this.
|
|
172
|
-
this.
|
|
173
|
-
this.environment = options.environment;
|
|
174
|
-
this.deploymentId = process.env.DEPLOYMENT_ID || '';
|
|
171
|
+
this.workflowId = process.env.UNNBOUND_WORKFLOW_ID || '';
|
|
172
|
+
this.deploymentId = process.env.UNNBOUND_DEPLOYMENT_ID || '';
|
|
175
173
|
this.traceHeaderKey = options.traceHeaderKey || 'unnbound-trace-id';
|
|
176
174
|
this.ignoreTraceRoutes = options.ignoreTraceRoutes || [];
|
|
177
175
|
this.ignoreAxiosTraceRoutes = options.ignoreAxiosTraceRoutes || [];
|
|
178
176
|
// Create Pino logger
|
|
179
177
|
this.logger = (0, pino_1.default)({
|
|
180
|
-
level:
|
|
181
|
-
base: {
|
|
182
|
-
...(this.serviceName && { service: this.serviceName }),
|
|
183
|
-
...(this.environment && { environment: this.environment }),
|
|
184
|
-
},
|
|
178
|
+
level: 'info',
|
|
179
|
+
base: {}, // Disable all default base fields (pid, hostname)
|
|
185
180
|
timestamp: false, // Let CloudWatch handle timestamps
|
|
186
181
|
formatters: {
|
|
187
182
|
level: (label) => {
|
|
@@ -214,10 +209,19 @@ class UnnboundLogger {
|
|
|
214
209
|
* @param options - Additional logging options
|
|
215
210
|
*/
|
|
216
211
|
log(level, message, options = {}) {
|
|
212
|
+
const logId = (0, uuid_1.v4)();
|
|
217
213
|
const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, uuid_1.v4)();
|
|
218
214
|
const requestId = options.requestId || (0, uuid_1.v4)();
|
|
219
215
|
let logEntry;
|
|
220
216
|
const { traceId: optionTraceId, requestId: optionRequestId, ...restOptions } = options;
|
|
217
|
+
const baseEntry = {
|
|
218
|
+
logId,
|
|
219
|
+
type: 'general',
|
|
220
|
+
workflowId: this.workflowId,
|
|
221
|
+
traceId,
|
|
222
|
+
requestId,
|
|
223
|
+
deploymentId: this.deploymentId,
|
|
224
|
+
};
|
|
221
225
|
if (message instanceof Error) {
|
|
222
226
|
const error = {
|
|
223
227
|
name: message.name,
|
|
@@ -225,10 +229,7 @@ class UnnboundLogger {
|
|
|
225
229
|
stack: message.stack,
|
|
226
230
|
};
|
|
227
231
|
logEntry = {
|
|
228
|
-
|
|
229
|
-
traceId,
|
|
230
|
-
requestId,
|
|
231
|
-
deploymentId: this.deploymentId,
|
|
232
|
+
...baseEntry,
|
|
232
233
|
message: message.name,
|
|
233
234
|
error,
|
|
234
235
|
...restOptions,
|
|
@@ -236,10 +237,7 @@ class UnnboundLogger {
|
|
|
236
237
|
}
|
|
237
238
|
else if (typeof message === 'string') {
|
|
238
239
|
logEntry = {
|
|
239
|
-
|
|
240
|
-
traceId,
|
|
241
|
-
requestId,
|
|
242
|
-
deploymentId: this.deploymentId,
|
|
240
|
+
...baseEntry,
|
|
243
241
|
message,
|
|
244
242
|
...restOptions,
|
|
245
243
|
};
|
|
@@ -247,10 +245,7 @@ class UnnboundLogger {
|
|
|
247
245
|
else {
|
|
248
246
|
// If message is an object, it's part of the log entry
|
|
249
247
|
logEntry = {
|
|
250
|
-
|
|
251
|
-
traceId,
|
|
252
|
-
requestId,
|
|
253
|
-
deploymentId: this.deploymentId,
|
|
248
|
+
...baseEntry,
|
|
254
249
|
...message,
|
|
255
250
|
message: message.message || 'Structured log data',
|
|
256
251
|
...restOptions,
|
|
@@ -319,6 +314,7 @@ class UnnboundLogger {
|
|
|
319
314
|
* @returns The request ID for correlating with the response
|
|
320
315
|
*/
|
|
321
316
|
httpRequest(req, options = {}) {
|
|
317
|
+
const logId = (0, uuid_1.v4)();
|
|
322
318
|
const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, uuid_1.v4)();
|
|
323
319
|
const requestId = options.requestId || (0, uuid_1.v4)();
|
|
324
320
|
const startTime = options.startTime || Date.now();
|
|
@@ -327,10 +323,13 @@ class UnnboundLogger {
|
|
|
327
323
|
req.res.locals.requestId = requestId;
|
|
328
324
|
req.res.locals.startTime = startTime;
|
|
329
325
|
req.res.locals.traceId = traceId;
|
|
326
|
+
req.res.locals.workflowId = this.workflowId;
|
|
330
327
|
}
|
|
331
328
|
const logEntry = {
|
|
329
|
+
logId,
|
|
332
330
|
type: 'httpRequest',
|
|
333
331
|
message: req.ip === 'outgoing' ? 'Outgoing HTTP Request' : 'Incoming HTTP Request',
|
|
332
|
+
workflowId: this.workflowId,
|
|
334
333
|
traceId,
|
|
335
334
|
requestId,
|
|
336
335
|
deploymentId: this.deploymentId,
|
|
@@ -343,7 +342,7 @@ class UnnboundLogger {
|
|
|
343
342
|
body: (0, logger_utils_1.safeJsonParse)(req.body),
|
|
344
343
|
},
|
|
345
344
|
};
|
|
346
|
-
this.
|
|
345
|
+
this.log(options.level || 'info', logEntry);
|
|
347
346
|
return requestId;
|
|
348
347
|
}
|
|
349
348
|
/**
|
|
@@ -353,12 +352,14 @@ class UnnboundLogger {
|
|
|
353
352
|
* @param options - Additional logging options
|
|
354
353
|
*/
|
|
355
354
|
httpResponse(res, req, options = {}) {
|
|
355
|
+
const logId = (0, uuid_1.v4)();
|
|
356
356
|
const requestId = res.locals.requestId || options.requestId || (0, uuid_1.v4)();
|
|
357
357
|
const startTime = res.locals.startTime || options.startTime || Date.now();
|
|
358
|
+
const workflowId = res.locals.workflowId || this.workflowId;
|
|
358
359
|
const traceId = res.locals.traceId || options.traceId || trace_context_1.traceContext.getTraceId() || (0, uuid_1.v4)();
|
|
359
360
|
const duration = options.duration || (Date.now() - startTime);
|
|
360
361
|
// Determine log level based on status code
|
|
361
|
-
let level = options.level ||
|
|
362
|
+
let level = options.level || 'info';
|
|
362
363
|
if (!options.level) {
|
|
363
364
|
if (res.statusCode >= 400) {
|
|
364
365
|
level = 'error';
|
|
@@ -368,8 +369,10 @@ class UnnboundLogger {
|
|
|
368
369
|
}
|
|
369
370
|
}
|
|
370
371
|
const logEntry = {
|
|
372
|
+
logId,
|
|
371
373
|
type: 'httpResponse',
|
|
372
374
|
message: (0, http_status_messages_1.getStatusMessage)(res.statusCode),
|
|
375
|
+
workflowId: workflowId || '',
|
|
373
376
|
traceId,
|
|
374
377
|
requestId,
|
|
375
378
|
deploymentId: this.deploymentId,
|
|
@@ -383,7 +386,7 @@ class UnnboundLogger {
|
|
|
383
386
|
body: (0, logger_utils_1.safeJsonParse)(res.locals.body),
|
|
384
387
|
},
|
|
385
388
|
};
|
|
386
|
-
this.
|
|
389
|
+
this.log(level, logEntry);
|
|
387
390
|
}
|
|
388
391
|
/**
|
|
389
392
|
* Logs an SFTP transaction
|
|
@@ -391,20 +394,23 @@ class UnnboundLogger {
|
|
|
391
394
|
* @param options - Additional logging options
|
|
392
395
|
*/
|
|
393
396
|
sftpTransaction(operation, options = {}) {
|
|
397
|
+
const logId = (0, uuid_1.v4)();
|
|
394
398
|
const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, uuid_1.v4)();
|
|
395
399
|
const requestId = options.requestId || (0, uuid_1.v4)();
|
|
396
400
|
const duration = options.duration || (options.startTime ? Date.now() - options.startTime : 0);
|
|
397
401
|
const level = operation.status === 'success' ? 'info' : 'error';
|
|
398
402
|
const logEntry = {
|
|
403
|
+
logId,
|
|
399
404
|
type: 'sftpTransaction',
|
|
400
405
|
message: `SFTP ${operation.operation} ${operation.status} - ${operation.path}`,
|
|
406
|
+
workflowId: this.workflowId,
|
|
401
407
|
traceId,
|
|
402
408
|
requestId,
|
|
403
409
|
deploymentId: this.deploymentId,
|
|
404
410
|
duration,
|
|
405
411
|
sftp: operation,
|
|
406
412
|
};
|
|
407
|
-
this.
|
|
413
|
+
this.log(level, logEntry);
|
|
408
414
|
}
|
|
409
415
|
/**
|
|
410
416
|
* Logs a database query transaction
|
|
@@ -412,20 +418,23 @@ class UnnboundLogger {
|
|
|
412
418
|
* @param options - Additional logging options
|
|
413
419
|
*/
|
|
414
420
|
dbQueryTransaction(query, options = {}) {
|
|
421
|
+
const logId = (0, uuid_1.v4)();
|
|
415
422
|
const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, uuid_1.v4)();
|
|
416
423
|
const requestId = options.requestId || (0, uuid_1.v4)();
|
|
417
424
|
const duration = options.duration || (options.startTime ? Date.now() - options.startTime : 0);
|
|
418
425
|
const level = query.status === 'success' ? 'info' : 'error';
|
|
419
426
|
const logEntry = {
|
|
427
|
+
logId,
|
|
420
428
|
type: 'dbQueryTransaction',
|
|
421
429
|
message: `DB Query ${query.status} - ${query.vendor}`,
|
|
430
|
+
workflowId: this.workflowId,
|
|
422
431
|
traceId,
|
|
423
432
|
requestId,
|
|
424
433
|
deploymentId: this.deploymentId,
|
|
425
434
|
duration,
|
|
426
435
|
db: query,
|
|
427
436
|
};
|
|
428
|
-
this.
|
|
437
|
+
this.log(level, logEntry);
|
|
429
438
|
}
|
|
430
439
|
}
|
|
431
440
|
exports.UnnboundLogger = UnnboundLogger;
|
|
@@ -49,7 +49,7 @@ exports.httpStatusDetails = {
|
|
|
49
49
|
function getStatusMessage(statusCode) {
|
|
50
50
|
const status = exports.httpStatusDetails[statusCode];
|
|
51
51
|
if (status) {
|
|
52
|
-
return `${status.message} - ${status.description}`;
|
|
52
|
+
return `${statusCode} ${status.message} - ${status.description}`;
|
|
53
53
|
}
|
|
54
|
-
return
|
|
54
|
+
return `${statusCode} Unknown Status`;
|
|
55
55
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unnbound-logger-sdk",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "A structured logging library with TypeScript support using Pino. Provides consistent, well-typed logging
|
|
3
|
+
"version": "2.0.5",
|
|
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",
|
|
7
7
|
"scripts": {
|