第12章 日志分析
完整 485 页的 《编译与调试完全指南》见: lengjingzju-notes发布页
日志是 Linux 系统调试和运维的第一手信息来源。无论是服务崩溃、内核异常、安全事件还是性能劣化,日志都能提供关键线索。本章系统介绍 Linux 日志体系的完整知识:从 systemd 日志查询(journalctl)、内核环形缓冲区(dmesg)、传统日志文件(/var/log),到底层内核消息接口(/proc/kmsg)、传统 syslog 体系(rsyslog/logger),再到日志生命周期管理(logrotate),构建从"日志产生→采集→存储→查询→管理"的完整工具链。
#mermaid-svg-cXTxePLj5FZCGFRX{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-cXTxePLj5FZCGFRX .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-cXTxePLj5FZCGFRX .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-cXTxePLj5FZCGFRX .error-icon{fill:#552222;}#mermaid-svg-cXTxePLj5FZCGFRX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-cXTxePLj5FZCGFRX .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-cXTxePLj5FZCGFRX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-cXTxePLj5FZCGFRX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-cXTxePLj5FZCGFRX .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-cXTxePLj5FZCGFRX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-cXTxePLj5FZCGFRX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-cXTxePLj5FZCGFRX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-cXTxePLj5FZCGFRX .marker.cross{stroke:#333333;}#mermaid-svg-cXTxePLj5FZCGFRX svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-cXTxePLj5FZCGFRX p{margin:0;}#mermaid-svg-cXTxePLj5FZCGFRX .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-cXTxePLj5FZCGFRX .cluster-label text{fill:#333;}#mermaid-svg-cXTxePLj5FZCGFRX .cluster-label span{color:#333;}#mermaid-svg-cXTxePLj5FZCGFRX .cluster-label span p{background-color:transparent;}#mermaid-svg-cXTxePLj5FZCGFRX .label text,#mermaid-svg-cXTxePLj5FZCGFRX span{fill:#333;color:#333;}#mermaid-svg-cXTxePLj5FZCGFRX .node rect,#mermaid-svg-cXTxePLj5FZCGFRX .node circle,#mermaid-svg-cXTxePLj5FZCGFRX .node ellipse,#mermaid-svg-cXTxePLj5FZCGFRX .node polygon,#mermaid-svg-cXTxePLj5FZCGFRX .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-cXTxePLj5FZCGFRX .rough-node .label text,#mermaid-svg-cXTxePLj5FZCGFRX .node .label text,#mermaid-svg-cXTxePLj5FZCGFRX .image-shape .label,#mermaid-svg-cXTxePLj5FZCGFRX .icon-shape .label{text-anchor:middle;}#mermaid-svg-cXTxePLj5FZCGFRX .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-cXTxePLj5FZCGFRX .rough-node .label,#mermaid-svg-cXTxePLj5FZCGFRX .node .label,#mermaid-svg-cXTxePLj5FZCGFRX .image-shape .label,#mermaid-svg-cXTxePLj5FZCGFRX .icon-shape .label{text-align:center;}#mermaid-svg-cXTxePLj5FZCGFRX .node.clickable{cursor:pointer;}#mermaid-svg-cXTxePLj5FZCGFRX .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-cXTxePLj5FZCGFRX .arrowheadPath{fill:#333333;}#mermaid-svg-cXTxePLj5FZCGFRX .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-cXTxePLj5FZCGFRX .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-cXTxePLj5FZCGFRX .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cXTxePLj5FZCGFRX .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-cXTxePLj5FZCGFRX .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cXTxePLj5FZCGFRX .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-cXTxePLj5FZCGFRX .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-cXTxePLj5FZCGFRX .cluster text{fill:#333;}#mermaid-svg-cXTxePLj5FZCGFRX .cluster span{color:#333;}#mermaid-svg-cXTxePLj5FZCGFRX div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-cXTxePLj5FZCGFRX .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-cXTxePLj5FZCGFRX rect.text{fill:none;stroke-width:0;}#mermaid-svg-cXTxePLj5FZCGFRX .icon-shape,#mermaid-svg-cXTxePLj5FZCGFRX .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cXTxePLj5FZCGFRX .icon-shape p,#mermaid-svg-cXTxePLj5FZCGFRX .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-cXTxePLj5FZCGFRX .icon-shape .label rect,#mermaid-svg-cXTxePLj5FZCGFRX .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cXTxePLj5FZCGFRX .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-cXTxePLj5FZCGFRX .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-cXTxePLj5FZCGFRX :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 日志管理层
日志查询层
日志存储层
日志采集层
日志产生层
内核 printk
systemd 服务
用户应用
脚本 logger
systemd-journald
klogd
rsyslog
run-log-journal/
var-log-journal
二进制格式
var-log-*.log
文本格式
内核环形缓冲区
journalctl
dmesg
grep-tail-awk
logrotate
12.1 系统日志
本节介绍 Linux 系统中三类主要的日志查询途径:systemd 日志(journalctl)、内核环形缓冲区(dmesg)和传统日志文件(/var/log)。它们分别对应不同的日志来源和存储机制,适用于不同的排查场景。
12.1.1 journalctl(查询 systemd 日志)
journalctl 是 systemd 日志系统(systemd-journald)的查询工具,能够查询由 systemd-journald 服务收集的所有日志,包括内核日志、系统服务日志和用户会话日志。日志以二进制格式存储在 /run/log/journal/(易失性)或 /var/log/journal/(持久化)目录中。
基本用法
bash
journalctl [OPTIONS...] [MATCHES...]
常用选项
| 选项 | 说明 | 典型用途 |
|---|---|---|
-b / -b 0 |
仅显示本次启动的日志 | 排查当前启动问题 |
-b -1 |
显示上次启动的日志 | 排查重启前的问题 |
-b -2 |
显示上上次启动的日志 | 追溯历史问题 |
-u <unit> |
过滤指定服务/单元的日志 | 排查特定服务问题 |
-p <priority> |
按优先级过滤(0-7 或名称) | 只看错误/警告 |
-f |
实时跟踪新日志(类似 tail -f) |
实时监控 |
-n <num> |
显示最后 N 条日志 | 快速查看最近日志 |
--since <time> |
起始时间过滤 | 按时间段查询 |
--until <time> |
截止时间过滤 | 按时间段查询 |
-o <format> |
输出格式(short/json/verbose/cat 等) | 脚本解析/详细查看 |
-k |
仅显示内核日志 | 等价于 dmesg 的 journal 版本 |
-g <pattern> |
使用正则表达式过滤消息内容 | 关键词搜索 |
--no-pager |
不使用分页器 | 脚本中使用 |
--no-hostname |
不显示主机名 | 简化输出 |
-x |
显示目录(catalog)中的解释信息 | 获取错误的详细说明 |
--list-boots |
列出所有启动记录 | 查看启动历史 |
--disk-usage |
显示日志占用的磁盘空间 | 磁盘空间管理 |
--vacuum-size=<size> |
清理日志至指定大小 | 释放磁盘空间 |
--vacuum-time=<time> |
清理指定时间之前的日志 | 释放磁盘空间 |
匹配字段(MATCHES)
journalctl 支持通过 FIELD=VALUE 形式的匹配字段进行精确过滤。这些字段对应日志条目中的元数据,比 -u、-p 等选项提供更细粒度的过滤能力:
| 匹配字段 | 说明 | 示例 |
|---|---|---|
_PID=<pid> |
按产生日志的进程 ID 过滤 | journalctl _PID=1234 |
_UID=<uid> |
按产生日志的用户 ID 过滤 | journalctl _UID=1000 |
_GID=<gid> |
按产生日志的组 ID 过滤 | journalctl _GID=1000 |
_COMM=<name> |
按进程命令名过滤(不含路径) | journalctl _COMM=nginx |
_EXE=<path> |
按可执行文件完整路径过滤 | journalctl _EXE=/usr/sbin/nginx |
_SYSTEMD_UNIT=<unit> |
按 systemd 单元名过滤 | journalctl _SYSTEMD_UNIT=sshd.service |
_SYSTEMD_SLICE=<slice> |
按 systemd slice 过滤 | journalctl _SYSTEMD_SLICE=user.slice |
_BOOT_ID=<id> |
按启动 ID 过滤 | journalctl _BOOT_ID=xxx |
_TRANSPORT=<type> |
按日志传输方式过滤(stdout/syslog/journal 等) | journalctl _TRANSPORT=stdout |
SYSLOG_FACILITY=<num> |
按 syslog facility 编号过滤(0-23) | journalctl SYSLOG_FACILITY=3 |
SYSLOG_IDENTIFIER=<name> |
按 syslog 标识符过滤 | journalctl SYSLOG_IDENTIFIER=sshd |
PRIORITY=<num> |
按优先级过滤(等价于 -p) |
journalctl PRIORITY=3 |
MESSAGE=<text> |
按消息内容精确匹配 | journalctl MESSAGE="Started" |
提示 :使用
journalctl -o verbose可以查看日志条目的所有可用字段,从而发现更多可过滤的字段。多个匹配字段同时指定时,默认为 AND 关系;同一字段的多个值之间为 OR 关系。
优先级(Priority)级别
| 数值 | 名称 | 缩写 | 说明 |
|---|---|---|---|
| 0 | emerg | emerg | 系统不可用 |
| 1 | alert | alert | 必须立即处理 |
| 2 | crit | crit | 严重情况 |
| 3 | err | err | 错误 |
| 4 | warning | warning | 警告 |
| 5 | notice | notice | 正常但值得注意 |
| 6 | info | info | 信息性消息 |
| 7 | debug | debug | 调试信息 |
实战示例
bash
# 查看所有日志
journalctl
# 查看本次启动的所有日志
journalctl -b
# 查看上次启动的日志(排查崩溃原因)
journalctl -b -1
# 查看指定服务的日志
journalctl -u nginx
journalctl -u sshd.service
# 实时跟踪日志(类似 tail -f)
journalctl -f
# 实时跟踪特定服务的日志
journalctl -u nginx -f
# 按时间范围过滤
journalctl --since "2024-01-01" --until "2024-01-02"
journalctl --since "1 hour ago"
journalctl --since today
# 按优先级过滤(只看错误及以上)
journalctl -p err
journalctl -p 3
# 只看内核日志
journalctl -k
# 显示最后 50 条日志
journalctl -n 50
# 按进程 ID 过滤
journalctl _PID=1234
# 按用户过滤
journalctl _UID=1000
# 按命令名过滤
journalctl _COMM=nginx
# 按可执行文件路径过滤
journalctl /usr/sbin/nginx
# 按 syslog facility 过滤(3 = daemon)
journalctl SYSLOG_FACILITY=3
# 使用正则表达式搜索
journalctl -g "segfault|OOM|error"
# JSON 格式输出(便于脚本解析)
journalctl -o json --no-pager
# 显示详细字段信息(查看所有可用匹配字段)
journalctl -o verbose -n 5
# 查看日志占用的磁盘空间
journalctl --disk-usage
# 清理日志:只保留最近 7 天
journalctl --vacuum-time=7d
# 清理日志:只保留 500M
journalctl --vacuum-size=500M
# 列出所有启动记录
journalctl --list-boots
# 组合过滤:查看 nginx 服务今天的错误日志
journalctl -u nginx -p err --since today
输出解读
Jan 15 10:30:01 hostname sshd[1234]: Failed password for root from 192.168.1.100 port 52341 ssh2
| 字段 | 含义 |
|---|---|
Jan 15 10:30:01 |
时间戳 |
hostname |
主机名 |
sshd |
产生日志的程序名 |
[1234] |
进程 PID |
| 后续内容 | 日志消息 |
journalctl 持久化配置
默认情况下,systemd-journald 的日志可能仅存储在 /run/log/journal/(内存中,重启丢失)。要启用持久化存储:
bash
# 创建持久化目录
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
# 重启 journald 服务
sudo systemctl restart systemd-journald
配置文件位于 /etc/systemd/journald.conf,关键参数:
| 参数 | 说明 | 默认值 | 建议值 |
|---|---|---|---|
Storage |
存储方式(auto/persistent/volatile/none) | auto | persistent |
SystemMaxUse |
日志最大占用空间 | 4G 或磁盘的 10% | 根据磁盘调整 |
SystemMaxFileSize |
单个日志文件最大大小 | 1/8 的 SystemMaxUse | 默认即可 |
MaxRetentionSec |
日志最大保留时间 | 0(不限) | 1month |
Compress |
是否压缩 | yes | yes |
ForwardToSyslog |
是否转发给 syslog | no | 按需 |
易错点
-b选项不带参数时等同于-b 0(本次启动),-b -1才是上次启动--since和--until的时间格式灵活,支持"2024-01-01"、"today"、"1 hour ago"、"yesterday"等- 如果 journal 未持久化,重启后历史日志会丢失
journalctl -u中的服务名可以省略.service后缀- 匹配字段区分大小写,
_COMM=nginx和_COMM=Nginx是不同的过滤条件 - 同一字段指定多个值时为 OR 关系:
journalctl _COMM=nginx _COMM=sshd表示 nginx 或 sshd
12.1.2 dmesg(查看内核环形缓冲区)
dmesg(diagnostic message)用于显示和控制内核环形缓冲区(kernel ring buffer)中的消息。内核通过 printk() 函数输出的所有消息都存储在这个环形缓冲区中,包括硬件检测、驱动加载、系统错误、OOM 事件等。
基本用法
bash
dmesg [OPTIONS...]
常用选项
| 选项 | 说明 | 典型用途 |
|---|---|---|
-T |
显示人类可读的时间戳(而非秒数) | 日常查看 |
-w |
实时跟踪新消息(类似 tail -f) |
实时监控内核事件 |
-c |
读取并清除内核环形缓冲区 | 获取增量日志 |
-C |
清除内核环形缓冲区(不显示) | 重置缓冲区 |
-n <level> |
设置内核日志输出到控制台的级别 | 控制控制台输出 |
-l <level> |
按级别过滤显示 | 只看特定级别 |
-f <facility> |
按 facility 过滤(如 kern, user) | 按来源过滤 |
-t |
不显示时间戳 | 简化输出 |
-x |
显示 facility 和 level 的十六进制编码 | 详细分类 |
--color[=when] |
彩色输出(auto/always/never) | 终端查看 |
-S |
强制使用 syslog(2) 系统调用 | 兼容旧内核 |
-s <size> |
设置读取缓冲区大小 | 读取大量日志 |
内核日志级别
| 级别 | 名称 | 说明 |
|---|---|---|
| 0 | KERN_EMERG | 系统不可用(如内核崩溃) |
| 1 | KERN_ALERT | 必须立即采取行动 |
| 2 | KERN_CRIT | 严重情况(如硬件故障) |
| 3 | KERN_ERR | 错误(如驱动报错) |
| 4 | KERN_WARNING | 警告 |
| 5 | KERN_NOTICE | 正常但重要 |
| 6 | KERN_INFO | 信息性消息 |
| 7 | KERN_DEBUG | 调试信息 |
实战示例
bash
# 查看所有内核消息(带时间戳)
dmesg -T
# 实时跟踪内核消息
dmesg -w
# 查看最后 20 条内核消息
dmesg -T | tail -20
# 只看错误级别及以上
dmesg -l err,crit,alert,emerg
# 只看警告及以上
dmesg -l warn
# 按 facility 过滤(只看内核消息)
dmesg -f kern
# 搜索特定关键词
dmesg -T | grep -i "error"
dmesg -T | grep -i "usb"
dmesg -T | grep -i "oom"
# 查看段错误信息(定位崩溃程序)
dmesg | grep segfault
# 输出示例:
# [83208.450712] a.out[13275]: segfault at 491f44 ip 0000000000400b80 sp 00007ffecb47fd50 error 7 in a.out[400000+b6000]
# 查看 OOM killer 事件
dmesg -T | grep -i "out of memory"
# 查看硬件相关信息
dmesg -T | grep -i "sda"
dmesg -T | grep -i "eth0"
# 清除内核环形缓冲区
dmesg -C
# 读取并清除(用于脚本获取增量日志)
dmesg -c > /tmp/new_kernel_msgs.txt
# 设置控制台日志级别(只显示 emerg~err)
dmesg -n 3
输出解读
[83208.450712] a.out[13275]: segfault at 491f44 ip 0000000000400b80 sp 00007ffecb47fd50 error 7 in a.out[400000+b6000]
| 字段 | 含义 |
|---|---|
[83208.450712] |
系统启动后的秒数(加 -T 显示为日期时间) |
a.out |
进程名 |
[13275] |
进程 PID |
segfault at 491f44 |
段错误发生的地址 |
ip 0000000000400b80 |
指令指针(出错指令的地址,可用 addr2line 定位源码行) |
sp 00007ffecb47fd50 |
栈指针 |
error 7 |
页表错误码 |
in a.out[400000+b6000] |
出错指令所在的内存映射区域 |
dmesg 与 journalctl -k 的区别
| 对比项 | dmesg | journalctl -k |
|---|---|---|
| 数据来源 | 直接读取内核环形缓冲区 | 从 journald 数据库中读取 |
| 历史保留 | 环形缓冲区,会被覆盖 | 持久化存储(如果配置了) |
| 重启后 | 缓冲区被清空 | 可查看历史启动的内核日志 |
| 权限 | 通常需要 root(或 dmesg_restrict=0) |
通常需要 adm 组或 root |
| 适用场景 | 实时调试、嵌入式系统 | 历史日志分析 |
易错点
- 内核环形缓冲区大小有限(默认 128KB~1MB),高日志量时旧消息会被覆盖
- 可通过内核启动参数
log_buf_len=4M增大缓冲区 /proc/sys/kernel/dmesg_restrict控制非 root 用户是否可以读取 dmesg(1 = 限制)- 使用
dmesg -c会清除缓冲区,慎用
12.1.3 /var/log 目录结构(传统日志文件)
/var/log/ 是 Linux 系统中存放各类日志文件的标准目录。不同的服务和系统组件将日志写入不同的文件中。
常见日志文件
| 文件/目录 | 说明 | 写入者 |
|---|---|---|
/var/log/syslog |
系统综合日志(Debian/Ubuntu) | rsyslog |
/var/log/messages |
系统综合日志(RHEL/CentOS) | rsyslog |
/var/log/kern.log |
内核日志 | rsyslog |
/var/log/auth.log |
认证和授权日志(Debian/Ubuntu) | rsyslog |
/var/log/secure |
认证和授权日志(RHEL/CentOS) | rsyslog |
/var/log/dmesg |
启动时的内核日志 | 系统初始化脚本 |
/var/log/dpkg.log |
软件包安装/卸载日志(Debian/Ubuntu) | dpkg |
/var/log/apt/history.log |
APT 操作历史(Debian/Ubuntu) | apt |
/var/log/yum.log |
YUM 操作日志(RHEL/CentOS) | yum |
/var/log/boot.log |
系统启动日志 | 系统初始化 |
/var/log/cron |
定时任务日志 | crond |
/var/log/lastlog |
用户最后登录信息(二进制) | login |
/var/log/wtmp |
登录/登出记录(二进制) | login |
/var/log/btmp |
失败登录记录(二进制) | login |
/var/log/journal/ |
systemd-journald 持久化日志 | systemd-journald |
/var/log/nginx/ |
Nginx 日志 | nginx |
/var/log/apache2/ |
Apache 日志 | apache2 |
/var/log/mysql/ |
MySQL 日志 | mysql |
/var/log/sssd/ |
SSSD 日志 | sssd |
查看命令
bash
# 查看系统日志最后 50 行
tail -50 /var/log/syslog
# 实时跟踪认证日志
tail -f /var/log/auth.log
# 搜索失败的 SSH 登录
grep "Failed password" /var/log/auth.log
# 查看最后登录记录
lastlog
# 查看登录/登出历史
last
# 查看失败登录尝试
lastb
# 查看内核日志文件
cat /var/log/kern.log | tail -20
Debian/Ubuntu 与 RHEL/CentOS 日志文件对比
| 功能 | Debian/Ubuntu | RHEL/CentOS |
|---|---|---|
| 系统综合日志 | /var/log/syslog |
/var/log/messages |
| 认证日志 | /var/log/auth.log |
/var/log/secure |
| 内核日志 | /var/log/kern.log |
/var/log/messages(含内核) |
| 包管理日志 | /var/log/dpkg.log |
/var/log/yum.log |
12.2 内核日志
本节介绍内核日志的底层接口和传统守护进程。理解这些机制有助于掌握内核消息从产生到用户空间可见的完整链路,在嵌入式系统和旧系统中尤为重要。
12.2.1 /proc/kmsg(内核消息原始接口)
/proc/kmsg 是内核消息的接口文件,提供了对用户空间读取内核日志的原始访问方式。它是一个只读的伪文件,读取时会阻塞直到有新消息到达。
特性说明
| 特性 | 说明 |
|---|---|
| 文件类型 | 只读伪文件(proc 文件系统) |
| 读取行为 | 阻塞式读取,每次读取返回一批新消息 |
| 消息格式 | <级别>时间戳 消息内容 |
| 权限 | 需要 root 权限 |
| 互斥性 | 同一时间只能有一个进程读取 |
实战示例
bash
# 直接读取(需要 root,会持续输出直到 Ctrl+C)
sudo cat /proc/kmsg
# 输出示例:
# <6>[ 123.456789] usb 1-1: new high-speed USB device number 5 using xhci_hcd
# <3>[ 124.567890] EXT4-fs error (device sda1): ...
输出解读
<N> 中的 N 表示日志级别(0-7),对应关系与 dmesg 的级别一致。
/proc/kmsg 与 dmesg 的关系
/proc/kmsg 是内核消息的原始接口 ,而 dmesg 是对该接口的用户空间封装。两者的关系如下图所示:
#mermaid-svg-wUHZDcLkfpxMSZFr{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-wUHZDcLkfpxMSZFr .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-wUHZDcLkfpxMSZFr .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-wUHZDcLkfpxMSZFr .error-icon{fill:#552222;}#mermaid-svg-wUHZDcLkfpxMSZFr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-wUHZDcLkfpxMSZFr .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-wUHZDcLkfpxMSZFr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-wUHZDcLkfpxMSZFr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-wUHZDcLkfpxMSZFr .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-wUHZDcLkfpxMSZFr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-wUHZDcLkfpxMSZFr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-wUHZDcLkfpxMSZFr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-wUHZDcLkfpxMSZFr .marker.cross{stroke:#333333;}#mermaid-svg-wUHZDcLkfpxMSZFr svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-wUHZDcLkfpxMSZFr p{margin:0;}#mermaid-svg-wUHZDcLkfpxMSZFr .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-wUHZDcLkfpxMSZFr .cluster-label text{fill:#333;}#mermaid-svg-wUHZDcLkfpxMSZFr .cluster-label span{color:#333;}#mermaid-svg-wUHZDcLkfpxMSZFr .cluster-label span p{background-color:transparent;}#mermaid-svg-wUHZDcLkfpxMSZFr .label text,#mermaid-svg-wUHZDcLkfpxMSZFr span{fill:#333;color:#333;}#mermaid-svg-wUHZDcLkfpxMSZFr .node rect,#mermaid-svg-wUHZDcLkfpxMSZFr .node circle,#mermaid-svg-wUHZDcLkfpxMSZFr .node ellipse,#mermaid-svg-wUHZDcLkfpxMSZFr .node polygon,#mermaid-svg-wUHZDcLkfpxMSZFr .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-wUHZDcLkfpxMSZFr .rough-node .label text,#mermaid-svg-wUHZDcLkfpxMSZFr .node .label text,#mermaid-svg-wUHZDcLkfpxMSZFr .image-shape .label,#mermaid-svg-wUHZDcLkfpxMSZFr .icon-shape .label{text-anchor:middle;}#mermaid-svg-wUHZDcLkfpxMSZFr .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-wUHZDcLkfpxMSZFr .rough-node .label,#mermaid-svg-wUHZDcLkfpxMSZFr .node .label,#mermaid-svg-wUHZDcLkfpxMSZFr .image-shape .label,#mermaid-svg-wUHZDcLkfpxMSZFr .icon-shape .label{text-align:center;}#mermaid-svg-wUHZDcLkfpxMSZFr .node.clickable{cursor:pointer;}#mermaid-svg-wUHZDcLkfpxMSZFr .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-wUHZDcLkfpxMSZFr .arrowheadPath{fill:#333333;}#mermaid-svg-wUHZDcLkfpxMSZFr .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-wUHZDcLkfpxMSZFr .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-wUHZDcLkfpxMSZFr .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wUHZDcLkfpxMSZFr .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-wUHZDcLkfpxMSZFr .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wUHZDcLkfpxMSZFr .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-wUHZDcLkfpxMSZFr .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-wUHZDcLkfpxMSZFr .cluster text{fill:#333;}#mermaid-svg-wUHZDcLkfpxMSZFr .cluster span{color:#333;}#mermaid-svg-wUHZDcLkfpxMSZFr div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-wUHZDcLkfpxMSZFr .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-wUHZDcLkfpxMSZFr rect.text{fill:none;stroke-width:0;}#mermaid-svg-wUHZDcLkfpxMSZFr .icon-shape,#mermaid-svg-wUHZDcLkfpxMSZFr .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wUHZDcLkfpxMSZFr .icon-shape p,#mermaid-svg-wUHZDcLkfpxMSZFr .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-wUHZDcLkfpxMSZFr .icon-shape .label rect,#mermaid-svg-wUHZDcLkfpxMSZFr .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wUHZDcLkfpxMSZFr .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-wUHZDcLkfpxMSZFr .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-wUHZDcLkfpxMSZFr :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} printk()
内核打印函数
内核环形缓冲区
(kernel ring buffer)
/proc/kmsg
原始接口(阻塞读取)
dmesg 命令
(syslog(2) 系统调用)
klogd 守护进程
(传统系统)
systemd-journald
(现代系统)
rsyslog
journalctl
/var/log/kern.log
关键关系总结
| 对比项 | /proc/kmsg | dmesg |
|---|---|---|
| 本质 | 内核提供的原始文件接口 | 用户空间命令工具 |
| 访问方式 | read() 系统调用(阻塞) |
syslog(2) 系统调用(非阻塞快照) |
| 读取行为 | 每次读取返回新消息(消费式) | 每次读取返回全部缓冲区内容(快照式) |
| 互斥性 | 同一时间只能有一个读者 | 多个进程可同时读取 |
| 典型使用者 | klogd、systemd-journald | 用户手动查看 |
| 适用场景 | 守护进程持续消费内核消息 | 人工排查、脚本获取快照 |
核心区别 :
/proc/kmsg是"消费式"读取------读过的消息不会再返回给下一个读者;dmesg是"快照式"读取------每次都能看到缓冲区中的全部内容。因此,如果systemd-journald已经在读取/proc/kmsg,用户再执行cat /proc/kmsg将无法获取任何消息(被 journald 消费了),但dmesg仍然可以正常显示。
易错点
/proc/kmsg只能被一个进程同时读取,如果systemd-journald或klogd已经在读取,其他进程将无法获取消息- 在现代 systemd 系统中,通常由
systemd-journald负责读取/proc/kmsg - 不建议直接使用
cat /proc/kmsg,应优先使用dmesg或journalctl -k
12.2.2 klogd(内核日志守护进程)
klogd(kernel log daemon)是传统的内核日志守护进程,负责从内核环形缓冲区(通过 /proc/kmsg 或 syslog(2) 系统调用)读取内核消息,并将其转发给 syslogd(如 rsyslog)进行持久化存储。
工作方式
| 特性 | 说明 |
|---|---|
| 数据来源 | /proc/kmsg 或 syslog(2) 系统调用 |
| 输出目标 | 转发给 syslog 守护进程(rsyslog/syslog-ng) |
| 运行模式 | 作为守护进程在后台运行 |
| 现代替代 | systemd 系统中由 systemd-journald 取代 |
基本用法
bash
# 启动 klogd(通常由系统自动管理)
klogd
# 指定日志级别(只转发此级别及以上的消息)
klogd -c 4
# 从 syslog(2) 读取而非 /proc/kmsg
klogd -s
常用选项
| 选项 | 说明 |
|---|---|
-c <level> |
设置控制台日志级别(1-8) |
-s |
使用 syslog(2) 系统调用读取内核消息 |
-k <file> |
指定内核符号表文件(用于解析 oops 消息) |
-p |
兼容模式(与 syslogd 的 -p 配合) |
-n |
前台运行(不 fork 为守护进程) |
在现代系统中的地位
在使用 systemd 的现代 Linux 发行版中,klogd 通常不再需要,因为 systemd-journald 已经承担了读取内核日志的职责。但在以下场景中仍可能遇到 klogd:
- 使用 SysVinit 或 OpenRC 的旧系统
- 嵌入式 Linux 系统(如 BusyBox 环境)
- 使用传统 syslog 配置且未启用 systemd-journald 的系统
12.3 传统 Syslog 体系
本节介绍传统的 syslog 日志体系,包括日志守护进程 rsyslog 和日志发送工具 logger。虽然现代系统已广泛使用 systemd-journald,但 syslog 体系仍然是许多应用程序和旧系统的日志基础设施,理解它对于日志路由配置和跨系统日志管理至关重要。
12.3.1 rsyslog(日志守护进程)
rsyslog 是 Linux 上最广泛使用的 syslog 守护进程实现,负责接收、过滤、路由和存储来自各种来源的日志消息。它是传统 syslogd 的增强替代品。
核心概念
rsyslog 使用 facility(设施) 和 priority(优先级) 两个维度对日志进行分类和路由。
Facility(设施)分类
| 数值 | 名称 | 说明 |
|---|---|---|
| 0 | kern | 内核消息 |
| 1 | user | 用户级消息 |
| 2 | 邮件系统 | |
| 3 | daemon | 系统守护进程 |
| 4 | auth | 认证/授权消息 |
| 5 | syslog | syslog 内部消息 |
| 6 | lpr | 打印系统 |
| 7 | news | 网络新闻 |
| 8 | uucp | UUCP 子系统 |
| 9 | cron | 时钟/定时任务 |
| 10 | authpriv | 敏感认证消息 |
| 11 | ftp | FTP 守护进程 |
| 16-23 | local0-local7 | 本地自定义(应用程序可用) |
local0~local7 自定义 facility 详解
local0 到 local7 是 syslog 标准预留的 8 个自定义 facility,供用户自定义应用程序使用。它们没有预定义的语义,开发者可以自由分配用途。
典型使用场景:
| 使用场景 | 推荐 facility | 说明 |
|---|---|---|
| 自研业务应用 | local0 | 最常用,作为默认自定义 facility |
| 数据库服务 | local1 | 如 MySQL、PostgreSQL 自定义日志 |
| Web 服务器 | local2 | 如 Nginx 自定义格式日志 |
| 监控系统 | local3 | 如 Zabbix Agent 日志 |
| 部署/CI 脚本 | local4 | 部署流程记录 |
| 安全审计 | local5 | 自定义安全事件 |
| 预留扩展 | local6-local7 | 多应用共存时分配 |
配置示例------将自定义应用的日志路由到独立文件:
bash
# /etc/rsyslog.d/myapp.conf
# 将 local0 的所有消息写入 /var/log/myapp.log
local0.* /var/log/myapp.log
# 将 local1 的错误及以上级别写入 /var/log/db-error.log
local1.err /var/log/db-error.log
# 将 local2 的 info 及以上写入 /var/log/webapp.log,排除 debug
local2.info;local2.!debug /var/log/webapp.log
# 将 local3 的消息同时写入文件和转发到远程服务器
local3.* /var/log/monitor.log
local3.* @192.168.1.100:514
配合 logger 命令测试:
bash
# 发送测试消息到 local0
logger -p local0.info "MyApp started successfully"
# 验证消息已写入
tail -1 /var/log/myapp.log
# 输出: Jan 15 10:30:01 hostname myapp: MyApp started successfully
配合应用程序使用(C 语言示例):
c
#include <syslog.h>
int main(void) {
// 打开 syslog,标识为 "myapp",使用 local0 facility
openlog("myapp", LOG_PID | LOG_NDELAY, LOG_LOCAL0);
syslog(LOG_INFO, "Service started, listening on port %d", 8080);
syslog(LOG_ERR, "Failed to connect to database: %s", strerror(errno));
closelog();
return 0;
}
注意 :使用
local0~local7时,需要确保 rsyslog 配置中有对应的规则将消息路由到目标文件,否则消息会被丢弃或写入默认的/var/log/syslog。
配置文件与规则格式
配置文件:/etc/rsyslog.conf 及 /etc/rsyslog.d/*.conf
配置规则格式:
facility.priority action
配置示例
bash
# 所有 kern 级别的消息写入 /var/log/kern.log
kern.* /var/log/kern.log
# auth 和 authpriv 的所有消息写入 /var/log/auth.log
auth,authpriv.* /var/log/auth.log
# 所有 mail 消息写入 /var/log/mail.log(- 前缀表示异步写入,提升性能)
mail.* -/var/log/mail.log
# 所有 info 及以上级别(排除 mail、authpriv、cron)写入 /var/log/syslog
*.*;auth,authpriv.none;cron.none -/var/log/syslog
# 所有 emerg 级别的消息发送给所有登录用户
*.emerg :omusrmsg:*
# 将 local0 的所有消息写入自定义文件
local0.* /var/log/myapp.log
常用管理命令
bash
# 查看 rsyslog 服务状态
systemctl status rsyslog
# 重启 rsyslog
systemctl restart rsyslog
# 检查配置文件语法
rsyslogd -N1
# 以调试模式运行
rsyslogd -d
12.3.2 logger(手动发送日志消息)
logger 命令用于从命令行或脚本手动向 syslog 发送日志消息,是测试日志系统和在脚本中记录事件的实用工具。
基本用法
bash
logger [OPTIONS] MESSAGE
常用选项
| 选项 | 说明 | 示例 |
|---|---|---|
-p <facility.priority> |
指定 facility 和 priority | logger -p local0.info "msg" |
-t <tag> |
指定日志标签(标识来源) | logger -t myscript "msg" |
-i |
记录发送进程的 PID | logger -i "msg" |
-f <file> |
从文件读取消息内容 | logger -f /tmp/msg.txt |
-s |
同时输出到 stderr | logger -s "msg" |
-n <server> |
发送到远程 syslog 服务器 | logger -n 192.168.1.1 "msg" |
-P <port> |
指定远程端口(默认 514) | logger -n server -P 1514 "msg" |
-d |
使用 TCP 而非 UDP | logger -d -n server "msg" |
实战示例
bash
# 发送简单的日志消息(默认 user.notice)
logger "This is a test message"
# 指定 facility 和 priority
logger -p local0.err "Application error occurred"
# 带标签的消息(便于在日志中识别来源)
logger -t backup_script "Backup completed successfully"
# 在脚本中记录事件
#!/bin/bash
logger -t myapp -p local0.info "Service started at $(date)"
# ... 业务逻辑 ...
logger -t myapp -p local0.err "Failed to connect to database"
# 验证消息已写入
grep "backup_script" /var/log/syslog
12.4 日志轮转与管理
本节介绍日志轮转工具 logrotate,它是防止日志文件无限增长占满磁盘的关键管理工具。通过合理的轮转策略,可以在保留历史日志的同时控制磁盘使用。
12.4.1 logrotate(日志轮转工具)
logrotate 是 Linux 系统的日志轮转工具,用于自动管理日志文件的大小、数量和生命周期,防止日志文件无限增长占满磁盘。
工作原理
#mermaid-svg-Moyd0IXgk0a76tVK{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Moyd0IXgk0a76tVK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Moyd0IXgk0a76tVK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Moyd0IXgk0a76tVK .error-icon{fill:#552222;}#mermaid-svg-Moyd0IXgk0a76tVK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Moyd0IXgk0a76tVK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Moyd0IXgk0a76tVK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Moyd0IXgk0a76tVK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Moyd0IXgk0a76tVK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Moyd0IXgk0a76tVK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Moyd0IXgk0a76tVK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Moyd0IXgk0a76tVK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Moyd0IXgk0a76tVK .marker.cross{stroke:#333333;}#mermaid-svg-Moyd0IXgk0a76tVK svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Moyd0IXgk0a76tVK p{margin:0;}#mermaid-svg-Moyd0IXgk0a76tVK .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Moyd0IXgk0a76tVK .cluster-label text{fill:#333;}#mermaid-svg-Moyd0IXgk0a76tVK .cluster-label span{color:#333;}#mermaid-svg-Moyd0IXgk0a76tVK .cluster-label span p{background-color:transparent;}#mermaid-svg-Moyd0IXgk0a76tVK .label text,#mermaid-svg-Moyd0IXgk0a76tVK span{fill:#333;color:#333;}#mermaid-svg-Moyd0IXgk0a76tVK .node rect,#mermaid-svg-Moyd0IXgk0a76tVK .node circle,#mermaid-svg-Moyd0IXgk0a76tVK .node ellipse,#mermaid-svg-Moyd0IXgk0a76tVK .node polygon,#mermaid-svg-Moyd0IXgk0a76tVK .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Moyd0IXgk0a76tVK .rough-node .label text,#mermaid-svg-Moyd0IXgk0a76tVK .node .label text,#mermaid-svg-Moyd0IXgk0a76tVK .image-shape .label,#mermaid-svg-Moyd0IXgk0a76tVK .icon-shape .label{text-anchor:middle;}#mermaid-svg-Moyd0IXgk0a76tVK .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Moyd0IXgk0a76tVK .rough-node .label,#mermaid-svg-Moyd0IXgk0a76tVK .node .label,#mermaid-svg-Moyd0IXgk0a76tVK .image-shape .label,#mermaid-svg-Moyd0IXgk0a76tVK .icon-shape .label{text-align:center;}#mermaid-svg-Moyd0IXgk0a76tVK .node.clickable{cursor:pointer;}#mermaid-svg-Moyd0IXgk0a76tVK .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Moyd0IXgk0a76tVK .arrowheadPath{fill:#333333;}#mermaid-svg-Moyd0IXgk0a76tVK .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Moyd0IXgk0a76tVK .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Moyd0IXgk0a76tVK .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Moyd0IXgk0a76tVK .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Moyd0IXgk0a76tVK .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Moyd0IXgk0a76tVK .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Moyd0IXgk0a76tVK .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Moyd0IXgk0a76tVK .cluster text{fill:#333;}#mermaid-svg-Moyd0IXgk0a76tVK .cluster span{color:#333;}#mermaid-svg-Moyd0IXgk0a76tVK div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Moyd0IXgk0a76tVK .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Moyd0IXgk0a76tVK rect.text{fill:none;stroke-width:0;}#mermaid-svg-Moyd0IXgk0a76tVK .icon-shape,#mermaid-svg-Moyd0IXgk0a76tVK .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Moyd0IXgk0a76tVK .icon-shape p,#mermaid-svg-Moyd0IXgk0a76tVK .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Moyd0IXgk0a76tVK .icon-shape .label rect,#mermaid-svg-Moyd0IXgk0a76tVK .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Moyd0IXgk0a76tVK .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Moyd0IXgk0a76tVK .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Moyd0IXgk0a76tVK :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
日志文件增长
达到轮转条件?
重命名当前日志
app.log → app.log.1
压缩旧日志
app.log.1 → app.log.2.gz
删除超出保留数量的日志
创建新的空日志文件
通知服务重新打开日志
发送 SIGHUP 或执行 postrotate
继续写入
配置文件位置
| 路径 | 说明 |
|---|---|
/etc/logrotate.conf |
主配置文件(全局默认设置) |
/etc/logrotate.d/ |
各服务的独立配置目录 |
/etc/cron.daily/logrotate |
每日自动执行的 cron 任务 |
配置语法
/path/to/logfile {
directive1
directive2
...
}
常用指令
| 指令 | 说明 | 示例 |
|---|---|---|
daily |
每天轮转 | daily |
weekly |
每周轮转 | weekly |
monthly |
每月轮转 | monthly |
rotate <N> |
保留 N 个旧日志文件 | rotate 4 |
compress |
压缩旧日志(gzip) | compress |
delaycompress |
延迟一个周期再压缩 | delaycompress |
missingok |
日志文件不存在时不报错 | missingok |
notifempty |
空文件不轮转 | notifempty |
copytruncate |
复制后截断原文件(无需重启服务) | copytruncate |
create <mode> <owner> <group> |
创建新日志文件的权限和属主 | create 0640 root adm |
size <size> |
按大小轮转(如 100M) | size 100M |
minsize <size> |
最小大小(配合时间轮转) | minsize 10M |
postrotate/endscript |
轮转后执行的脚本 | 发送信号给服务 |
prerotate/endscript |
轮转前执行的脚本 | 预处理 |
sharedscripts |
所有日志轮转完成后只执行一次 postrotate | sharedscripts |
dateext |
使用日期作为后缀而非数字 | dateext |
dateformat |
自定义日期格式 | dateformat -%Y%m%d |
dateext 与 dateformat 详解
默认情况下,logrotate 使用数字后缀命名轮转后的日志文件(如 app.log.1、app.log.2)。启用 dateext 后,改用日期作为后缀,便于直观识别日志的时间范围。
| 指令 | 作用 | 示例效果 |
|---|---|---|
dateext |
启用日期后缀(替代数字后缀) | app.log-20240115 |
dateformat |
自定义日期格式字符串 | 配合 dateext 使用 |
dateformat 支持的格式说明符:
| 说明符 | 含义 | 示例输出 |
|---|---|---|
%Y |
四位年份 | 2024 |
%m |
两位月份 | 01 |
%d |
两位日期 | 15 |
%H |
两位小时 | 10 |
%M |
两位分钟 | 30 |
%s |
Unix 时间戳 | 1705312200 |
配置示例对比:
bash
# 默认数字后缀
/var/log/myapp/*.log {
daily
rotate 7
compress
}
# 轮转结果: myapp.log.1.gz, myapp.log.2.gz, ...
# 使用 dateext(日期后缀)
/var/log/myapp/*.log {
daily
rotate 7
compress
dateext
}
# 轮转结果: myapp.log-20240115.gz, myapp.log-20240114.gz, ...
# 使用 dateext + dateformat(自定义格式)
/var/log/myapp/*.log {
daily
rotate 30
compress
dateext
dateformat -%Y%m%d-%H%M%S
}
# 轮转结果: myapp.log-20240115-030001.gz
注意 :
dateext和rotate配合使用时,如果同一天内多次强制执行轮转(logrotate -f),由于日期后缀相同,旧文件会被覆盖。可通过dateformat加入时分秒来避免。
实战示例
bash
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
# /etc/logrotate.d/myapp
/var/log/myapp/*.log {
weekly
rotate 8
compress
delaycompress
missingok
notifempty
copytruncate
size 50M
}
copytruncate 与信号方式的区别
| 对比项 | copytruncate | postrotate + 信号 |
|---|---|---|
| 原理 | 复制文件后截断原文件 | 重命名文件,通知服务重新打开 |
| 是否需要服务支持 | 不需要 | 需要服务支持重新打开日志 |
| 数据丢失风险 | 复制和截断之间可能丢失少量数据 | 无 |
| 适用场景 | 不支持重新打开日志的程序 | nginx、rsyslog 等支持的服务 |
管理命令
bash
# 手动执行轮转(测试配置是否正确)
sudo logrotate -d /etc/logrotate.conf # -d 调试模式,不实际执行
sudo logrotate -f /etc/logrotate.conf # -f 强制执行
# 只轮转特定配置
sudo logrotate -f /etc/logrotate.d/nginx
# 查看轮转状态(上次轮转时间)
cat /var/lib/logrotate/status
# 查看详细输出
sudo logrotate -v /etc/logrotate.conf
易错点
logrotate默认由 cron 每天执行一次,如果系统长时间运行不重启,注意检查 cron 是否正常- 使用
copytruncate时,在复制和截断之间的极短时间内写入的数据会丢失 postrotate脚本中的命令必须正确处理 PID 文件不存在的情况- 修改配置后可用
logrotate -d进行干跑测试 dateext模式下同一天多次强制轮转会覆盖同名文件,建议配合dateformat加入时间
12.5 日志分析工具对比总结
本章介绍了 Linux 日志分析从产生、采集、存储到查询、管理的完整工具链。以下从多个维度进行总结对比。
工具功能对比总表
| 工具/接口 | 类别 | 主要用途 | 典型命令 |
|---|---|---|---|
| journalctl | systemd 日志 | 查询 systemd-journald 日志 | journalctl -u nginx -p err |
| dmesg | 内核日志 | 查看内核环形缓冲区 | dmesg -T -w |
| /proc/kmsg | 内核日志接口 | 原始内核消息读取 | cat /proc/kmsg |
| klogd | 内核日志守护进程 | 转发内核消息到 syslog | klogd -c 4 |
| rsyslog | 日志守护进程 | 接收、路由、存储日志 | systemctl status rsyslog |
| logger | 日志发送 | 手动/脚本发送日志消息 | logger -p local0.info "msg" |
| logrotate | 日志管理 | 自动轮转、压缩、清理日志 | logrotate -f /etc/logrotate.conf |
| /var/log/* | 日志文件 | 各类服务的文本日志 | tail -f /var/log/syslog |
| last/lastb/lastlog | 登录日志 | 查看登录/登出/失败记录 | last -20 |
工具适用场景对比
| 工具 | 适用场景 | 数据格式 | 查询能力 | 是否需要额外安装 | 持久化 |
|---|---|---|---|---|---|
| journalctl | systemd 系统的全量日志查询 | 二进制 | 强(时间/服务/级别/正则) | 系统自带(systemd) | 可配置 |
| dmesg | 内核消息实时查看 | 文本 | 中(级别/facility 过滤) | 系统自带 | 否(环形缓冲区) |
| rsyslog | 日志路由和持久化存储 | 文本 | 弱(需配合 grep 等) | 系统自带 | 是 |
| logger | 脚本/应用发送日志 | --- | --- | 系统自带 | --- |
| logrotate | 日志文件生命周期管理 | --- | --- | 系统自带 | --- |
| /var/log 文件 | 直接查看文本日志 | 文本 | 依赖 grep/tail/awk | 系统自带 | 是 |
日志查询工具选择决策图
#mermaid-svg-eB1YXWCpJ5ioeh7J{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-eB1YXWCpJ5ioeh7J .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-eB1YXWCpJ5ioeh7J .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-eB1YXWCpJ5ioeh7J .error-icon{fill:#552222;}#mermaid-svg-eB1YXWCpJ5ioeh7J .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-eB1YXWCpJ5ioeh7J .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-eB1YXWCpJ5ioeh7J .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-eB1YXWCpJ5ioeh7J .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-eB1YXWCpJ5ioeh7J .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-eB1YXWCpJ5ioeh7J .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-eB1YXWCpJ5ioeh7J .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-eB1YXWCpJ5ioeh7J .marker{fill:#333333;stroke:#333333;}#mermaid-svg-eB1YXWCpJ5ioeh7J .marker.cross{stroke:#333333;}#mermaid-svg-eB1YXWCpJ5ioeh7J svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-eB1YXWCpJ5ioeh7J p{margin:0;}#mermaid-svg-eB1YXWCpJ5ioeh7J .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-eB1YXWCpJ5ioeh7J .cluster-label text{fill:#333;}#mermaid-svg-eB1YXWCpJ5ioeh7J .cluster-label span{color:#333;}#mermaid-svg-eB1YXWCpJ5ioeh7J .cluster-label span p{background-color:transparent;}#mermaid-svg-eB1YXWCpJ5ioeh7J .label text,#mermaid-svg-eB1YXWCpJ5ioeh7J span{fill:#333;color:#333;}#mermaid-svg-eB1YXWCpJ5ioeh7J .node rect,#mermaid-svg-eB1YXWCpJ5ioeh7J .node circle,#mermaid-svg-eB1YXWCpJ5ioeh7J .node ellipse,#mermaid-svg-eB1YXWCpJ5ioeh7J .node polygon,#mermaid-svg-eB1YXWCpJ5ioeh7J .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-eB1YXWCpJ5ioeh7J .rough-node .label text,#mermaid-svg-eB1YXWCpJ5ioeh7J .node .label text,#mermaid-svg-eB1YXWCpJ5ioeh7J .image-shape .label,#mermaid-svg-eB1YXWCpJ5ioeh7J .icon-shape .label{text-anchor:middle;}#mermaid-svg-eB1YXWCpJ5ioeh7J .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-eB1YXWCpJ5ioeh7J .rough-node .label,#mermaid-svg-eB1YXWCpJ5ioeh7J .node .label,#mermaid-svg-eB1YXWCpJ5ioeh7J .image-shape .label,#mermaid-svg-eB1YXWCpJ5ioeh7J .icon-shape .label{text-align:center;}#mermaid-svg-eB1YXWCpJ5ioeh7J .node.clickable{cursor:pointer;}#mermaid-svg-eB1YXWCpJ5ioeh7J .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-eB1YXWCpJ5ioeh7J .arrowheadPath{fill:#333333;}#mermaid-svg-eB1YXWCpJ5ioeh7J .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-eB1YXWCpJ5ioeh7J .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-eB1YXWCpJ5ioeh7J .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-eB1YXWCpJ5ioeh7J .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-eB1YXWCpJ5ioeh7J .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-eB1YXWCpJ5ioeh7J .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-eB1YXWCpJ5ioeh7J .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-eB1YXWCpJ5ioeh7J .cluster text{fill:#333;}#mermaid-svg-eB1YXWCpJ5ioeh7J .cluster span{color:#333;}#mermaid-svg-eB1YXWCpJ5ioeh7J div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-eB1YXWCpJ5ioeh7J .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-eB1YXWCpJ5ioeh7J rect.text{fill:none;stroke-width:0;}#mermaid-svg-eB1YXWCpJ5ioeh7J .icon-shape,#mermaid-svg-eB1YXWCpJ5ioeh7J .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-eB1YXWCpJ5ioeh7J .icon-shape p,#mermaid-svg-eB1YXWCpJ5ioeh7J .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-eB1YXWCpJ5ioeh7J .icon-shape .label rect,#mermaid-svg-eB1YXWCpJ5ioeh7J .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-eB1YXWCpJ5ioeh7J .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-eB1YXWCpJ5ioeh7J .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-eB1YXWCpJ5ioeh7J :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 内核消息
是
否
systemd 服务
传统应用日志
安全/认证
脚本记录事件
按时间
按级别
实时跟踪
需要查看日志
日志来源?
需要历史数据?
journalctl -k -b -1
dmesg -T
journalctl -u 服务名
cat/grep /var/log/xxx
cat /var/log/auth.log
logger -t tag -p facility.level
需要过滤?
journalctl -u svc --since today
journalctl -u svc -p err
journalctl -u svc -f
12.6 日志分析实战决策图
以下决策图和示例展示了面对不同类型问题时的日志排查路径。
#mermaid-svg-e8RhU0wkR3ROfJSK{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-e8RhU0wkR3ROfJSK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-e8RhU0wkR3ROfJSK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-e8RhU0wkR3ROfJSK .error-icon{fill:#552222;}#mermaid-svg-e8RhU0wkR3ROfJSK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-e8RhU0wkR3ROfJSK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-e8RhU0wkR3ROfJSK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-e8RhU0wkR3ROfJSK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-e8RhU0wkR3ROfJSK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-e8RhU0wkR3ROfJSK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-e8RhU0wkR3ROfJSK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-e8RhU0wkR3ROfJSK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-e8RhU0wkR3ROfJSK .marker.cross{stroke:#333333;}#mermaid-svg-e8RhU0wkR3ROfJSK svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-e8RhU0wkR3ROfJSK p{margin:0;}#mermaid-svg-e8RhU0wkR3ROfJSK .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-e8RhU0wkR3ROfJSK .cluster-label text{fill:#333;}#mermaid-svg-e8RhU0wkR3ROfJSK .cluster-label span{color:#333;}#mermaid-svg-e8RhU0wkR3ROfJSK .cluster-label span p{background-color:transparent;}#mermaid-svg-e8RhU0wkR3ROfJSK .label text,#mermaid-svg-e8RhU0wkR3ROfJSK span{fill:#333;color:#333;}#mermaid-svg-e8RhU0wkR3ROfJSK .node rect,#mermaid-svg-e8RhU0wkR3ROfJSK .node circle,#mermaid-svg-e8RhU0wkR3ROfJSK .node ellipse,#mermaid-svg-e8RhU0wkR3ROfJSK .node polygon,#mermaid-svg-e8RhU0wkR3ROfJSK .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-e8RhU0wkR3ROfJSK .rough-node .label text,#mermaid-svg-e8RhU0wkR3ROfJSK .node .label text,#mermaid-svg-e8RhU0wkR3ROfJSK .image-shape .label,#mermaid-svg-e8RhU0wkR3ROfJSK .icon-shape .label{text-anchor:middle;}#mermaid-svg-e8RhU0wkR3ROfJSK .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-e8RhU0wkR3ROfJSK .rough-node .label,#mermaid-svg-e8RhU0wkR3ROfJSK .node .label,#mermaid-svg-e8RhU0wkR3ROfJSK .image-shape .label,#mermaid-svg-e8RhU0wkR3ROfJSK .icon-shape .label{text-align:center;}#mermaid-svg-e8RhU0wkR3ROfJSK .node.clickable{cursor:pointer;}#mermaid-svg-e8RhU0wkR3ROfJSK .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-e8RhU0wkR3ROfJSK .arrowheadPath{fill:#333333;}#mermaid-svg-e8RhU0wkR3ROfJSK .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-e8RhU0wkR3ROfJSK .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-e8RhU0wkR3ROfJSK .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-e8RhU0wkR3ROfJSK .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-e8RhU0wkR3ROfJSK .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-e8RhU0wkR3ROfJSK .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-e8RhU0wkR3ROfJSK .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-e8RhU0wkR3ROfJSK .cluster text{fill:#333;}#mermaid-svg-e8RhU0wkR3ROfJSK .cluster span{color:#333;}#mermaid-svg-e8RhU0wkR3ROfJSK div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-e8RhU0wkR3ROfJSK .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-e8RhU0wkR3ROfJSK rect.text{fill:none;stroke-width:0;}#mermaid-svg-e8RhU0wkR3ROfJSK .icon-shape,#mermaid-svg-e8RhU0wkR3ROfJSK .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-e8RhU0wkR3ROfJSK .icon-shape p,#mermaid-svg-e8RhU0wkR3ROfJSK .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-e8RhU0wkR3ROfJSK .icon-shape .label rect,#mermaid-svg-e8RhU0wkR3ROfJSK .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-e8RhU0wkR3ROfJSK .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-e8RhU0wkR3ROfJSK .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-e8RhU0wkR3ROfJSK :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 内核/硬件问题
是
否
服务异常
按时间
按级别
实时跟踪
安全/认证
启动问题
磁盘空间
遇到系统问题
问题类型?
dmesg -T
需要历史日志?
journalctl -k -b -1
dmesg -T 当前缓冲区
journalctl -u 服务名
需要过滤?
journalctl -u svc --since today
journalctl -u svc -p err
journalctl -u svc -f
cat /var/log/auth.log
grep 'Failed password' /var/log/auth.log
journalctl -b
journalctl -b -1 -p err
journalctl --disk-usage
journalctl --vacuum-size=500M
典型排查流程示例
bash
# 场景1:服务突然崩溃,排查原因
journalctl -u myservice -b -p err --no-pager
# 场景2:系统重启后排查上次崩溃原因
journalctl -b -1 -p err
dmesg -T | grep -i "oom\|panic\|bug"
# 场景3:SSH 暴力破解排查
grep "Failed password" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn
# 场景4:磁盘空间被日志占满
journalctl --disk-usage
du -sh /var/log/*
journalctl --vacuum-size=200M
sudo logrotate -f /etc/logrotate.conf
# 场景5:在脚本中记录关键事件
#!/bin/bash
logger -t deploy -p local0.info "Deployment started: version=$VERSION"
# ... 部署逻辑 ...
if [ $? -ne 0 ]; then
logger -t deploy -p local0.err "Deployment failed!"
exit 1
fi
logger -t deploy -p local0.info "Deployment completed successfully"
12.7 本章小结
本章从日志产生、采集、存储、查询到管理的完整生命周期,系统介绍了 Linux 日志分析的工具链和排查方法。以下是日志排查速查总表:
日志排查速查总表
| 排查场景 | 首选命令 | 辅助命令 | 关键关注点 |
|---|---|---|---|
| 服务崩溃 | journalctl -u svc -p err -b |
systemctl status svc |
错误消息和退出码 |
| 内核崩溃/panic | `dmesg -T | grep -i panic` | journalctl -k -b -1 |
| OOM 事件 | `dmesg -T | grep -i oom` | `journalctl -k |
| 段错误 | `dmesg | grep segfault` | addr2line -e prog <ip> |
| 硬件故障 | `dmesg -T | grep -i error` | journalctl -k -p err |
| SSH 入侵 | grep "Failed" /var/log/auth.log |
lastb |
来源 IP 和频率 |
| 启动失败 | journalctl -b -p err |
journalctl -b -1 |
失败的 unit 和原因 |
| 磁盘满 | journalctl --disk-usage |
du -sh /var/log/* |
占用最大的日志 |
| 驱动加载 | `dmesg -T | grep |
lsmod |
| 网络问题 | `dmesg -T | grep eth0` | journalctl -u NetworkManager |
选项速查总表
| 工具 | 最常用选项 | 说明 |
|---|---|---|
| journalctl | -u <unit> -p err -b |
按服务+级别+启动过滤 |
| journalctl | -f |
实时跟踪 |
| journalctl | --since "1 hour ago" |
时间过滤 |
| journalctl | _PID=<pid> / _COMM=<name> |
匹配字段过滤 |
| journalctl | --vacuum-size=500M |
清理磁盘空间 |
| journalctl | -o json |
JSON 输出(脚本解析) |
| dmesg | -T |
人类可读时间戳 |
| dmesg | -w |
实时跟踪 |
| dmesg | -l err |
按级别过滤 |
| dmesg | -c |
读取并清除 |
| rsyslog | rsyslogd -N1 |
检查配置语法 |
| logger | -t tag -p facility.level |
指定标签和级别 |
| logrotate | -d |
干跑测试 |
| logrotate | -f |
强制执行 |
| logrotate | dateext + dateformat |
日期后缀命名 |
本章从 systemd 日志查询(journalctl)、内核环形缓冲区(dmesg)、传统日志文件(/var/log)、内核消息底层接口(/proc/kmsg、klogd)、syslog 体系(rsyslog、logger)到日志生命周期管理(logrotate),构建了完整的日志分析知识体系。日常排查中,journalctl 是 systemd 系统的首选日志查询工具,dmesg 用于快速查看内核消息,/var/log 下的文本日志配合 grep/tail 适用于传统应用,logrotate 则是保障磁盘空间不被日志耗尽的关键管理手段。