Node.js中loggers与logging的正确实现方式是什么
主动捕获运行时日志的实现方案
建议优先选用成熟的日志库(比如winston、pino)实现,不需要手动封装底层能力,主动捕获日志可覆盖以下几个场景:
- 全局异常兜底捕获
针对没被业务代码catch的异常,直接监听Node.js进程的全局事件统一打日志:// 捕获未处理的Promise拒绝 process.on('unhandledRejection', (reason, promise) => { logger.error('未处理的Promise异常', { errorInfo: reason instanceof Error ? reason.stack : String(reason), promise: promise.toString() }) }) // 捕获未处理的同步异常 process.on('uncaughtException', (err) => { logger.error('未捕获的同步异常', err.stack) // 异常捕获后建议退出进程,此时应用状态可能已经不稳定 process.exit(1) }) - 框架层全局错误中间件捕获
如果使用了Express、Koa这类Web框架,新增全局错误处理中间件,统一捕获所有请求链路的异常:// Express 全局错误中间件示例 app.use((err, req, res, next) => { logger.error('接口请求异常', { method: req.method, path: req.originalUrl, clientIp: req.ip, errorStack: err.stack }) res.status(500).send('服务内部错误') }) - 业务逻辑埋点
在第三方调用、IO操作、临界逻辑块增加try/catch,主动打印异常或告警日志,不要吞掉错误:async function queryOrderInfo(orderId) { try { const result = await orderDb.query({ id: orderId }) // 非错误但需要关注的异常状态也可以打warn日志 if (result.payTimeout) { logger.warn('订单支付超时', { orderId, createTime: result.createTime }) } return result } catch (err) { logger.error('订单查询失败', { orderId, error: err.message }) return null } } - 运行状态监控告警
定时检测应用运行指标,达到阈值时主动打印warn日志,比如内存占用过高、连接池排队、请求qps超限等:// 每分钟检测一次堆内存占用,超过80%打印告警 setInterval(() => { const mem = process.memoryUsage() const usageRate = mem.heapUsed / mem.heapTotal if (usageRate > 0.8) { logger.warn('堆内存占用过高', { usage: `${(usageRate * 100).toFixed(1)}%`, used: `${(mem.heapUsed / 1024 / 1024).toFixed(2)}MB` }) } }, 60000)
日志写入文本文件的优劣分析
优势
- 数据持久化:服务重启、崩溃后日志不会丢失,方便事后回溯排查问题
- 适配生产环境日志链路:可以配合日志采集工具同步到统一日志平台做检索、统计、告警
- 性能更优:成熟日志库写文件的性能远高于控制台输出,不会因为控制台打印阻塞主进程
注意事项
- 本地开发阶段可以只输出控制台方便调试,生产环境建议同时配置文件存储和控制台输出
- 需要配置日志轮转规则,按天/按文件大小切分日志,自动清理过期日志,避免占满磁盘,主流日志库都有配套插件支持该能力
- 禁止在日志中输出密码、用户token、身份证等敏感信息,避免数据泄露
内容的提问来源于stack exchange,提问作者Sara BB
相关产品推荐
相关产品推荐

