日志与监控体系
问题
服务端如何设计日志和监控体系?前端需要了解哪些?
答案
监控体系全景
日志分级
logger.ts
import winston from 'winston';
const logger = winston.createLogger({
level: process.env.LOG_LEVEL || 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json(),
),
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' }),
],
});
// 日志级别(从高到低)
// error: 错误,需要立即处理
// warn: 警告,可能有问题
// info: 信息,正常业务流程
// debug: 调试,开发阶段使用
| 级别 | 用途 | 示例 |
|---|---|---|
| error | 系统错误 | 数据库连接失败、未捕获异常 |
| warn | 潜在问题 | 接口超时重试、缓存未命中率过高 |
| info | 业务流程 | 用户登录、订单创建、支付完成 |
| debug | 调试信息 | 请求参数、SQL 查询、中间状态 |
结构化日志
structured-log.ts
// ✅ 结构化日志(易于搜索和分析)
logger.info('Order created', {
orderId: 'ORD-001',
userId: 'USR-123',
amount: 99.99,
duration: 45, // 处理耗时 ms
traceId: 'abc-def-123',
});
// ❌ 非结构化日志(难以检索)
logger.info(`User USR-123 created order ORD-001, amount: 99.99`);
请求链路追踪
trace-middleware.ts
import { v4 as uuid } from 'uuid';
// 中间件:为每个请求添加 traceId
const traceMiddleware = (req: Request, res: Response, next: NextFunction) => {
const traceId = req.headers['x-trace-id'] as string || uuid();
req.traceId = traceId;
res.setHeader('x-trace-id', traceId);
// 记录请求日志
logger.info('Request received', {
traceId,
method: req.method,
path: req.path,
userAgent: req.headers['user-agent'],
ip: req.ip,
});
// 记录响应日志
const start = Date.now();
res.on('finish', () => {
logger.info('Response sent', {
traceId,
statusCode: res.statusCode,
duration: Date.now() - start,
});
});
next();
};
常见面试问题
Q1: 前端错误发生后,如何通过日志快速定位问题?
答案:
- 前端上报时携带
traceId(从响应头获取) - 用
traceId在服务端日志系统中搜索完整链路 - 查看链路上每个服务的日志:请求参数 → 处理过程 → 返回结果
Q2: ELK 是什么?
答案:
- Elasticsearch:日志存储和搜索引擎
- Logstash:日志收集和处理管道
- Kibana:可视化查询和仪表盘
日志采集流程:应用 → Filebeat → Logstash → Elasticsearch → Kibana
Q3: 什么样的日志应该记录?什么不该记录?
答案:
应该记录:请求入口和出口、关键业务操作、错误堆栈、性能指标 不该记录:用户密码、信用卡号、Token 明文等敏感信息
Q4: Prometheus 和 ELK 的区别?
答案:
- Prometheus + Grafana:适合指标监控(CPU、内存、QPS、响应时间),时序数据
- ELK:适合日志分析(搜索具体请求、错误排查),全文搜索
两者互补,通常一起使用。
Q5: 日志量太大怎么办?
答案:
- 日志分级:生产环境只记 info 及以上
- 采样:正常请求按比例采样,错误请求全量记录
- 轮转和归档:定期压缩、过期自动删除
- 异步写入:不阻塞主流程