Linux 日志管理完全指南
日志是 Linux 系统的”黑匣子”——它默默记录着系统运行的一切信息:用户登录、程序启动、错误告警、安全事件……当系统出现问题时,日志是你最可靠的排查工具。
但日志文件如果无限增长,会占满磁盘空间。如何既保留重要日志,又控制磁盘占用?这就是日志管理的核心命题。本文将系统讲解
rsyslog系统日志管理和logrotate日志轮转工具,帮你建立完整的日志管理能力。
简介
日志管理的两大核心任务
| 任务 | 工具 | 核心问题 | 说明 |
|---|---|---|---|
| 任务一:日志收集与存储 | rsyslog | 哪类程序 → 产生什么日志 → 放到哪里 | 系统专职日志程序 |
| 任务二:日志轮转与清理 | logrotate | 如何分割管理、删除旧日志 | 节省空间、整理方便 |
打个比方:
rsyslog就像快递员——负责把各种程序的日志收集起来,送到对应的文件里logrotate就像档案管理员——负责把堆积如山的日志文件分类整理,销毁过期档案
任务一:rsyslog 系统日志管理
处理日志的进程
Linux 中的日志主要由两类进程处理:
第一类:系统专职日志程序(rsyslogd)
rsyslogd 是系统的专职日志程序,负责处理绝大部分日志记录,包括:
- 系统操作相关信息
- 用户登录/登出信息
- 程序启动/关闭信息
- 系统错误信息
查看 rsyslogd 进程:
[root@localhost ~]# ps aux | grep rsyslogd
root 7523 0.0 0.4 214452 4560 ? Ssl 15:01 0:00 /usr/sbin/rsyslogd -n
rsyslogd进程正常运行,是系统日志记录的根本保障。
第二类:应用程序自身日志
各类应用程序可以以自己的方式记录日志:
| 程序 | 日志文件 | 说明 |
|---|---|---|
| httpd | /var/log/httpd/access_log | Web 访问日志 |
| nginx | /var/log/nginx/access.log | Nginx 访问日志 |
| mysql | /var/log/mysqld.log | MySQL 运行日志 |
这些应用程序的日志会在后续学习对应程序时逐步介绍。
常见的日志文件
系统、进程、应用程序产生的日志存放在 /var/log/ 目录下。
核心日志文件
| 日志文件 | 说明 | 查看命令示例 |
|---|---|---|
/var/log/messages | 系统主日志文件(最重要) | tail -10 /var/log/messages |
/var/log/secure | 认证、安全日志(SSH 登录等) | tail -f /var/log/secure |
/var/log/yum.log | YUM 包管理日志 | tail /var/log/yum.log |
/var/log/maillog | 邮件(Postfix)相关日志 | tail /var/log/maillog |
/var/log/cron | 计划任务(crond、at)日志 | tail /var/log/cron |
/var/log/dmesg | 系统启动相关日志 | tail /var/log/dmesg |
其他日志文件
| 日志文件 | 说明 | 对应命令 |
|---|---|---|
/var/log/audit/audit.log | 系统审计日志 | – |
/var/log/mysqld.log | MySQL 数据库日志 | – |
/var/log/xferlog | FTP 服务器访问日志 | – |
/var/log/wtmp | 当前登录的用户 | w 命令 |
/var/log/btmp | 最近登录的用户 | last 命令 |
/var/log/lastlog | 所有用户的登录情况 | lastlog 命令 |
注意:
wtmp、btmp、lastlog是二进制文件,不能用cat直接查看,需要使用对应的命令(w、last、lastlog)。
实时查看日志
# 动态查看日志文件尾部(实时更新)
[root@localhost ~]# tail -f /var/log/messages
# 或者
[root@localhost ~]# tailf /var/log/secure
-f参数的作用:持续跟踪日志文件的最新内容,非常适合实时监控。
实战:观察网站访问日志
步骤 1:安装并启动 Apache
[root@localhost ~]# yum install -y httpd
[root@localhost ~]# systemctl start httpd
[root@localhost ~]# systemctl stop firewalld
步骤 2:访问服务器 IP
打开浏览器,输入服务器 IP 地址进行访问。
步骤 3:观察访问日志
[root@localhost ~]# tailf /var/log/httpd/access_log
每次有人访问网站,这里都会产生一条新的记录,包括访问者 IP、访问时间、访问的页面等。
rsyslogd 配置
安装与启动
# 安装(通常默认已安装)
[root@localhost ~]# yum install rsyslog logrotate
# 启动服务
[root@localhost ~]# systemctl start rsyslog.service
# 设置开机自启
[root@localhost ~]# systemctl enable rsyslog.service
相关配置文件
# 查看 rsyslog 的配置文件
[root@localhost ~]# rpm -qc rsyslog
| 文件 | 说明 | 重要程度 |
|---|---|---|
/etc/rsyslog.conf | rsyslogd 主配置文件 | ⭐⭐⭐ 最关键 |
/etc/sysconfig/rsyslog | rsyslogd 相关配置,定义级别等 | ⭐ 了解即可 |
/etc/logrotate.d/syslog | 日志轮转(切割)配置 | 任务二讲解 |
主配置文件详解
/etc/rsyslog.conf的核心是 RULES(规则)——它告诉 rsyslogd 进程:什么日志,应该存到哪里。
规则的组成
每条规则由三部分组成:
设备(FACILITY)+ 级别(LEVEL)+ 存放位置(FILE)
示例:
authpriv.* /var/log/secure # SSH 安全信息
mail.* -/var/log/maillog # 邮件日志(异步写入)
cron.* /var/log/cron # 计划任务日志
-符号的含义:表示使用异步方式记录日志。因为日志一般比较大,异步写入可以提高性能。
排除规则
*.info;mail.none;authpriv.none;cron.none /var/log/messages
这条规则表示:记录所有设备 info 级别及以上的日志,但排除邮件(mail)、认证(authpriv)、计划任务(cron)的日志。因为这些日志已经有各自专门的日志文件了。
FACILITY(设备类型)
Facility(设备) 是系统对某种类型应用事件的定义。程序自身会决定将日志交给哪类设备处理。比如 SSH 程序会选择安全类设备(AUTHPRIV),这一点由开发者在程序中定义。
| 设备 | 说明 | 示例场景 |
|---|---|---|
syslog | syslogd 自身产生的日志 | 日志系统内部信息 |
authpriv | 安全认证 | SSH 登录、sudo 操作 |
cron | 调度程序 | crond 和 at 计划任务 |
mail | 邮件子系统 | Postfix、Sendmail |
user | 用户相关(默认) | 用户空间程序 |
daemon | 后台进程 | 系统守护进程 |
ftp | FTP 守护进程 | vsftpd、proftpd |
kern | 内核消息 | 内核级别的错误 |
lpr | 打印机子系统 | 打印服务 |
local0 ~ local7 | 用户自定义设备 | 自定义应用程序日志 |
local0~local7是预留给用户自定义的设备类型,当某个应用程序需要将日志单独管理时,可以分配一个 local 设备。
查看完整的设备定义:
[root@localhost ~]# man 3 syslog
LEVEL(日志级别)
日志级别定义了日志的重要程度。从下到上,级别从低到高,记录的信息越来越少(即高级别包含低级别的所有信息)。
| 级别 | 英文 | 说明 | 示例场景 |
|---|---|---|---|
| debug | LOG_DEBUG | 调试信息 | 开发排错所需,生产环境不建议使用 |
| info | LOG_INFO | 标准信息 | 正常的运行信息 |
| notice | LOG_NOTICE | 重要的标准信息 | 需要关注但不紧急 |
| warning | LOG_WARNING | 警告信息 | 潜在问题,需要关注 |
| err | LOG_ERR | 错误行为 | 程序运行出现错误 |
| crit | LOG_CRIT | 致命行为 | 严重的系统问题 |
| alert | LOG_ALERT | 需要立即处理 | 如磁盘使用率达到 95% |
| emerg | LOG_EMERG | 紧急,致命 | 服务无法继续运行,如配置文件丢失 |
级别符号说明:
| 符号 | 含义 | 示例 | 说明 |
|---|---|---|---|
* | 所有级别 | authpriv.* | 认证设备的所有级别 |
. | 该级别及以上 | mail.info | 邮件的 info 及更高级别 |
.= | 仅该级别 | mail.=info | 仅邮件的 info 级别 |
.! | 排除该级别 | mail.!info | 邮件的所有级别但排除 info |
规则工作原理图示
┌─────────────────────────────────────────────────┐
│ 应用程序产生日志 │
│ (SSH、cron、httpd、mysql ...) │
└──────────────┬──────────────────────────────────┘
↓
┌─────────────────────────────────────────────────┐
│ rsyslogd 守护进程 │
│ ┌───────────────────────────────────────────┐ │
│ │ 匹配 RULES 规则 │ │
│ │ 设备(FACILITY) + 级别(LEVEL) → 文件路径 │ │
│ └───────────────────────────────────────────┘ │
└──────────────┬──────────────────────────────────┘
↓
┌─────────────────────────────────────────────────┐
│ 写入对应的日志文件 │
│ /var/log/secure ← authpriv.* │
│ /var/log/cron ← cron.* │
│ /var/log/messages ← *.info (排除特定设备) │
│ ... │
└─────────────────────────────────────────────────┘
实战:自定义 SSH 日志输出
场景:将 SSH 登录日志输出到自定义的日志文件中,方便单独管理。
步骤 1:修改 SSH 程序的设备类型
[root@localhost ~]# vim /etc/ssh/sshd_config
# 找到这行:
# SyslogFacility AUTHPRIV
# 修改为:
SyslogFacility LOCAL5
将 SSH 程序的日志输出设备从
AUTHPRIV改为LOCAL5(用户自定义设备)。
步骤 2:修改 rsyslog 规则
[root@localhost ~]# vim /etc/rsyslog.conf
# 在文件末尾添加:
local5.* /var/log/sshd_custom.log
这表示:LOCAL5 设备的所有级别日志,都写入
/var/log/sshd_custom.log。
步骤 3:重启服务
[root@localhost ~]# systemctl restart rsyslog.service sshd
步骤 4:测试验证
使用另一个终端登录服务器,然后查看新的日志文件:
[root@localhost ~]# tailf /var/log/sshd_custom.log
May 25 17:26:37 localhost sshd[14441]: Accepted password for root from 192.168.100.1 port 62925 ssh2
可以看到 SSH 登录信息被成功记录到了自定义的日志文件中!
任务二:logrotate 日志轮转
简介
日志轮转(Log Rotation):将大量日志文件按时间或大小等维度分割成多份,并自动删除时间久远的旧日志。
为什么需要日志轮转?
- 日志记录了程序运行时的各种信息,通过日志可以分析用户行为、记录运行轨迹、查找程序问题
- 但是磁盘空间是有限的——如果日志无限增长,最终会占满整个磁盘
- 日志轮转就像飞机里的黑匣子——记录的信息再重要,也只能保留最后一段时间发生的事
打个比方:
日志文件就像一本记录系统行为的日记本。如果一直写下去,日记本会越来越厚,最终书架都放不下。日志轮转的做法就是:每天换一本新日记本,旧日记本保留一段时间后就扔掉。
工作原理
logrotate 按照配置文件中的规则自动进行日志轮转。
配置文件种类
| 配置文件 | 路径 | 说明 |
|---|---|---|
| 主配置文件 | /etc/logrotate.conf | 全局设置,决定每个日志文件如何轮转 |
| 子配置目录 | /etc/logrotate.d/* | 自定义配置,便于管理各个服务的日志轮转 |
查看主配置文件和子配置文件:
[root@localhost ~]# ls /etc/logrotate.conf /etc/logrotate.d/
/etc/logrotate.conf
/etc/logrotate.d/:
bootlog chrony cups httpd iscsiuiolog libvirtd libvirtd.qemu numad ppp psacct samba syslog wpa_supplicant yum
主配置文件详解
[root@localhost ~]# vim /etc/logrotate.conf
全局设置
# 全局轮转设置
weekly # 轮转周期:每周轮转一次
rotate 4 # 保留 4 份旧日志
create # 轮转后创建新的空日志文件
dateext # 使用日期作为文件后缀名
# compress # 是否压缩旧日志文件(注释掉表示不压缩)
# 包含子配置目录
include /etc/logrotate.d
全局参数说明:
| 参数 | 说明 |
|---|---|
daily | 每天轮转 |
weekly | 每周轮转 |
monthly | 每月轮转 |
yearly | 每年轮转 |
rotate N | 保留 N 份旧日志 |
create | 轮转后创建新文件 |
dateext | 使用日期作为后缀 |
compress | 压缩旧日志文件(gzip) |
missingok | 日志文件丢失不报错 |
notifempty | 空文件不轮转 |
minsize N | 最小达到指定大小才轮转 |
maxsize N | 达到指定大小就轮转 |
针对特定日志的配置
# 针对 /var/log/wtmp 的轮转配置
/var/log/wtmp {
monthly # 一月轮转一次
minsize 1M # 最小达到 1M 才轮转(需同时满足 monthly 和 minsize)
create 0664 root utmp # 轮转后创建新文件,并设置权限
rotate 1 # 保留 1 份
}
# 针对 /var/log/btmp 的轮转配置
/var/log/btmp {
missingok # 丢失不提示
monthly # 每月轮转一次
create 0600 root utmp # 轮转后创建新文件,并设置权限
rotate 1 # 保留 1 份
}
实战:配置 YUM 日志轮转
目标:对 /var/log/yum.log 设置自定义轮转规则。
步骤 1:创建轮转规则
[root@localhost ~]# vim /etc/logrotate.d/yum
/var/log/yum.log {
missingok # 日志文件丢失不报错
# notifempty # 空文件不轮转(注释掉)
# maxsize 30k # 达到 30k 就轮转
# yearly # 或者一年一轮转
daily # 改为每天轮转(测试用,缩短周期)
rotate 3 # 保留 3 份旧日志
create 0777 root root # 轮转后创建新文件,并设置权限
}
步骤 2:手动轮转(测试)
# 错误示范:直接执行,不会生效
[root@localhost ~]# /usr/sbin/logrotate /etc/logrotate.conf
[root@localhost ~]# ls /var/log/yum*
/var/log/yum.log
# 只有一个文件,因为日期没变,logrotate 认为还没到轮转时间
步骤 3:修改时间,手动触发轮转
# 把时间向未来推移(格式:月日时分)
[root@localhost ~]# date 05291000
2026年 05月 29日 星期五 10:00:00 CST
# 强制执行轮转
[root@localhost ~]# /usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf
# 查看结果
[root@localhost ~]# ls /var/log/yum*
/var/log/yum.log /var/log/yum.log-20260529
日志文件已经出现多个,说明轮转成功!
关于轮转时间记录
logrotate 会记录每个日志文件最近一次轮转的时间:
[root@localhost ~]# grep 'yum' /var/lib/logrotate/logrotate.status
"/var/log/yum.log" 2026-5-29-10:0:12
如果从未轮转过:第一次执行只记录时间,不会立即轮转。
这就是为什么第一次手动执行
logrotate看不到效果的原因——logrotate 认为”今天已经轮转过了”。
logrotate 常用参数汇总
| 参数 | 说明 | 示例 |
|---|---|---|
daily | 每天轮转 | daily |
weekly | 每周轮转 | weekly |
monthly | 每月轮转 | monthly |
rotate N | 保留 N 份 | rotate 4(保留 4 份) |
create mode owner group | 轮转后创建新文件 | create 0644 root root |
dateext | 使用日期后缀 | dateext |
dateformat | 自定义日期格式 | dateformat -%Y%m%d |
compress | 压缩旧日志 | compress |
delaycompress | 延迟一次压缩 | compress + delaycompress |
missingok | 文件丢失不报错 | missingok |
notifempty | 空文件不轮转 | notifempty |
minsize N | 最小大小才轮转 | minsize 1M |
maxsize N | 达到大小就轮转 | maxsize 100M |
copytruncate | 复制并截断(替代 create) | copytruncate |
postrotate | 轮转后执行的脚本 | postrotate ... endscript |
prerotate | 轮转前执行的脚本 | prerotate ... endscript |
生产环境实战
实战一:Nginx 日志轮转
[root@localhost ~]# vim /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily # 每天轮转
rotate 30 # 保留 30 天
missingok # 丢失不报错
notifempty # 空文件不轮转
compress # 压缩旧日志
delaycompress # 延迟一次压缩(最新的旧日志不压缩,方便查看)
dateext # 使用日期后缀
dateformat -%Y%m%d # 日期格式
sharedscripts # 所有日志轮转后只执行一次脚本
postrotate
# 轮转后通知 nginx 重新打开日志文件
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
实战二:自定义应用日志轮转
[root@localhost ~]# vim /etc/logrotate.d/myapp
/var/log/myapp/*.log {
daily
rotate 7
missingok
notifempty
compress
size 50M # 达到 50MB 就轮转(覆盖 daily)
create 0644 www www
postrotate
systemctl reload myapp
endscript
}
实战三:MySQL 日志轮转
[root@localhost ~]# vim /etc/logrotate.d/mysql
/var/log/mysql/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 mysql adm
sharedscripts
postrotate
test -x /usr/bin/mysqladmin && \
/usr/bin/mysqladmin flush-logs
endscript
}
手动执行 logrotate
# 普通执行(检查配置文件是否有误)
[root@localhost ~]# logrotate /etc/logrotate.conf
# 强制执行(不管是否到期都轮转)
[root@localhost ~]# logrotate -f /etc/logrotate.conf
# 调试模式(不实际执行,只输出会做什么)
[root@localhost ~]# logrotate -d /etc/logrotate.conf
# 详细模式(输出详细执行过程)
[root@localhost ~]# logrotate -v /etc/logrotate.conf
生产环境建议:先用
-d调试模式测试,确认无误后再正式执行。
常见问题
rsyslog 服务没有运行怎么办?
# 检查服务状态
[root@localhost ~]# systemctl status rsyslog
# 启动并设置开机自启
[root@localhost ~]# systemctl start rsyslog
[root@localhost ~]# systemctl enable rsyslog
日志文件太大,如何快速清理?
# 方法一:清空文件(保留文件,清空内容)
[root@localhost ~]# > /var/log/messages
# 方法二:手动触发轮转
[root@localhost ~]# logrotate -f /etc/logrotate.conf
# 方法三:压缩旧日志
[root@localhost ~]# gzip /var/log/messages-20240101
不要直接删除日志文件!这会导致 rsyslogd 继续向已删除的文件描述符写入,磁盘空间不会释放。正确做法是清空文件内容或触发轮转。
如何查看谁在什么时候登录了系统?
# 查看当前登录的用户
[root@localhost ~]# w
# 查看最近的登录记录
[root@localhost ~]# last
# 查看所有用户的最近登录时间
[root@localhost ~]# lastlog
# 查看认证日志(SSH 登录详情)
[root@localhost ~]# tail -f /var/log/secure
logrotate 没有自动执行怎么办?
logrotate 是通过 cron 定时任务触发执行的:
# 检查 cron 任务
[root@localhost ~]# cat /etc/cron.daily/logrotate
# 检查 cron 服务
[root@localhost ~]# systemctl status crond
# 手动执行测试
[root@localhost ~]# /usr/sbin/logrotate /etc/logrotate.conf
最佳实践
定期检查日志大小
# 找出 /var/log 下最大的日志文件
du -sh /var/log/* | sort -rh | head -10合理设置日志保留时间
- 系统日志:保留 4-8 周
- 安全日志:保留 3-6 个月(合规要求)
- 应用日志:根据磁盘空间决定
启用日志压缩
compress
delaycompress # 延迟一次压缩,最新旧日志保持未压缩方便查看集中日志管理
- 多台服务器的日志建议集中到一台日志服务器
- 可以使用
rsyslog的远程日志功能或 ELK 栈
安全日志特殊处理
# /var/log/secure 需要保留更长时间
# 建议设置单独的轮转规则,保留 6 个月以上日志轮转后重启服务
postrotate
systemctl reload httpd
endscript
总结
通过本章节的学习,你应该掌握了:
- 理解 rsyslog 系统日志管理的工作原理
- 掌握常见的日志文件及其用途(messages、secure、cron 等)
- 理解 rsyslog.conf 中的 RULES 规则(设备 + 级别 + 存放位置)
- 熟悉各种 FACILITY(设备类型)和 LEVEL(日志级别)
- 能够自定义程序日志输出到指定文件
- 理解 logrotate 日志轮转的必要性和工作原理
- 掌握 logrotate.conf 主配置文件的编写
- 能够为不同服务配置独立的日志轮转规则
- 熟练使用手动轮转命令进行测试
学习建议:日志管理是运维排障的核心技能。建议在自己的虚拟机上:修改 rsyslog 配置将特定日志输出到自定义文件;配置一个服务的日志轮转规则;手动触发轮转并观察结果。实际操作一遍,胜过阅读十遍文档!