85 lines
2.1 KiB
TypeScript
85 lines
2.1 KiB
TypeScript
import winston from 'winston';
|
|
import path from 'path';
|
|
import { config } from './config';
|
|
|
|
const logDir = path.join(__dirname, '../logs');
|
|
|
|
// Create logs directory if it doesn't exist
|
|
import fs from 'fs';
|
|
if (!fs.existsSync(logDir)) {
|
|
fs.mkdirSync(logDir, { recursive: true });
|
|
}
|
|
|
|
const logFormat = winston.format.combine(
|
|
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
|
|
winston.format.errors({ stack: true }),
|
|
winston.format.json()
|
|
);
|
|
|
|
const consoleFormat = winston.format.combine(
|
|
winston.format.colorize(),
|
|
winston.format.timestamp({ format: 'HH:mm:ss' }),
|
|
winston.format.printf(({ timestamp, level, message, ...meta }) => {
|
|
const metaStr = Object.keys(meta).length ? ` ${JSON.stringify(meta)}` : '';
|
|
return `${timestamp} ${level}: ${message}${metaStr}`;
|
|
})
|
|
);
|
|
|
|
// log auth attempts and failures
|
|
export const logger = winston.createLogger({
|
|
level: config.logging.level,
|
|
format: logFormat,
|
|
transports: [
|
|
// logs auth and security events
|
|
new winston.transports.File({
|
|
filename: path.join(logDir, 'security.log'),
|
|
level: 'info',
|
|
format: winston.format.combine(
|
|
winston.format.timestamp(),
|
|
winston.format.json()
|
|
)
|
|
}),
|
|
|
|
// logs all errors
|
|
new winston.transports.File({
|
|
filename: path.join(logDir, 'error.log'),
|
|
level: 'error'
|
|
}),
|
|
|
|
// logs everything
|
|
new winston.transports.File({
|
|
filename: path.join(logDir, 'combined.log')
|
|
})
|
|
]
|
|
});
|
|
|
|
// console log in dev
|
|
if (config.server.nodeEnv === 'development') {
|
|
logger.add(new winston.transports.Console({
|
|
format: consoleFormat
|
|
}));
|
|
}
|
|
|
|
// Security specific logging
|
|
export const securityLogger = {
|
|
rateLimitExceeded: (ip: string, endpoint: string) => {
|
|
logger.warn('Rate limit exceeded', {
|
|
event: 'rate_limit_exceeded',
|
|
ip,
|
|
endpoint,
|
|
timestamp: new Date().toISOString()
|
|
});
|
|
},
|
|
|
|
suspiciousActivity: (ip: string, activity: string, details?: any) => {
|
|
logger.warn('Suspicious activity detected', {
|
|
event: 'suspicious_activity',
|
|
ip,
|
|
activity,
|
|
details,
|
|
timestamp: new Date().toISOString()
|
|
});
|
|
}
|
|
};
|
|
|
|
export default logger; |