发布于2026-07-15 阅读(0)
扫一扫,手机访问
在Ubuntu环境下折腾Node.js应用,HTTP请求日志就是那根“救命稻草”——出了啥问题、性能哪里卡壳、用户访问到底是什么情况,都得靠翻日志来找线索。但现实是,很多人要么只用console.log凑合,要么日志堆在一起占满硬盘。怎么把日志管好、用好,让日志真正变成开发运维的利器?下面就从配置、中间件、存储、追踪到分析,把这个事儿彻底捋一遍。

Node.js原生自带的console.log确实简单粗暴,开发阶段拿来快速看个请求入口没问题。比如在Express里,想记录一下请求什么时候进来的:
const express = require('express');
const app = express();
app.get('/', (req, res) => {
console.log(`Request received at ${new Date()}`); // 输出到控制台
res.send('Hello World!');
});
app.listen(3000, () => console.log('Server running on port 3000'));
不过,控制台这东西,一关窗口或者进程意外退出,日志就没了。一个临时补救办法是把输出重定向到文件里:
node app.js > app.log 2>&1
但讲真,这只能算“应急方案”,既没有结构化管理,也没有日志轮转,日志量大一点很快就能把硬盘塞满。所以,这种方式只适合临时看两眼,千万别当主力。
如果用的是Express,那Morgan几乎是标配。它能快速生成那种像Apache、Nginx风格的日志,而且支持自定义字段。装起来也简单:
npm install morgan
最基本的用法,一行代码就能把请求信息打印到控制台:
const morgan = require('morgan');
app.use(morgan('combined')); // 组合格式:method status response-time等
但更实用的是自定义格式,比如把请求体也记下来,然后输出到文件里:
const fs = require('fs');
const path = require('path');
const logStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' });
// 自定义token(比如请求体)
morgan.token('body', (req) => JSON.stringify(req.body));
app.use(morgan(':method :url :status :response-time ms - :res[content-length] :body', {
stream: logStream // 输出到文件
}));
这样记录下来的日志,大概是这个样子的:
GET /api/data 200 15ms - 12 - {"keyword":"test"}
一目了然。Morgan的好处就是开箱即用,覆盖绝大多数场景够用了。
但如果你的应用对日志有更高要求——比如要分级别、要存成JSON方便后续分析、要同时输出到文件和数据库——那么Winston就是更合适的选择。它支持多种传输方式(文件、控制台、数据库等),也支持日志级别(info/error/debug):
npm install winston
配置一个典型的Winston示例:
const { createLogger, format, transports } = require('winston');
const logger = createLogger({
level: process.env.LOG_LEVEL || 'info', // 通过环境变量设置日志级别
format: format.combine(
format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), // 时间戳
format.json() // 结构化输出(便于后续分析)
),
transports: [
new transports.File({ filename: 'error.log', level: 'error' }), // 错误日志单独存储
new transports.File({ filename: 'combined.log' }), // 所有日志合并...
...(process.env.NODE_ENV !== 'production' ? [ // 开发环境输出到控制台
new transports.Console({ format: format.simple() })
] : [])
]
});
// 在路由中使用
app.get('/', (req, res) => {
logger.info('Request received', { method: req.method, url: req.url }); // 结构化日志
res.send('Hello World!');
});
生产环境下,Winston的价值尤其明显:错误日志和常规日志分开存放,能更快定位问题,而且JSON格式天然适合接入日志分析平台。
实践中最基础也是最有效的一条原则:把错误日志和常规日志分开。Winston给的配置里,通过level参数就能方便地实现:
transports: [
new transports.File({ filename: 'error.log', level: 'error' }), // 仅存储error及以上级别日志
new transports.File({ filename: 'combined.log' }) // 存储所有级别日志
]
这样一来,排查问题时直接翻error.log就行,不用在海量常规日志里大海捞针。
日志文件如果一直写下去,迟早会把磁盘撑爆。这时候就必须用上日志轮转。推荐winston-daily-rotate-file这个库,按日期自动归档老日志:
npm install winston-daily-rotate-file
配置也很清晰:
const DailyRotateFile = require('winston-daily-rotate-file');
const logger = createLogger({
transports: [
new DailyRotateFile({
filename: 'logs/application-%DATE%.log', // 日志文件名格式
datePattern: 'YYYY-MM-DD', // 按天轮转
maxSize: '20m', // 单个文件最大20MB
maxFiles: '30d' // 保留30天日志
})
]
});
按天、按大小、按保留天数轮转,三种策略配合使用,日志管理就很省心了。
如果Node.js应用是以systemd服务运行的,还可以直接通过journalctl来查看日志,非常方便:
sudo journalctl -u your-node-service.service -f // 实时查看服务日志
也可以把Winston的日志输出到系统日志里,需要配合winston-syslog库来实现。
要真正追踪一次请求的完整路径,光记个URL和状态码是不够的。更推荐的做法是写一个中间件,把方法、路径、查询参数、请求头、请求体、客户端IP全部抓下来:
function logRequest(req, res, next) {
const logData = {
timestamp: new Date().toISOString(),
method: req.method,
url: req.originalUrl,
query: req.query,
headers: req.headers,
body: req.body,
clientIp: req.ip
};
console.log(JSON.stringify(logData, null, 2)); // 输出到控制台(生产环境建议用Winston)
next();
}
app.use(logRequest); // 应用到所有路由
有了这些信息,不管是排查接口传参错误,还是分析异常IP的攻击行为,都有据可查。
PM2可以说是Node.js开发者离不开的工具了,除了进程管理,它的日志聚合功能也相当好用:
npm install pm2 -g
pm2 start app.js --name "my-node-app" // 启动应用
pm2 logs my-node-app // 实时查看日志
pm2 logs my-node-app --lines 100 // 查看最近100行日志
PM2还支持日志文件轮转,甚至可以把日志发送到ELK Stack这样的集中式平台,适合微服务架构下的日志统一管理。
日志存下来了,怎么用?在还需要上ELK之前,先掌握几个好用的命令行技巧,能解决80%的日常排查需求:
/api/data这个路径的GET请求有多少次:grep '"GET /api/data"' combined.log | wc -l
response-time字段,算一下平均响应时间:awk -F'"' '{print $4}' combined.log | awk '{sum += $1} END {print "A verage response time: " sum/NR " ms"}'
grep -E ' 4[0-9]{2} | 5[0-9]{2} ' combined.log
当应用规模变大,或者需要长期跟踪性能趋势时,命令行就显得不够用了。这时候就该上专业工具:
从基础的手动配置到后期的自动化分析,每一步都是在为应用的可观测性添砖加瓦。真正把日志管好了,不仅能更快定位问题,还能从日志数据中发现性能瓶颈和用户行为模式,这才是日志管理的最终目的。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8