unnbound-logger-sdk 1.1.5 → 2.0.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/README.md CHANGED
@@ -53,6 +53,7 @@ interface Log<T extends LogType = 'general'> {
53
53
  message: string;
54
54
  traceId: string;
55
55
  requestId: string;
56
+ deploymentId: string; // Automatically populated from DEPLOYMENT_ID environment variable
56
57
  error?: SerializableError; // Only present for Error objects
57
58
  }
58
59
 
@@ -61,6 +62,25 @@ interface LogTransaction<T extends LogType> extends Log<T> {
61
62
  }
62
63
  ```
63
64
 
65
+ ## Deployment Tracking
66
+
67
+ The logger automatically includes a `deploymentId` field in all log entries. This field is populated from the `DEPLOYMENT_ID` environment variable, allowing you to track logs across different deployments of your application.
68
+
69
+ ```bash
70
+ # Set the deployment ID in your environment
71
+ export DEPLOYMENT_ID="v1.2.3-prod-20231201"
72
+
73
+ # Or in your deployment configuration
74
+ DEPLOYMENT_ID=v1.2.3-prod-20231201
75
+ ```
76
+
77
+ If the `DEPLOYMENT_ID` environment variable is not set, the `deploymentId` field will be an empty string. This field helps with:
78
+
79
+ - Tracking logs across different application deployments
80
+ - Correlating issues with specific releases
81
+ - Monitoring deployment health and performance
82
+ - Debugging problems in specific deployment versions
83
+
64
84
  ## HTTP Request/Response Logging
65
85
 
66
86
  ```typescript
package/dist/index.d.ts CHANGED
@@ -6,33 +6,5 @@
6
6
  */
7
7
  import { UnnboundLogger } from './unnbound-logger';
8
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;
9
+ import { clearTraceId } from './utils/logger-utils';
10
+ export { UnnboundLogger, LogLevel, LogType, HttpMethod, LoggerOptions, GeneralLogOptions, HttpRequestLogOptions, HttpResponseLogOptions, SftpTransactionLogOptions, DbQueryTransactionLogOptions, Log, LogTransaction, HttpRequestLog, HttpResponseLog, SftpTransactionLog, DbQueryTransactionLog, SerializableError, clearTraceId, };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
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;
3
+ exports.clearTraceId = exports.UnnboundLogger = void 0;
4
4
  /**
5
5
  * unnbound-logger
6
6
  *
@@ -9,21 +9,5 @@ exports.dbQueryTransaction = exports.sftpTransaction = exports.httpResponse = ex
9
9
  */
10
10
  const unnbound_logger_1 = require("./unnbound-logger");
