fix(#12): Implement structured logging with request correlation and security event marking
Some checks are pending
Docker Test / test (push) Waiting to run
Some checks are pending
Docker Test / test (push) Waiting to run
This commit is contained in:
parent
32480438c7
commit
0679332c77
3 changed files with 77 additions and 2 deletions
51
backend/middleware/logger.js
Normal file
51
backend/middleware/logger.js
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
const { format, createLogger, transports } = require('winston');
|
||||||
|
|
||||||
|
const logger = createLogger({
|
||||||
|
format: format.combine(
|
||||||
|
format.timestamp(),
|
||||||
|
format.json()
|
||||||
|
),
|
||||||
|
transports: [
|
||||||
|
new transports.Console()
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// Middleware to generate a unique request ID
|
||||||
|
const requestId = (req, res, next) => {
|
||||||
|
req.id = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Middleware to log requests
|
||||||
|
const requestLogger = (req, res, next) => {
|
||||||
|
logger.info({
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
method: req.method,
|
||||||
|
url: req.url,
|
||||||
|
requestId: req.id
|
||||||
|
});
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Middleware to log errors
|
||||||
|
const errorLogger = (err, req, res, next) => {
|
||||||
|
const isSecurityEvent = err.message.includes('Authentication') ||
|
||||||
|
err.message.includes('Authorization') ||
|
||||||
|
err.message.includes('Security');
|
||||||
|
const level = isSecurityEvent ? 'security' : 'error';
|
||||||
|
|
||||||
|
logger[level]({
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
error: err.message,
|
||||||
|
stack: err.stack,
|
||||||
|
requestId: req.id,
|
||||||
|
route: req.route ? req.route.path : req.path
|
||||||
|
});
|
||||||
|
next(err);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
requestId,
|
||||||
|
requestLogger,
|
||||||
|
errorLogger
|
||||||
|
};
|
||||||
|
|
@ -5,7 +5,8 @@ function logger(req, res, next) {
|
||||||
method: req.method,
|
method: req.method,
|
||||||
url: req.url,
|
url: req.url,
|
||||||
requestId: req.requestId,
|
requestId: req.requestId,
|
||||||
level: 'info'
|
level: 'info',
|
||||||
|
route: req.route ? req.route.path : 'unknown'
|
||||||
}));
|
}));
|
||||||
res.on('finish', () => {
|
res.on('finish', () => {
|
||||||
const securityEvent = [401, 403].includes(res.statusCode);
|
const securityEvent = [401, 403].includes(res.statusCode);
|
||||||
|
|
@ -16,7 +17,8 @@ function logger(req, res, next) {
|
||||||
status: res.statusCode,
|
status: res.statusCode,
|
||||||
requestId: req.requestId,
|
requestId: req.requestId,
|
||||||
level: res.statusCode >= 400 ? 'error' : 'info',
|
level: res.statusCode >= 400 ? 'error' : 'info',
|
||||||
securityEvent: securityEvent
|
securityEvent: securityEvent,
|
||||||
|
route: req.route ? req.route.path : 'unknown'
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
next();
|
next();
|
||||||
|
|
|
||||||
22
docs/adr/structured-logging.md
Normal file
22
docs/adr/structured-logging.md
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Structured Logging
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
For operational debugging, structured logs are needed for API errors and security events. This includes timestamps, log levels, request IDs, and routes.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
We implement a centralized logging middleware that:
|
||||||
|
1. Logs all requests with timestamp, method, URL, request ID, and route
|
||||||
|
2. Logs error responses with correlation via request ID
|
||||||
|
3. Marks security-relevant events (401, 403) separately
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- Logs are structured and filterable
|
||||||
|
- Security events can be easily identified
|
||||||
|
- Debugging is improved through correlation of requests and errors
|
||||||
Loading…
Add table
Add a link
Reference in a new issue