在 Node.js 项目进入测试环境和生产环境后,问题的发现和定位往往不再依赖调试器,而是依赖日志和监控系统。日志记录了系统运行过程中的关键行为,监控则帮助我们实时掌握系统健康状态。
本文将系统介绍 Node.js 中常见的日志方案和监控思路,帮助你构建稳定、可观测的后端服务。
一、为什么日志与监控如此重要
在真实生产环境中,常常会遇到以下问题:
- 接口偶发报错但无法复现
- 性能逐渐下降却没有明显异常
- 某些用户请求失败但无报警
如果缺乏日志和监控,这类问题几乎无法定位。
日志解决的是"发生了什么",监控解决的是"系统现在怎么样"。
二、Node.js 日志的基本设计原则
在开始选型之前,先明确日志设计的基本原则。
- 日志要有明确的目的
- 日志级别要清晰
- 日志结构要统一
- 日志不能影响性能
日志不是越多越好,而是越有价值越好。
三、Node.js 常见日志级别
一个合理的日志系统通常包含以下级别:
- error:程序错误、异常、影响功能的问题
- warn:潜在风险或非致命问题
- info:关键业务流程信息
- debug:调试信息,通常只在开发环境开启
合理使用日志级别,有助于快速过滤关键信息。
四、使用 console 记录日志的局限性
在项目早期,console.log 是最常见的日志方式。
但在正式项目中,它存在明显问题:
- 无法区分日志级别
- 不支持日志切割
- 不便于集中管理
- 不适合生产环境
因此,在中大型项目中,应尽早引入专业日志库。
五、Node.js 常用日志库
1. Winston
Winston 是 Node.js 中使用最广泛的日志库之一。
它支持多种日志级别、输出格式和日志目标。
js
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'app.log' })
]
});
logger.info('Service started');
2. Pino
Pino 以高性能著称,适合高并发场景。
它输出结构化 JSON 日志,便于后续分析。
js
const logger = require('pino')();
logger.info({ userId: 1 }, 'User login');
六、结构化日志的优势
结构化日志使用 JSON 格式记录信息。
它的优势包括:
- 易于搜索和过滤
- 便于日志分析系统处理
- 更适合分布式系统
在实际项目中,推荐尽量使用结构化日志。
七、Node.js 中的错误日志处理
错误日志是日志系统中最重要的一部分。
建议在以下位置记录错误日志:
- 接口统一错误处理中间件
- 关键业务逻辑捕获异常
- 进程级异常处理
例如:
js
process.on('uncaughtException', err => {
logger.error(err);
});
八、Node.js 监控的核心指标
监控关注的是系统的实时状态。
常见监控指标包括:
- CPU 使用率
- 内存占用
- 请求 QPS
- 响应时间
- 错误率
这些指标可以帮助快速判断系统是否健康。
九、Node.js 应用层监控方式
在应用层,可以通过中间件统计请求信息。
例如记录接口耗时、状态码等。
这些数据可以用于性能分析和报警。
十、使用 PM2 进行基础监控
PM2 是 Node.js 常用的进程管理工具。
它自带基础监控能力,包括:
- 进程状态
- CPU 和内存使用
- 日志管理
PM2 非常适合中小型项目。
十一、集中式日志与监控系统
在生产环境中,通常会将日志和监控数据集中管理。
常见方案包括:
- 日志系统:ELK、EFK
- 监控系统:Prometheus + Grafana
集中式方案更适合分布式和微服务架构。
十二、日志与监控的最佳实践
在实际项目中,可以遵循以下建议:
- 日志中包含请求标识
- 监控指标与业务关联
- 为关键指标设置报警
- 定期检查日志质量
日志和监控不是一次性工作,而是持续优化的过程。
十三、总结
日志与监控是 Node.js 应用稳定运行的重要保障。通过合理的日志设计和完善的监控体系,可以在问题发生时快速定位,在问题发生前提前预警。
在《Node.js 编程实战》中,掌握日志与监控方案,不仅是调试能力的提升,更是工程能力的重要体现。