KOA技术分享

专注 Koa.js 框架的编程知识分享

Koa.js 日志系统与异常监控

日志系统的重要性

完善的日志系统是排查问题和监控应用健康状态的基础。生产环境中的日志不仅用于问题定位,还支撑着性能分析、用户行为分析、安全审计等高级需求。一个好的日志系统应该具备:结构化输出、多级别支持、轮转策略、集中存储、实时分析等能力。

日志级别设计

级别 使用场景 示例
error 错误信息,需要处理 数据库连接失败
warn 警告信息,可能有问题 请求超时
info 重要业务信息 用户登录、订单创建
debug 调试信息 变量值、流程分支

日志库配置

const log4js = require('log4js');

// 日志配置
log4js.configure({
  appenders: {
    console: { type: 'console' },
    file: {
      type: 'file',
      filename: 'logs/app.log',
      maxLogSize: 10485760,  // 10MB
      backups: 5,
      compress: true
    },
    errorFile: {
      type: 'file',
      filename: 'logs/error.log'
    }
  },
  categories: {
    default: { appenders: ['console', 'file'], level: 'info' },
    error: { appenders: ['console', 'errorFile'], level: 'error' }
  }
});

const logger = log4js.getLogger();
const errorLogger = log4js.getLogger('error');

// Koa 中间件中使用
app.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;

  logger.info({
    method: ctx.method,
    url: ctx.url,
    status: ctx.status,
    responseTime: ms,
    ip: ctx.ip
  });
});

统一异常处理

在 Koa 中实现全局异常捕获:

// 错误处理中间件
app.use(async (ctx, next) => {
  try {
    await next();
  } catch (err) {
    // 记录错误日志
    errorLogger.error({
      message: err.message,
      stack: err.stack,
      url: ctx.url,
      method: ctx.method,
      body: ctx.request.body,
      headers: ctx.headers
    });

    // 根据错误类型返回不同状态码
    const status = err.status || err.statusCode || 500;
    const message = err.message || 'Internal Server Error';

    ctx.status = status;
    ctx.body = {
      success: false,
      error: message,
      ...(process.env.NODE_ENV === 'development' && { stack: err.stack })
    };

    // 触发告警通知
    if (status >= 500) {
      await notifyAdmin(err, ctx);
    }
  }
});

// 404 处理
app.use(async (ctx) => {
  ctx.status = 404;
  ctx.body = { success: false, error: 'Not Found' };
});

结构化日志

使用 JSON 格式便于日志分析和搜索:

// 业务日志记录器
const businessLogger = {
  log(orderId, action, data) {
    logger.info(JSON.stringify({
      type: 'business',
      orderId,
      action,
      data,
      timestamp: new Date().toISOString(),
      service: 'order-service'
    }));
  }
};

// 记录订单创建
router.post('/order', async (ctx) => {
  const order = await createOrder(ctx.request.body);

  businessLogger.log(order.id, 'order_created', {
    userId: order.userId,
    amount: order.amount,
    items: order.items.length
  });

  ctx.body = { success: true, data: order };
});

日志分析与告警

常见日志分析场景和告警规则:

  1. 错误率告警:5分钟内错误数超过阈值(如10个/分钟)
  2. 响应时间告警:P95 响应时间超过设定阈值
  3. 特定错误告警:如数据库连接失败、支付异常等
  4. 异常堆栈:记录完整堆栈信息便于定位

日志收集方案

方案 特点 适用场景
ELK Stack 功能强大,生态完善 大型应用
EFK Stack 轻量级,易部署 中小型应用
Loki 简单高效,成本低 云原生场景
商业方案 Datadog, NewRelic 开箱即用

性能考量

← 下一篇:Koa.js 服务端渲染与模板引擎实践 上篇:Koa.js API 版本控制与向后兼容 →