Learn by Directing AI
All materials

logging.js

jslogging.js
const winston = require('winston');
const crypto = require('crypto');

const logger = winston.createLogger({
  level: process.env.LOG_LEVEL || 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    new winston.transports.Console()
  ]
});

function requestLogger(req, res, next) {
  req.requestId = crypto.randomUUID().slice(0, 8);
  const start = Date.now();

  res.on('finish', () => {
    const duration = Date.now() - start;
    logger.info('Request completed', {
      requestId: req.requestId,
      method: req.method,
      route: req.originalUrl,
      status: res.statusCode,
      duration: `${duration}ms`
    });
  });

  next();
}

function errorHandler(err, req, res, next) {
  logger.error('Unhandled error', {
    requestId: req.requestId,
    method: req.method,
    route: req.originalUrl,
    error: err.message,
    stack: process.env.NODE_ENV === 'development' ? err.stack : undefined
  });

  res.status(500).json({
    error: 'Internal server error',
    requestId: req.requestId
  });
}

module.exports = { logger, requestLogger, errorHandler };