Linux 日志管理

rsyslog 服务

rsyslog是一个日志管理服务,用于收集和管理操作系统和应用程序产生的日志信息。 一般现在的Linux发行版中,rsyslog是默认作为操作系统的日志管理服务。

官网地址:https://www.rsyslog.com/

rsyslog 服务介绍


rsyslog 的service文件:

syslog服务提供了一个守护进程,只有这个守护进程正常运行了,才能对系统日志进行收集和管理。

在采用 systemd 作为其初始化系统的现代 Linux 系统中,通常包含一个名为 rsyslog.service 的服务文件,用于管理和控制 rsyslog 守护进程。

ehigh@ubuntu:~$ systemctl cat  rsyslog.service
# /lib/systemd/system/rsyslog.service
[Unit]
Description=System Logging Service
Requires=syslog.socket
Documentation=man:rsyslogd(8)
Documentation=https://www.rsyslog.com/doc/

[Service]
Type=notify
ExecStart=/usr/sbin/rsyslogd -n -iNONE
StandardOutput=null
Restart=on-failure

# Increase the default a bit in order to allow many simultaneous
# files to be monitored, we might need a lot of fds.
LimitNOFILE=16384

[Install]
WantedBy=multi-user.target
Alias=syslog.service

rsyslog收集日志的两种方式:

  1. rsyslog 直接从系统接收日志信息。这包括各种程序和系统服务生成的日志,如内核日志、邮件服务器日志等。这些日志消息通常通过 UNIX 的 syslog 接口发送。

  2. 在使用 systemd 的现代 Linux 系统中,rsyslog 可以与 systemd 的日志组件 journald 配合工作。journald 收集并管理系统日志,然后 rsyslog 可以从 journald 获取这些日志数据。


rsyslog 工作流程:

  1. 从本地收集日志或者从网络上接收日志信息

  2. 将收集到的日志进行解析处理,然后根据配置文件中定义的日志处理规格进行相关处理。

rsyslog 配置管理


rsyslog 配置文件:

  • 主配置文件:/etc/rsyslog.conf

  • 子配置文件:通过 $IncludeConfig 选项在主配置文件中指定,一般默认定义的是:/etc/rsyslog.d/下以.conf结尾的文件


rsyslog配置文件内容组成:

配置文件的内容有三大块组成,模块配置、全局配置和规则配置

  • 模块配置:rsyslog是基于模块设计的,使用不同的功能就需要加载不同的模块。

  • 全局配置:用于设置整个 rsyslog 服务的基本操作参数和行为。

  • 规则配置:rsyslog收集到日志信息后,通过定义的规则对这些日志数据进行处理。

rsyslog 规则管理


rsyslog日志管理规则:

rsyslog的每条日志管理规则都是由两大部分组成:

  • 选择器:定义哪些日志消息应该被处理。

  • 动作:定义了对匹配选择器的日志消息要执行的操作。

选择器


rsyslog 选择器的组成:

日志规则中的选择器又由两部分组成,设施(facility)和优先级(priority)。

  • 设施:指定日志消息的来源,比如邮件系统、内核、授权系统等。

  • 优先级:表示消息的重要性,比如错误、警告、信息等。


常见的设施有这些:

  • auth: 认证相关的消息

  • kern: 内核消息

  • mail: 邮件系统

  • daemon: 系统守护进程相关消息

  • user: 用户级消息

  • *:表示所有设施


常见的优先级有这些:

  • emerg: 最高的日志级别,表示系统遇到了灾难性的问题

  • alert: 通常是非常严重的问题。

  • crit: 表示严重的错误或问题,可能会导致系统或应用的部分功能中断。

  • err或error: 表示发生了错误,但系统或应用仍然在正常运行

  • warn或warning: 表示可能的问题,可能会导致错误,但还没有达到错误状态。

  • notice: 不表示错误或问题,但是值得注意

  • info: 在正常操作中生成,但它们不指示问题。

  • debug: 用于调试目的的消息。这是最详细的日志级别

  • none:明确表示不选择任何优先级

  • *:表示匹配所有优先级

动作


rsyslog 动作说明:

动作定义了对匹配选择器的日志消息要执行的操作。这些操作可以是将消息写入文件、发送到远程服务器、转发给另一个程序等。


写入文件

写入文件:指定为一个文件时,表示将日志消息写入本地文件系统中的文件。


例如:所有日志消息写入 /var/log/messages

*.* /var/log/messages

例如:所有info级别的消息都写入 /var/log/info.log

*.info /var/log/info.log

例如:对于auth和authpriv来源的所有消息都写入 /var/log/auth.log

auth,authpriv.* /var/log/auth.log

