1. 日志基础入门:日志是什么、为什么重要、常见日志类型

各位同学好,我是老赵。咱们这门课叫《启动日志分析与故障排查》,第一节课,我想先聊聊最基础的问题——日志到底是什么。

说白了,日志就是系统、应用或者设备在运行过程中,记录下来的“流水账”。它告诉你:什么时间、在哪个模块、发生了什么事、结果如何。我经常跟团队里的新人讲,日志就是系统的“黑匣子”。飞机出事了要找黑匣子,系统出故障了,第一反应也应该是翻日志。

核心定义:日志是带有时间戳的、按时间顺序排列的事件记录。它是系统运行状态的客观证据。

1.1 为什么日志这么重要?

你可能觉得日志就是些文本文件,没什么大不了的。但我告诉你,在我十几年的运维生涯里,至少 80% 的故障定位,最终都是靠日志找到根因的。

日志的重要性,主要体现在这几个方面:

  • 故障排查的第一手资料 —— 系统崩了,你问开发“你改了什么?”,他可能说“我就改了一行配置”。但日志不会撒谎。我曾经遇到过一次线上大面积 502,查了所有中间件都没问题,最后是应用日志里一条“数据库连接池耗尽”的报错,直接锁定了问题。
  • 安全审计的基石 —— 谁在什么时间登录了服务器?执行了什么命令?访问了哪些敏感数据?这些都得靠安全日志说话。合规审计的时候,拿不出日志,那就是你的失职。
  • 性能分析的依据 —— 接口响应慢了,是数据库查询慢,还是第三方调用超时?通过分析应用日志里的耗时记录,一眼就能看出来。
  • 业务监控的眼睛 —— 交易成功率、用户登录失败率、订单异常率,这些业务指标都可以从日志里实时计算出来。

我的个人习惯:接手任何一个新系统,第一件事就是搞清楚它的日志目录在哪、日志格式是什么、日志滚动策略是怎样的。这比看架构图管用多了。

1.2 常见日志类型

日志虽然多,但大致可以分为三类。我画了张图,帮你快速建立整体认知:

常见日志类型与核心作用 日志系统 系统日志 应用日志 安全日志 核心作用 • 内核/服务启停记录 • 硬件/驱动状态变化 • 系统资源告警 • 典型:/var/log/messages 核心作用 • 业务请求处理记录 • 异常/错误堆栈 • 接口调用耗时 • 典型:app.log, catalina.out 核心作用 • 用户登录/登出记录 • 权限变更审计 • 防火墙/入侵检测 • 典型:secure, audit.log

1.2.1 系统日志

系统日志,是操作系统层面记录的日志。它关注的是硬件、内核、服务、驱动这些底层组件的状态。

在 Linux 系统里,系统日志通常集中在 /var/log/ 目录下。我列几个最常见的:

日志文件 记录内容 典型用途
/var/log/messages 通用系统消息,包括内核、服务启停 排查系统级异常、服务崩溃
/var/log/dmesg 内核环缓冲区消息,硬件检测 排查硬件故障、驱动加载失败
/var/log/cron 计划任务执行记录 检查定时任务是否正常执行
/var/log/boot.log 系统启动过程中的服务启动日志 排查开机启动失败问题

避坑指南:我曾经遇到一个案例,服务器频繁重启,查了三天没找到原因。最后发现是 /var/log/messages 里有一条 Out of memory: Kill process 的记录,OOM Killer 把关键进程杀了,导致系统自动重启。如果早点看系统日志,半小时就能搞定。

1.2.2 应用日志

应用日志,是咱们自己写的程序输出的日志。它记录的是业务逻辑的执行过程。

应用日志的格式,通常由开发人员定义。但好的应用日志,一般会包含这些信息:

  • 时间戳 —— 精确到毫秒,最好带时区
  • 日志级别 —— DEBUG, INFO, WARN, ERROR, FATAL
  • 线程/进程 ID —— 方便追踪并发请求
  • 类名/方法名 —— 快速定位代码位置
  • 请求追踪 ID —— Trace ID,用于串联一次完整的请求链路
  • 具体消息 —— 发生了什么,参数是什么

举个例子,一个标准的 Java 应用日志长这样:

2025-03-21 14:30:22.156 [http-nio-8080-exec-3] INFO  com.example.OrderService - 创建订单成功, orderId=123456, userId=789, amount=299.00
2025-03-21 14:30:22.158 [http-nio-8080-exec-3] WARN  com.example.PaymentClient - 调用支付接口超时, retryCount=1, orderId=123456
2025-03-21 14:30:22.160 [http-nio-8080-exec-3] ERROR com.example.OrderController - 订单处理异常: java.sql.SQLException: Connection is not available

