在Ubuntu环境中,Node.js应用程序的HTTP请求处理日志是监控应用状态、排查问题及优化性能的关键依据。以下从日志记录配置、常用日志中间件、日志存储与管理、请求流程追踪、日志分析与优化五大维度,详解如何在Ubuntu中实现HTTP请求日志的全生命周期管理。
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
这种方式适合临时存储日志,但缺乏结构化管理和日志轮转功能。
Morgan是Express生态中最流行的HTTP请求日志工具,可快速生成符合Apache/Nginx格式的日志,或自定义日志字段。
安装与配置:
npm install morgan
基本用法:输出组合格式日志到控制台:
const morgan = require('morgan');
app.use(morgan('combined')); // 组合格式:method status response-time等
自定义日志格式:通过token定义字段(如请求体、URL参数),输出到文件:
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适合快速集成,能满足大多数HTTP请求日志需求。
Winston是功能强大的结构化日志库,支持多传输方式(文件、控制台、数据库等)、日志级别(info/error/debug)和日志格式(JSON/文本)。
安装与配置:
npm install 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适合生产环境,能实现日志的分类存储、结构化分析和多渠道输出。
建议将错误日志(error.log)与常规日志(combined.log)分开存储,便于快速定位问题。例如,Winston配置中通过level参数区分:
transports: [
new transports.File({ filename: 'error.log', level: 'error' }), // 仅存储error及以上级别日志
new transports.File({ filename: 'combined.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天日志
})
]
});
通过journalctl查看Ubuntu系统日志(若Node.js以systemd服务运行):
sudo journalctl -u your-node-service.service -f // 实时查看服务日志
或配置Node.js日志写入系统日志(需配合winston-syslog库)。
通过中间件捕获请求的方法、路径、查询参数、请求头、请求体,实现完整的请求流程追踪:
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); // 应用到所有路由
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)。
/api/data)的GET请求数量:grep '"GET /api/data"' combined.log | wc -l
response-time字段为ms单位):awk -F'"' '{print $4}' combined.log | awk '{sum += $1} END {print "Average response time: " sum/NR " ms"}'
grep -E ' 4[0-9]{2} | 5[0-9]{2} ' combined.log
通过以上步骤,可在Ubuntu环境中实现Node.js HTTP请求日志的全面管理,从基础记录到结构化分析,帮助开发者快速定位问题、优化应用性能。