1. 系统日志基础:日志的定义、日志级别与日志的价值
大家好,我是你们的老朋友。今天咱们聊聊系统日志——这个看似基础,却常常被忽视的稳定性基石。
说实话,我见过太多团队把日志当成“可有可无”的东西。直到线上出了故障,才手忙脚乱地翻日志。嗯,那时候往往已经晚了。
1.1 日志到底是什么?
日志,说白了就是系统运行时的“黑匣子”。它记录着系统在什么时间、什么位置、发生了什么。
我个人习惯把日志分成三类:
- 系统日志:操作系统层面的记录,比如内核日志、系统启动日志
- 应用日志:业务代码里打印的日志,比如用户登录、订单创建
- 访问日志:Web 服务器的请求记录,比如 Nginx、Apache 的 access log
你想想看,没有日志的系统就像没有仪表盘的飞机。飞得再高,你也心里没底。
核心定义:日志是系统运行时产生的、带有时间戳的结构化或半结构化文本记录。它是我们了解系统行为的唯一可靠途径。
1.2 日志级别:从 DEBUG 到 FATAL
日志级别这东西,很多新手觉得无所谓。我在项目中遇到过不少团队,所有日志都用 INFO 级别。结果呢?日志量爆炸,真正有用的信息反而被淹没了。
咱们来看看标准的日志级别体系:
| 级别 | 含义 | 使用场景 | 我个人的建议 |
|---|---|---|---|
| DEBUG | 调试信息 | 开发环境、问题排查时临时开启 | 生产环境默认关闭,否则日志量会爆炸 |
| INFO | 常规信息 | 记录关键业务流程、系统状态变化 | 用来追踪“系统在做什么” |
| WARN | 警告 | 潜在问题、非预期但可容忍的情况 | 比如重试、降级、限流触发 |
| ERROR | 错误 | 功能不可用、操作失败 | 需要立即关注,但不一定导致系统崩溃 |
| FATAL | 致命错误 | 系统无法继续运行 | 比如内存溢出、核心组件挂掉 |
避坑指南:我曾经在一个项目中看到有人把 ERROR 当 INFO 用,结果告警系统天天报警。最后大家直接无视了所有 ERROR 日志。这很危险——狼来了的故事,在日志系统里同样适用。
为什么会这样?因为日志级别不仅仅是分类,它还是我们判断问题严重性的第一道防线。级别用错了,整个监控体系都会失效。
1.3 日志的作用与价值
日志的价值,我总结为四个字:可观测性。没有日志,你根本不知道系统里发生了什么。
具体来说,日志有三大核心作用:
- 故障排查:系统出问题了,第一件事就是看日志。我记得有一次线上服务突然超时,查了半小时代码没找到原因。最后翻日志发现,是数据库连接池被耗尽了。嗯,日志里清清楚楚地打印了连接获取超时的异常。
- 性能分析:通过日志里的耗时数据,可以定位慢查询、慢接口。比如在关键路径上打印“开始处理”和“处理完成”的日志,计算时间差。
- 安全审计:谁在什么时间做了什么操作?日志里一清二楚。这在合规场景下尤其重要。
小技巧:我个人习惯在日志里加上 request_id 或者 trace_id。这样一次请求的所有日志就能串起来。排查问题时,按 ID 一搜,整个调用链路就出来了。
你想想看,如果没有日志,线上出了故障怎么办?靠猜吗?靠重启吗?那不是运维,那是玄学。
1.4 一个简单的日志示例
说了这么多,咱们看个实际的例子。假设你写了一个用户注册接口:
# Python 示例
import logging
import uuid
logger = logging.getLogger(__name__)
def register_user(username, email):
request_id = str(uuid.uuid4())
logger.info(f"[{request_id}] 开始处理用户注册: {username}")
try:
# 检查用户是否存在
if user_exists(username):
logger.warning(f"[{request_id}] 用户已存在: {username}")
return {"code": 400, "msg": "用户已存在"}
# 创建用户
user = create_user(username, email)
logger.info(f"[{request_id}] 用户创建成功: {user.id}")
# 发送欢迎邮件
send_welcome_email(email)
logger.info(f"[{request_id}] 欢迎邮件已发送: {email}")
return {"code": 200, "msg": "注册成功"}
except Exception as e:
logger.error(f"[{request_id}] 用户注册失败: {str(e)}", exc_info=True)
return {"code": 500, "msg": "系统异常"}
你看,这个例子里的日志级别用得很清晰:
- INFO 记录正常流程
- WARN 记录业务上的异常情况
- ERROR 记录系统异常,还带了堆栈信息
这样的日志,排查问题的时候一看就懂。而不是满屏的“用户注册成功”或者“系统异常”。
1.5 日志的黄金法则
最后,分享几条我这些年总结的日志黄金法则:
- 该打的日志一定要打:关键路径、异常分支、边界条件,一个都不能少
- 不该打的日志别打:循环里打日志、敏感信息打日志,都是大忌
- 日志要有上下文:光说“失败”没用,得说清楚“谁在什么操作上失败了”
- 日志要结构化:能用 JSON 就别用纯文本,方便后续分析
一句话总结:日志是系统的眼睛。眼睛瞎了,再好的代码也跑不稳。
好了,这一章就到这里。下一章咱们聊聊日志框架的选择和配置。到时候我会分享一些我在生产环境里踩过的坑,保证让你少走弯路。
公众号:蓝海资料掘金营,微信deep3321