一、系统日志的作用
系统日志记录了系统运行过程中产生的各种信息,如错误信息、警告信息、提示信息等。这些信息对于了解系统的运行状态、诊断故障、保障系统安全等方面具有重要作用。当系统出现问题时,通过查看日志可以快速定位故障原因,便于进行修复。同时,日志可以帮助系统管理员了解系统的运行状况,及时发现并解决问题。
二、rsyslog与systemd-journald
2.1 两者的区别
从RHEL7 开始系统的日志被rsyslog 和systemd-journald 这两个程序来管理
rsyslog 是持久日志,重启不会丢失,记录在/var/log
目录下
systemd-journald 默认是易失性日志,重启会丢失,系统日志记录在/run/log/journal/*/systemd.journal
文件中,“*
”代表的是通常为一串随机生成的文件名
2.2 rsyslog的日志文件
文件名 |
作用 |
/var/log/messages |
大多数系统日志消息记录在此处,包括记录服务信息,系统报错信息等 |
/var/log/secure |
与安全性和身份验证相关的日志 |
/var/log/cron |
与定时任务执行相关的日志 |
/var/log/maillog |
与系统中邮件服务日志 |
/var/log/boot.log |
与系统启动相关日志 |
rsyslog 根据不同的日志类型和优先级将日志信息存储在不同的文件中,在/etc/rsyslog.conf
配置文件中将日志信息拆分成两部分,一部分是类型,另一部分是优先级
比如cron服务的日志信息:cron.none
,其中cron 属于日志的类型,none 就属于优先级,可以将多个类型和优先级写成一行 ,中间用“;
”号隔开,保存日志在同一个文件中,如果类型或优先级用“*
”号占位表示匹配所有的类型或优先级,有些日志保存的文件路径前面有一个“-
”号,默认情况下,日志信息会直接写入日志文件,而在日志路径前面加个“-
”,系统会先将日志信息保存到缓存中,只有缓存保存完毕后才会输入到日志文件中,即异步写入
2.3 日志消息的类型
常用的日志类型 |
类型描述 |
lpr |
打印相关的日志 |
auth |
认证相关的日志 |
user |
用户相关的日志 |
cron |
计划任务相关的日志 |
kern |
内核相关的日志 |
|
邮件相关的日志 |
daemon |
系统服务相关的日志 |
authpri |
授权相关的日志 |
security |
安全相关的日志 |
local0-local7 |
自定义相关的日志信息(自定义时可以使用通配符) |
日志的类型由开发者定义,rsyslog只是负责调用,如果开发者没有调用rsyslog,通常有自己的日志管理方法,例如Apache的服务日志在“/var/log/httpd”目录下,“access_log”文件记录的是访问成功的日志,“error_log”记录的是访问失败的日志
2.4 日志消息的优先级
优先级 |
代码 |
严重性 |
none |
无 |
不记录任何信息 |
emerg |
0 |
内核崩溃等严重信息 |
alert |
1 |
需要立刻修改的信息 |
crit |
2 |
严重错误级别 |
err |
3 |
错误界别 |
warning |
4 |
警告级别 |
notice |
5 |
具有重要性的普通条件的信息 |
info |
6 |
一般信息的日志,最常用 |
debug |
7 |
调试级别消息 |
2.5 编写rsyslog的日志规则
写法示例 |
作用 |
mail.info /var/log/maillog |
比指定级别更高的日志级别,包括指定级别自身,保存到/var/log/maillog中 |
mail.=info /var/log/maillog |
明确指定日志级别为info,保存至/var/log/maillog |
mail.!info /var/log/maillog |
除了指定的日志级别(info)所有日志级别信息,保存至/var/log/maillog |
*.info /var/log/maillog |
所有类型的info级别,保存至/var/log/maillog |
mail.* /var/log/maillog |
mail的所有日志级別信息,都保存至/var/log/maillog |
mail.notice;news.info /var/log/maillog |
mail的notice以上日志级别和news的info以上日志级别保存至/var/log/maillog |
mail,news.crit -/var/log/maillog |
mail和news的crit以上的日志级别保^/var/log/maillog中;“-” 代表异步模式 |
三、实验一:定义rsyslog服务的cron日志
定义cron的日志,将cron类型的info级别以上的日志存储到
/var/log/jhrw
文件中,编辑/etc/rsyslog.conf
文件,添加如下图这一行:
重启rsyslog服务
[root@localhost ~]# systemctl restart rsyslog.service
编写一个cron计划任务,每分钟执行一次echo hello 2&> /dev/null
命令
[root@localhost ~]# crontab -e
*/1 * * * * echo hello 2&> /dev/null
[root@localhost ~]# crontab -l
*/1 * * * * echo hello 2&> /dev/null
查看日志
[root@localhost ~]# cat /var/log/jhrw
Jan 12 12:56:01 localhost anacron[2938]: Job `cron.weekly' started
Jan 12 12:56:01 localhost ana服务器托管网cron[2938]: Job `cron.weekly' terminated
Jan 12 12:58:31 localhost crontab[4524]: (root) BEGIN EDIT (root)
Jan 12 12:58:56 localhost crontab[4524]: (root) REPLACE (root)
Jan 12 12:58:56 localhost crontab[4524]: (root) END EDIT (root)
Jan 12 12:59:02 localhost CROND[4571]: (root) CMD (echo hello 2&> /dev/null)
Jan 12 12:59:22 localhost crontab[4618]: (root) BEGIN EDIT (root)
Jan 12 12:59:36 localhost crontab[4618]: (root) END EDIT (root)
Jan 12 12:59:38 localhost crontab[4620]: (root) LIST (root)
Jan 12 13:00:01 localhost CROND[4646]: (root) CMD (echo hello 2&> /dev/null)
[root@localhost ~]#
[root@localhost ~]# tail -n 30 -f /var/log/jhrw
Jan 12 12:56:01 localhost anacron[2938]: Job `cron.weekly' started
Jan 12 12:56:01 localhost anacron[2938]: Job `cron.weekly' terminated
Jan 12 12:58:31 localhost crontab[4524]: (root) BEGIN EDIT (root)
Jan 12 12:58:56 localhost crontab[4524]: (root) REPLACE (root)
Jan 12 12:58:56 localhost crontab[4524]: (root) END EDIT (root)
Jan 12 12:59:02 localhost CROND[4571]: (root) CMD (echo hello 2&> /dev/null)
Jan 12 12:59:22 localhost crontab[4618]: (root) BEGIN EDIT (root)
Jan 12 12:59:36 localhost crontab[4618]: (root) END EDIT (root)
Jan 12 12:59:38 localhost crontab[4620]: (root) LIST (root)
Jan 12 13:00:01 localhost CROND[4646]: (root) CMD (echo hello 2&> /dev/null)
Jan 12 13:01:01 localhost CROND[4703]: (root) CMD (run-parts /etc/cron.hourly)
Jan 12 13:01:01 localhost run-parts[4707]: (/etc/cron.hourly) starting 0anacron
Jan 12 13:01:01 localhost run-parts[4721]: (/etc/cron.hourly) finished 0anacron
Jan 12 13:01:02 localhost CROND[4740]: (root) CMD (echo hello 2&> /dev/null) # 可以查看到该命令每分钟执行一次
Jan 12 13:02:01 localhost CROND[4825]: (root) CMD (echo hello 2&> /dev/null)
Jan 12 13:03:01 localhost CROND[4902]: (root) CMD (echo hello 2&> /dev/null)
日志内容解析:以如下这一行内容为例
Jan 12 13:01:02 localhost CROND[4740]: (root) CMD (echo hello 2&> /dev/null)
Jan 12 13:01:02 时间戳
也就是日志产生的时间localhost 主机名
CROND 程序的名称
[4740] 程序的PID
(root) 用户名
CMD (echo hello 2&> /dev/null) 日志的内容
四、实验二:手动发送syslog日志
logger
命令可以发送消息到rsyslog服务,默认情况下,它的优先级为notice
常用选项:
-p:指定输入消息的优先级,格式为“facility.level”
-t:指定日志类型
-i:在每行都记录PID
举例:
[root@localhost ~]# logger -i -t mail -p mail.info ""
实验:打开两个命令行窗口,在其中一个窗口输入tail -f /var/log/message
命令实时查看日志
为了更加清楚地分辨出新增的日志内容,我们可以在内容的最后划上一条线
接着在另外一个窗口,使用logger
命令手动发送一条syslog日志
五、实验三:实现rsyslog日志服务器收集日志
准备工作:rsyslog是一个典型的C/S架构的服务,准备两台主机,分别配置主机名为node1.example.com
和node2.example.com
,网络互通,使用node1 作为服务器端,node2作为客户端
配置host解析
5.1 服务端配置
第一步:在node1 上编辑/etc/rsyslog.conf
,打开udp和tcp接收,见下图红色标记部分,默认是注释行,取消注释
第二步:重启rsyslog服务,防火墙放行syslog服务
[root@node1 ~]# systemctl restart rsyslog.service
[root@node1 ~]# firewall-cmd --add-service=syslog
success
[root@node1 ~]# firewall-cmd --runtime-to-permanent
success
5.2 客户端配置
第一步:在/etc/rsyslog.conf
中设置日志类型的转发,例如:将所有类型info及以上级别的日志转发到rsyslog服务端
第二步:重启rsyslog服务
[root@node2 ~]# systemctl restart rsyslog.service
测试:使用logger
命令发送一条info级别的消息
[root@node2 ~]# logger -i -t user -p user.info "logger from node2"
服务端查看/var/log/message
日志
[root@node1 ~]# tail -n 20 /var/log/messages
Jan 12 13:54:50 node1 systemd[1]: Stopping System Logging Service...
Jan 12 13:54:51 node1 rsyslogd[4450]: [origin software="rsyslogd" swVersion="8.2102.0-15.el8" x-pid="4450" x-info="https://www.rsyslog.com"] exiting on signal 15.
Jan 12 13:54:51 node1 systemd[1]: rsyslog.service: Succeeded.
Jan 12 13:54:51 node1 systemd[1]: Stopped System Logging Service.
Jan 12 13:54:51 node1 systemd[1]: Starting System Logging Service...
Jan 12 13:54:51 node1 rsyslogd[6131]: [origin software="rsyslogd" swVersion="8.2102.0-15.el8" x-pid="6131" x-info="https://www.rsyslog.com"] start
Jan 12 13:54:51 node1 systemd[1]: Started System Logging Service.
Jan 12 13:54:51 node1 rsyslogd[6131]: imjournal: journal files changed, reloading... [v8.2102.0-15.el8 try https://www.rsyslog.com/e/0 ]
Jan 12 13:56:08 node1 org.gnome.Shell.desktop[2022]: libinput error: event2 - VirtualPS/2 VMware VMMouse: client bug: event processing lagging behind by 16ms, your system is too slow
Jan 12 14:02:19 node2 systemd[1]: Stopping System Logging Service...
Jan 12 14:02:19 node2 rsyslogd[1054]: [origin software="rsyslogd" swVersion="8.2102.0-15.el8" x-pid="1054" x-info="https://www.rsyslog.com"] exiting on signal 15.
Jan 12 14:02:19 node2 systemd[1]: rsyslog.service: Succeeded.
Jan 12 14:02:19 node2 systemd[1]: Stopped System Logging Service.
Jan 12 14:02:19 node2 systemd[1]: Starting System Logging Service...
Jan 12 14:02:19 node2 rsyslogd[5431]: [origin software="rsyslogd" swVersion="8.2102.0-15.el8" x-pid="5431" x-info="https://www.rsyslog.com"] start
Jan 12 14:02:19 node2 systemd[1]: Started System Logging Service.
Jan 12 14:02:19 node2 rsyslogd[5431]: imjournal: journal files changed, reloading... [v8.2102.0-15.el8 try https://www.rsyslog.com/e/0 ]
Jan 12 14:03:31 node2 org.gnome.Shell.desktop[1958]: libinput error: event2 - VirtualPS/2 VMware VMMouse: client bug: event processing lagging behind by 31ms, your system is too slow
Jan 12 14:03:31 node2 org.gnome.Shell.desktop[1958]: libinput error: event2 - VirtualPS/2 VMware VMMouse: WARNING: log rate limit exceeded (5 msgs per 60min). Discarding future messages.
Jan 12 14:03:57 node2 user[5444]: logger from node2 # 测试成功
六、实验四:配置rsyslog日志轮循
logrotate
工具会轮循日志文件,防止日志文件占用过多的系统空间,轮循日志文件时,会使用日期作为文件的扩展名对其重命名,配置文件为:/etc/logrotate.conf
和/etc/logrotate.d/*
,所谓日志轮循就是将日志按照指定的规则来进行处理
我们可以查看到/var/log
目录下有一些日志的文件名是以“文件名+时间戳
”的格式保存的
我们来查看一下logrotate这个软件包
[root@node1 ~]# rpm -ql logrotate
/etc/cron.daily
/etc/cron.daily/logrotate
/etc/logrotate.conf
/etc/logrotate.d
/etc/logrotate.d/btmp
/etc/logrotate.d/wtmp
/etc/rwtab.d/logrotate
/usr/lib/.build-id
/usr/lib/.build-id/0e
/usr/lib/.build-id/0e/dd48ab54c5df23180d8380d8aa1a2aed05b031
/usr/sbin/logrotate
/usr/share/doc/logrotate
/usr/share/doc/logrotate/ChangeLog.md
/usr/share/licenses/logrotate
/usr/share/licenses/logrotate/COPYING
/usr/share/man/man5/logrotate.conf.5.gz
/usr/share/man/man8/logrotate.8.gz
/var/lib/logrotate
/var/lib/logrotate/logrotate.status
[root@node1 ~]#
[root@node1 ~]# cd /etc/logrotate.d/
[root@node1 logrotate.d]# ls
bootlog btmp chrony cups dnf firewalld httpd iscsiuiolog kvm_stat libvirtd libvirtd.qemu numad psacct samba sssd syslog wpa_supplicant wtmp
[root@node1 logrotate.d]#
在/etc/logrotate.d
目录中存放的即是与日志轮循相关的配置文件,配置文件内容的格式类似于下图所示:
常用的轮循参数:
参数 |
作用 |
missingok |
忽略错误 |
daily |
时间单位:天 |
copytruncate |
拷贝副本 |
rotate 7 |
保留最近的7个副本 |
notifempty |
空文件则忽略轮循 |
size 100k |
日志文件的大小100k |
create user group |
创建的日志文件的拥有人为user,所属组为group |
实验:例如我想对/var/log/message
日志文件做轮循,我们先来查看一下这个文件的大小
[root@node1 logrotate.d]# ls /var/log/messages -lh
-rw-------. 1 root root 1.9M Jan 12 14:42 /var/log/messages
第一步:在/etc/logrotate.d
目录下新增一个配置文件message
,配置轮循参数:
- 忽略错误
- 时间单位:天
- 拷贝副本
- 保留最近的7个副本
- 空文件则忽略轮循
- 日志文件的大小为100k
[root@node1 logrotate.d]# vim message
[root@node1 logrotate.d]# cat message
/var/log/message
{
missingok
daily
copytruncate
rotate 7
notifempty
size 100k
}
第二步:使用logrotate
命令加上“-f” 选项强制轮循
[root@node1 logrotate.d]# logrotate -f /etc/logrotate.conf
测试:查看/var/log目录下的message日志文件
[root@node1 logrotate.d]# ls -lh /var/log/messages*
-rw-------. 1 root root 372 Jan 12 14:55 /var/log/messages # 新增的日志保存在这里
-rw-------. 1 root root 1.9M Jan 12 14:55 /var/log/messages-20240112 # 旧的日志以文件名+时间戳命令
因为测试时间不够长,只得到1个副本,如果在保存第8个副本时,第1个副本会被删除,只保留最近的7个副本,通过这种方式来保障日志文件不会过于庞大
七、journalctl命令常用用法
从RHEL7 开始引入journald进行日志管理,journald的日志更加全面,在默认情况下不持久存储
journalctl 是journald的管理工具,常用选项如下表:
查看日志选项 |
作用 |
-f |
实时查看日志 |
-n 10 |
查看最近的10条日志 |
-p info |
查看指定级别的日志(这里是info以上级别) |
–until 17:00 |
查看17:00之前的日志 |
–since, –until |
查看某个时间段的日志,时间格式为”YYYY-MM-DD hh:mm:ss”或者yesterday, today, tommorow这样的时间参数。 |
-o FORMAT |
按照指定的格式输出日志,例如:“-o verbose”、“-o json” |
检索日志选项 |
作用 |
_PID |
通过PID检索日志 |
_UID |
通过用户的UID检索日志 |
_SYSTEM_UNIT |
通过系统单元检索日志,例如:“ |
_COMM |
通过命令的名称来检索日志 |
_EXE |
通过可执行文件的路径来检索日志 |
八、实验五:永久存储journald的日志
systemd-journald服务的配置文件在/etc/systemd/journald.conf
,当你打开这个文件时,你将看到类似于以下的内容:
上图红色标记的位置,默认值为auto
,/etc/systemd/journald.conf
中的storage
参数决定系统日志是易失性还是持久性,该参数可以设置为persistent, volatile或auto
- persistent:将日志存储在
/var/log/journal
目录中,若该目录不存在,systemd-journald服务 会创建它 - volatile:将日志存储在易失性目录
/run/log/journal
中,临时保存 - auto:如果
/var/log/journal
目录存在,那么systemd-journald会使用持久存储,否则为易失性存储,此为默认参数。
Case1:系统中不存在/var/log/journal
目录,我们来手动创建它
[root@node1 journal]# ls
[root@node1 journal]#
[root@node1 ~]# mkdir /var/log/journal # 当这个文件夹存在时,systemd-journald自动成为了持久化存储
[root@localhost journal]# ls
b6fb602bdd874c1b858ab31468b8c3fc # 自动生成该文件夹
[root@localhost journal]# cd b6fb602bdd874c1b858ab31468b8c3fc/ # 切换进去看看
[root@localhost b6fb602bdd874c1b858ab31468b8c3fc]# ls
system.journal
[root@localhost b6fb602bdd874c1b858ab31468b8c3fc]# file system.journal
system.journal: Journal file, online # 这是一个二进制文件,无法用cat等命令查看,只能通过journalctl
Case2:系统中不存在/var/log/journal
目录服务器托管网,我们修改配置文件,然后重启服务
[root@localhost ~]# rm -rf /var/log/journal
[root@localhost ~]# vim /etc/systemd/journald.conf
... 省略部分内容 ...
[Journal]
Storage=persistent
... 省略部分内容 ...
[root@localhost ~]# systemctl restart systemd-journald.service
[root@localhost ~]# ls /var/log/journal/
b6fb602bdd874c1b858ab31468b8c3fc
[root@localhost ~]# cd /var/log/journal/b6fb602bdd874c1b858ab31468b8c3fc/
[root@localhost b6fb602bdd874c1b858ab31468b8c3fc]# ls
system.journal
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net