rsyslog 介绍
日志(Log)是记录和存储计算机、软件、应用或其他系统的操作和事件的文件或数据流。它们可以为系统管理员、开发人员和最终用户提供详细的背景信息,以帮助他们了解和诊断系统的行为。
rsyslog 是一个开源的日志处理工具,一般用在类Unix系统上,是syslogd 的扩展。它提供了更好的性能和更多的功能,因此在许多现代 Linux 发行版中,已经成为默认的日志管理服务。
rsyslog 本地日志管理
rsyslog作为默认的系统日志管理服务,默认会在/var/log目录下生成一些日志文件,这些文件都是通过rsyslog配置文件(/etc/rsyslog.conf)定义,在主配置文件中通过 $IncludeConfig
指令引入 /etc/rsyslog.d/ 下以 .conf 结尾的配置,加载主配置文件的时候,这些子配置文件也会一同被读取和应用。
例如: 这是ubuntu2004这个发行版系统中,rsyslog的默认配置示例,定义了哪些消息应当被写入哪些日志文件。
auth,authpriv.* /var/log/auth.log
表示对于 auth 和 authpriv 这两个日志类别的所有优先级(由 .* 表示)的消息,都写入 /var/log/auth.log 文件。
rsyslog 配置文件
总体来说,rsyslog 配置文件由三部分组成,模块配置、全局配置、日志规则。
1、模块配置:
因为rsyslog时基于模块设计的,加载不同的模块,需要通过加载不同的模块来支持各种不同的输入、输出、消息格式和协议
$ModLoad modulename
2、全局配置:
会影响rsyslog的整体行为。例如,定义默认的日志文件目录、设置队列大小、指定工作线程数等。
3、日志规则:
定义了日志消息如何被处理。每个规则通常由两部分组成:选择器(决定哪些消息被选中)和动作(决定对这些消息做什么)
日志规则格式
定义本地的一些日志文件,只需要添加对应的日志规则就行了,不用修改模块和全局配置
选择器 动作
选择器:
用于确定哪些日志消息被选中。选择器又由两部分组成:设施和优先级。格式: 设施.优先级
设施: 定义日志的来源,有以下几种常见的设施:
-
auth: 认证相关的消息
-
kern: 内核消息
-
mail: 邮件系统
-
daemon: 系统守护进程
-
user: 用户级消息
-
*:表示所有设置
优先级; 表示消息的重要性级别,有几种常见的级别:
-
emerg: 最高的日志级别,表示系统遇到了灾难性的问题
-
alert: 通常是非常严重的问题。
-
crit: 表示严重的错误或问题,可能会导致系统或应用的部分功能中断。
-
err或error: 表示发生了错误,但系统或应用仍然在正常运行
-
warn或warning: 表示可能的问题,可能会导致错误,但还没有达到错误状态。
-
notice: 不表示错误或问题,但是值得注意
-
info: 在正常操作中生成,但它们不指示问题。
-
debug: 用于调试目的的消息。这是最详细的日志级别
-
none:明确表示不选择任何优先级
-
*:表示匹配所有优先级
动作:
动作决定对所选消息做什么。常见的动作有:
-
写入本地文件,例如:/var/log/mail.log
-
发送到远程服务器,例如:@192.168.1.1
-
发送电子邮件,数据库写入等,取决于加载的rsyslog模块
例如:
*.*;auth,authpriv.none -/var/log/syslog
这条规则定义了三个子选择器,共同形成了一个复合选择器。
-
.: 选择所有设施的所有优先级的消息
-
auth.none: 排除来自 auth 设施的所有消息
-
authpriv.none: 排除来自 authpriv 设施的所有消息
在 rsyslog 的选择器语法中,可以通过 逗号, 来分隔不同的设施,这样可以在单个选择器内同时指定多个设施。 因此,auth,authpriv.none 实际上是两个选择器,但它们都有相同的优先级 .none。
所以 .;auth,authpriv.none 效果等同于 .;auth.none;authpriv.none
-/var/log/syslog 表示消息应该被写入的文件路径, -: 是一个前缀,告诉rsyslog将日志条目先写入操作系统的缓冲区,而不是立即同步到硬盘。操作系统会在适当的时机(基于其内部逻辑和策略)将这些缓冲区中的数据刷新到硬盘。
所以由此可知,在rsyslog的规则语法中:
-
使用分号 ; 来分隔不同的子选择器。
-
使用逗号 , 来分隔具有相同优先级的不同设施,使表示更为紧凑。
-
动作是一个文件路径时,前面加上 - 前缀,表示异步写入硬件
例如:
auth,authpriv.* /var/log/auth.log
根据上面我们知道规则中使用逗号是用来隔离具有相同优先级的不同设施,所以这里表示将auth和authpriv的所有优先级消息写入/var/log/auth.log
rsyslog 自定义设施
在rsyslog中,自定义了8个设置。loca0到local8,应用程序和用户可以自定义这些设施时用来做啥的。
例如:
公司开发了一个名为"MyApp"的应用程序,他们可以选择使用local0作为"MyApp"的日志设施。然后,在rsyslog配置中,可以专门为local0指定日志处理规则,如将"MyApp"的日志消息写入一个特定的日志文件
例如: 自定义ssh的日志存放位置:(sshd服务支持rsyslog,调用了rsyslog的接口,所以我们可以修改)
(1)查看sshd的日志存放位置,默认sshd使用AUTH设施来发送它的日志消息,且日志信息的优先级是 info。
(2)修改sshd的配置文件
# 指示sshd将其日志消息发送到local7设施。
vim /etc/ssh/sshd_config
SyslogFacility local7
(3)修改rsyslog配置文件,定义local7这种级别的日志处理方式
# 指示rsyslog将所有local7设施的消息写入/var/log/sshd.log文件
vim /etc/rsyslog.d/50-default.conf
local7.* -/var/log/sshd.log
(4)重启sshd服务和rsyslog服务
sudo systemctl restart sshd.service
sudo systemctl restart rsyslog.service
(5)测试是否成功
可以用logger命令来进行测试:
logger -p local7.info "hello sshd"
logger工具说明
logger 是一个用于向系统日志发送消息的命令行工具。
格式:
# 不指定任何设施和优先级参数,它默认向user.notice发送消息。
logger " this is a log "
# 指定设施,没指定优先级,默认优先级是notice
logger -p local7.info "hello sshd"
说明:
logger 默认情况下是向系统日志发送一条信息,也可以使用-p参数来指定日志的设施和优先级,但是如果就指定了设施,没有指定优先级的话,默认使用的是notice。编写shell脚本的时候,可以直接用logger工具来将指定的日志信息写入日志文件中。
rsyslog 网络日志管理
可以将将多个远程主机的日志集中发送到一台日志服务器上存储,方便后期的管理。
例如:
docker场景中,可以将多个docker容器的日志发送到一个专门的日志容器中,再将这个容器中存储日志的位置映射到宿主机上,这样就实现了容器日志的统一管理。
服务端配置
服务端需要启动相应的输入模块来来监听指定的端口并接收日志消息。有两个模块可以实现这个功能;
imudp.so模块:提供udp连接
imptcp.so模块:提供tcp连接
加载模块方法:
vim /etc/rsyslog.conf
# 加载udp模块
module(load="imudp") # needs to be done just once
input(type="imudp" port="514") #表示打开udp的514端口
# 加载tcp模块
module(load="imtcp") # needs to be done just once
input(type="imtcp" port="514") #表示打开tcp的514端口
客户端配置
服务端开启指定的端口后,客户端只需要编写对应的规则,将指定的日志消息发送给服务端就行了。
选择器 @server_iphost:port 或 选择器 @@server_iphost:port
说明:
指定远程服务器地址的时候,如果使用一个@符号,表示使用的是udp协议发送日志信息到日志服务器,如果使用两个@符号,表示使用的是TCP协议发送日志信息到日志服务器
例如:
*.info;mail.none;authpriv.none;cron.none @10.0.0.11:514
测试验证:
可以通过在客户端使用logger工具来将执行信息写入到日志中,然后再去服务端查看。如果有对应的信息就说明成功了。
说明:
还可以通过gtls模块来配置数据传输过程的加密,需要结合证书使用,如果日志存在敏感数据以及日志需要跨互联网或其他公共网络发送,使用加密可以增加安全性,防止数据被截获或篡改。
journalctl 介绍
journalctl是systemd提供的一个命令行工具,用于查询和显示由 systemd-journald 服务收集和管理的日志信息。
systemd-journald 是 systemd 初始化系统的组成部分,负责收集和存储系统日志,不仅包括系统服务的日志,还包括内核、应用程序和其他系统组件的日志。
journalctl 使用说明
直接输入journalctl命令,就会显示系统上所有的日志信息:
journalctl
查看系统全部日志太多了不好查看,可以用 --since "开始时间" --until "结束时间" 来查看指定时间段的所有日志
journalctl --since "2023-10-1" --util "2023-10-8"
如果想要实时查看所有日志中最后几行日志,可以使用 -f 参数类似于tail命令的-f选项
journalctl -f
要查看指定service的日志话,通过 -u选项,然后指定service命令就行了
journalctl -u service_name
还可以查看指定进程的日志,需要使用 _PID=PID_num 指定进程的编号即可,同理查看指定用户的日志用 _UID=UID_NUM 即可。
journalctl _PID=1234
查看内核日志用 -k 选项, 查看启动日志用 -b 选项
journalctl -k
journalctl -b
logrotate 介绍
存在这么一种情况,随着Linux系统的长时间运行,系统上的日志文件会越来越大,最终结果就是将存储空间全部占满,为了确保它们不会无限制地增长,所以有了logrotate。
简单来说,logrotate 的主要目的是防止日志文件无限制地增长并消耗所有的磁盘空间,并且根据定义的规则定期轮换、压缩和管理旧日志文件,确保只保留有价值和必要的日志记录。
logrotate 配置文件
和rsyslog一样,logrotate也有主配置文件(/etc/logrotate.conf)和子配置文件(默认/etc/logrotate.d目录下),主配置文件通过include指令指定子配置文件的存放位置。
通过编写指定日志的配置文件,就可以实现对指定日志文件大小的管理了。一般都是在/etc/logrotate.d下编辑,命名方式以日志文件名称命名,这个方便后期管理。
规格文件的格式大致是这样的:
被管理的日志文件的路径
{
# 具体该如何处理这个日志文件
}
例如:系统上rsyslog这个日志文件的管理规则是这样的:
# 指定了如何处理 /var/log/syslog 这个日志文件
/var/log/syslog # 被管理的日志文件的路径
{
rotate 7 # 保留7个旧的日志文件
daily # 每天轮换日志文件
missingok # 如果日志文件丢失,不要发出错误消息
notifempty # 如果日志文件为空,不进行轮换
delaycompress # 在下次轮换时才压缩上一次的旧日志
compress # 压缩旧的日志文件,通常使用gzip进行压缩,所以会看到 .gz 的后缀。
# 在日志文件轮换之后,执行指定的命令或脚本,脚本位于postrotate和endscript中间
postrotate
/usr/lib/rsyslog/rsyslog-rotate
endscript
}
例如:让/var/log/nginx目录下的日志保存半年
/var/log/nginx/*.log
{
monthly # 每月轮换一次。
rotate 6 # 保存6个旧日志文件,也就是前六个月的日志文件都保存
compress # 旧日志文件采用gzip算法压缩
delaycompress # 在下次轮换时才压缩上一次的旧日志
missingok
notifempty # 如果日志文件为空,则不进行轮换。
create 0640 nginx adm # 使用指定的权限重新创建日志文件,并指定其属主和组。
sharedscripts # 如果/var/log/nginx/下有多个日志文件,默认会针对每个单独的日志文件执行。通过指定sharedscripts 不论多少日志文件涉及到轮换,这些脚本只会执行一次。
postrotate # 日志文件轮换后要执行的命令,发送一个信号给nginx,通知它日志文件已经被轮换,它应该开始写新的日志文件。
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
logrotate 转换选项
转换时间:
-
daily 每天一次
-
weekly 每周一次
-
monthly 每月一次
转换大小:
- size 当日志文件到达指定的大小时才转储,默认值字节,例如:size 200MB
保留旧日志数量:
- rotate 指定保留旧日志的数量,例如:rotate 7表示保留7个旧的日志文件(加上当前的日志文件,将最多有8个日志文件:当前的和7个旧的)。
压缩选项:
-
compress 使用gzip算法将旧日志进行压缩,文件名默认以gz结尾
-
nocompress 不对旧日志进行压缩
-
delaycompress 在下次轮换时才压缩上一次的旧日志
其它规则:
-
missingok 如果日志不存在,不提示错误,继续处理下一个
-
notifempty 如果日志文件为空,不进行轮换
-
ifempty 即使是空文件也转储,此为默认选项
-
postrotate xxxx endscript 在日志文件轮换之后,执行指定的命令或脚本
-
sharedscripts 指定的位置下面有多个日志文件,只执行postrotate xxxx endscript中的脚本一次,也不是一个日志文件就要执行一次。
-
olddir 转储后的日志文件放入指定目录,必须和当前日志文件在同一个文件系统。默认是存放在和当前日志所在的目录中
-
noolddir 转储后的日志文件和当前日志文件放在同一个目录下,默认就是这个选项。
logrotate 默认配置
我们在查看logrotate.conf配置文件的时候也可以看到有如下的默认规则:
这些配置都是logrotate 的全局或默认配置。它定义了一些默认的设置,但这部分配置本身并不直接管理任何特定的日志文件。它为后续在 logrotate 配置中定义的日志文件或在 /etc/logrotate.d/ 目录下的配置文件提供了默认值。
logrotate 工作原理
在以前的一些版本中,logrotate 的配置默认是通过cron.daily目录中的脚本来运行的。如果你查看 /etc/cron.daily 目录,你可能会发现一个名为logrotate的脚本,这个脚本通常会调用logrotate命令,并使用 /etc/logrotate.conf 作为其配置文件。
但是现在,大多数Linux发行版给它加了个service文件,通过systemd来管理logrotate
logrotate.service 文件定义了如何运行 logrotate
说明:
-
Loaded: 表示这个服务已被加载。这里的“static”意味着这个服务不能被直接启动,但可以被其他单位(如一个timer)所触发。
-
TriggeredBy: 显示哪个单位(如timer)会触发此服务。
说明: 是通过调用logrotate命令,并使用/etc/logrotate.conf作为其配置文件实现的service服务。
logrotate.timer 文件定义了何时运行 logrotate.service。
说明:
-
Trigger: 显示下一次logrotate会被触发的时间。
-
Triggers: 这个timer会触发的服务。在此例中,它会触发logrotate.service,这是执行实际的日志轮换的服务。