例如:除了auth和authpriv的消息,都异步写入/var/log/syslog

*.*;auth,authpriv.none          -/var/log/syslog

说明:

  • 分号(;) 后面的部分用于指定过滤条件

  • 逗号(,) 用于分隔多个过滤条件或设施名称。auth,authpriv.none等价于 auth.none,authpriv.none

  • 减号(-) 号表示异步写入硬盘,即先将日志写入缓冲区,到特定时候再由缓冲区刷新到硬盘

日志转发

转发到远程服务器:指定为@host:port时,表示将日志消息发送到远程 syslog 服务器。**


例如:将所有日志消息通过 TCP 发送到指定的远程服务器。

*.* @@remote-server:514
停止处理

停止处理规则:当动作指定为 ~时,表示在某些条件下停止处理后续规则


例如:丢弃包含 "some text" 的消息,不再进行后续处理

:msg, contains, "some text" ~

自定义设施


在 rsyslog 中,有许多预定义的日志设施,用于分类不同来源的日志消息。不同的设施各自对应不同类型的系统活动和服务。

除此之外,rsyslog 也提供了八个自定义设施(local0 到 local7)。这些设施没有预先定义的用途,而是留给用户根据自己的需求来自定义和使用。


例如:

可以专门为一个特定的应用程序使用 local7 设施。在 rsyslog 的配置文件中,通过创建一条专门针对 local7 的规则。然后,在应用程序中,当发送日志消息时,指定这些消息属于 local7 设施。

这样,rsyslog 就会根据你为 local7 定义的规则来处理这个应用程序的日志,从而实现日志的有效分类和管理。

修改sshd日志位置

默认sshd使用AUTH设施来发送它的日志消息,且日志信息的优先级是 info,因为sshd服务支持rsyslog,调用了rsyslog的接口,所以我们可以自定义sshd的日志存放位置。

(1)查看sshd的日志存放位置。