11
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;
12
+ const logger_utils_1 = require("./utils/logger-utils");
13
+ Object.defineProperty(exports, "clearTraceId", { enumerable: true, get: function () { return logger_utils_1.clearTraceId; } });
package/dist/types.d.ts CHANGED
@@ -22,6 +22,7 @@ export interface Log<T extends LogType = 'general'> {
22
22
  level: LogLevel;
23
23
  type: T;
24
24
  message: string;
25
+ deploymentId: string;
25
26
  traceId: string;
26
27
  requestId: string;
27
28
  error?: SerializableError;
@@ -5,6 +5,7 @@ declare module 'axios' {
5
5
  interface InternalAxiosRequestConfig {
6
6
  metadata?: {
7
7
  startTime: number;
8
+ requestId?: string;
8
9
  };
9
10
  }
10
11
  }
@@ -16,6 +17,7 @@ export declare class UnnboundLogger {
16
17
  private defaultLevel;
17
18
  private serviceName?;
18
19
  private environment?;
20
+ private deploymentId;
19
21
  private traceHeaderKey;
20
22
  private ignoreTraceRoutes;
21
23
  private ignoreAxiosTraceRoutes;
@@ -62,6 +64,12 @@ export declare class UnnboundLogger {
62
64
  * @param options - Additional logging options
63
65
  */
64
66
  debug(message: string | Error | Record<string, unknown>, options?: GeneralLogOptions): void;
67
+ /**
68
+ * Constructs the full URL from request information
69
+ * @param req - Express request object
70
+ * @returns Full URL string
71
+ */
72
+ private constructFullUrl;
65
73
  /**
66
74
  * Logs an HTTP request
67
75
  * @param req - Express request object
@@ -8,11 +8,11 @@ exports.UnnboundLogger = void 0;
8
8
  * Core logger implementation
9
9
  */
10
10
  const pino_1 = __importDefault(require("pino"));
11
- const id_generator_1 = require("./utils/id-generator");
12
11
  const logger_utils_1 = require("./utils/logger-utils");
13
12
  const uuid_1 = require("uuid");
14
13
  const trace_context_1 = require("./utils/trace-context");
15
14
  const axios_1 = require("axios");
15
+ const http_status_messages_1 = require("./utils/http-status-messages");
16
16
  /**
17
17
  * UnnboundLogger provides typed, structured logging using Pino
18
18
  */
@@ -59,8 +59,10 @@ class UnnboundLogger {
59
59
  headers.set(this.traceHeaderKey, traceId);
60
60
  config.headers = headers;
61
61
  }
62
- // Store request start time for duration calculation
63
- config.metadata = { startTime: Date.now() };
62
+ // Store request start time and generate requestId for duration calculation and correlation
63
+ const startTime = Date.now();
64
+ const requestId = (0, uuid_1.v4)();
65
+ config.metadata = { startTime, requestId };
64
66
  // Log the outgoing request using proper httpRequest method
65
67
  const mockReq = {
66
68
  method: config.method?.toUpperCase() || 'UNKNOWN',
@@ -68,11 +70,15 @@ class UnnboundLogger {
68
70
  originalUrl: `${config.baseURL || ''}${config.url}`,
69
71
  headers: config.headers || {},
70
72
  body: config.data,
71
- ip: 'outgoing' // Mark as outgoing request
73
+ ip: 'outgoing', // Mark as outgoing request
74
+ protocol: 'https', // Default for outgoing
75
+ secure: true,
76
+ get: () => undefined // Mock get method for constructFullUrl
72
77
  };
73
78
  this.httpRequest(mockReq, {
74
79
  traceId,
75
- startTime: config.metadata.startTime
80
+ requestId,
81
+ startTime
76
82
  });
77
83
  return config;
78
84
  },
@@ -85,24 +91,30 @@ class UnnboundLogger {
85
91
  onFulfilled: (response) => {
86
92
  // Calculate duration
87
93
  const startTime = response.config.metadata?.startTime || Date.now();
94
+ const requestId = response.config.metadata?.requestId;
88
95
  const duration = Date.now() - startTime;
89
96
  // Log the successful response using proper httpResponse method
90
97
  const mockReq = {
91
98
  method: response.config.method?.toUpperCase() || 'UNKNOWN',
92
99
  url: `${response.config.baseURL || ''}${response.config.url}`,
93
100
  originalUrl: `${response.config.baseURL || ''}${response.config.url}`,
94
- ip: 'outgoing' // Mark as outgoing request
101
+ ip: 'outgoing', // Mark as outgoing request
102
+ protocol: 'https', // Default for outgoing
103
+ secure: true,
104
+ get: () => undefined // Mock get method for constructFullUrl
95
105
  };
96
106
  const mockRes = {
97
107
  statusCode: response.status,
98
108
  locals: {
99
109
  body: response.data,
100
110
  startTime: startTime,
101
- traceId: trace_context_1.traceContext.getTraceId()
111
+ traceId: trace_context_1.traceContext.getTraceId(),
112
+ requestId: requestId
102
113
  },
103
114
  getHeaders: () => response.headers || {}
104
115
  };
105
116
  this.httpResponse(mockRes, mockReq, {
117
+ requestId,
106
118
  duration,
107
119
  traceId: trace_context_1.traceContext.getTraceId()
108
120
  });
@@ -111,6 +123,7 @@ class UnnboundLogger {
111
123
  onRejected: (error) => {
112
124
  // Calculate duration for error responses
113
125
  const startTime = error.config?.metadata?.startTime || Date.now();
126
+ const requestId = error.config?.metadata?.requestId;
114
127
  const duration = Date.now() - startTime;
115
128
  // Log the error response using proper httpResponse method
116
129
  if (error.response) {
@@ -118,27 +131,38 @@ class UnnboundLogger {
118
131
  method: error.config?.method?.toUpperCase() || 'UNKNOWN',
119
132
  url: `${error.config?.baseURL || ''}${error.config?.url}`,
120
133
  originalUrl: `${error.config?.baseURL || ''}${error.config?.url}`,
121
- ip: 'outgoing' // Mark as outgoing request
134
+ ip: 'outgoing', // Mark as outgoing request
135
+ protocol: 'https', // Default for outgoing
136
+ secure: true,
137
+ get: () => undefined // Mock get method for constructFullUrl
122
138
  };
123
139
  const mockRes = {
124
140
  statusCode: error.response.status,
125
141
  locals: {
126
142
  body: error.response.data,
127
143
  startTime: startTime,
128
- traceId: trace_context_1.traceContext.getTraceId()
144
+ traceId: trace_context_1.traceContext.getTraceId(),
145
+ requestId: requestId
129
146
  },
130
147
  getHeaders: () => error.response.headers || {}
131
148
  };
132
149
  this.httpResponse(mockRes, mockReq, {
150
+ requestId,
133
151
  duration,
134
152
  traceId: trace_context_1.traceContext.getTraceId()
135
153
  });
136
154
  }
137
155
  else {
138
156
  // For network errors without response, log as general error
139
- this.error(`HTTP Request Failed: ${error.config?.method?.toUpperCase()} ${error.config?.baseURL || ''}${error.config?.url}`, {
140
- context: 'No response received',
141
- error: error.message
157
+ this.error('HTTP Request Failed', {
158
+ context: {
159
+ reason: 'No response received',
160
+ method: error.config?.method?.toUpperCase() || 'UNKNOWN',
161
+ url: `${error.config?.baseURL || ''}${error.config?.url}`,
162
+ },
163
+ error: error.message,
164
+ requestId,
165
+ traceId: trace_context_1.traceContext.getTraceId()
142
166
  });
143
167
  }
144
168
  return Promise.reject(error);
@@ -147,6 +171,7 @@ class UnnboundLogger {
147
171
  this.defaultLevel = options.defaultLevel || 'info';
148
172
  this.serviceName = options.serviceName;
149
173
  this.environment = options.environment;
174
+ this.deploymentId = process.env.DEPLOYMENT_ID || '';
150
175
  this.traceHeaderKey = options.traceHeaderKey || 'unnbound-trace-id';
151
176
  this.ignoreTraceRoutes = options.ignoreTraceRoutes || [];
152
177
  this.ignoreAxiosTraceRoutes = options.ignoreAxiosTraceRoutes || [];
@@ -157,7 +182,7 @@ class UnnboundLogger {
157
182
  ...(this.serviceName && { service: this.serviceName }),
158
183
  ...(this.environment && { environment: this.environment }),
159
184
  },
160
- timestamp: () => `,"timestamp":"${new Date().toISOString()}"`,
185
+ timestamp: false, // Let CloudWatch handle timestamps
161
186
  formatters: {
162
187
  level: (label) => {
163
188
  return { level: label };
@@ -189,39 +214,46 @@ class UnnboundLogger {
189
214
  * @param options - Additional logging options
190
215
  */
191
216
  log(level, message, options = {}) {
192
- const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, id_generator_1.generateUuid)();
193
- const requestId = options.requestId || (0, id_generator_1.generateUuid)();
217
+ const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, uuid_1.v4)();
218
+ const requestId = options.requestId || (0, uuid_1.v4)();
194
219
  let logEntry;
195
- let error;
220
+ const { traceId: optionTraceId, requestId: optionRequestId, ...restOptions } = options;
196
221
  if (message instanceof Error) {
197
- error = {
222
+ const error = {
198
223
  name: message.name,
199
224
  message: message.message,
200
225
  stack: message.stack,
201
226
  };
202
227
  logEntry = {
203
228
  type: 'general',
204
- message: message.message,
205
229
  traceId,
206
230
  requestId,
231
+ deploymentId: this.deploymentId,
232
+ message: message.name,
207
233
  error,
234
+ ...restOptions,
208
235
  };
209
236
  }
210
237
  else if (typeof message === 'string') {
211
238
  logEntry = {
212
239
  type: 'general',
213
- message,
214
240
  traceId,
215
241
  requestId,
242
+ deploymentId: this.deploymentId,
243
+ message,
244
+ ...restOptions,
216
245
  };
217
246
  }
218
247
  else {
219
- // If message is an object, stringify it
248
+ // If message is an object, it's part of the log entry
220
249
  logEntry = {
221
250
  type: 'general',
222
- message: JSON.stringify(message),
223
251
  traceId,
224
252
  requestId,
253
+ deploymentId: this.deploymentId,
254
+ ...message,
255
+ message: message.message || 'Structured log data',
256
+ ...restOptions,
225
257
  };
226
258
  }
227
259
  this.logger[level](logEntry);
@@ -258,6 +290,28 @@ class UnnboundLogger {
258
290
  debug(message, options = {}) {
259
291
  this.log('debug', message, options);
260
292
  }
293
+ /**
294
+ * Constructs the full URL from request information
295
+ * @param req - Express request object
296
+ * @returns Full URL string
297
+ */
298
+ constructFullUrl(req) {
299
+ // If the URL is already absolute, return it directly
300
+ const reqUrl = req.originalUrl || req.url;
301
+ if (reqUrl?.startsWith('http://') || reqUrl?.startsWith('https://')) {
302
+ return reqUrl;
303
+ }
304
+ // Check if we have a base URL configured via environment variable
305
+ const serviceBaseUrl = process.env.SERVICE_BASE_URL;
306
+ if (serviceBaseUrl) {
307
+ // Use configured base URL (useful for ECS when you know your service URL)
308
+ return `${serviceBaseUrl.replace(/\/$/, '')}${reqUrl}`;
309
+ }
310
+ // Fallback to constructing from request info for incoming requests
311
+ const protocol = req.protocol || (req.secure ? 'https' : 'http');
312
+ const host = req.get('host') || req.get('x-forwarded-host') || 'localhost';
313
+ return `${protocol}://${host}${reqUrl}`;
314
+ }
261
315
  /**
262
316
  * Logs an HTTP request
263
317
  * @param req - Express request object
@@ -265,8 +319,8 @@ class UnnboundLogger {
265
319
  * @returns The request ID for correlating with the response
266
320
  */
267
321
  httpRequest(req, options = {}) {
268
- const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, id_generator_1.generateUuid)();
269
- const requestId = options.requestId || (0, id_generator_1.generateUuid)();
322
+ const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, uuid_1.v4)();
323
+ const requestId = options.requestId || (0, uuid_1.v4)();
270
324
  const startTime = options.startTime || Date.now();
271
325
  // Store request metadata in res.locals for later use
272
326
  if (req.res) {
@@ -276,12 +330,13 @@ class UnnboundLogger {
276
330
  }
277
331
  const logEntry = {
278
332
  type: 'httpRequest',
279
- message: `${req.method} ${req.originalUrl || req.url}`,
333
+ message: req.ip === 'outgoing' ? 'Outgoing HTTP Request' : 'Incoming HTTP Request',
280
334
  traceId,
281
335
  requestId,
336
+ deploymentId: this.deploymentId,
282
337
  duration: 0, // Will be updated in response
283
338
  httpRequest: {
284
- url: req.originalUrl || req.url,
339
+ url: this.constructFullUrl(req),
285
340
  method: req.method,
286
341
  headers: (0, logger_utils_1.filterHeaders)(req.headers),
287
342
  ip: (0, logger_utils_1.normalizeIp)(req.ip),
@@ -298,9 +353,9 @@ class UnnboundLogger {
298
353
  * @param options - Additional logging options
299
354
  */
300
355
  httpResponse(res, req, options = {}) {
301
- const requestId = res.locals.requestId || options.requestId || (0, id_generator_1.generateUuid)();
356
+ const requestId = res.locals.requestId || options.requestId || (0, uuid_1.v4)();
302
357
  const startTime = res.locals.startTime || options.startTime || Date.now();
303
- const traceId = res.locals.traceId || options.traceId || trace_context_1.traceContext.getTraceId() || (0, id_generator_1.generateUuid)();
358
+ const traceId = res.locals.traceId || options.traceId || trace_context_1.traceContext.getTraceId() || (0, uuid_1.v4)();
304
359
  const duration = options.duration || (Date.now() - startTime);
305
360
  // Determine log level based on status code
306
361
  let level = options.level || this.defaultLevel;
@@ -317,12 +372,13 @@ class UnnboundLogger {
317
372
  }
318
373
  const logEntry = {
319
374
  type: 'httpResponse',
320
- message: `${req.method} ${req.originalUrl || req.url} - ${res.statusCode}`,
375
+ message: (0, http_status_messages_1.getStatusMessage)(res.statusCode),
321
376
  traceId,
322
377
  requestId,
378
+ deploymentId: this.deploymentId,
323
379
  duration,
324
380
  httpResponse: {
325
- url: req.originalUrl || req.url,
381
+ url: this.constructFullUrl(req),
326
382
  method: req.method,
327
383
  headers: (0, logger_utils_1.filterHeaders)(res.getHeaders()),
328
384
  ip: (0, logger_utils_1.normalizeIp)(req.ip),
@@ -338,8 +394,8 @@ class UnnboundLogger {
338
394
  * @param options - Additional logging options
339
395
  */
340
396
  sftpTransaction(operation, options = {}) {
341
- const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, id_generator_1.generateUuid)();
342
- const requestId = options.requestId || (0, id_generator_1.generateUuid)();
397
+ const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, uuid_1.v4)();
398
+ const requestId = options.requestId || (0, uuid_1.v4)();
343
399
  const duration = options.duration || (options.startTime ? Date.now() - options.startTime : 0);
344
400
  const level = operation.status === 'success' ? 'info' : 'error';
345
401
  const logEntry = {
@@ -347,6 +403,7 @@ class UnnboundLogger {
347
403
  message: `SFTP ${operation.operation} ${operation.status} - ${operation.path}`,
348
404
  traceId,
349
405
  requestId,
406
+ deploymentId: this.deploymentId,
350
407
  duration,
351
408
  sftp: operation,
352
409
  };
@@ -358,8 +415,8 @@ class UnnboundLogger {
358
415
  * @param options - Additional logging options
359
416
  */
360
417
  dbQueryTransaction(query, options = {}) {
361
- const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, id_generator_1.generateUuid)();
362
- const requestId = options.requestId || (0, id_generator_1.generateUuid)();
418
+ const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, uuid_1.v4)();
419
+ const requestId = options.requestId || (0, uuid_1.v4)();
363
420
  const duration = options.duration || (options.startTime ? Date.now() - options.startTime : 0);
364
421
  const level = query.status === 'success' ? 'info' : 'error';
365
422
  const logEntry = {
@@ -367,6 +424,7 @@ class UnnboundLogger {
367
424
  message: `DB Query ${query.status} - ${query.vendor}`,
368
425
  traceId,
369
426
  requestId,
427
+ deploymentId: this.deploymentId,
370
428
  duration,
371
429
  db: query,
372
430
  };
@@ -0,0 +1,9 @@
1
+ interface HttpStatus {
2
+ message: string;
3
+ description: string;
4
+ }
5
+ export declare const httpStatusDetails: {
6
+ [key: number]: HttpStatus;
7
+ };
8
+ export declare function getStatusMessage(statusCode: number): string;
9
+ export {};
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.httpStatusDetails = void 0;
4
+ exports.getStatusMessage = getStatusMessage;
5
+ exports.httpStatusDetails = {
6
+ 100: { message: 'Continue', description: 'The server has received the request headers, and the client should proceed to send the request body' },
7
+ 101: { message: 'Switching Protocols', description: 'The requester has asked the server to switch protocols' },
8
+ 103: { message: 'Early Hints', description: 'Used with the Link header to allow the browser to start preloading resources while the server prepares a response' },
9
+ 200: { message: 'OK', description: 'The request is OK' },
10
+ 201: { message: 'Created', description: 'The request has been fulfilled, and a new resource is created' },
11
+ 202: { message: 'Accepted', description: 'The request has been accepted for processing, but the processing has not been completed' },
12
+ 203: { message: 'Non-Authoritative Information', description: 'The request has been successfully processed, but is returning information that may be from another source' },
13
+ 204: { message: 'No Content', description: 'The request has been successfully processed, but is not returning any content' },
14
+ 205: { message: 'Reset Content', description: 'The request has been successfully processed, but is not returning any content, and requires that the requester reset the document view' },
15
+ 206: { message: 'Partial Content', description: 'The server is delivering only part of the resource due to a range header sent by the client' },
16
+ 300: { message: 'Multiple Choices', description: 'A link list. The user can select a link and go to that location. Maximum five addresses' },
17
+ 301: { message: 'Moved Permanently', description: 'The requested page has moved to a new URL' },
18
+ 302: { message: 'Found', description: 'The requested page has moved temporarily to a new URL' },
19
+ 303: { message: 'See Other', description: 'The requested page can be found under a different URL' },
20
+ 304: { message: 'Not Modified', description: 'Indicates the requested page has not been modified since last requested' },
21
+ 307: { message: 'Temporary Redirect', description: 'The requested page has moved temporarily to a new URL' },
22
+ 308: { message: 'Permanent Redirect', description: 'The requested page has moved permanently to a new URL' },
23
+ 400: { message: 'Bad Request', description: 'The request cannot be fulfilled due to bad syntax' },
24
+ 401: { message: 'Unauthorized', description: 'The request was a legal request, but the server is refusing to respond to it. For use when authentication is possible but has failed or not yet been provided' },
25
+ 402: { message: 'Payment Required', description: 'Reserved for future use' },
26
+ 403: { message: 'Forbidden', description: 'The request was a legal request, but the server is refusing to respond to it' },
27
+ 404: { message: 'Not Found', description: 'The requested page could not be found but may be available again in the future' },
28
+ 405: { message: 'Method Not Allowed', description: 'A request was made of a page using a request method not supported by that page' },
29
+ 406: { message: 'Not Acceptable', description: 'The server can only generate a response that is not accepted by the client' },
30
+ 407: { message: 'Proxy Authentication Required', description: 'The client must first authenticate itself with the proxy' },
31
+ 408: { message: 'Request Timeout', description: 'The server timed out waiting for the request' },
32
+ 409: { message: 'Conflict', description: 'The request could not be completed because of a conflict in the request' },
33
+ 410: { message: 'Gone', description: 'The requested page is no longer available' },
34
+ 411: { message: 'Length Required', description: 'The "Content-Length" is not defined. The server will not accept the request without it' },
35
+ 412: { message: 'Precondition Failed', description: 'The precondition given in the request evaluated to false by the server' },
36
+ 413: { message: 'Request Too Large', description: 'The server will not accept the request, because the request entity is too large' },
37
+ 414: { message: 'Request-URI Too Long', description: 'The server will not accept the request, because the URI is too long. Occurs when you convert a POST request to a GET request with a long query information' },
38
+ 415: { message: 'Unsupported Media Type', description: 'The server will not accept the request, because the media type is not supported' },
39
+ 416: { message: 'Range Not Satisfiable', description: 'The client has asked for a portion of the file, but the server cannot supply that portion' },
40
+ 417: { message: 'Expectation Failed', description: 'The server cannot meet the requirements of the Expect request-header field' },
41
+ 500: { message: 'Internal Server Error', description: 'A generic error message, given when no more specific message is suitable' },
42
+ 501: { message: 'Not Implemented', description: 'The server either does not recognize the request method, or it lacks the ability to fulfill the request' },
43
+ 502: { message: 'Bad Gateway', description: 'The server was acting as a gateway or proxy and received an invalid response from the upstream server' },
44
+ 503: { message: 'Service Unavailable', description: 'The server is currently unavailable (overloaded or down)' },
45
+ 504: { message: 'Gateway Timeout', description: 'The server was acting as a gateway or proxy and did not receive a timely response from the upstream server' },
46
+ 505: { message: 'HTTP Version Not Supported', description: 'The server does not support the HTTP protocol version used in the request' },
47
+ 511: { message: 'Network Authentication Required', description: 'The client needs to authenticate to gain network access' },
48
+ };
49
+ function getStatusMessage(statusCode) {
50
+ const status = exports.httpStatusDetails[statusCode];
51
+ if (status) {
52
+ return `${status.message} - ${status.description}`;
53
+ }
54
+ return 'Unknown Status';
55
+ }
@@ -1,6 +1,19 @@
1
1
  /**
2
- * Utility functions for logging
2
+ * Generates the current timestamp in ISO format
3
+ * @returns ISO timestamp string
3
4
  */
5
+ export declare function generateTimestamp(): string;
6
+ /**
7
+ * Gets or creates a trace ID for a workflow
8
+ * @param workflowId - The workflow ID to get a trace ID for
9
+ * @returns A trace ID associated with the workflow
10
+ */
11
+ export declare function getTraceId(workflowId: string): string;
12
+ /**
13
+ * Clears a trace ID from the map
14
+ * @param workflowId - The workflow ID to clear
15
+ */
16
+ export declare function clearTraceId(workflowId: string): void;
4
17
  /**
5
18
  * Filters an object of headers, returning a new object with only the allowed headers.
6
19
  * @param headers The original headers object.
@@ -1,11 +1,44 @@
1
1
  "use strict";
2
- /**
3
- * Utility functions for logging
4
- */
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateTimestamp = generateTimestamp;
4
+ exports.getTraceId = getTraceId;
5
+ exports.clearTraceId = clearTraceId;
6
6
  exports.filterHeaders = filterHeaders;
7
7
  exports.safeJsonParse = safeJsonParse;
8
8
  exports.normalizeIp = normalizeIp;
9
+ /**
10
+ * Utility functions for logging
11
+ */
12
+ const uuid_1 = require("uuid");
13
+ /**
14
+ * Generates the current timestamp in ISO format
15
+ * @returns ISO timestamp string
16
+ */
17
+ function generateTimestamp() {
18
+ return new Date().toISOString();
19
+ }
20
+ /**
21
+ * Stores trace IDs by workflow ID for consistent tracking
22
+ */
23
+ const traceIdMap = new Map();
24
+ /**
25
+ * Gets or creates a trace ID for a workflow
26
+ * @param workflowId - The workflow ID to get a trace ID for
27
+ * @returns A trace ID associated with the workflow
28
+ */
29
+ function getTraceId(workflowId) {
30
+ if (!traceIdMap.has(workflowId)) {
31
+ traceIdMap.set(workflowId, (0, uuid_1.v4)());
32
+ }
33
+ return traceIdMap.get(workflowId);
34
+ }
35
+ /**
36
+ * Clears a trace ID from the map
37
+ * @param workflowId - The workflow ID to clear
38
+ */
39
+ function clearTraceId(workflowId) {
40
+ traceIdMap.delete(workflowId);
41
+ }
9
42
  // --- Header Allow-Listing ---
10
43
  const ALLOWED_HEADERS = new Set([
11
44
  'content-type',
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.withTrace = withTrace;
4
+ /**
5
+ * Utility function to wrap a function with trace context
6
+ */
4
7
  const uuid_1 = require("uuid");
5
8
  const trace_context_1 = require("./trace-context");
6
9
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unnbound-logger-sdk",
3
- "version": "1.1.5",
3
+ "version": "2.0.1",
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",