@designofadecade/server 4.0.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/CHANGELOG.md +62 -0
- package/LICENSE +21 -0
- package/README.md +297 -0
- package/dist/client/ApiClient.d.ts +121 -0
- package/dist/client/ApiClient.d.ts.map +1 -0
- package/dist/client/ApiClient.js +289 -0
- package/dist/client/ApiClient.js.map +1 -0
- package/dist/context/Context.d.ts +71 -0
- package/dist/context/Context.d.ts.map +1 -0
- package/dist/context/Context.js +81 -0
- package/dist/context/Context.js.map +1 -0
- package/dist/docs/OpenApiGenerator.d.ts +135 -0
- package/dist/docs/OpenApiGenerator.d.ts.map +1 -0
- package/dist/docs/OpenApiGenerator.js +165 -0
- package/dist/docs/OpenApiGenerator.js.map +1 -0
- package/dist/events/Events.d.ts +52 -0
- package/dist/events/Events.d.ts.map +1 -0
- package/dist/events/Events.js +70 -0
- package/dist/events/Events.js.map +1 -0
- package/dist/events/EventsManager.d.ts +46 -0
- package/dist/events/EventsManager.d.ts.map +1 -0
- package/dist/events/EventsManager.js +137 -0
- package/dist/events/EventsManager.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/local/Local.d.ts +83 -0
- package/dist/local/Local.d.ts.map +1 -0
- package/dist/local/Local.js +114 -0
- package/dist/local/Local.js.map +1 -0
- package/dist/logger/Logger.d.ts +365 -0
- package/dist/logger/Logger.d.ts.map +1 -0
- package/dist/logger/Logger.js +582 -0
- package/dist/logger/Logger.js.map +1 -0
- package/dist/middleware/RequestLogger.d.ts +62 -0
- package/dist/middleware/RequestLogger.d.ts.map +1 -0
- package/dist/middleware/RequestLogger.js +71 -0
- package/dist/middleware/RequestLogger.js.map +1 -0
- package/dist/notifications/Slack.d.ts +19 -0
- package/dist/notifications/Slack.d.ts.map +1 -0
- package/dist/notifications/Slack.js +55 -0
- package/dist/notifications/Slack.js.map +1 -0
- package/dist/router/RouteError.d.ts +21 -0
- package/dist/router/RouteError.d.ts.map +1 -0
- package/dist/router/RouteError.js +31 -0
- package/dist/router/RouteError.js.map +1 -0
- package/dist/router/Router.d.ts +66 -0
- package/dist/router/Router.d.ts.map +1 -0
- package/dist/router/Router.js +327 -0
- package/dist/router/Router.js.map +1 -0
- package/dist/router/Routes.d.ts +30 -0
- package/dist/router/Routes.d.ts.map +1 -0
- package/dist/router/Routes.js +52 -0
- package/dist/router/Routes.js.map +1 -0
- package/dist/router/StaticFileHandler.d.ts +44 -0
- package/dist/router/StaticFileHandler.d.ts.map +1 -0
- package/dist/router/StaticFileHandler.js +148 -0
- package/dist/router/StaticFileHandler.js.map +1 -0
- package/dist/sanitizer/HtmlSanitizer.d.ts +306 -0
- package/dist/sanitizer/HtmlSanitizer.d.ts.map +1 -0
- package/dist/sanitizer/HtmlSanitizer.js +808 -0
- package/dist/sanitizer/HtmlSanitizer.js.map +1 -0
- package/dist/server/Server.d.ts +28 -0
- package/dist/server/Server.d.ts.map +1 -0
- package/dist/server/Server.js +95 -0
- package/dist/server/Server.js.map +1 -0
- package/dist/state/AppState.d.ts +64 -0
- package/dist/state/AppState.d.ts.map +1 -0
- package/dist/state/AppState.js +89 -0
- package/dist/state/AppState.js.map +1 -0
- package/dist/utils/HtmlRenderer.d.ts +6 -0
- package/dist/utils/HtmlRenderer.d.ts.map +1 -0
- package/dist/utils/HtmlRenderer.js +128 -0
- package/dist/utils/HtmlRenderer.js.map +1 -0
- package/dist/websocket/WebSocketMessageFormatter.d.ts +40 -0
- package/dist/websocket/WebSocketMessageFormatter.d.ts.map +1 -0
- package/dist/websocket/WebSocketMessageFormatter.js +99 -0
- package/dist/websocket/WebSocketMessageFormatter.js.map +1 -0
- package/dist/websocket/WebSocketServer.d.ts +14 -0
- package/dist/websocket/WebSocketServer.d.ts.map +1 -0
- package/dist/websocket/WebSocketServer.js +138 -0
- package/dist/websocket/WebSocketServer.js.map +1 -0
- package/package.json +97 -0
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured logger for AWS Lambda with CloudWatch Logs
|
|
3
|
+
*
|
|
4
|
+
* @module Logger
|
|
5
|
+
* @description Provides JSON-formatted logging for better CloudWatch Insights queries
|
|
6
|
+
* with configurable log levels and structured context support. Automatically captures
|
|
7
|
+
* AWS Lambda request IDs and properly serializes Error objects.
|
|
8
|
+
*
|
|
9
|
+
* Best Practices for CloudWatch Alarms:
|
|
10
|
+
* - Add a `code` field to log entries (e.g., 'DB_CONNECTION_ERROR') for alarm filtering
|
|
11
|
+
* - Add a `source` field to track where logs originated (e.g., 'UserService.login')
|
|
12
|
+
* - Use consistent error codes across your application
|
|
13
|
+
* - Create CloudWatch metric filters based on specific codes
|
|
14
|
+
*
|
|
15
|
+
* Features:
|
|
16
|
+
* ✅ JSON-formatted logs for CloudWatch Insights
|
|
17
|
+
* ✅ Automatic error serialization (message, name, stack)
|
|
18
|
+
* ✅ AWS Lambda context (request ID, X-Ray trace ID, function name, version)
|
|
19
|
+
* ✅ Environment metadata (stage/environment tracking)
|
|
20
|
+
* ✅ Cold start detection (Lambda performance monitoring)
|
|
21
|
+
* ✅ Sensitive data redaction (passwords, tokens, API keys, etc.)
|
|
22
|
+
* ✅ Performance timing helpers (duration tracking)
|
|
23
|
+
* ✅ Error codes for alarm creation
|
|
24
|
+
* ✅ Source tracking for debugging
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* import { logger } from './Logger';
|
|
28
|
+
*
|
|
29
|
+
* logger.info('User action completed', {
|
|
30
|
+
* source: 'UserController.login',
|
|
31
|
+
* userId: '123',
|
|
32
|
+
* action: 'login'
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* // Error objects are automatically serialized with message, name, and stack
|
|
36
|
+
* // Use 'code' field for CloudWatch alarms
|
|
37
|
+
* try {
|
|
38
|
+
* await riskyOperation();
|
|
39
|
+
* } catch (err) {
|
|
40
|
+
* logger.error('Operation failed', {
|
|
41
|
+
* code: 'PAYMENT_PROCESSING_ERROR', // For CloudWatch alarm filtering
|
|
42
|
+
* source: 'PaymentService.processPayment', // For debugging
|
|
43
|
+
* error: err
|
|
44
|
+
* });
|
|
45
|
+
* }
|
|
46
|
+
*
|
|
47
|
+
* // Performance timing
|
|
48
|
+
* const timer = logger.startTimer();
|
|
49
|
+
* await expensiveOperation();
|
|
50
|
+
* timer.end('expensiveOperation', { source: 'MyService.process' });
|
|
51
|
+
*
|
|
52
|
+
* // Sensitive data is automatically redacted
|
|
53
|
+
* logger.info('User logged in', {
|
|
54
|
+
* username: 'john',
|
|
55
|
+
* password: 'secret123' // Automatically redacted as [REDACTED]
|
|
56
|
+
* });
|
|
57
|
+
*/
|
|
58
|
+
/**
|
|
59
|
+
* Log level enumeration
|
|
60
|
+
* Lower values indicate higher priority
|
|
61
|
+
*
|
|
62
|
+
* Log Level Guidelines:
|
|
63
|
+
*
|
|
64
|
+
* ERROR (0) - Critical failures requiring immediate attention
|
|
65
|
+
* - Application crashes or unrecoverable errors
|
|
66
|
+
* - Failed database connections or critical service failures
|
|
67
|
+
* - Data corruption or loss scenarios
|
|
68
|
+
* - Security violations or authentication failures
|
|
69
|
+
* - Use when: The application cannot continue normal operation
|
|
70
|
+
*
|
|
71
|
+
* WARN (1) - Potentially harmful situations that don't stop execution
|
|
72
|
+
* - Deprecated API usage or configuration issues
|
|
73
|
+
* - Rate limiting being approached
|
|
74
|
+
* - Retryable failures (e.g., temporary network issues)
|
|
75
|
+
* - Resource constraints (low memory, disk space)
|
|
76
|
+
* - Use when: Something unexpected happened but the app can continue
|
|
77
|
+
*
|
|
78
|
+
* INFO (2) - Informational messages highlighting application progress
|
|
79
|
+
* - Application startup/shutdown events
|
|
80
|
+
* - Successful business operations (user login, order placed)
|
|
81
|
+
* - Configuration loaded successfully
|
|
82
|
+
* - API request/response summaries
|
|
83
|
+
* - Use when: Tracking normal application flow and important milestones
|
|
84
|
+
*
|
|
85
|
+
* DEBUG (3) - Detailed diagnostic information for troubleshooting
|
|
86
|
+
* - Variable values and state changes
|
|
87
|
+
* - Cache hits/misses
|
|
88
|
+
* - Detailed request/response payloads
|
|
89
|
+
* - Function entry/exit points
|
|
90
|
+
* - Use when: Debugging issues in development or production
|
|
91
|
+
*/
|
|
92
|
+
export var LogLevel;
|
|
93
|
+
(function (LogLevel) {
|
|
94
|
+
LogLevel[LogLevel["ERROR"] = 0] = "ERROR";
|
|
95
|
+
LogLevel[LogLevel["WARN"] = 1] = "WARN";
|
|
96
|
+
LogLevel[LogLevel["INFO"] = 2] = "INFO";
|
|
97
|
+
LogLevel[LogLevel["DEBUG"] = 3] = "DEBUG";
|
|
98
|
+
})(LogLevel || (LogLevel = {}));
|
|
99
|
+
/**
|
|
100
|
+
* Mapping of string log levels to numeric values
|
|
101
|
+
*/
|
|
102
|
+
const LOG_LEVEL_MAP = {
|
|
103
|
+
ERROR: LogLevel.ERROR,
|
|
104
|
+
WARN: LogLevel.WARN,
|
|
105
|
+
INFO: LogLevel.INFO,
|
|
106
|
+
DEBUG: LogLevel.DEBUG,
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Structured logger class for AWS Lambda with CloudWatch Logs integration
|
|
110
|
+
*
|
|
111
|
+
* @class Logger
|
|
112
|
+
* @description Outputs JSON-formatted logs for optimal CloudWatch Insights querying.
|
|
113
|
+
* Log level can be configured via LOG_LEVEL environment variable.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* const logger = new Logger();
|
|
117
|
+
* logger.info('Processing started', { requestId: '12345' });
|
|
118
|
+
* logger.error('Failed to process', { error: 'Connection timeout', retries: 3 });
|
|
119
|
+
*/
|
|
120
|
+
export class Logger {
|
|
121
|
+
level;
|
|
122
|
+
// Sensitive field patterns - more specific to avoid false positives
|
|
123
|
+
sensitiveKeys = [
|
|
124
|
+
'password',
|
|
125
|
+
'passwd',
|
|
126
|
+
'pwd',
|
|
127
|
+
'token',
|
|
128
|
+
'accesstoken',
|
|
129
|
+
'refreshtoken',
|
|
130
|
+
'bearertoken',
|
|
131
|
+
'apikey',
|
|
132
|
+
'api_key',
|
|
133
|
+
'secret',
|
|
134
|
+
'secretkey',
|
|
135
|
+
'clientsecret',
|
|
136
|
+
'authorization',
|
|
137
|
+
'auth',
|
|
138
|
+
'cookie',
|
|
139
|
+
'session',
|
|
140
|
+
'sessionid',
|
|
141
|
+
'creditcard',
|
|
142
|
+
'cardnumber',
|
|
143
|
+
'cvv',
|
|
144
|
+
'ccv',
|
|
145
|
+
'ssn',
|
|
146
|
+
'socialsecurity',
|
|
147
|
+
'privatekey',
|
|
148
|
+
'private_key',
|
|
149
|
+
];
|
|
150
|
+
isColdStart = true; // Track Lambda cold starts
|
|
151
|
+
maxLogSize = 256000; // CloudWatch limit is 256KB per log event
|
|
152
|
+
/**
|
|
153
|
+
* Creates a new Logger instance
|
|
154
|
+
* Reads LOG_LEVEL from environment variable (defaults to INFO)
|
|
155
|
+
*/
|
|
156
|
+
constructor() {
|
|
157
|
+
const envLevel = (process.env.LOG_LEVEL?.toUpperCase() || 'INFO');
|
|
158
|
+
this.level = LOG_LEVEL_MAP[envLevel] ?? LogLevel.INFO;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Determines if a message at the given level should be logged
|
|
162
|
+
*
|
|
163
|
+
* @param level - The log level to check
|
|
164
|
+
* @returns True if the message should be logged
|
|
165
|
+
* @private
|
|
166
|
+
*/
|
|
167
|
+
shouldLog(level) {
|
|
168
|
+
return level <= this.level;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Serializes an Error object for CloudWatch
|
|
172
|
+
* Extracts message, name, and stack trace for better CloudWatch Insights queries
|
|
173
|
+
*
|
|
174
|
+
* @param error - The error to serialize
|
|
175
|
+
* @returns Serialized error object
|
|
176
|
+
* @private
|
|
177
|
+
*/
|
|
178
|
+
serializeError(error) {
|
|
179
|
+
return {
|
|
180
|
+
message: error.message,
|
|
181
|
+
name: error.name,
|
|
182
|
+
stack: error.stack,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Redacts sensitive data from log context for security/compliance
|
|
187
|
+
* Handles circular references and prevents infinite recursion
|
|
188
|
+
*
|
|
189
|
+
* @param obj - The object to redact
|
|
190
|
+
* @param seen - WeakSet to track visited objects (prevents circular references)
|
|
191
|
+
* @param depth - Current recursion depth (prevents stack overflow)
|
|
192
|
+
* @returns Redacted object
|
|
193
|
+
* @private
|
|
194
|
+
*/
|
|
195
|
+
redactSensitiveData(obj, seen = new WeakSet(), depth = 0) {
|
|
196
|
+
// Prevent infinite recursion
|
|
197
|
+
if (depth > 10)
|
|
198
|
+
return '[MAX_DEPTH]';
|
|
199
|
+
if (obj === null || obj === undefined)
|
|
200
|
+
return obj;
|
|
201
|
+
// Handle primitives and special types before object check
|
|
202
|
+
if (typeof obj !== 'object') {
|
|
203
|
+
// Handle Symbol (convert to string for JSON compatibility)
|
|
204
|
+
if (typeof obj === 'symbol') {
|
|
205
|
+
return obj.toString();
|
|
206
|
+
}
|
|
207
|
+
// Handle BigInt (convert to string for JSON compatibility)
|
|
208
|
+
if (typeof obj === 'bigint') {
|
|
209
|
+
return obj.toString() + 'n';
|
|
210
|
+
}
|
|
211
|
+
// Handle functions
|
|
212
|
+
if (typeof obj === 'function') {
|
|
213
|
+
return '[Function]';
|
|
214
|
+
}
|
|
215
|
+
return obj;
|
|
216
|
+
}
|
|
217
|
+
// Handle circular references
|
|
218
|
+
if (seen.has(obj)) {
|
|
219
|
+
return '[CIRCULAR]';
|
|
220
|
+
}
|
|
221
|
+
if (Array.isArray(obj)) {
|
|
222
|
+
return obj.map((item) => this.redactSensitiveData(item, seen, depth + 1));
|
|
223
|
+
}
|
|
224
|
+
// Mark this object as seen
|
|
225
|
+
seen.add(obj);
|
|
226
|
+
const redacted = {};
|
|
227
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
228
|
+
const lowerKey = key.toLowerCase();
|
|
229
|
+
const isSensitive = this.sensitiveKeys.some((sensitive) => lowerKey.includes(sensitive.toLowerCase()));
|
|
230
|
+
if (isSensitive) {
|
|
231
|
+
redacted[key] = '[REDACTED]';
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
// Always recursively process values to handle BigInt, Symbol, Function, etc.
|
|
235
|
+
redacted[key] = this.redactSensitiveData(value, seen, depth + 1);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return redacted;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Processes context to handle special types (Errors) for CloudWatch compatibility
|
|
242
|
+
*
|
|
243
|
+
* @param context - The context object to process
|
|
244
|
+
* @returns Processed context
|
|
245
|
+
* @private
|
|
246
|
+
*/
|
|
247
|
+
processContext(context) {
|
|
248
|
+
if (!context)
|
|
249
|
+
return {};
|
|
250
|
+
const processed = {};
|
|
251
|
+
for (const [key, value] of Object.entries(context)) {
|
|
252
|
+
if (value instanceof Error) {
|
|
253
|
+
// Serialize Error objects properly for CloudWatch
|
|
254
|
+
processed[key] = this.serializeError(value);
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
processed[key] = value;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
// Redact sensitive data
|
|
261
|
+
return this.redactSensitiveData(processed);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Safely stringifies an object, handling BigInt, circular refs, and other edge cases
|
|
265
|
+
*
|
|
266
|
+
* @param obj - The object to stringify
|
|
267
|
+
* @returns JSON string
|
|
268
|
+
* @private
|
|
269
|
+
*/
|
|
270
|
+
safeStringify(obj) {
|
|
271
|
+
return JSON.stringify(obj, (_key, value) => {
|
|
272
|
+
// Handle BigInt (convert to string with 'n' suffix)
|
|
273
|
+
if (typeof value === 'bigint') {
|
|
274
|
+
return value.toString() + 'n';
|
|
275
|
+
}
|
|
276
|
+
// Handle Symbol (convert to string)
|
|
277
|
+
if (typeof value === 'symbol') {
|
|
278
|
+
return value.toString();
|
|
279
|
+
}
|
|
280
|
+
// Handle functions (skip them)
|
|
281
|
+
if (typeof value === 'function') {
|
|
282
|
+
return '[Function]';
|
|
283
|
+
}
|
|
284
|
+
return value;
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Outputs a structured log entry to stdout optimized for CloudWatch Logs
|
|
289
|
+
* Handles CloudWatch's 256KB log size limit
|
|
290
|
+
*
|
|
291
|
+
* @param level - The log level string
|
|
292
|
+
* @param message - The log message
|
|
293
|
+
* @param context - Additional context data to include in the log entry
|
|
294
|
+
* @private
|
|
295
|
+
*/
|
|
296
|
+
log(level, message, context) {
|
|
297
|
+
try {
|
|
298
|
+
const processedContext = this.processContext(context);
|
|
299
|
+
const logEntry = {
|
|
300
|
+
timestamp: new Date().toISOString(),
|
|
301
|
+
level,
|
|
302
|
+
message,
|
|
303
|
+
// AWS Lambda context
|
|
304
|
+
...(process.env.AWS_REQUEST_ID && { requestId: process.env.AWS_REQUEST_ID }),
|
|
305
|
+
...(process.env._X_AMZN_TRACE_ID && { traceId: process.env._X_AMZN_TRACE_ID }),
|
|
306
|
+
...(process.env.AWS_LAMBDA_FUNCTION_NAME && {
|
|
307
|
+
functionName: process.env.AWS_LAMBDA_FUNCTION_NAME,
|
|
308
|
+
}),
|
|
309
|
+
...(process.env.AWS_LAMBDA_FUNCTION_VERSION && {
|
|
310
|
+
functionVersion: process.env.AWS_LAMBDA_FUNCTION_VERSION,
|
|
311
|
+
}),
|
|
312
|
+
// Environment metadata
|
|
313
|
+
...(process.env.ENVIRONMENT && { environment: process.env.ENVIRONMENT }),
|
|
314
|
+
...(process.env.STAGE && { environment: process.env.STAGE }),
|
|
315
|
+
// Cold start tracking
|
|
316
|
+
...(this.isColdStart && level !== 'DEBUG' && { coldStart: true }),
|
|
317
|
+
...processedContext,
|
|
318
|
+
};
|
|
319
|
+
// Mark cold start as false after first log
|
|
320
|
+
if (this.isColdStart) {
|
|
321
|
+
this.isColdStart = false;
|
|
322
|
+
}
|
|
323
|
+
let logString = this.safeStringify(logEntry);
|
|
324
|
+
// CloudWatch has a 256KB limit per log event
|
|
325
|
+
if (logString.length > this.maxLogSize) {
|
|
326
|
+
const truncated = {
|
|
327
|
+
...logEntry,
|
|
328
|
+
_truncated: true,
|
|
329
|
+
_originalSize: logString.length,
|
|
330
|
+
message: logEntry.message.substring(0, 1000),
|
|
331
|
+
};
|
|
332
|
+
// Remove large fields if still too big
|
|
333
|
+
const truncatedRecord = truncated;
|
|
334
|
+
if (truncatedRecord.error && typeof truncatedRecord.error === 'object') {
|
|
335
|
+
delete truncatedRecord.error.stack;
|
|
336
|
+
}
|
|
337
|
+
logString = this.safeStringify(truncated);
|
|
338
|
+
// If still too large, just log basic info
|
|
339
|
+
if (logString.length > this.maxLogSize) {
|
|
340
|
+
logString = this.safeStringify({
|
|
341
|
+
timestamp: logEntry.timestamp,
|
|
342
|
+
level: logEntry.level,
|
|
343
|
+
message: 'Log too large to output',
|
|
344
|
+
_truncated: true,
|
|
345
|
+
_originalSize: logString.length,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
console.log(logString);
|
|
350
|
+
}
|
|
351
|
+
catch (err) {
|
|
352
|
+
// Fallback to plain console.log if JSON serialization fails
|
|
353
|
+
try {
|
|
354
|
+
console.log(JSON.stringify({
|
|
355
|
+
timestamp: new Date().toISOString(),
|
|
356
|
+
level,
|
|
357
|
+
message,
|
|
358
|
+
_error: 'Failed to serialize log entry',
|
|
359
|
+
_errorMessage: err instanceof Error ? err.message : String(err),
|
|
360
|
+
}));
|
|
361
|
+
}
|
|
362
|
+
catch {
|
|
363
|
+
// Last resort fallback
|
|
364
|
+
console.log(`[${level}] ${message}`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Logs an error message
|
|
370
|
+
*
|
|
371
|
+
* @param message - The error message
|
|
372
|
+
* @param context - Additional context data (error details, stack traces, etc.)
|
|
373
|
+
*
|
|
374
|
+
* @example
|
|
375
|
+
* // Pass Error objects directly - they'll be serialized automatically
|
|
376
|
+
* try {
|
|
377
|
+
* await connectToDatabase();
|
|
378
|
+
* } catch (err) {
|
|
379
|
+
* logger.error('Database connection failed', {
|
|
380
|
+
* code: 'DB_CONNECTION_ERROR', // For CloudWatch alarms
|
|
381
|
+
* source: 'DatabaseService.connect', // Track where error occurred
|
|
382
|
+
* error: err, // Error object is automatically serialized
|
|
383
|
+
* database: 'users',
|
|
384
|
+
* retry: 3
|
|
385
|
+
* });
|
|
386
|
+
* }
|
|
387
|
+
*
|
|
388
|
+
* @example
|
|
389
|
+
* // CloudWatch Alarm can filter on code field:
|
|
390
|
+
* // fields @timestamp, message, code
|
|
391
|
+
* // | filter code = "DB_CONNECTION_ERROR"
|
|
392
|
+
*/
|
|
393
|
+
error(message, context) {
|
|
394
|
+
if (this.shouldLog(LogLevel.ERROR)) {
|
|
395
|
+
this.log('ERROR', message, context);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Logs a warning message
|
|
400
|
+
*
|
|
401
|
+
* @param message - The warning message
|
|
402
|
+
* @param context - Additional context data
|
|
403
|
+
*
|
|
404
|
+
* @example
|
|
405
|
+
* logger.warn('Rate limit approaching', {
|
|
406
|
+
* code: 'RATE_LIMIT_WARNING',
|
|
407
|
+
* source: 'ApiGateway.checkRateLimit',
|
|
408
|
+
* current: 95,
|
|
409
|
+
* limit: 100,
|
|
410
|
+
* timeWindow: '1m'
|
|
411
|
+
* });
|
|
412
|
+
*/
|
|
413
|
+
warn(message, context) {
|
|
414
|
+
if (this.shouldLog(LogLevel.WARN)) {
|
|
415
|
+
this.log('WARN', message, context);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Logs an informational message
|
|
420
|
+
*
|
|
421
|
+
* @param message - The info message
|
|
422
|
+
* @param context - Additional context data
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* logger.info('Request processed successfully', {
|
|
426
|
+
* source: 'ApiHandler.processRequest',
|
|
427
|
+
* requestId: 'req-123',
|
|
428
|
+
* duration: 245,
|
|
429
|
+
* statusCode: 200
|
|
430
|
+
* });
|
|
431
|
+
*/
|
|
432
|
+
info(message, context) {
|
|
433
|
+
if (this.shouldLog(LogLevel.INFO)) {
|
|
434
|
+
this.log('INFO', message, context);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Logs a debug message
|
|
439
|
+
*
|
|
440
|
+
* @param message - The debug message
|
|
441
|
+
* @param context - Additional context data
|
|
442
|
+
*
|
|
443
|
+
* @example
|
|
444
|
+
* logger.debug('Cache lookup', {
|
|
445
|
+
* key: 'user:123',
|
|
446
|
+
* hit: true,
|
|
447
|
+
* ttl: 3600
|
|
448
|
+
* });
|
|
449
|
+
*/
|
|
450
|
+
debug(message, context) {
|
|
451
|
+
if (this.shouldLog(LogLevel.DEBUG)) {
|
|
452
|
+
this.log('DEBUG', message, context);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Gets the current log level
|
|
457
|
+
*
|
|
458
|
+
* @returns The current log level
|
|
459
|
+
*/
|
|
460
|
+
getLevel() {
|
|
461
|
+
return this.level;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Gets the current log level as a string
|
|
465
|
+
*
|
|
466
|
+
* @returns The current log level string
|
|
467
|
+
*/
|
|
468
|
+
getLevelString() {
|
|
469
|
+
const entry = Object.entries(LogLevel).find(([, val]) => val === this.level);
|
|
470
|
+
return entry?.[0] || 'INFO';
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Logs operation performance metrics
|
|
474
|
+
* Helper method for tracking duration of operations
|
|
475
|
+
*
|
|
476
|
+
* @param operation - Name of the operation
|
|
477
|
+
* @param durationMs - Duration in milliseconds
|
|
478
|
+
* @param context - Additional context data
|
|
479
|
+
*
|
|
480
|
+
* @example
|
|
481
|
+
* const start = Date.now();
|
|
482
|
+
* await processPayment();
|
|
483
|
+
* logger.performance('processPayment', Date.now() - start, {
|
|
484
|
+
* source: 'PaymentService.process',
|
|
485
|
+
* paymentId: '12345',
|
|
486
|
+
* amount: 99.99
|
|
487
|
+
* });
|
|
488
|
+
*
|
|
489
|
+
* @example
|
|
490
|
+
* // CloudWatch Insights - Track slow operations:
|
|
491
|
+
* // fields @timestamp, message, duration, source
|
|
492
|
+
* // | filter duration > 1000
|
|
493
|
+
* // | sort duration desc
|
|
494
|
+
*/
|
|
495
|
+
performance(operation, durationMs, context) {
|
|
496
|
+
this.info(`Operation completed: ${operation}`, {
|
|
497
|
+
duration: durationMs,
|
|
498
|
+
...context,
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Creates a performance timing wrapper
|
|
503
|
+
* Returns start function that returns end function for measuring duration
|
|
504
|
+
*
|
|
505
|
+
* @returns Object with start method that returns end method
|
|
506
|
+
*
|
|
507
|
+
* @example
|
|
508
|
+
* const timer = logger.startTimer();
|
|
509
|
+
* await someAsyncOperation();
|
|
510
|
+
* timer.end('someAsyncOperation', { source: 'MyService.method', userId: '123' });
|
|
511
|
+
*/
|
|
512
|
+
startTimer() {
|
|
513
|
+
const startTime = Date.now();
|
|
514
|
+
return {
|
|
515
|
+
/**
|
|
516
|
+
* Ends the timer and logs performance
|
|
517
|
+
* @param operation - Name of the operation
|
|
518
|
+
* @param context - Additional context
|
|
519
|
+
*/
|
|
520
|
+
end: (operation, context) => {
|
|
521
|
+
this.performance(operation, Date.now() - startTime, context);
|
|
522
|
+
},
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Singleton logger instance
|
|
528
|
+
* Use this for all logging throughout the application
|
|
529
|
+
*
|
|
530
|
+
* Environment Variables:
|
|
531
|
+
* - LOG_LEVEL: Set log level (ERROR, WARN, INFO, DEBUG) - defaults to INFO
|
|
532
|
+
* - ENVIRONMENT or STAGE: Environment name (dev/staging/prod) - auto-included in logs
|
|
533
|
+
* - AWS_REQUEST_ID: Lambda request ID - auto-captured
|
|
534
|
+
* - _X_AMZN_TRACE_ID: X-Ray trace ID - auto-captured
|
|
535
|
+
* - AWS_LAMBDA_FUNCTION_NAME: Function name - auto-captured
|
|
536
|
+
* - AWS_LAMBDA_FUNCTION_VERSION: Function version - auto-captured
|
|
537
|
+
*
|
|
538
|
+
* @example
|
|
539
|
+
* import { logger } from './Logger';
|
|
540
|
+
*
|
|
541
|
+
* logger.info('Application started', { source: 'App.main' });
|
|
542
|
+
*
|
|
543
|
+
* logger.error('Failed to load config', {
|
|
544
|
+
* code: 'CONFIG_LOAD_ERROR',
|
|
545
|
+
* source: 'ConfigService.load',
|
|
546
|
+
* error: err
|
|
547
|
+
* });
|
|
548
|
+
*
|
|
549
|
+
* // Performance tracking
|
|
550
|
+
* const timer = logger.startTimer();
|
|
551
|
+
* await processData();
|
|
552
|
+
* timer.end('processData', { source: 'DataProcessor.process', recordCount: 100 });
|
|
553
|
+
*
|
|
554
|
+
* // CloudWatch Insights query examples:
|
|
555
|
+
*
|
|
556
|
+
* // Find specific error codes:
|
|
557
|
+
* // fields @timestamp, message, code, source
|
|
558
|
+
* // | filter code = "DB_CONNECTION_ERROR"
|
|
559
|
+
* // | sort @timestamp desc
|
|
560
|
+
*
|
|
561
|
+
* // Track errors by source:
|
|
562
|
+
* // fields @timestamp, message, source
|
|
563
|
+
* // | filter source like /UserService/
|
|
564
|
+
* // | stats count() by source
|
|
565
|
+
*
|
|
566
|
+
* // Monitor cold starts:
|
|
567
|
+
* // fields @timestamp, message, coldStart, duration
|
|
568
|
+
* // | filter coldStart = true
|
|
569
|
+
* // | stats count() as coldStartCount
|
|
570
|
+
*
|
|
571
|
+
* // Track slow operations:
|
|
572
|
+
* // fields @timestamp, message, duration, source
|
|
573
|
+
* // | filter duration > 1000
|
|
574
|
+
* // | sort duration desc
|
|
575
|
+
* // | limit 20
|
|
576
|
+
*/
|
|
577
|
+
export const logger = new Logger();
|
|
578
|
+
/**
|
|
579
|
+
* Default export for convenience
|
|
580
|
+
*/
|
|
581
|
+
export default logger;
|
|
582
|
+
//# sourceMappingURL=Logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Logger.js","sourceRoot":"","sources":["../../src/logger/Logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request logging middleware for API routes
|
|
3
|
+
* Extends the base Logger with HTTP-specific context
|
|
4
|
+
*
|
|
5
|
+
* @module RequestLogger
|
|
6
|
+
*/
|
|
7
|
+
interface RequestLoggerInterface {
|
|
8
|
+
info: (message: string, context?: Record<string, any>) => void;
|
|
9
|
+
error: (message: string, context?: Record<string, any>) => void;
|
|
10
|
+
warn: (message: string, context?: Record<string, any>) => void;
|
|
11
|
+
debug: (message: string, context?: Record<string, any>) => void;
|
|
12
|
+
}
|
|
13
|
+
interface RequestEvent {
|
|
14
|
+
requestContext?: {
|
|
15
|
+
requestId?: string;
|
|
16
|
+
http?: {
|
|
17
|
+
method: string;
|
|
18
|
+
path: string;
|
|
19
|
+
};
|
|
20
|
+
identity?: {
|
|
21
|
+
sourceIp?: string;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
httpMethod?: string;
|
|
25
|
+
path?: string;
|
|
26
|
+
headers?: Record<string, any>;
|
|
27
|
+
body?: string;
|
|
28
|
+
queryStringParameters?: Record<string, any>;
|
|
29
|
+
pathParameters?: Record<string, any>;
|
|
30
|
+
}
|
|
31
|
+
interface ResponseObject {
|
|
32
|
+
statusCode: number;
|
|
33
|
+
[key: string]: any;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Creates a request-scoped logger with HTTP context
|
|
37
|
+
*
|
|
38
|
+
* @param {Object} request - AWS Lambda event or custom request object
|
|
39
|
+
* @param {string} request.requestContext.requestId - Request ID
|
|
40
|
+
* @param {string} request.httpMethod - HTTP method
|
|
41
|
+
* @param {string} request.path - Request path
|
|
42
|
+
* @returns {Object} Logger with request context
|
|
43
|
+
*/
|
|
44
|
+
export declare function createRequestLogger(event: RequestEvent): RequestLoggerInterface;
|
|
45
|
+
/**
|
|
46
|
+
* Middleware to automatically log incoming requests
|
|
47
|
+
*
|
|
48
|
+
* @param {Object} event - AWS Lambda event
|
|
49
|
+
* @returns {void}
|
|
50
|
+
*/
|
|
51
|
+
export declare function logRequest(event: RequestEvent): void;
|
|
52
|
+
/**
|
|
53
|
+
* Middleware to log outgoing responses
|
|
54
|
+
*
|
|
55
|
+
* @param {Object} event - AWS Lambda event
|
|
56
|
+
* @param {Object} response - API response
|
|
57
|
+
* @param {number} durationMs - Request duration in milliseconds
|
|
58
|
+
* @returns {void}
|
|
59
|
+
*/
|
|
60
|
+
export declare function logResponse(event: RequestEvent, response: ResponseObject, durationMs: number): void;
|
|
61
|
+
export {};
|
|
62
|
+
//# sourceMappingURL=RequestLogger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RequestLogger.d.ts","sourceRoot":"","sources":["../../src/middleware/RequestLogger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,UAAU,sBAAsB;IAC9B,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IAC/D,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IAChE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IAC/D,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;CACjE;AAED,UAAU,YAAY;IACpB,cAAc,CAAC,EAAE;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE;YACL,MAAM,EAAE,MAAM,CAAC;YACf,IAAI,EAAE,MAAM,CAAC;SACd,CAAC;QACF,QAAQ,CAAC,EAAE;YACT,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,CAAC;KACH,CAAC;IACF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACtC;AAED,UAAU,cAAc;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,YAAY,GAAG,sBAAsB,CAuB/E;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAQpD;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,MAAM,GACjB,IAAI,CAUN"}
|