(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"
单个服务日志存放

rsyslog 网络日志管理

可以将将多个远程主机的日志集中发送到一台日志服务器上存储,方便后期的管理。


例如:

docker场景中,可以将多个docker容器的日志发送到一个专门的日志容器中,再将这个容器中存储日志的位置映射到宿主机上,这样就实现了容器日志的统一管理。

1、服务端配置

服务端需要启动相应的输入模块来来监听指定的端口并接收日志消息。有两个模块可以实现这个功能;

  • 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端口

2、客户端配置

服务端开启指定的端口后,客户端只需要编写对应的规则,将指定的日志消息发送给服务端就行了。

选择器  @server_iphost:port   或    选择器  @@server_iphost:port

指定远程服务器地址时:

  • 使用一个@符号,表示使用的是udp协议发送日志信息到日志服务器

  • 使用两个@符号,表示使用的是TCP协议发送日志信息到日志服务器


例如:

*.info;mail.none;authpriv.none;cron.none                @10.0.0.11:514

说明:还可以通过gtls模块来配置数据传输过程的加密,需要结合证书使用,如果日志存在敏感数据以及日志需要跨互联网或其他公共网络发送,使用加密可以增加安全性,防止数据被截获或篡改。

logger 工具

logger 用于向系统的日志管理器(如 syslog 或 rsyslog)发送日志消息。一般是用于在在脚本和命令行操作中,用于记录自定义的日志信息。

发送日志消息

不指定任何设施和优先级参数,它默认向user.notice发送消息

logger "This is a test message"

例如:向系统日志发送一条指定消息

logger " this is a log  "

指定日志优先级

发送日志消息的时候,可以通过-p参数来指定日志的优先级。


例如:发送消息的时候指定消息的优先级和设施

logger -p local7.info "hello sshd"

添加自定义标签

使用 -t 参数,可以为日志消息添加一个标签,这样可以在日志管理器中添加对应的规则来匹配含有指定消息的日志消息。


例如:有一个叫作cleanmem.sh的脚本,需要自定义日志存放位置

(1)在脚本中使用 logger 命令时,使用 -t 选项来为日志消息指定一个唯一的标签。

# -t 选项用于指定这条消息的“标签”或“程序名”
logger -t  cleanmem  "This is a log message"

(2)配置rsyslog,添加规则将带有这个标签的消息重定向到特定文件。

# 匹配并处理带有特定标签的日志
:programname, isequal, "cleanmem" /var/log/cleanmem.log
  • 冒号(:)用作特定类型的选择器的前缀。:programname 使用冒号来表示它是一个属性选择器,属性选择器用于基于日志消息的特定属性(如程序名、优先级等)来应用过滤规则。

  • isequal 是一个比较操作符,用于在属性选择器中指定比较的类型,以决定日志消息是否与指定的条件匹配。

  • logger 命令并通过 -t 参数指定一个标签时,这个标签实际上就是日志消息的 programname 属性


(3)重启rsyslog服务

sudo systemctl restart rsyslog.service

journald 服务

journald 是 systemd集成的日志服务,负责收集和存储系统上的日志信息。它提供了一个命令行工具journalctl,通过这个工具即可查看相关的日志信息。

journald 服务介绍

journald对应的service为 systemd-journald.service,只有确保这个服务正常运行,系统和应用程序产生的日志将才会被正确收集和管理。

日志存放位置:

默认情况下,收集的日志是以二进制格式存储在日志文件中,日志文件存放在 /var/log/journal/ 目录,如果这个目录不存在,就存放在/run/log/journal/ 目录。

journald和rsyslog

  • journald:提供了一些现代化的日志功能,如元数据支持、高效的二进制存储格式、更好的系统集成等。

  • rsyslog:也具备强大的日志处理能力,包括远程日志传输、高度可配置的日志过滤、格式化和转发能力。

两个服务可以协同运行不会冲突,尽管journald功能很强大,但是rsyslog 因其更强大的日志处理能力在某些场景下仍然非常重要。并且一些老旧的系统和应用可能依赖于传统的文本日志文件,而 rsyslog 可以提供这些文件,确保兼容性。

journald 配置管理

journald 本身具备一定的日志管理能力,可以限制其日志文件的大小。可以通过修改journald的配置文件来实现对systemd-journald 的日志文件管理。

  • 主配置文件:/etc/systemd/journald.conf

  • 子配置文件:/etc/systemd/journald.conf.d/

存储位置

通过 Storage 选项可以定义日志存储的位置,有四个值:

  • volatile:日志仅存储在内存中

  • persistent:日志持久化到磁盘

  • auto:(默认值)如果 /var/log/journal 存在则持久化,否则使用内存

  • none:不存储日志


例如:

Storage=auto

日志保留时间

通过 MaxRetentionSec 可以定义 systemd-journald 保留日志的最长时间,journald 将超过这个时间的旧日志自动清除。


例如:

MaxRetentionSec=30day

可以使用这些单位:s(秒)、m(分)、h(时)、day(天)、month(月)、year(年)


通过 MaxFileSec 可以设置单个日志文件的最大生命周期,超过这个时间的单个日志,将会被删除。


例如:

MaxFileSec=1month

日志大小

通过 SystemMaxUse 可以设置/var/log/journal/ 中日志使用的最大磁盘空间。当日志数据的大小超过这个限制时,journald 会自动删除旧的日志数据


例如:

SystemMaxUse=50M

可以使用这些单位:K(千字节)、M(兆字节)、G(吉字节)


其它设置

通过 ForwardToSyslog 可以设置是否将消息转发到传统的 syslog 守护进程。开启后rsyslog会从journald服务获取日志。


例如:

forwardToSyslog=yes

通过 SyncIntervalSec 可以定义 journald 多久同步一次内存中的日志数据到磁盘。


例如:

SyncIntervalSec=5m

可以使用这些单位:包括秒(s)、分钟(m)、小时(h)等。

journalctl 工具使用

使用 journalctl工具可以查看journald服务收集的相关日志信息。

显示系统所有日志信息

# 直接输入journalctl命令,不加任何参数
journalctl

查看指定时间日志信息

  • --since "开始时间"

  • --until "结束时间"


journalctl  --since "2023-10-1" --util "2023-10-8"

查看最后几行日志

journalctl -f

查看指定服务日志

要查看指定service的日志话,通过 -u选项,然后指定service命令就行了

journalctl -u service_name

查看某个服务的日志时,一般结合 -x 和 -e 选项使用:

  • -x:用于显示扩展的信息。journalctl 会显示更多有关日志条目的详细信息,包括与该日志条目相关的字段和元数据。

  • -e:用于启动 journalctl 并自动滚动到日志文件的末尾。

查看指定进程日志

还可以查看指定进程的日志,需要使用 _PID=PID_num 指定进程的编号即可,同理查看指定用户的日志用 _UID=UID_NUM 即可。

journalctl _PID=1234

查看内核日志信息

查看内核日志用 -k 选项, 查看启动日志用 -b 选项

journalctl -k

journalctl -b

logrotate

在大多数Linux发行版中,通过logrotate来管理和轮换系统上的日志文件,防止已经存在的日志文件无限制增长,占满存储空间。


logrotate和rsyslog、journald 别:

  • rsyslog:负责收集、处理和转发日志消息,不可以自我管理日志文件。

  • journald:负责收集、处理日志信息,但是它可以实现日志文件的自我管理。

  • ogrotate:不负责生成日志内容,而是处理已经存在的日志文件,确保这些日志文件不会变得过大或过旧。

logrotate 配置文件

logrotate 首先读取其配置文件,根据配置文件里面定义的规则检查每个指定的日志文件,如果满足了轮换条件,就对文件进行压缩、重命名或者删除。


轮换:某个日志文件满足轮换条件,logrotate 会将当前的日志文件重命名(通常是添加一个后缀,如 .1、.2 等),然后创建一个新的空日志文件以供后续记录。这个过程称为“轮换”。

  • 主配置文件:/etc/logrotate.conf

  • 子配置文件:通过include指令指定子配置文件的存放位置,一般是/etc/logrotate.d


例如:

通过编写指定日志的配置文件,就可以实现对指定日志文件大小的管理了。一般都是在/etc/logrotate.d下编辑,命名方式以日志文件名称命名,这个方便后期管理。

配置文件组成

通过编写和日志同名的配置来实现对指定日志的管理。


配置文件由两部分组成,日志路径和规则:

  • 日志路径:定义了当前配置会应用于哪些日志文件

  • 规则:对特定日志文件的管理方法


被管理的日志文件的路径
{
    # 具体该如何处理这个日志文件
}

例如: /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 工作流程

1、读取配置文件

配置文件定义了如何处理特定的日志文件,包括轮换频率、压缩选项、保留的文件数量等。

2、日志文件检查

根据配置文件定义的信息,检查每个日志文件,确定它们是否满足轮换条件。这些条件可能基于文件的大小、年龄(比如每天、每周轮换)或者其他自定义的条件。

3、执行轮换

如果日志文件满足轮换条件,logrotate 会将当前的日志文件重命名(比如添加一个数字或日期后缀),然后创建一个新的空日志文件。

在轮换日志之前或之后,可以配置 logrotate 执行特定的脚本(如重启服务等)。

4、压缩和删除旧文件

  • 压缩:根据配置,logrotate 可以压缩旧的日志文件以节省空间。

  • 删除:根据配置的保留策略,logrotate 会删除超出保留数量的旧日志文件。

logrotate 服务

早期版本

在早期版本中,logrotate是通过cron进行管理的,在/etc/cron.daily 目录下,有一个名为logrotate的脚本,这个脚本会默认使用/etc/logrotate.conf 文件启动一个进程。

systemd管理

现在大多数Linux发行版使用systemd作为系统初始化进程,通过编写service文件来管理logrotate。然后再通过systemd的定时器来定期调用这个service文件。

service文件:

ehigh@ubuntu:/etc/rsyslog.d$ systemctl cat logrotate.service 
# /lib/systemd/system/logrotate.service
[Unit]
Description=Rotate log files
Documentation=man:logrotate(8) man:logrotate.conf(5)
ConditionACPower=true

[Service]
Type=oneshot
ExecStart=/usr/sbin/logrotate /etc/logrotate.conf

# performance options
Nice=19
IOSchedulingClass=best-effort
IOSchedulingPriority=7

# hardening options
#  details: https://www.freedesktop.org/software/systemd/man/systemd.exec.html
#  no ProtectHome for userdir logs
#  no PrivateNetwork for mail deliviery
#  no ProtectKernelTunables for working SELinux with systemd older than 235
#  no MemoryDenyWriteExecute for gzip on i686
PrivateDevices=true
PrivateTmp=true
ProtectControlGroups=true
ProtectKernelModules=true
ProtectSystem=full
RestrictRealtime=true
  • Loaded: 表示这个服务已被加载。这里的“static”意味着这个服务不能被直接启动,但可以被其他单位(如一个timer)所触发。

  • TriggeredBy: 显示哪个单位(如timer)会触发此服务。


定时器文件:

ehigh@ubuntu:/etc/rsyslog.d$ systemctl cat  logrotate.timer 
# /lib/systemd/system/logrotate.timer
[Unit]
Description=Daily rotation of log files
Documentation=man:logrotate(8) man:logrotate.conf(5)

[Timer]
# 定时器在每天的同一时间点触发。如果没有指定具体时间,默认是午夜(00:00)。
OnCalendar=daily
# 实际的触发时间可以在计划时间的前后最多12小时内。定时器可以在前一天中午(12:00)到当天中午(12:00)之间的任何时间触发。
AccuracySec=12h
Persistent=true

[Install]
WantedBy=timers.target
  • Trigger: 显示下一次logrotate会被触发的时间。

  • Triggers: 这个timer会触发的服务。在此例中,它会触发logrotate.service,这是执行实际的日志轮换的服务。

posted on 2023-11-06 09:54  背对背依靠  阅读(372)  评论(0编辑  收藏  举报