你看,从 INFO 到 WARN 再到 ERROR,一条完整的故障链路就出来了。先创建订单成功,然后支付超时,最后数据库连接异常导致订单处理失败。这就是应用日志的价值。

我建议:在开发阶段就约定好日志规范。比如统一使用 JSON 格式输出,这样后续接入日志平台(ELK、Loki 等)解析起来非常方便。别等到出故障了,才发现日志格式乱七八糟,没法自动化分析。

1.2.3 安全日志

安全日志,记录的是与系统安全、用户认证、权限控制相关的事件。

在 Linux 系统中,安全日志主要由 auditd 和 sshd 等组件产生。常见的包括:

日志文件 记录内容 典型用途
/var/log/secure 用户认证、SSH 登录、sudo 执行 排查暴力破解、非法登录
/var/log/audit/audit.log 系统调用审计、文件访问审计 安全合规、入侵溯源
/var/log/faillog 登录失败记录 监控暴力破解尝试
/var/log/lastlog 所有用户最近一次登录记录 检查异常登录行为

我记得有一次,客户反馈服务器 CPU 持续 100%,但业务量并没有增长。我第一反应就是查安全日志。果然,在 /var/log/secure 里发现大量来自国外 IP 的 SSH 登录失败记录,每分钟上千次。服务器被当成肉鸡在搞暴力破解,CPU 全耗在密码验证上了。直接封 IP、改端口、配置 fail2ban,问题秒解。

一句话总结:系统日志看“机器健康”,应用日志看“业务状态”,安全日志看“谁在搞事”。三者缺一不可。

1.3 日志的通用结构

不管哪种日志,它们都有一个通用的结构。你理解了这一点,后面分析任何日志都能快速上手。

一条完整的日志记录,通常包含四个要素:

  1. 时间 —— 事件发生的时刻
  2. 来源 —— 哪个组件、哪个进程、哪个用户产生的
  3. 事件 —— 具体发生了什么
  4. 结果 —— 成功还是失败,附带什么状态码或错误信息

举个例子,一条系统日志:

Mar 21 14:30:15 web01 sshd[12345]: Failed password for root from 192.168.1.100 port 22 ssh2

拆解一下:

  • 时间: Mar 21 14:30:15
  • 来源: web01 主机上的 sshd 进程(PID 12345)
  • 事件: root 用户登录失败
  • 结果: 来自 192.168.1.100 的密码验证失败

再比如一条 Nginx 访问日志:

192.168.1.100 - - [21/Mar/2025:14:30:22 +0800] "GET /api/order HTTP/1.1" 200 1234 "-" "Mozilla/5.0"

拆解:

  • 时间: 21/Mar/2025:14:30:22 +0800
  • 来源: 客户端 IP 192.168.1.100
  • 事件: 请求 GET /api/order
  • 结果: 状态码 200,返回 1234 字节

你看,万变不离其宗。掌握了这个结构,任何日志在你眼里都是透明的。

一个小技巧:刚开始接触一个新系统的日志时,先找一条典型的日志记录,手动拆解出时间、来源、事件、结果四个部分。拆上十次,你就能摸清它的“脾气”了。

1.4 日志的级别

日志级别,说白了就是给日志贴了个“严重程度”的标签。它帮助我们快速过滤和定位问题。

大部分日志框架都遵循类似的级别定义,从低到高排列:

级别 含义 什么时候用
TRACE 追踪 最细粒度的调试信息,生产环境一般不开启
DEBUG 调试 开发调试阶段使用,记录变量值、执行路径
INFO 信息 正常的业务操作记录,如“订单创建成功”
WARN 警告 潜在问题,不影响当前功能但需要注意,如“重试第一次”
ERROR 错误 功能不可用,需要立即关注,如“数据库连接失败”
FATAL 致命 系统即将崩溃或无法恢复,如“内存溢出”

我曾经踩过的坑:有次线上排查问题,发现 ERROR 日志很少,但系统就是不稳定。后来才发现,开发把本该打 ERROR 的异常,全用 WARN 级别输出了。原因是他觉得“打 ERROR 显得代码质量差”。嗯,从那以后我定了个规矩:ERROR 级别必须打,不打就 code review 不通过。

好了,第一节课的内容就到这里。日志这东西,入门不难,但真正用好它,需要你在实践中不断积累经验。后面的课程,我会带你一步步深入,从怎么收集日志,到怎么分析日志,再到怎么通过日志快速定位故障。咱们下节课见。