unnbound-logger-sdk 1.0.0 → 1.1.0
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 +18 -11
- package/dist/unnbound-logger.d.ts +11 -0
- package/dist/unnbound-logger.js +71 -0
- package/package.json +8 -8
- package/dist/src/index.d.ts +0 -38
- package/dist/src/index.js +0 -29
- package/dist/src/types.d.ts +0 -134
- package/dist/src/types.js +0 -5
- package/dist/src/unnbound-logger.d.ts +0 -105
- package/dist/src/unnbound-logger.js +0 -292
- package/dist/src/utils/id-generator.d.ts +0 -21
- package/dist/src/utils/id-generator.js +0 -46
- package/dist/src/utils/logger-utils.d.ts +0 -21
- package/dist/src/utils/logger-utils.js +0 -63
- package/dist/src/utils/trace-context.d.ts +0 -10
- package/dist/src/utils/trace-context.js +0 -23
- package/dist/src/utils/with-trace.d.ts +0 -7
- package/dist/src/utils/with-trace.js +0 -17
package/README.md
CHANGED
|
@@ -169,7 +169,7 @@ logger.dbQueryTransaction({
|
|
|
169
169
|
|
|
170
170
|
### Express Trace Middleware
|
|
171
171
|
|
|
172
|
-
The library provides a trace middleware for Express applications that automatically
|
|
172
|
+
The library provides a comprehensive trace middleware for Express applications that automatically handles trace context and HTTP logging:
|
|
173
173
|
|
|
174
174
|
```typescript
|
|
175
175
|
import { UnnboundLogger } from 'unnbound-logger';
|
|
@@ -178,20 +178,21 @@ import express from 'express';
|
|
|
178
178
|
const app = express();
|
|
179
179
|
const logger = new UnnboundLogger();
|
|
180
180
|
|
|
181
|
-
// Apply the trace middleware globally
|
|
181
|
+
// Apply the comprehensive trace middleware globally
|
|
182
182
|
app.use(logger.traceMiddleware);
|
|
183
|
-
|
|
184
183
|
```
|
|
185
184
|
|
|
186
185
|
The trace middleware automatically:
|
|
187
|
-
- Logs incoming requests with method, URL, headers, and body
|
|
188
186
|
- Generates and maintains trace IDs across the request lifecycle
|
|
189
|
-
-
|
|
187
|
+
- Logs incoming requests with method, URL, headers, and body (filtered for security)
|
|
188
|
+
- Logs outgoing responses with status code, headers, body, and duration
|
|
189
|
+
- Measures request duration automatically
|
|
190
190
|
- Handles errors and logs them appropriately
|
|
191
|
+
- Captures response bodies for logging
|
|
191
192
|
|
|
192
193
|
### Axios Trace Middleware
|
|
193
194
|
|
|
194
|
-
For logging outgoing HTTP requests made with Axios:
|
|
195
|
+
For comprehensive logging of outgoing HTTP requests made with Axios:
|
|
195
196
|
|
|
196
197
|
```typescript
|
|
197
198
|
import { UnnboundLogger } from 'unnbound-logger';
|
|
@@ -199,20 +200,26 @@ import axios from 'axios';
|
|
|
199
200
|
|
|
200
201
|
const logger = new UnnboundLogger();
|
|
201
202
|
|
|
202
|
-
// Add
|
|
203
|
+
// Add both request and response interceptors for complete HTTP logging
|
|
203
204
|
axios.interceptors.request.use(
|
|
204
205
|
logger.axiosTraceMiddleware.onFulfilled,
|
|
205
206
|
logger.axiosTraceMiddleware.onRejected
|
|
206
207
|
);
|
|
207
208
|
|
|
209
|
+
axios.interceptors.response.use(
|
|
210
|
+
logger.axiosResponseInterceptor.onFulfilled,
|
|
211
|
+
logger.axiosResponseInterceptor.onRejected
|
|
212
|
+
);
|
|
213
|
+
|
|
208
214
|
// All requests made with axios will be automatically logged
|
|
209
215
|
axios.get('https://api.example.com/data');
|
|
210
216
|
```
|
|
211
217
|
|
|
212
|
-
The Axios
|
|
213
|
-
- Logs outgoing requests with method, URL, headers, and body
|
|
214
|
-
- Maintains trace context across requests
|
|
215
|
-
-
|
|
218
|
+
The Axios middleware:
|
|
219
|
+
- Logs outgoing requests with method, URL, headers, and body (filtered for security)
|
|
220
|
+
- Maintains trace context across requests by propagating trace IDs
|
|
221
|
+
- Logs successful responses with status, headers, body, and duration
|
|
222
|
+
- Logs error responses with detailed error information
|
|
216
223
|
- Supports request/response filtering through configuration
|
|
217
224
|
|
|
218
225
|
## Function Tracing with withTrace
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { LogLevel, LoggerOptions, GeneralLogOptions, HttpRequestLogOptions, HttpResponseLogOptions, SftpTransactionLogOptions, DbQueryTransactionLogOptions } from './types';
|
|
2
2
|
import { Request, Response, NextFunction } from 'express';
|
|
3
3
|
import { InternalAxiosRequestConfig } from 'axios';
|
|
4
|
+
declare module 'axios' {
|
|
5
|
+
interface InternalAxiosRequestConfig {
|
|
6
|
+
metadata?: {
|
|
7
|
+
startTime: number;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
}
|
|
4
11
|
/**
|
|
5
12
|
* UnnboundLogger provides typed, structured logging using Pino
|
|
6
13
|
*/
|
|
@@ -102,4 +109,8 @@ export declare class UnnboundLogger {
|
|
|
102
109
|
onFulfilled: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig;
|
|
103
110
|
onRejected: (error: any) => any;
|
|
104
111
|
};
|
|
112
|
+
axiosResponseInterceptor: {
|
|
113
|
+
onFulfilled: (response: any) => any;
|
|
114
|
+
onRejected: (error: any) => any;
|
|
115
|
+
};
|
|
105
116
|
}
|
package/dist/unnbound-logger.js
CHANGED
|
@@ -31,6 +31,18 @@ class UnnboundLogger {
|
|
|
31
31
|
const traceId = req.header(this.traceHeaderKey) || (0, uuid_1.v4)();
|
|
32
32
|
res.setHeader(this.traceHeaderKey, traceId);
|
|
33
33
|
trace_context_1.traceContext.run(traceId, () => {
|
|
34
|
+
// Log the incoming request
|
|
35
|
+
const requestId = this.httpRequest(req, { traceId });
|
|
36
|
+
// Capture response body for logging
|
|
37
|
+
const originalSend = res.send;
|
|
38
|
+
res.send = function (body) {
|
|
39
|
+
res.locals.body = body;
|
|
40
|
+
return originalSend.call(this, body);
|
|
41
|
+
};
|
|
42
|
+
// Log the response when it finishes
|
|
43
|
+
res.on('finish', () => {
|
|
44
|
+
this.httpResponse(res, req, { requestId, traceId });
|
|
45
|
+
});
|
|
34
46
|
next();
|
|
35
47
|
});
|
|
36
48
|
};
|
|
@@ -47,12 +59,71 @@ class UnnboundLogger {
|
|
|
47
59
|
headers.set(this.traceHeaderKey, traceId);
|
|
48
60
|
config.headers = headers;
|
|
49
61
|
}
|
|
62
|
+
// Store request start time for duration calculation
|
|
63
|
+
config.metadata = { startTime: Date.now() };
|
|
64
|
+
// Log the outgoing request
|
|
65
|
+
this.info(`HTTP Request: ${config.method?.toUpperCase()} ${config.baseURL || ''}${config.url}`, {
|
|
66
|
+
type: 'httpRequest',
|
|
67
|
+
httpRequest: {
|
|
68
|
+
url: `${config.baseURL || ''}${config.url}`,
|
|
69
|
+
method: config.method?.toUpperCase(),
|
|
70
|
+
headers: (0, logger_utils_1.filterHeaders)(config.headers),
|
|
71
|
+
body: config.data
|
|
72
|
+
}
|
|
73
|
+
});
|
|
50
74
|
return config;
|
|
51
75
|
},
|
|
52
76
|
onRejected: (error) => {
|
|
53
77
|
return Promise.reject(error);
|
|
54
78
|
}
|
|
55
79
|
};
|
|
80
|
+
// Axios response interceptor (should be used separately)
|
|
81
|
+
this.axiosResponseInterceptor = {
|
|
82
|
+
onFulfilled: (response) => {
|
|
83
|
+
// Calculate duration
|
|
84
|
+
const startTime = response.config.metadata?.startTime || Date.now();
|
|
85
|
+
const duration = Date.now() - startTime;
|
|
86
|
+
// Log the successful response
|
|
87
|
+
this.info(`HTTP Response: ${response.config.method?.toUpperCase()} ${response.config.baseURL || ''}${response.config.url} - ${response.status}`, {
|
|
88
|
+
type: 'httpResponse',
|
|
89
|
+
duration,
|
|
90
|
+
httpResponse: {
|
|
91
|
+
url: `${response.config.baseURL || ''}${response.config.url}`,
|
|
92
|
+
method: response.config.method?.toUpperCase(),
|
|
93
|
+
status: response.status,
|
|
94
|
+
headers: (0, logger_utils_1.filterHeaders)(response.headers),
|
|
95
|
+
body: response.data
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
return response;
|
|
99
|
+
},
|
|
100
|
+
onRejected: (error) => {
|
|
101
|
+
// Calculate duration for error responses
|
|
102
|
+
const startTime = error.config?.metadata?.startTime || Date.now();
|
|
103
|
+
const duration = Date.now() - startTime;
|
|
104
|
+
// Log the error response
|
|
105
|
+
if (error.response) {
|
|
106
|
+
this.error(`HTTP Error Response: ${error.config?.method?.toUpperCase()} ${error.config?.baseURL || ''}${error.config?.url} - ${error.response.status}`, {
|
|
107
|
+
type: 'httpResponse',
|
|
108
|
+
duration,
|
|
109
|
+
httpResponse: {
|
|
110
|
+
url: `${error.config?.baseURL || ''}${error.config?.url}`,
|
|
111
|
+
method: error.config?.method?.toUpperCase(),
|
|
112
|
+
status: error.response.status,
|
|
113
|
+
headers: (0, logger_utils_1.filterHeaders)(error.response.headers),
|
|
114
|
+
body: error.response.data
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
this.error(`HTTP Request Failed: ${error.config?.method?.toUpperCase()} ${error.config?.baseURL || ''}${error.config?.url}`, {
|
|
120
|
+
context: 'No response received',
|
|
121
|
+
error: error.message
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return Promise.reject(error);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
56
127
|
this.defaultLevel = options.defaultLevel || 'info';
|
|
57
128
|
this.serviceName = options.serviceName;
|
|
58
129
|
this.environment = options.environment;
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unnbound-logger-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "A structured logging library with TypeScript support using Pino. Provides consistent, well-typed logging across different operational contexts with automatic trace ID propagation.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "tsc",
|
|
9
|
-
"test": "jest",
|
|
10
|
-
"test:coverage": "jest --coverage",
|
|
11
|
-
"test:watch": "jest --watch",
|
|
9
|
+
"test": "npx jest",
|
|
10
|
+
"test:coverage": "npx jest --coverage",
|
|
11
|
+
"test:watch": "npx jest --watch",
|
|
12
12
|
"lint": "eslint src/**/*.ts",
|
|
13
13
|
"lint:fix": "eslint . --ext .ts --fix",
|
|
14
14
|
"format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"url": "https://github.com/unnbound/logger/issues"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"axios": "^1.
|
|
44
|
-
"express": "^5.
|
|
43
|
+
"axios": "^1.0.0",
|
|
44
|
+
"express": "^4.0.0 || ^5.0.0",
|
|
45
45
|
"pino": "^8.17.2",
|
|
46
46
|
"uuid": "^11.1.0"
|
|
47
47
|
},
|
|
@@ -64,8 +64,8 @@
|
|
|
64
64
|
"typescript": "^5.3.3"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
|
-
"
|
|
68
|
-
"
|
|
67
|
+
"axios": "^1.0.0",
|
|
68
|
+
"express": "^4.0.0 || ^5.0.0"
|
|
69
69
|
},
|
|
70
70
|
"peerDependenciesMeta": {
|
|
71
71
|
"express": {
|
package/dist/src/index.d.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* unnbound-logger
|
|
3
|
-
*
|
|
4
|
-
* A structured logging library built on Pino with TypeScript support.
|
|
5
|
-
* Provides consistent, well-typed logging across different operational contexts.
|
|
6
|
-
*/
|
|
7
|
-
import { UnnboundLogger } from './unnbound-logger';
|
|
8
|
-
import { LogLevel, LogType, HttpMethod, LoggerOptions, GeneralLogOptions, HttpRequestLogOptions, HttpResponseLogOptions, SftpTransactionLogOptions, DbQueryTransactionLogOptions, Log, LogTransaction, HttpRequestLog, HttpResponseLog, SftpTransactionLog, DbQueryTransactionLog, SerializableError } from './types';
|
|
9
|
-
import { generateUuid, clearTraceId } from './utils/id-generator';
|
|
10
|
-
export { UnnboundLogger, LogLevel, LogType, HttpMethod, LoggerOptions, GeneralLogOptions, HttpRequestLogOptions, HttpResponseLogOptions, SftpTransactionLogOptions, DbQueryTransactionLogOptions, Log, LogTransaction, HttpRequestLog, HttpResponseLog, SftpTransactionLog, DbQueryTransactionLog, SerializableError, generateUuid, clearTraceId, };
|
|
11
|
-
declare const defaultLogger: UnnboundLogger;
|
|
12
|
-
export { defaultLogger };
|
|
13
|
-
export declare const log: (level: LogLevel, message: string | Error | Record<string, unknown>, options?: GeneralLogOptions) => void;
|
|
14
|
-
export declare const error: (message: string | Error | Record<string, unknown>, options?: GeneralLogOptions) => void;
|
|
15
|
-
export declare const warn: (message: string | Error | Record<string, unknown>, options?: GeneralLogOptions) => void;
|
|
16
|
-
export declare const info: (message: string | Error | Record<string, unknown>, options?: GeneralLogOptions) => void;
|
|
17
|
-
export declare const debug: (message: string | Error | Record<string, unknown>, options?: GeneralLogOptions) => void;
|
|
18
|
-
export declare const httpRequest: (req: import("express").Request, options?: HttpRequestLogOptions) => string;
|
|
19
|
-
export declare const httpResponse: (res: import("express").Response, req: import("express").Request, options?: HttpResponseLogOptions) => void;
|
|
20
|
-
export declare const sftpTransaction: (operation: {
|
|
21
|
-
host: string;
|
|
22
|
-
username: string;
|
|
23
|
-
operation: "upload" | "download" | "list" | "delete" | "rename" | "stat";
|
|
24
|
-
path: string;
|
|
25
|
-
status: "success" | "failure";
|
|
26
|
-
bytesTransferred?: number;
|
|
27
|
-
filesListed?: number;
|
|
28
|
-
sourcePath?: string;
|
|
29
|
-
}, options?: SftpTransactionLogOptions) => void;
|
|
30
|
-
export declare const dbQueryTransaction: (query: {
|
|
31
|
-
instance: string;
|
|
32
|
-
vendor: "postgres" | "mysql" | "mssql" | "mongodb";
|
|
33
|
-
query?: string;
|
|
34
|
-
status: "success" | "failure";
|
|
35
|
-
rowsReturned?: number;
|
|
36
|
-
rowsAffected?: number;
|
|
37
|
-
}, options?: DbQueryTransactionLogOptions) => void;
|
|
38
|
-
export default UnnboundLogger;
|
package/dist/src/index.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.dbQueryTransaction = exports.sftpTransaction = exports.httpResponse = exports.httpRequest = exports.debug = exports.info = exports.warn = exports.error = exports.log = exports.defaultLogger = exports.clearTraceId = exports.generateUuid = exports.UnnboundLogger = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* unnbound-logger
|
|
6
|
-
*
|
|
7
|
-
* A structured logging library built on Pino with TypeScript support.
|
|
8
|
-
* Provides consistent, well-typed logging across different operational contexts.
|
|
9
|
-
*/
|
|
10
|
-
const unnbound_logger_1 = require("./unnbound-logger");
|
|
11
|
-
Object.defineProperty(exports, "UnnboundLogger", { enumerable: true, get: function () { return unnbound_logger_1.UnnboundLogger; } });
|
|
12
|
-
const id_generator_1 = require("./utils/id-generator");
|
|
13
|
-
Object.defineProperty(exports, "generateUuid", { enumerable: true, get: function () { return id_generator_1.generateUuid; } });
|
|
14
|
-
Object.defineProperty(exports, "clearTraceId", { enumerable: true, get: function () { return id_generator_1.clearTraceId; } });
|
|
15
|
-
// Create a default logger instance
|
|
16
|
-
const defaultLogger = new unnbound_logger_1.UnnboundLogger();
|
|
17
|
-
exports.defaultLogger = defaultLogger;
|
|
18
|
-
// Export default logger functions for convenience
|
|
19
|
-
exports.log = defaultLogger.log.bind(defaultLogger);
|
|
20
|
-
exports.error = defaultLogger.error.bind(defaultLogger);
|
|
21
|
-
exports.warn = defaultLogger.warn.bind(defaultLogger);
|
|
22
|
-
exports.info = defaultLogger.info.bind(defaultLogger);
|
|
23
|
-
exports.debug = defaultLogger.debug.bind(defaultLogger);
|
|
24
|
-
exports.httpRequest = defaultLogger.httpRequest.bind(defaultLogger);
|
|
25
|
-
exports.httpResponse = defaultLogger.httpResponse.bind(defaultLogger);
|
|
26
|
-
exports.sftpTransaction = defaultLogger.sftpTransaction.bind(defaultLogger);
|
|
27
|
-
exports.dbQueryTransaction = defaultLogger.dbQueryTransaction.bind(defaultLogger);
|
|
28
|
-
// Default export is the UnnboundLogger class
|
|
29
|
-
exports.default = unnbound_logger_1.UnnboundLogger;
|
package/dist/src/types.d.ts
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Type definitions for structured logging library
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Available log levels
|
|
6
|
-
*/
|
|
7
|
-
export type LogLevel = "info" | "debug" | "error" | "warn";
|
|
8
|
-
/**
|
|
9
|
-
* Available log types
|
|
10
|
-
*/
|
|
11
|
-
export type LogType = "general" | "httpRequest" | "httpResponse" | "sftpTransaction" | "dbQueryTransaction";
|
|
12
|
-
/**
|
|
13
|
-
* HTTP methods supported for HTTP logging
|
|
14
|
-
*/
|
|
15
|
-
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD';
|
|
16
|
-
export interface SerializableError {
|
|
17
|
-
name: string;
|
|
18
|
-
message: string;
|
|
19
|
-
stack?: string;
|
|
20
|
-
}
|
|
21
|
-
export interface Log<T extends LogType = 'general'> {
|
|
22
|
-
level: LogLevel;
|
|
23
|
-
type: T;
|
|
24
|
-
message: string;
|
|
25
|
-
traceId: string;
|
|
26
|
-
requestId: string;
|
|
27
|
-
error?: SerializableError;
|
|
28
|
-
}
|
|
29
|
-
export interface LogTransaction<T extends LogType> extends Log<T> {
|
|
30
|
-
duration: number;
|
|
31
|
-
}
|
|
32
|
-
export interface HttpRequestLog extends LogTransaction<'httpRequest'> {
|
|
33
|
-
httpRequest: {
|
|
34
|
-
url: string;
|
|
35
|
-
method: string;
|
|
36
|
-
headers: Record<string, string>;
|
|
37
|
-
ip?: string;
|
|
38
|
-
body?: unknown;
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
export interface HttpResponseLog extends LogTransaction<'httpResponse'> {
|
|
42
|
-
httpResponse: {
|
|
43
|
-
url: string;
|
|
44
|
-
method: string;
|
|
45
|
-
headers: Record<string, string>;
|
|
46
|
-
ip?: string;
|
|
47
|
-
status: number;
|
|
48
|
-
body?: unknown;
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
export interface SftpTransactionLog extends LogTransaction<'sftpTransaction'> {
|
|
52
|
-
sftp: {
|
|
53
|
-
host: string;
|
|
54
|
-
username: string;
|
|
55
|
-
operation: 'upload' | 'download' | 'list' | 'delete' | 'rename' | 'stat';
|
|
56
|
-
path: string;
|
|
57
|
-
status: 'success' | 'failure';
|
|
58
|
-
bytesTransferred?: number;
|
|
59
|
-
filesListed?: number;
|
|
60
|
-
sourcePath?: string;
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
export interface DbQueryTransactionLog extends LogTransaction<'dbQueryTransaction'> {
|
|
64
|
-
db: {
|
|
65
|
-
instance: string;
|
|
66
|
-
vendor: 'postgres' | 'mysql' | 'mssql' | 'mongodb';
|
|
67
|
-
query?: string;
|
|
68
|
-
status: 'success' | 'failure';
|
|
69
|
-
rowsReturned?: number;
|
|
70
|
-
rowsAffected?: number;
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Configuration options for the logger
|
|
75
|
-
*/
|
|
76
|
-
export interface LoggerOptions {
|
|
77
|
-
/** Default log level */
|
|
78
|
-
defaultLevel?: LogLevel;
|
|
79
|
-
/** Optional service name to include in logs */
|
|
80
|
-
serviceName?: string;
|
|
81
|
-
/** Optional environment name to include in logs */
|
|
82
|
-
environment?: string;
|
|
83
|
-
/** Optional trace header key */
|
|
84
|
-
traceHeaderKey?: string;
|
|
85
|
-
/** Routes to ignore in trace middleware (supports glob patterns) */
|
|
86
|
-
ignoreTraceRoutes?: string[];
|
|
87
|
-
/** Routes to ignore in axios trace middleware (supports glob patterns) */
|
|
88
|
-
ignoreAxiosTraceRoutes?: string[];
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Options for general logs
|
|
92
|
-
*/
|
|
93
|
-
export interface GeneralLogOptions {
|
|
94
|
-
/** Log level override */
|
|
95
|
-
level?: LogLevel;
|
|
96
|
-
/** Custom trace ID */
|
|
97
|
-
traceId?: string;
|
|
98
|
-
/** Custom request ID */
|
|
99
|
-
requestId?: string;
|
|
100
|
-
/** Custom metadata */
|
|
101
|
-
[key: string]: unknown;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Options for HTTP request logs
|
|
105
|
-
*/
|
|
106
|
-
export interface HttpRequestLogOptions extends GeneralLogOptions {
|
|
107
|
-
/** Start time of the request for duration calculation */
|
|
108
|
-
startTime?: number;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Options for HTTP response logs
|
|
112
|
-
*/
|
|
113
|
-
export interface HttpResponseLogOptions extends HttpRequestLogOptions {
|
|
114
|
-
/** Duration of the request in milliseconds */
|
|
115
|
-
duration?: number;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Options for SFTP transaction logs
|
|
119
|
-
*/
|
|
120
|
-
export interface SftpTransactionLogOptions extends GeneralLogOptions {
|
|
121
|
-
/** Start time of the transaction for duration calculation */
|
|
122
|
-
startTime?: number;
|
|
123
|
-
/** Duration of the transaction in milliseconds */
|
|
124
|
-
duration?: number;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Options for database query transaction logs
|
|
128
|
-
*/
|
|
129
|
-
export interface DbQueryTransactionLogOptions extends GeneralLogOptions {
|
|
130
|
-
/** Start time of the query for duration calculation */
|
|
131
|
-
startTime?: number;
|
|
132
|
-
/** Duration of the query in milliseconds */
|
|
133
|
-
duration?: number;
|
|
134
|
-
}
|
package/dist/src/types.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { LogLevel, LoggerOptions, GeneralLogOptions, HttpRequestLogOptions, HttpResponseLogOptions, SftpTransactionLogOptions, DbQueryTransactionLogOptions } from './types';
|
|
2
|
-
import { Request, Response, NextFunction } from 'express';
|
|
3
|
-
import { InternalAxiosRequestConfig } from 'axios';
|
|
4
|
-
/**
|
|
5
|
-
* UnnboundLogger provides typed, structured logging using Pino
|
|
6
|
-
*/
|
|
7
|
-
export declare class UnnboundLogger {
|
|
8
|
-
private logger;
|
|
9
|
-
private defaultLevel;
|
|
10
|
-
private serviceName?;
|
|
11
|
-
private environment?;
|
|
12
|
-
private traceHeaderKey;
|
|
13
|
-
private ignoreTraceRoutes;
|
|
14
|
-
private ignoreAxiosTraceRoutes;
|
|
15
|
-
/**
|
|
16
|
-
* Creates a new UnnboundLogger instance
|
|
17
|
-
* @param options - Configuration options for the logger
|
|
18
|
-
*/
|
|
19
|
-
constructor(options?: LoggerOptions);
|
|
20
|
-
/**
|
|
21
|
-
* Checks if a path matches any of the ignore patterns
|
|
22
|
-
* @param path - The path to check
|
|
23
|
-
* @param patterns - Array of glob patterns to match against
|
|
24
|
-
* @returns boolean indicating if the path should be ignored
|
|
25
|
-
*/
|
|
26
|
-
private shouldIgnorePath;
|
|
27
|
-
/**
|
|
28
|
-
* Logs a general message
|
|
29
|
-
* @param level - Log level
|
|
30
|
-
* @param message - Log message
|
|
31
|
-
* @param options - Additional logging options
|
|
32
|
-
*/
|
|
33
|
-
log(level: LogLevel, message: string | Error | Record<string, unknown>, options?: GeneralLogOptions): void;
|
|
34
|
-
/**
|
|
35
|
-
* Logs an error message
|
|
36
|
-
* @param message - Error message or object
|
|
37
|
-
* @param options - Additional logging options
|
|
38
|
-
*/
|
|
39
|
-
error(message: string | Error | Record<string, unknown>, options?: GeneralLogOptions): void;
|
|
40
|
-
/**
|
|
41
|
-
* Logs a warning message
|
|
42
|
-
* @param message - Warning message
|
|
43
|
-
* @param options - Additional logging options
|
|
44
|
-
*/
|
|
45
|
-
warn(message: string | Error | Record<string, unknown>, options?: GeneralLogOptions): void;
|
|
46
|
-
/**
|
|
47
|
-
* Logs an info message
|
|
48
|
-
* @param message - Info message
|
|
49
|
-
* @param options - Additional logging options
|
|
50
|
-
*/
|
|
51
|
-
info(message: string | Error | Record<string, unknown>, options?: GeneralLogOptions): void;
|
|
52
|
-
/**
|
|
53
|
-
* Logs a debug message
|
|
54
|
-
* @param message - Debug message
|
|
55
|
-
* @param options - Additional logging options
|
|
56
|
-
*/
|
|
57
|
-
debug(message: string | Error | Record<string, unknown>, options?: GeneralLogOptions): void;
|
|
58
|
-
/**
|
|
59
|
-
* Logs an HTTP request
|
|
60
|
-
* @param req - Express request object
|
|
61
|
-
* @param options - Additional logging options
|
|
62
|
-
* @returns The request ID for correlating with the response
|
|
63
|
-
*/
|
|
64
|
-
httpRequest(req: Request, options?: HttpRequestLogOptions): string;
|
|
65
|
-
/**
|
|
66
|
-
* Logs an HTTP response
|
|
67
|
-
* @param res - Express response object
|
|
68
|
-
* @param req - Express request object
|
|
69
|
-
* @param options - Additional logging options
|
|
70
|
-
*/
|
|
71
|
-
httpResponse(res: Response, req: Request, options?: HttpResponseLogOptions): void;
|
|
72
|
-
/**
|
|
73
|
-
* Logs an SFTP transaction
|
|
74
|
-
* @param operation - SFTP operation details
|
|
75
|
-
* @param options - Additional logging options
|
|
76
|
-
*/
|
|
77
|
-
sftpTransaction(operation: {
|
|
78
|
-
host: string;
|
|
79
|
-
username: string;
|
|
80
|
-
operation: 'upload' | 'download' | 'list' | 'delete' | 'rename' | 'stat';
|
|
81
|
-
path: string;
|
|
82
|
-
status: 'success' | 'failure';
|
|
83
|
-
bytesTransferred?: number;
|
|
84
|
-
filesListed?: number;
|
|
85
|
-
sourcePath?: string;
|
|
86
|
-
}, options?: SftpTransactionLogOptions): void;
|
|
87
|
-
/**
|
|
88
|
-
* Logs a database query transaction
|
|
89
|
-
* @param query - Database query details
|
|
90
|
-
* @param options - Additional logging options
|
|
91
|
-
*/
|
|
92
|
-
dbQueryTransaction(query: {
|
|
93
|
-
instance: string;
|
|
94
|
-
vendor: 'postgres' | 'mysql' | 'mssql' | 'mongodb';
|
|
95
|
-
query?: string;
|
|
96
|
-
status: 'success' | 'failure';
|
|
97
|
-
rowsReturned?: number;
|
|
98
|
-
rowsAffected?: number;
|
|
99
|
-
}, options?: DbQueryTransactionLogOptions): void;
|
|
100
|
-
traceMiddleware: (req: Request, res: Response, next: NextFunction) => void;
|
|
101
|
-
axiosTraceMiddleware: {
|
|
102
|
-
onFulfilled: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig;
|
|
103
|
-
onRejected: (error: any) => any;
|
|
104
|
-
};
|
|
105
|
-
}
|
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.UnnboundLogger = void 0;
|
|
7
|
-
/**
|
|
8
|
-
* Core logger implementation
|
|
9
|
-
*/
|
|
10
|
-
const pino_1 = __importDefault(require("pino"));
|
|
11
|
-
const id_generator_1 = require("./utils/id-generator");
|
|
12
|
-
const logger_utils_1 = require("./utils/logger-utils");
|
|
13
|
-
const uuid_1 = require("uuid");
|
|
14
|
-
const trace_context_1 = require("./utils/trace-context");
|
|
15
|
-
const axios_1 = require("axios");
|
|
16
|
-
/**
|
|
17
|
-
* UnnboundLogger provides typed, structured logging using Pino
|
|
18
|
-
*/
|
|
19
|
-
class UnnboundLogger {
|
|
20
|
-
/**
|
|
21
|
-
* Creates a new UnnboundLogger instance
|
|
22
|
-
* @param options - Configuration options for the logger
|
|
23
|
-
*/
|
|
24
|
-
constructor(options = {}) {
|
|
25
|
-
// Trace middleware
|
|
26
|
-
this.traceMiddleware = (req, res, next) => {
|
|
27
|
-
// Check if the route should be ignored
|
|
28
|
-
if (this.shouldIgnorePath(req.path, this.ignoreTraceRoutes)) {
|
|
29
|
-
return next();
|
|
30
|
-
}
|
|
31
|
-
const traceId = req.header(this.traceHeaderKey) || (0, uuid_1.v4)();
|
|
32
|
-
res.setHeader(this.traceHeaderKey, traceId);
|
|
33
|
-
trace_context_1.traceContext.run(traceId, () => {
|
|
34
|
-
next();
|
|
35
|
-
});
|
|
36
|
-
};
|
|
37
|
-
// Axios trace middleware
|
|
38
|
-
this.axiosTraceMiddleware = {
|
|
39
|
-
onFulfilled: (config) => {
|
|
40
|
-
// Check if the URL should be ignored
|
|
41
|
-
if (config.url && this.shouldIgnorePath(config.url, this.ignoreAxiosTraceRoutes)) {
|
|
42
|
-
return config;
|
|
43
|
-
}
|
|
44
|
-
const traceId = trace_context_1.traceContext.getTraceId();
|
|
45
|
-
if (traceId) {
|
|
46
|
-
const headers = new axios_1.AxiosHeaders(config.headers);
|
|
47
|
-
headers.set(this.traceHeaderKey, traceId);
|
|
48
|
-
config.headers = headers;
|
|
49
|
-
}
|
|
50
|
-
return config;
|
|
51
|
-
},
|
|
52
|
-
onRejected: (error) => {
|
|
53
|
-
return Promise.reject(error);
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
this.defaultLevel = options.defaultLevel || 'info';
|
|
57
|
-
this.serviceName = options.serviceName;
|
|
58
|
-
this.environment = options.environment;
|
|
59
|
-
this.traceHeaderKey = options.traceHeaderKey || 'unnbound-trace-id';
|
|
60
|
-
this.ignoreTraceRoutes = options.ignoreTraceRoutes || [];
|
|
61
|
-
this.ignoreAxiosTraceRoutes = options.ignoreAxiosTraceRoutes || [];
|
|
62
|
-
// Create Pino logger
|
|
63
|
-
this.logger = (0, pino_1.default)({
|
|
64
|
-
level: this.defaultLevel,
|
|
65
|
-
base: {
|
|
66
|
-
...(this.serviceName && { service: this.serviceName }),
|
|
67
|
-
...(this.environment && { environment: this.environment }),
|
|
68
|
-
},
|
|
69
|
-
formatters: {
|
|
70
|
-
level: (label) => {
|
|
71
|
-
return { level: label };
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
timestamp: () => `,"timestamp":"${new Date().toISOString()}"`,
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Checks if a path matches any of the ignore patterns
|
|
79
|
-
* @param path - The path to check
|
|
80
|
-
* @param patterns - Array of glob patterns to match against
|
|
81
|
-
* @returns boolean indicating if the path should be ignored
|
|
82
|
-
*/
|
|
83
|
-
shouldIgnorePath(path, patterns) {
|
|
84
|
-
return patterns.some(pattern => {
|
|
85
|
-
// Convert glob pattern to regex
|
|
86
|
-
const regexPattern = pattern
|
|
87
|
-
.replace(/\./g, '\\.') // Escape dots
|
|
88
|
-
.replace(/\*/g, '.*') // Convert * to .*
|
|
89
|
-
.replace(/\?/g, '.'); // Convert ? to .
|
|
90
|
-
const regex = new RegExp(`^${regexPattern}$`);
|
|
91
|
-
return regex.test(path);
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Logs a general message
|
|
96
|
-
* @param level - Log level
|
|
97
|
-
* @param message - Log message
|
|
98
|
-
* @param options - Additional logging options
|
|
99
|
-
*/
|
|
100
|
-
log(level, message, options = {}) {
|
|
101
|
-
const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, id_generator_1.generateUuid)();
|
|
102
|
-
const requestId = options.requestId || (0, id_generator_1.generateUuid)();
|
|
103
|
-
let logEntry;
|
|
104
|
-
let error;
|
|
105
|
-
if (message instanceof Error) {
|
|
106
|
-
error = {
|
|
107
|
-
name: message.name,
|
|
108
|
-
message: message.message,
|
|
109
|
-
stack: message.stack,
|
|
110
|
-
};
|
|
111
|
-
logEntry = {
|
|
112
|
-
level,
|
|
113
|
-
type: 'general',
|
|
114
|
-
message: message.message,
|
|
115
|
-
traceId,
|
|
116
|
-
requestId,
|
|
117
|
-
error,
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
else if (typeof message === 'string') {
|
|
121
|
-
logEntry = {
|
|
122
|
-
level,
|
|
123
|
-
type: 'general',
|
|
124
|
-
message,
|
|
125
|
-
traceId,
|
|
126
|
-
requestId,
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
// If message is an object, stringify it
|
|
131
|
-
logEntry = {
|
|
132
|
-
level,
|
|
133
|
-
type: 'general',
|
|
134
|
-
message: JSON.stringify(message),
|
|
135
|
-
traceId,
|
|
136
|
-
requestId,
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
this.logger[level](logEntry);
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Logs an error message
|
|
143
|
-
* @param message - Error message or object
|
|
144
|
-
* @param options - Additional logging options
|
|
145
|
-
*/
|
|
146
|
-
error(message, options = {}) {
|
|
147
|
-
this.log('error', message, options);
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Logs a warning message
|
|
151
|
-
* @param message - Warning message
|
|
152
|
-
* @param options - Additional logging options
|
|
153
|
-
*/
|
|
154
|
-
warn(message, options = {}) {
|
|
155
|
-
this.log('warn', message, options);
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Logs an info message
|
|
159
|
-
* @param message - Info message
|
|
160
|
-
* @param options - Additional logging options
|
|
161
|
-
*/
|
|
162
|
-
info(message, options = {}) {
|
|
163
|
-
this.log('info', message, options);
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Logs a debug message
|
|
167
|
-
* @param message - Debug message
|
|
168
|
-
* @param options - Additional logging options
|
|
169
|
-
*/
|
|
170
|
-
debug(message, options = {}) {
|
|
171
|
-
this.log('debug', message, options);
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Logs an HTTP request
|
|
175
|
-
* @param req - Express request object
|
|
176
|
-
* @param options - Additional logging options
|
|
177
|
-
* @returns The request ID for correlating with the response
|
|
178
|
-
*/
|
|
179
|
-
httpRequest(req, options = {}) {
|
|
180
|
-
const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, id_generator_1.generateUuid)();
|
|
181
|
-
const requestId = options.requestId || (0, id_generator_1.generateUuid)();
|
|
182
|
-
const startTime = options.startTime || Date.now();
|
|
183
|
-
// Store request metadata in res.locals for later use
|
|
184
|
-
if (req.res) {
|
|
185
|
-
req.res.locals.requestId = requestId;
|
|
186
|
-
req.res.locals.startTime = startTime;
|
|
187
|
-
req.res.locals.traceId = traceId;
|
|
188
|
-
}
|
|
189
|
-
const logEntry = {
|
|
190
|
-
level: options.level || this.defaultLevel,
|
|
191
|
-
type: 'httpRequest',
|
|
192
|
-
message: `${req.method} ${req.originalUrl || req.url}`,
|
|
193
|
-
traceId,
|
|
194
|
-
requestId,
|
|
195
|
-
duration: 0, // Will be updated in response
|
|
196
|
-
httpRequest: {
|
|
197
|
-
url: req.originalUrl || req.url,
|
|
198
|
-
method: req.method,
|
|
199
|
-
headers: (0, logger_utils_1.filterHeaders)(req.headers),
|
|
200
|
-
ip: req.ip,
|
|
201
|
-
body: req.body,
|
|
202
|
-
},
|
|
203
|
-
};
|
|
204
|
-
this.logger[options.level || this.defaultLevel](logEntry);
|
|
205
|
-
return requestId;
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Logs an HTTP response
|
|
209
|
-
* @param res - Express response object
|
|
210
|
-
* @param req - Express request object
|
|
211
|
-
* @param options - Additional logging options
|
|
212
|
-
*/
|
|
213
|
-
httpResponse(res, req, options = {}) {
|
|
214
|
-
const requestId = res.locals.requestId || options.requestId || (0, id_generator_1.generateUuid)();
|
|
215
|
-
const startTime = res.locals.startTime || options.startTime || Date.now();
|
|
216
|
-
const traceId = res.locals.traceId || options.traceId || trace_context_1.traceContext.getTraceId() || (0, id_generator_1.generateUuid)();
|
|
217
|
-
const duration = options.duration || (Date.now() - startTime);
|
|
218
|
-
// Determine log level based on status code
|
|
219
|
-
let level = options.level || this.defaultLevel;
|
|
220
|
-
if (!options.level) {
|
|
221
|
-
if (res.statusCode >= 500) {
|
|
222
|
-
level = 'error';
|
|
223
|
-
}
|
|
224
|
-
else if (res.statusCode >= 400) {
|
|
225
|
-
level = 'warn';
|
|
226
|
-
}
|
|
227
|
-
else {
|
|
228
|
-
level = 'info';
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
const logEntry = {
|
|
232
|
-
level,
|
|
233
|
-
type: 'httpResponse',
|
|
234
|
-
message: `${req.method} ${req.originalUrl || req.url} - ${res.statusCode}`,
|
|
235
|
-
traceId,
|
|
236
|
-
requestId,
|
|
237
|
-
duration,
|
|
238
|
-
httpResponse: {
|
|
239
|
-
url: req.originalUrl || req.url,
|
|
240
|
-
method: req.method,
|
|
241
|
-
headers: (0, logger_utils_1.filterHeaders)(res.getHeaders()),
|
|
242
|
-
ip: req.ip,
|
|
243
|
-
status: res.statusCode,
|
|
244
|
-
body: res.locals.body,
|
|
245
|
-
},
|
|
246
|
-
};
|
|
247
|
-
this.logger[level](logEntry);
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Logs an SFTP transaction
|
|
251
|
-
* @param operation - SFTP operation details
|
|
252
|
-
* @param options - Additional logging options
|
|
253
|
-
*/
|
|
254
|
-
sftpTransaction(operation, options = {}) {
|
|
255
|
-
const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, id_generator_1.generateUuid)();
|
|
256
|
-
const requestId = options.requestId || (0, id_generator_1.generateUuid)();
|
|
257
|
-
const duration = options.duration || (options.startTime ? Date.now() - options.startTime : 0);
|
|
258
|
-
const level = operation.status === 'success' ? 'info' : 'error';
|
|
259
|
-
const logEntry = {
|
|
260
|
-
level,
|
|
261
|
-
type: 'sftpTransaction',
|
|
262
|
-
message: `SFTP ${operation.operation} ${operation.status} - ${operation.path}`,
|
|
263
|
-
traceId,
|
|
264
|
-
requestId,
|
|
265
|
-
duration,
|
|
266
|
-
sftp: operation,
|
|
267
|
-
};
|
|
268
|
-
this.logger[level](logEntry);
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Logs a database query transaction
|
|
272
|
-
* @param query - Database query details
|
|
273
|
-
* @param options - Additional logging options
|
|
274
|
-
*/
|
|
275
|
-
dbQueryTransaction(query, options = {}) {
|
|
276
|
-
const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, id_generator_1.generateUuid)();
|
|
277
|
-
const requestId = options.requestId || (0, id_generator_1.generateUuid)();
|
|
278
|
-
const duration = options.duration || (options.startTime ? Date.now() - options.startTime : 0);
|
|
279
|
-
const level = query.status === 'success' ? 'info' : 'error';
|
|
280
|
-
const logEntry = {
|
|
281
|
-
level,
|
|
282
|
-
type: 'dbQueryTransaction',
|
|
283
|
-
message: `DB Query ${query.status} - ${query.vendor}`,
|
|
284
|
-
traceId,
|
|
285
|
-
requestId,
|
|
286
|
-
duration,
|
|
287
|
-
db: query,
|
|
288
|
-
};
|
|
289
|
-
this.logger[level](logEntry);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
exports.UnnboundLogger = UnnboundLogger;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generates a new UUID v4
|
|
3
|
-
* @returns A UUID v4 string
|
|
4
|
-
*/
|
|
5
|
-
export declare function generateUuid(): string;
|
|
6
|
-
/**
|
|
7
|
-
* Generates the current timestamp in ISO format
|
|
8
|
-
* @returns ISO timestamp string
|
|
9
|
-
*/
|
|
10
|
-
export declare function generateTimestamp(): string;
|
|
11
|
-
/**
|
|
12
|
-
* Gets or creates a trace ID for a workflow
|
|
13
|
-
* @param workflowId - The workflow ID to get a trace ID for
|
|
14
|
-
* @returns A trace ID associated with the workflow
|
|
15
|
-
*/
|
|
16
|
-
export declare function getTraceId(workflowId: string): string;
|
|
17
|
-
/**
|
|
18
|
-
* Clears a trace ID from the map
|
|
19
|
-
* @param workflowId - The workflow ID to clear
|
|
20
|
-
*/
|
|
21
|
-
export declare function clearTraceId(workflowId: string): void;
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateUuid = generateUuid;
|
|
4
|
-
exports.generateTimestamp = generateTimestamp;
|
|
5
|
-
exports.getTraceId = getTraceId;
|
|
6
|
-
exports.clearTraceId = clearTraceId;
|
|
7
|
-
/**
|
|
8
|
-
* Utilities for generating unique identifiers
|
|
9
|
-
*/
|
|
10
|
-
const uuid_1 = require("uuid");
|
|
11
|
-
/**
|
|
12
|
-
* Generates a new UUID v4
|
|
13
|
-
* @returns A UUID v4 string
|
|
14
|
-
*/
|
|
15
|
-
function generateUuid() {
|
|
16
|
-
return (0, uuid_1.v4)();
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Generates the current timestamp in ISO format
|
|
20
|
-
* @returns ISO timestamp string
|
|
21
|
-
*/
|
|
22
|
-
function generateTimestamp() {
|
|
23
|
-
return new Date().toISOString();
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Stores trace IDs by workflow ID for consistent tracking
|
|
27
|
-
*/
|
|
28
|
-
const traceIdMap = new Map();
|
|
29
|
-
/**
|
|
30
|
-
* Gets or creates a trace ID for a workflow
|
|
31
|
-
* @param workflowId - The workflow ID to get a trace ID for
|
|
32
|
-
* @returns A trace ID associated with the workflow
|
|
33
|
-
*/
|
|
34
|
-
function getTraceId(workflowId) {
|
|
35
|
-
if (!traceIdMap.has(workflowId)) {
|
|
36
|
-
traceIdMap.set(workflowId, generateUuid());
|
|
37
|
-
}
|
|
38
|
-
return traceIdMap.get(workflowId);
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Clears a trace ID from the map
|
|
42
|
-
* @param workflowId - The workflow ID to clear
|
|
43
|
-
*/
|
|
44
|
-
function clearTraceId(workflowId) {
|
|
45
|
-
traceIdMap.delete(workflowId);
|
|
46
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utility functions for logging
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Filters an object of headers, returning a new object with only the allowed headers.
|
|
6
|
-
* @param headers The original headers object.
|
|
7
|
-
* @returns A new object containing only the headers from the allow-list.
|
|
8
|
-
*/
|
|
9
|
-
export declare function filterHeaders(headers: Record<string, any>): Record<string, string>;
|
|
10
|
-
/**
|
|
11
|
-
* Safely parses JSON strings, returning the original data if parsing fails or if it's not a string.
|
|
12
|
-
* @param data The data to potentially parse as JSON.
|
|
13
|
-
* @returns Parsed JSON object or the original data.
|
|
14
|
-
*/
|
|
15
|
-
export declare function safeJsonParse(data: any): any;
|
|
16
|
-
/**
|
|
17
|
-
* Normalizes IP addresses by removing IPv6 mapping prefix for IPv4 addresses.
|
|
18
|
-
* @param ip The IP address to normalize.
|
|
19
|
-
* @returns Normalized IP address string.
|
|
20
|
-
*/
|
|
21
|
-
export declare function normalizeIp(ip: string | undefined): string | undefined;
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Utility functions for logging
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.filterHeaders = filterHeaders;
|
|
7
|
-
exports.safeJsonParse = safeJsonParse;
|
|
8
|
-
exports.normalizeIp = normalizeIp;
|
|
9
|
-
// --- Header Allow-Listing ---
|
|
10
|
-
const ALLOWED_HEADERS = new Set([
|
|
11
|
-
'content-type',
|
|
12
|
-
'accept',
|
|
13
|
-
'user-agent',
|
|
14
|
-
'host',
|
|
15
|
-
'x-forwarded-for',
|
|
16
|
-
'x-request-id',
|
|
17
|
-
'content-length',
|
|
18
|
-
'cache-control',
|
|
19
|
-
]);
|
|
20
|
-
/**
|
|
21
|
-
* Filters an object of headers, returning a new object with only the allowed headers.
|
|
22
|
-
* @param headers The original headers object.
|
|
23
|
-
* @returns A new object containing only the headers from the allow-list.
|
|
24
|
-
*/
|
|
25
|
-
function filterHeaders(headers) {
|
|
26
|
-
const filtered = {};
|
|
27
|
-
for (const key in headers) {
|
|
28
|
-
if (ALLOWED_HEADERS.has(key.toLowerCase())) {
|
|
29
|
-
filtered[key] = String(headers[key]);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return filtered;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Safely parses JSON strings, returning the original data if parsing fails or if it's not a string.
|
|
36
|
-
* @param data The data to potentially parse as JSON.
|
|
37
|
-
* @returns Parsed JSON object or the original data.
|
|
38
|
-
*/
|
|
39
|
-
function safeJsonParse(data) {
|
|
40
|
-
if (typeof data === 'string') {
|
|
41
|
-
try {
|
|
42
|
-
return JSON.parse(data);
|
|
43
|
-
}
|
|
44
|
-
catch {
|
|
45
|
-
return data;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return data;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Normalizes IP addresses by removing IPv6 mapping prefix for IPv4 addresses.
|
|
52
|
-
* @param ip The IP address to normalize.
|
|
53
|
-
* @returns Normalized IP address string.
|
|
54
|
-
*/
|
|
55
|
-
function normalizeIp(ip) {
|
|
56
|
-
if (!ip)
|
|
57
|
-
return ip;
|
|
58
|
-
// Remove IPv4-mapped IPv6 prefix (::ffff:) to get clean IPv4 address
|
|
59
|
-
if (ip.startsWith('::ffff:')) {
|
|
60
|
-
return ip.substring(7);
|
|
61
|
-
}
|
|
62
|
-
return ip;
|
|
63
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
declare class TraceContextManager {
|
|
2
|
-
private static instance;
|
|
3
|
-
private storage;
|
|
4
|
-
private constructor();
|
|
5
|
-
static getInstance(): TraceContextManager;
|
|
6
|
-
run<T>(traceId: string, callback: () => T): T;
|
|
7
|
-
getTraceId(): string | undefined;
|
|
8
|
-
}
|
|
9
|
-
export declare const traceContext: TraceContextManager;
|
|
10
|
-
export {};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.traceContext = void 0;
|
|
4
|
-
const async_hooks_1 = require("async_hooks");
|
|
5
|
-
class TraceContextManager {
|
|
6
|
-
constructor() {
|
|
7
|
-
this.storage = new async_hooks_1.AsyncLocalStorage();
|
|
8
|
-
}
|
|
9
|
-
static getInstance() {
|
|
10
|
-
if (!TraceContextManager.instance) {
|
|
11
|
-
TraceContextManager.instance = new TraceContextManager();
|
|
12
|
-
}
|
|
13
|
-
return TraceContextManager.instance;
|
|
14
|
-
}
|
|
15
|
-
run(traceId, callback) {
|
|
16
|
-
return this.storage.run({ traceId }, callback);
|
|
17
|
-
}
|
|
18
|
-
getTraceId() {
|
|
19
|
-
const context = this.storage.getStore();
|
|
20
|
-
return context?.traceId;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
exports.traceContext = TraceContextManager.getInstance();
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Higher-order function that wraps a function with trace context
|
|
3
|
-
* @param fn - Function to wrap with trace context
|
|
4
|
-
* @param traceId - Optional trace ID to use (will generate new one if not provided)
|
|
5
|
-
* @returns Wrapped function that maintains trace context
|
|
6
|
-
*/
|
|
7
|
-
export declare function withTrace<T extends (...args: any[]) => any>(fn: T, traceId?: string): T;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.withTrace = withTrace;
|
|
4
|
-
const uuid_1 = require("uuid");
|
|
5
|
-
const trace_context_1 = require("./trace-context");
|
|
6
|
-
/**
|
|
7
|
-
* Higher-order function that wraps a function with trace context
|
|
8
|
-
* @param fn - Function to wrap with trace context
|
|
9
|
-
* @param traceId - Optional trace ID to use (will generate new one if not provided)
|
|
10
|
-
* @returns Wrapped function that maintains trace context
|
|
11
|
-
*/
|
|
12
|
-
function withTrace(fn, traceId) {
|
|
13
|
-
const id = traceId || (0, uuid_1.v4)();
|
|
14
|
-
return ((...args) => {
|
|
15
|
-
return trace_context_1.traceContext.run(id, () => fn(...args));
|
|
16
|
-
});
|
|
17
|
-
}
|