作者:靠 tail -f debug.log 活着的后端守夜人
在一套互动娱乐组件中,日志、监控和健康机制往往被开发者忽视。直到你在凌晨三点被运营电话吵醒,才明白什么叫“没有日志的人生,一定会重来”。
这一部分我们将从日志设计、数据监控、告警处理、服务健康管理、实战排障等多个维度拆解整套系统中最底层、最关键但又最不被重视的“守夜人系统”。
一、日志系统设计原理
1.1 为什么日志是系统的“第三只眼”?
日志不仅是排障工具,更是行为审计、数据追踪、性能评估、用户画像的基础。
日志记录不是“出了问题才查”,而是“未雨绸缪,事后可追”。
常见日志分类:
类型 | 内容 | 文件路径 |
---|---|---|
启动日志 | 系统初始化、模块加载情况 | /logs/startup.log |
行为日志 | 用户进房/退出/操作记录 | /logs/action.log |
错误日志 | try/catch 异常、接口崩溃 | /logs/error.log |
配置日志 | 后台修改参数及应用结果 | /logs/config.log |
安全日志 | 登录IP、失败尝试等信息 | /logs/security.log |
1.2 日志格式推荐
{"timestamp": "2025-05-05T10:03:00Z","level": "INFO","module": "room_service","uid": 10023,"action": "enter_room","room_id": "ROOM-204"
}
推荐结构化输出,便于统一检索、索引与大数据分析。
二、Node服务端日志实现(Winston + 自定义)
const winston = require('winston');
const logger = winston.createLogger({level: 'info',format: winston.format.json(),transports: [new winston.transports.File({ filename: 'logs/error.log', level: 'error' }),new winston.transports.File({ filename: 'logs/action.log' })]
});logger.info({module: 'room_handler',uid: 20394,action: 'exit_room',room_id: 'ROOM-009'
});
支持每日轮换日志建议结合 winston-daily-rotate-file
插件。
三、前端日志采集与上传机制
window.onerror = function (message, source, lineno, colno, error) {const data = {msg: message,stack: error ? error.stack : '',time: new Date().toISOString()};navigator.sendBeacon('/api/log_front_error', JSON.stringify(data));
};
服务端接收保存:
$data = json_decode(file_get_contents('php://input'), true);
file_put_contents("logs/front_error.log", json_encode($data) . "
", FILE_APPEND);
四、实时监控指标体系设计
一个合格的双端系统应该具备如下运行指标:
指标项 | 含义 |
total_rooms | 当前房间数 |
online_users | 在线用户数 |
avg_ping | 平均响应延迟 |
socket_drop | 断连次数 |
error_rate | 接口错误比 |
建议通过 Prometheus 暴露 /metrics
接口供抓取。
app.get('/metrics', (req, res) => {res.send(`active_users_total ${userCount}
active_rooms_total ${roomCount}`);
});
五、运行监控系统选型建议
5.1 本地方案
-
PM2:最小化部署、崩溃自启、实时日志
-
NodeMailer + shell:简单报警机制
5.2 云端方案
-
Prometheus + Grafana:指标图表
-
Sentry:错误异常聚合
-
Loki + ELK:日志聚合检索
-
Pingdom/UptimeRobot:服务可用性检测
部署建议:
pm2 start app.js --name="dualend-server"
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M
六、异常预警系统搭建
通过告警脚本结合飞书/钉钉机器人实时通知:
#!/bin/bash
error_count=$(grep -c "ERROR" logs/error.log)
if [ "$error_count" -gt 50 ]; thencurl -X POST -H 'Content-Type: application/json' \-d '{"msg_type":"text","content":{"text":"警报:error.log 超过50条错误!"}}' \https://open.feishu.cn/xxx/robot/webhook
fi
推荐对以下事件设置告警:
-
服务 crash(pm2重启触发)
-
error.log 突增
-
redis/mysql 连接失败
-
某模块 QPS 激增或为 0(掉服务)
七、健康检查机制设计
没有健康检查的服务,就像没体检的老年人,哪天挂了都不知道。
服务端提供标准 /healthz
接口:
app.get('/healthz', (req, res) => {if (db.connected && redis.ping()) res.send('ok');else res.status(500).send('fail');
});
配合 Nginx 或 LoadBalancer:
location /healthz {proxy_pass http://localhost:3000/healthz;proxy_next_upstream error timeout invalid_header http_500;
}
八、服务恢复与追责机制(运维流程)
构建一整套标准流程文档:
-
日志收集:tail + grep
-
资源分析:htop / top / free
-
数据库连接检查:mysqlcli / redis-cli
-
恢复命令:pm2 restart all / docker restart all
-
故障通报机制:邮件 / 飞书模版
九、附加建议:分布式日志 + 数据隔离
-
日志按“项目+日期+类型”分目录
-
多服务部署建议使用集中日志平台(ELK)
-
高频写入日志建议采用缓冲队列写入,防止 I/O 阻塞
-
为防泄露,error.log 与 access.log 应分权限存储
十、小结
这一章节我们写满了每一个后端人心中的执念,从日志结构、前端采集、后端记录、指标采集、异常告警、健康检测,到实际故障恢复全流程。
这套系统不是为了“看着好看”,是为了在所有人睡觉时,能自动顶上去。
写日志不是怕出问题,是为了你有问题时,不再一脸懵逼地说:“我看不出来”。
愿你有日志可查,有监控可依,有告警能醒,有系统永不宕机。