红茶的个人站点

  • 首页
  • 专栏
  • 开发工具
  • 其它
  • 隐私政策
Awalon
Talk is cheap,show me the code.
  1. 首页
  2. 专栏
  3. Linux之旅
  4. 正文

Linux 之旅 18:认识与分析日志文件

2021年9月4日 1722点热度 0人点赞 0条评论

image-20210903201220509

什么是日志文件

对于开发者来说日志文件应该不陌生,无论是使用各种软件中遇到问题,还是自己开发的应用排查问题,都需要和各种各样的日志打交道,通过日志我们可以在程序没有按照我们预期的那样运行的时候,去排查到底发生了些什么事,以为问题的排查和解决提供参考依据。

CentOS 7 日志文件简易说明

常见的日志文件

Linux中同样有各种日志文件,都是由系统本身或者安装的一些程序产生的,其中常用的有以下这些:

  • /var/log/boot:开机产生的相关信息日志,包括硬件自检等。

  • /var/log/cron:crond服务运行中产生的日志,crontab设置的任务计划没有正常执行可以排查这里。

  • /var/log/dmesg:记录开机时系统内核产生的信息。

  • /var/log/lastlog:记录系统中的账号最近的登录情况。

  • /var/log/maillog与/var/log/mail/*:邮件收发记录,主要是postfix(使用SMTP协议)与dovecot(使用POP3协议)收发的邮件记录。

  • /var/log/messages:记录系统中主要的错误信息。

  • /var/log/secure:记录所有的账号登录行为。

  • /var/log/wtmp与/var/logfaillog:前者记录正确的登录行为,后者记录错误的登录行为。

  • /var/log/httpd:apache产生的日志

  • /var/log/samba:samba文件共享服务产生的日志

日志相关的服务与程序

Linux上产生日志的途径有两种,一种是程序自行产生日志,另一种是通过Linux系统提供的统一的日志记录功能来生成日志。后者主要是通过rsyslog.service这个服务来实现。

其它和日志有关的服务还有systemd-journald.service,这个服务是系统启动时,在启动systemd这个进程后,由systemd启动的日志服务,用于记录启动后系统产生的相关信息。

还有一个和日志有关的程序logrotate,这个程序可以用来定期地“整理”日志,即将过大的日志进行归档,并将不需要的日志删除,是一个相当有用的日志整理程序。

日志文件的一般格式

日志一般会记录以下几方面的内容:

  • 事件发生的时间

  • 发生事件的主机名称

  • 事件相关的服务名称或者shell命令

  • 事件内容

以登录相关的日志举例:

[root@xyz ~]# cat /var/log/secure | tail
Sep  3 20:39:16 xyz sshd[2057]: Received disconnect from 192.168.1.6 port 1903:11: disconnected by user
Sep  3 20:39:16 xyz sshd[2057]: Disconnected from 192.168.1.6 port 1903
Sep  3 20:39:16 xyz sshd[2048]: pam_unix(sshd:session): session closed for user icexmoon
Sep  3 20:39:37 xyz gdm-password]: pam_unix(gdm-password:session): session opened for user icexmoon by (uid=0)
Sep  3 20:39:40 xyz gdm-launch-environment]: pam_unix(gdm-launch-environment:session): session closed for user gdm
Sep  3 20:39:40 xyz polkitd[760]: Unregistered Authentication Agent for unix-session:c1 (system bus name :1.32, object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale zh_CN.UTF-8) (disconnected from bus)
Sep  3 20:39:51 xyz polkitd[760]: Registered Authentication Agent for unix-session:8 (system bus name :1.81 [/usr/bin/gnome-shell], object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale zh_CN.UTF-8)
Sep  4 10:51:54 xyz sshd[3461]: Accepted password for icexmoon from 192.168.1.6 port 12950 ssh2
Sep  4 10:51:55 xyz sshd[3461]: pam_unix(sshd:session): session opened for user icexmoon by (uid=0)
Sep  4 10:56:59 xyz su: pam_unix(su-l:session): session opened for user root by icexmoon(uid=1000)

最后3行的内容就是9月4日10点51分,xyz这个主机上的sshd服务进行了登录相关的操作。

之所以这里虽然是当前Linux主机的相关日志,但依然记录主机名,是因为Linux的日志系统是支持日志服务器的,也就是说可以将多台Linux主机上的日志发送到作为日志服务器的一台主机上进行汇总,此时用主机名来区分不同Linux主机产生的日志就很有必要了。

rsyslog.service

之前已经说了,Linux上提供的负责统一日志记录的服务是rsyslog.service:

[root@xyz ~]# ps aux | grep rsyslog
root       1252  0.1  0.3 214432  3920 ?        Ssl  10:06   0:03 /usr/sbin/rsyslogd -n
root       3820  0.0  0.0 112828   980 pts/0    R+   11:03   0:00 grep --color=auto rsyslog
[root@xyz ~]# systemctl status rsyslog
● rsyslog.service - System Logging Service
   Loaded: loaded (/usr/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabled)
   Active: active (running) since 五 2021-09-03 19:55:46 CST; 15h ago
     Docs: man:rsyslogd(8)
           http://www.rsyslog.com/doc/
 Main PID: 1252 (rsyslogd)
    Tasks: 3
   CGroup: /system.slice/rsyslog.service
           └─1252 /usr/sbin/rsyslogd -n
​
9月 03 19:55:45 xyz.icexmoon.centos systemd[1]: Starting System Logging Service...
9月 03 19:55:46 xyz.icexmoon.centos rsyslogd[1252]:  [origin software="rsyslogd" swVersion="8.24.0-55.el7" x-pid="1252" x-in...start
9月 03 19:55:46 xyz.icexmoon.centos systemd[1]: Started System Logging Service.
Hint: Some lines were ellipsized, use -l to show in full.

rsyslog.service 的配置文件

rsyslog.service的配置文件是/etc/rsyslog.conf:

[root@xyz ~]# cat /etc/rsyslog.conf | grep -v '^#' | grep -v '^$' | grep -v '^\$'
*.info;mail.none;authpriv.none;cron.none                /var/log/messages
authpriv.*                                              /var/log/secure
mail.*                                                  -/var/log/maillog
cron.*                                                  /var/log/cron
*.emerg                                                 :omusrmsg:*
uucp,news.crit                                          /var/log/spooler
local7.*                                                /var/log/boot.log

主要的配置项规定了产生日志的日志类型、日志级别以及日志文件路径。

日志类型

日志类型(facility)是由Linux内核的syslog规定的,可以通过man 3 syslog进行查看:

[root@xyz ~]# man 3 syslog

facility单词有设施的意思,用在这里主要是用于区分产生日志的程序的用途,也就是对日志来源进行区分。

下面列出主要的服务类型:

序号 服务类型 说明
0 kern (kernel) Linux内核产生的信息,大部分是硬件检测和内核功能的启用
1 user 用户层级产生的信息,例如后边介绍的通过logger产生的日志信息
2 mail 所有邮件收发的相关信息
3 daemon 系统服务产生的信息
4 auth 与认证、授权相关的信息,如login、ssh、su等产生的信息
5 syslog syslogd服务产生的信息
6 lpr 打印相关的信息
7 news 新闻群组相关的信息
8 uucp Unix to Unix Copy Protocol 早期Unix系统间的数据交换协议
9 cron 周期性计划任务程序,如cron、at等产生的信息
10 authpriv 与auth类似,但记录的多为帐号相关的信息,如pam模块的调用等
11 ftp FTP协议相关的信息
16~23 local0~local7 保留给本地用户使用的日志类型,通常与终端交互相关。

在实际使用中,本地运行的程序会使用上边定义的这些日志类型,通过rsyslogd服务生成日志,这种关系可以用下图表示:

syslog 所制訂的服務名稱與軟體呼叫的方式

图源:鸟哥的私房菜

日志级别

syslog将日志分为不同的级别(level)进行管理:

编号 名称 说明
7 debug 调试或排查错误时产生的信息
6 info 基本信息
5 notice 主要注意的信息
4 warning(warn) 警告,可能会影响到程序正常运行,或者会产生隐患的问题
3 err(error) 错误,已经产生了影响程序运行的问题
2 crit 紧急,可能需要立即处理的问题
1 alert 报警,比crit更验证的问题
0 emerg(panic) 最严重的问题,可能已经影响到系统运行(一般为硬件相关问题,直接影响到系统的正常运行)

日志级别从大到小越来越严重。

此外还有一个none,代表不需要进行日志记录。

日志类型和日志级别联合起来使用,就可以代表来自某种程序的某个级别的日志:

  • facility.level:记录来自facility类型的程序的level以上级别的日志

  • facility.=level:记录来自facility类型的程序的level级别的日志

  • facility.!level:记录来自facility类型的程序的非level级别的日志

  • facility.*:记录来自facility类型的程序的全部日志

  • facility.none:不记录来自facility类型的程序的日志

这里的level以上指的是比level更严重的意思。

日志文件

除了指定日志类型和日志级别,还需要指定具体记录日志的文件。

除了可以使用普通文件作为日志文件进行记录以外,还可以使用:

  • 打印机或其它设备:如打印机/dev/lp0

  • 用户名:直接显示给指定用户

  • 远程主机:使用远程主机作为日志服务器,发送日志给远程主机

  • *:表示所有用户,类似于广播(wall),将会把日志发送给当前登录的所有用户。

syslog

syslog、rsyslogd、rsyslog.service这三者的关系是:

  • syslog:Linux内核对日志的规范,包含日志的类型和级别等相关设定。

  • rsyslogd:Linux系统负责接收并产生符合syslog规范的日志的程序。

  • rsyslog.service:负责启动rsyslogd程序的服务。

rsyslog.conf 练习

现在我们做一些关于rsyslog.conf的练习,比如我们现在要新增一个日志文件,用来记录mail相关的日志:

[root@xyz etc]# cp /etc/rsyslog.conf /tmp/rsyslog_test.conf
[root@xyz etc]# vim /tmp/rsyslog_test.conf
[root@xyz etc]# diff /etc/rsyslog.conf /tmp/rsyslog_test.conf
61c61
<
---
> mail.info                                             /var/log/maillog2

为了不影响正常的日志功能,这里复制一份rsyslog.conf配置文件作为练习。

如果需要记录cron和news相关的日志,并且将warn级别的日志单独记录,可以:

[root@xyz etc]# cp /etc/rsyslog.conf /tmp/rsyslog_test2.conf
[root@xyz etc]# vim /tmp/rsyslog_test2.conf
[root@xyz etc]# diff /etc/rsyslog.conf /tmp/rsyslog_test2.conf
64a65,66
> cron.*;news.*                                         /var/log/cronnews
> cron.=warn;news.=warn                                 /var/log/cronnews.warn

像上面展示的那样,如果是多个日志来源要写入同一个日志文件,可以使用;进行分隔。

CentOS 7 默认的配置

CentOS 7 上rsyslog.conf中默认的配置为:

[root@xyz ~]# cat /etc/rsyslog.conf | grep -v '^#' | grep -v '^$' | grep -v '^\$'
*.info;mail.none;authpriv.none;cron.none                /var/log/messages
authpriv.*                                              /var/log/secure
mail.*                                                  -/var/log/maillog
cron.*                                                  /var/log/cron
*.emerg                                                 :omusrmsg:*
uucp,news.crit                                          /var/log/spooler
local7.*                                                /var/log/boot.log

也就是说在默认情况下rsyslogd会记录并生成以下日志:

  • *.info;mail.none;authpriv.none;cron.none /var/log/messages

    除了mail、authprive、cron以外的日志类型的info以上级别的日志都会记录到/var/log/messages

  • authpriv.* /var/log/secure

    认证相关的信息都写入/var/log/secure

  • mail.* -/var/log/maillog

    邮件相关的日志都写入/var/log/maillog

  • cron.* /var/log/cron

    计划任务相关的日志都写入/var/log/cron

  • *.emerg :omusrmsg:*

    无论是何种类型的日志,只要是最严重的日志级别,都显示给所有登录的用户

  • uucp,news.crit /var/log/spooler

    uucp和news类别crit以上级别的日志写入/var/log/spooler

  • local7.* /var/log/boot.log

    本机启动时应当写入屏幕的信息写入/var/log/boot.log

mail.* -/var/log/maillog中-的用途是,mail来源的日志不直接写入日志文件,而是先写入内存,在积累到一定数量后再一次性写入日志文件,以提高写入性能。但这样做有个缺点,就是如果非正常关机等没来得及写入文件,就会导致数据丢失。可以对数量大,但不那么重要的日志采用这种方式记录。

自行增加日志

假如我们需要将所有来源的info以上级别的日志记录下来:

[root@xyz etc]# cp rsyslog.conf rsyslog.conf.bak
[root@xyz etc]# vim rsyslog.conf
[root@xyz etc]# diff rsyslog.conf rsyslog.conf.bak
75,76d74
< # Save all info log
< *.info                                                        /var/log/admin.log
[root@xyz etc]# systemctl restart rsyslog.service
[root@xyz etc]# ll /var/log | grep admin
-rw-------. 1 root   root       766 9月   4 15:12 admin.log

日志文件的安全性设置

如果我们使用vim或者其他编辑器直接编辑日志文件,并保存,可能会导致rsyslogd服务进程无法继续将日志数据写入该文件,必须要重新启动rsyslog.service服务才行。

这可能是一种保护措施,因为日志写入显然是要长期占据该文件的资源锁的。

对于这种问题,我们可以使用在Linux 之旅 4:文件与目录管理中提到的文件的隐藏属性来保护日志文件,让日志文件只能追加数据,不能修改和删除数据。这样就可以杜绝上边的问题出现:

[root@xyz etc]# ll -a /var/log | grep admin
-rw-------.  1 root   root      1022 9月   4 15:20 admin.log
[root@xyz etc]# chattr +a /var/log/admin.log
[root@xyz etc]# lsattr /var/log/admin.log
-----a---------- /var/log/admin.log

似乎这么做很棒,不过这会带来一个新的问题,即如果使用logrotate之类的日志归档程序,可能会因为特殊属性a的存在无法分割和重命名原始日志文件。在之后我们会讨论如何处理这个问题,现在先去除a属性:

[root@xyz etc]# chattr -a /var/log/admin.log
[root@xyz etc]# lsattr /var/log/admin.log
---------------- /var/log/admin.log

日志文件服务器

我们之前说过,不仅可以使用本地日志文件作为载体来记录日志,还可以将日志上传到日志服务器。事实上CentOS 7.X默认就支持日志服务器的相关功能,只不过没有启用。如果Linux主机开启相关功能,当作日志服务器使用,将会监听TCP或UDP的514端口。

如果要当作日志服务器使用,在Server端的Linux主机中,需要按如下的方式修改/etc/rsyslog.conf:

[root@xyz etc]# cp /etc/rsyslog.conf /tmp/rsyslog.conf.server
[root@xyz etc]# vim /tmp/rsyslog.conf.server
[root@xyz etc]# diff /tmp/rsyslog.conf.server /etc/rsyslog.conf
19,20c19,20
< $ModLoad imtcp
< $InputTCPServerRun 514
---
> #$ModLoad imtcp
> #$InputTCPServerRun 514

为了不影响当前配置,这里在rsyslog.conf的备份中修改,实际使用中应当直接修改rsyslog.conf。

之后再使用systemctl restart rsyslog.service重启服务,并使用netstat命令查看端口是否已被监听即可。

这里InputTCPServerRun是启用TCP/514端口,此外也支持使用UDP协议,不过一般而言TCP协议比UDP在传输数据上要稳定一些。

在Client端,应当按如下方式设置rsyslog.conf:

[root@xyz etc]# cp /etc/rsyslog.conf /tmp/rsyslog.conf.client
[root@xyz etc]# vim /tmp/rsyslog.conf.client
[root@xyz etc]# diff /tmp/rsyslog.conf.client /etc/rsyslog.conf
78,81d77
< # save all log to server
< *.*                                                   @@192.168.1.105
< #*.*                                                  @192.168.1.105
<

如果是采用TCP协议传输,使用@@192.168.1.105指定服务器,如果是UDP协议传输,则使用@192.168.1.105指定服务器。

同样的,设置完之后需要使用systemctl restart rsyslog.service重启服务。

日志文件归档

如果程序不持续改进和优化(重构),就可能会变成“屎山”。同样的,如果日志不定期处理,就会越堆越多,不仅难以查阅,还会因为单一文件过大而影响到新的日志写入效率。

logrotate就是一个不错的日志处理程序,准确的说是对日志进行“归档”之类的工作。

rotate一词的意思是轮转,这很形象地形容了logrotate这个工具的工作原理。

事实上logrotate是挂在cron配置目录cron.daily下面的,所以会被cron每天执行一次:

[root@xyz etc]# ll /etc/cron.daily/
总用量 12
-rwx------. 1 root root 219 4月   1 2020 logrotate
-rwxr-xr-x. 1 root root 618 10月 30 2018 man-db.cron
-rwx------. 1 root root 208 4月  11 2018 mlocate

logrotate

工作原理

logrotate的工作方式可以用下图表示:

登錄檔進行 logrotate 的結果

图源:鸟哥的私房菜

可以看到,整个过程就像是旋转木马一样,将刚产生的日志逐渐“转向”远处的位置,腾出位置给新的日志。和旋转木马不同的是老的日志文件会一直转向远处,直到被删除,而不会被转回来。

大概这就是所谓的rotate(轮转)了吧。

在老的Linux版本中,因为老式电脑的磁盘空间有限,所以“轮转”过程中会将历史日志用log.1、log.2、log.3这样的方式用数字标记,并且设定当产生的日志的数字编号超过一个值时,会将其删除以节省磁盘空间。

但是现在的电脑的磁盘空间越来越大,存储设备的成本也在逐渐降低,所以新的Linux版本中的logrotate程序提供了以日志作为标记的历史日志命名方式,如果采用这种方式来进行“轮转”,就不会删除历史日志。

配置文件

logrotate的主配置文件是/etc/logrotate.conf:

[root@xyz etc]# cat /etc/logrotate.conf | grep include
include /etc/logrotate.d

这里边有一行配置是include /etc/logrotate.d,其用途类似于编程语言中的include作用,可以将指定目录(这里是/etc/logrotate.d)下的其它配置文件加载进来。

所以除了主配置文件,/etc/logrotate.d目录下的配置文件同样有效。

下面详细分析logrotate的主配置文件:

[root@xyz etc]# cat /etc/logrotate.conf | grep -v '^#' | grep -v '^$'
weekly # 多久会执行一次“轮转”,这里设置的是每周一次
rotate 4 # 轮转后会保留几个历史日志文件,这里是4,也就是说轮转后会删除编号为5的历史日志
create # 轮转后创建新的空白日志
dateext # 使用日期而非数字编号作为历史日志的标识进行轮转
include /etc/logrotate.d # 加载/etc/logrotate.d目录下的配置文件
/var/log/wtmp { # 对/var/log/wtmp日志的特殊设置
    monthly # 每月进行一次轮转
    create 0664 root utmp # 创建的新的空白日志权限为0664,用户为root,用户组为utmp
        minsize 1M # 原始日志文件超过1M大小才进行轮转
    rotate 1 # 仅保留1个历史日志文件
}
/var/log/btmp { # 对/var/log/btmp日志的特殊设置
    missingok # 日志轮转期间任何错误都会被忽略
    monthly # 每月进行一次轮转
    create 0600 root utmp # 创建的新日志文件权限为0600,用户为root,用户组为utmp
    rotate 1 # 仅保留1个历史日志文件
}

如果配置过大,需要压缩,还可以使用compress这个设置。

像默认的主配置文件中展示的那样,如果我们需要针对特别的日志文件的轮转进行特别的设置,可以使用下面的方式进行配置以覆盖默认设置:

日志文件路径{
    特殊设置
}

下面进行举例说明:

[root@xyz etc]# cat /etc/logrotate.d/syslog
/var/log/cron
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
{
    missingok
    sharedscripts
    postrotate
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}

/etc/logrotate.d/syslog同样是一个默认的logrotate配置,主要用于处理syslog产生的相关日志。

比较特别的是,这里加入了一个postrotate...endscript设置,在这个“语句块”中,可以实现在轮转后执行相应的shell命令。这里postrotate和endscript需要成对出现,且独占一行。如果要在轮赚钱执行shell命令,可以使用prerotate..endscript的设置。

此外sharedscripts设置是指postrotate和prerotate执行的shell脚本是否为所有日志“共享的”,也就是说只要设置了sharedscripts,则同一个{}中的postrotate和prerotate所设置的shell脚本,将在所有轮转执行前和执行后触发,否则将会在具体的日志轮转前后触发。

需要注意的是,如果涉及的日志文件不需要执行轮转(比如已经存在当前日期为标识的历史日志),就不会执行相应的prerotate和postrotate相关的命令。

所以上边syslog配置文件中/bin/kill命令会在所有日志文件的轮询处理完毕后,一次性执行。这样做是因为轮询会移动原始日志文件,并生成新的日志文件,这样会导致rsyslogd无法继续写入日志数据,所以需要重新启动rsyslogd服务进程。

之前我们有说过为了保护日志文件,可以给日志文件添加上隐藏属性a,但是这样就不能使用logrotate进行轮转了,但我们如果在logrotate的配置文件中添加上在轮转前取消隐藏属性,在轮转后添加隐藏属性的shell命令调用逻辑,就可以完美解决这个问题:

[root@xyz etc]# vim /etc/logrotate.d/syslog
[root@xyz etc]# cat /etc/logrotate.d/syslog
/var/log/cron
/var/log/maillog
/var/log/secure
/var/log/spooler
{
    missingok
    sharedscripts
    postrotate
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}
/var/log/messages
{
    missingok
    prerotate
        chattr -a /var/log/messages
    endscript
    postrotate
        chattr +a /var/log/messages
    endscript
}

因为隐藏属性的修改仅影响/var/log/messages这一个日志文件的轮询操作,所以这里没有设置为sharedscripts。

实际测试

之前我们说了,logrotate是挂在cron相关配置目录下的,每天都会被执行,但如果需要手动执行,可以:

[root@xyz etc]# logrotate -v /etc/logrotate.conf
reading config file /etc/logrotate.conf
including /etc/logrotate.d
reading config file bootlog
...省略
rotating pattern: /var/log/btmp  monthly (1 rotations)
empty log files are rotated, old logs are removed
considering log /var/log/btmp
  log does not need rotating (log has been rotated at 2021-9-1 12:50, that is not month ago yet)
set default create context

-v参数会输出执行过程。因为每天都被cron自动执行了,所以当前显然是不需要执行乱转的,所以输出的内容大多数都是don't need rotating。

此时我们可以强制执行轮转操作:

[root@xyz etc]# logrotate -vf /etc/logrotate.conf
reading config file /etc/logrotate.conf
including /etc/logrotate.d
reading config file bootlog
reading config file chrony
reading config file cups
reading config file firewalld
...省略
renaming /var/log/btmp to /var/log/btmp-20210904
creating new /var/log/btmp mode = 0600 uid = 0 gid = 22
removing old log /var/log/btmp-20210901
set default create context

-f可以强制执行轮转,无论配置文件中设置的轮转间隔时间和日志文件大小有没有达到标准,都会执行轮转操作。

现在查看messges相关日志:

[root@xyz etc]# ll /var/log/messages*
-rw-------. 1 root root       0 9月   4 17:17 /var/log/messages
-rw-------. 1 root root 1533626 8月  22 10:30 /var/log/messages-20210822
-rw-------. 1 root root  849155 8月  29 12:50 /var/log/messages-20210829
-rw-------. 1 root root  953501 9月   4 16:40 /var/log/messages-20210903
-rw-------. 1 root root     963 9月   4 17:11 /var/log/messages-20210904
[root@xyz etc]# lsattr /var/log/messages
-----a---------- /var/log/messages

可以看到不但产生了新的日志,也执行了chattr相关命令,新产生的日志文件同样受到隐藏属性a的保护。

自定义日志文件的轮转

我们之前通过修改rsyslog的配置文件,产生了一个自定义日志文件admin.log:

[root@xyz etc]# ll /var/log | grep admin
-rw-------. 1 root   root      5597 9月   4 17:20 admin.log

现在创建一个logrotate的配置文件来处理这个日志:

[root@xyz etc]# vim /etc/logrotate.d/admin
[root@xyz etc]# cat /etc/logrotate.d/admin
/var/log/admin.log
{
    missingok
    monthly
    size=10M
    rotate 5
    compress
    prerotate
        chattr -a /var/log/admin.log
    endscript
    postrotate
        chattr +a /var/log/admin.log
    endscript
}
[root@xyz etc]# chattr +a /var/log/admin.log
[root@xyz etc]# lsattr /var/log/admin.log
-----a---------- /var/log/admin.log

测试:

[root@xyz etc]# logrotate -vf /etc/logrotate.conf
reading config file /etc/logrotate.conf
including /etc/logrotate.d
reading config file admin
reading config file bootlog
reading config file chrony
reading config file cups
...省略
[root@xyz etc]# ll /var/log | grep admin
-rw-------. 1 root   root         0 9月   4 17:35 admin.log
-rw-------. 1 root   root       920 9月   4 17:30 admin.log-20210904.gz
[root@xyz etc]# lsattr /var/log/admin.log
-----a---------- /var/log/admin.log

system-journald.service

system-hournald.service是一个由systemd启动的服务,专门用于记录开机后内核产生的日志。其产生的日志信息也都记录在内存而非磁盘中。

因为在内存中,所以系统重启后上次记录的内容就会丢失,仅保留当次系统启动的相关信息。

事实上rsyslogd服务进程处理的所有日志都是来自于system-hournald.service产生的日志,可以看做是干了日志分析和分发的工作,将后者产生的“大杂烩”式日志进行了梳理和分门别类的存储。

查看登录信息

可以使用journalctl命令可以查看system-journald服务产生的日志:

[root@xyz etc]# journalctl
-- Logs begin at 五 2021-09-03 19:55:08 CST, end at 六 2021-09-04 17:50:01 CST. --
9月 03 19:55:08 xyz.icexmoon.centos systemd-journal[89]: Runtime journal is using 6.0M (max allowed 48.6M, trying to leave 72.9M free
9月 03 19:55:08 xyz.icexmoon.centos kernel: Initializing cgroup subsys cpuset
9月 03 19:55:08 xyz.icexmoon.centos kernel: Initializing cgroup subsys cpu
9月 03 19:55:08 xyz.icexmoon.centos kernel: Initializing cgroup subsys cpuacct
9月 03 19:55:08 xyz.icexmoon.centos kernel: Linux version 3.10.0-1160.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.
9月 03 19:55:08 xyz.icexmoon.centos kernel: Command line: BOOT_IMAGE=/vmlinuz-3.10.0-1160.el7.x86_64 root=/dev/mapper/centos-root ro
9月 03 19:55:08 xyz.icexmoon.centos kernel: Disabled fast string operations
。。。省略

如果要仅显示某天的日志:

[root@xyz etc]# journalctl --since='2021-09-03 00:00:00' --until='2021-09-04 00:00:00'
-- Logs begin at 五 2021-09-03 19:55:08 CST, end at 六 2021-09-04 18:01:01 CST. --
9月 03 19:55:08 xyz.icexmoon.centos systemd-journal[89]: Runtime journal is using 6.0M (max allowed 48.6M, trying to leave 72.9M free
9月 03 19:55:08 xyz.icexmoon.centos kernel: Initializing cgroup subsys cpuset
9月 03 19:55:08 xyz.icexmoon.centos kernel: Initializing cgroup subsys cpu
9月 03 19:55:08 xyz.icexmoon.centos kernel: Initializing cgroup subsys cpuacct
。。。省略

如果要查看今天的日志:

[root@xyz etc]# journalctl --since=today
-- Logs begin at 五 2021-09-03 19:55:08 CST, end at 六 2021-09-04 18:01:01 CST. --
9月 04 10:51:18 xyz.icexmoon.centos kernel: usb 2-2.1: new full-speed USB device number 5 using uhci_hcd
9月 04 10:51:18 xyz.icexmoon.centos systemd[1]: Time has been changed
9月 04 10:51:19 xyz.icexmoon.centos dnsmasq[1541]: no servers found in /etc/resolv.conf, will retry
9月 04 10:51:19 xyz.icexmoon.centos kernel: usb 2-2.1: New USB device found, idVendor=0e0f, idProduct=0008, bcdDevice= 1.00
9月 04 10:51:19 xyz.icexmoon.centos kernel: usb 2-2.1: New USB device strings: Mfr=1, Product=2
...省略

如果要查看昨天的日志:

[root@xyz etc]# journalctl --since=yesterday --until=today
-- Logs begin at 五 2021-09-03 19:55:08 CST, end at 六 2021-09-04 18:01:01 CST. --
9月 03 19:55:08 xyz.icexmoon.centos systemd-journal[89]: Runtime journal is using 6.0M (max allowed 48.6M, trying to leave 72.9M free
9月 03 19:55:08 xyz.icexmoon.centos kernel: Initializing cgroup subsys cpuset
9月 03 19:55:08 xyz.icexmoon.centos kernel: Initializing cgroup subsys cpu
9月 03 19:55:08 xyz.icexmoon.centos kernel: Initializing cgroup subsys cpuacct
9月 03 19:55:08 xyz.icexmoon.centos kernel: Linux version 3.10.0-1160.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.
9月 03 19:55:08 xyz.icexmoon.centos kernel: Command line: BOOT_IMAGE=/vmlinuz-3.1
...省略

如果要查看某个服务相关的最近的n条记录,可以:

[root@xyz etc]# journalctl _SYSTEMD_UNIT=crond.service -n 10
-- Logs begin at 五 2021-09-03 19:55:08 CST, end at 六 2021-09-04 18:01:01 CST. --
9月 03 19:55:46 xyz.icexmoon.centos crond[1272]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 79% if used.)
9月 03 19:56:04 xyz.icexmoon.centos crond[1272]: (CRON) INFO (running with inotify support)

如果要查看具体某些命令相关的日志:

[root@xyz etc]# journalctl _COMM=su _COMM=login -n 10
-- Logs begin at 五 2021-09-03 19:55:08 CST, end at 六 2021-09-04 18:01:01 CST. --
9月 04 10:56:59 xyz.icexmoon.centos su[3604]: (to root) icexmoon on pts/0
9月 04 10:56:59 xyz.icexmoon.centos su[3604]: pam_unix(su-l:session): session opened for user root by icexmoon(uid=1000)

如果要查看某些指定日志级别的日志:

[root@xyz etc]# journalctl -p err
-- Logs begin at 五 2021-09-03 19:55:08 CST, end at 六 2021-09-04 18:01:01 CST. --
9月 03 19:55:14 xyz.icexmoon.centos kernel: sd 0:0:0:0: [sda] Assuming drive cache: write through
9月 03 19:55:24 xyz.icexmoon.centos kernel: piix4_smbus 0000:00:07.3: SMBus Host Controller not enabled!
9月 03 19:55:33 xyz.icexmoon.centos systemd[1]: Failed to start Software RAID monitoring and management.
9月 03 19:55:46 xyz.icexmoon.centos systemd[1]: Failed to start Crash recovery kerne
...省略

如果要查看某些日志类型(facility)的日志:

[root@xyz etc]# journalctl SYSLOG_FACILITY=4 SYSLOG_FACILITY=10 -n 10
-- Logs begin at 五 2021-09-03 19:55:08 CST, end at 六 2021-09-04 18:10:01 CST. --
9月 03 20:40:20 xyz.icexmoon.centos dbus[766]: [system] Rejected send message, 1 matched rules; type="error", sender=":1.85" (uid=100
9月 03 20:40:20 xyz.icexmoon.centos dbus[766]: [system] Rejected send message, 1 matched rules; type="error", sender=":1.85" (uid=100
9月 03 20:40:20 xyz.icexmoon.centos dbus[766]: [system] Rejected send message, 1 matched rules; type="error", sender=":1.85" (uid=100
9月 04 10:51:54 xyz.icexmoon.centos sshd[3461]: Accepted password for icexmoon from 192.168.1.6 port 12950 ssh2
9月 04 10:51:55 xyz.icexmoon.centos sshd[3461]: pam_unix(sshd:session): session opened for user icexmoon by (uid=0)
9月 04 10:51:55 xyz.icexmoon.centos systemd-logind[750]: New session 10 of user icexmoon.
9月 04 10:56:59 xyz.icexmoon.centos su[3604]: (to root) icexmoon on pts/0
9月 04 10:56:59 xyz.icexmoon.centos su[3604]: pam_unix(su-l:session): session opened for user root by icexmoon(uid=1000)
9月 04 15:12:03 xyz.icexmoon.centos polkitd[760]: Registered Authentication Agent for unix-process:5659:1050988 (system bus name :1.1
9月 04 15:12:03 xyz.icexmoon.centos polkitd[760]: Unregistered Authentication Agent for unix-process:5659:1050988 (system bus name :1

如果要持续地查看产生的日志:

[root@xyz etc]# journalctl -f
-- Logs begin at 五 2021-09-03 19:55:08 CST. --
...省略
9月 04 18:14:55 xyz.icexmoon.centos sshd[8435]: Accepted password for icexmoon from 192.168.1.6 port 1529 ssh2
9月 04 18:14:56 xyz.icexmoon.centos systemd[1]: Started Session 56 of user icexmoon.
9月 04 18:14:56 xyz.icexmoon.centos sshd[8435]: pam_unix(sshd:session): session opened for user icexmoon by (uid=0)
9月 04 18:14:56 xyz.icexmoon.centos systemd-logind[750]: New session 56 of user icexmoon.
9月 04 18:14:56 xyz.icexmoon.centos dbus[766]: [system] Activating service name='org.freedesktop.problems' (using servicehelper)
9月 04 18:14:56 xyz.icexmoon.centos dbus[766]: [system] Successfully activated service 'org.freedesktop.problems'

如果此时通过一个新的ssh登录Linux主机,就可以看到相关的登录行为产生的日志。

logger

logger命令用于向Linux内核的syslog写入日志:

[root@xyz etc]# logger -p user.info 'test the logger command'
[root@xyz etc]# journalctl SYSLOG_FACILITY=1 -n 3
-- Logs begin at 五 2021-09-03 19:55:08 CST, end at 六 2021-09-04 18:18:29 CST. --
9月 03 20:39:59 xyz.icexmoon.centos spice-vdagent[2970]: Cannot access vdagent virtio channel /dev/virtio-ports/com.redhat.spice.0
9月 03 20:40:03 xyz.icexmoon.centos spice-streaming-agent[3023]: Failed to open the streaming device "/dev/virtio-ports/org.spice-spa
9月 04 18:18:29 xyz.icexmoon.centos icexmoon[8523]: test the logger command

我们可以利用这个命令在自己编写的shell脚本中向系统写入日志:

[root@xyz etc]# vim ~icexmoon/backup_system.sh
[root@xyz etc]# cat ~icexmoon/backup_system.sh
#!/bin/bash
# backup system
if [ "${1}" == 'log' ]
then
        logger -p syslog.info 'backup.sh is running'
fi
backup_dir='/etc /home /root /var/lib /var/spool/{cron,at,mail}'
backup_file="/backups/backup-system-$(date +%Y-%m-%d).tar.gz"
if [ ! -d /backups ]
then
        mkdir /backups
fi
if [ ! -f $backup_file ]
then
        tar -czvf $backup_file $backup_dir > /backups/backup-system.log 2>&1
fi
if [ "${1}" == 'log' ]
then
        logger -p syslog.info 'backup.sh is finished'
fi
exit 0
[root@xyz etc]# ~icexmoon/backup_system.sh log
[root@xyz etc]# journalctl SYSLOG_FACILITY=5 -n 3
-- Logs begin at 五 2021-09-03 19:55:08 CST, end at 六 2021-09-04 18:30:47 CST. --
9月 04 17:48:01 xyz.icexmoon.centos rsyslogd[5669]:  [origin software="rsyslogd" swVersion="8.24.0-55.el7" x-pid="5669" x-info="http:
9月 04 18:30:47 xyz.icexmoon.centos icexmoon[8743]: backup.sh is running
9月 04 18:30:47 xyz.icexmoon.centos icexmoon[8745]: backup.sh is finished

持久化 joural 日志

之前说过了system-jourald.service产生的日志都会在系统重启后消失,虽然事实上这些日志都会经由rsyslogd服务处理并分门别类进行保存,但如果你更喜欢使用jounalctl命令查看日志,就可以考虑改变system-journald.service的日志保存方式,让其持久化保存:

​
# 1. 先處理所需要的目錄與相關權限設定
[root@study ~]# mkdir /var/log/journal
[root@study ~]# chown root:systemd-journal /var/log/journal
[root@study ~]# chmod 2775 /var/log/journal
​
# 2. 重新啟動 systemd-journald 並且觀察備份的日誌資料!
[root@study ~]# systemctl restart systemd-journald.service
[root@study ~]# ll /var/log/journal/
drwxr-sr-x. 2 root systemd-journal 27 Aug 20 02:37 309eb890d09f440681f596543d95ec7a

这里没有在我的虚拟机实际操作,直接拷贝了鸟哥的示例,因为个人觉得这么做的意义不大,且可能会拖累Linux主机的性能。

分析日志文件

通过分析日志文件,可以让我们了解很多事情,比如Linux主机有没有被人入侵等。

但是,如果是人工分析,那将会是一件非常痛苦的事情,有没有程序帮助我们做这些事情呢?答案当然是有的。

logwatch

CentOS 本身提供一个日志分析工具logwatch,可以每天分析一次日志,并将分析报告用邮件的方式告知root用户。

CentOS默认没有安装logwatch,需要我们手动安装:

[root@xyz ~]# yum install logwatch
已加载插件:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 ...省略

logwatch会自动安装到cron的相关配置目录下:

[root@xyz ~]# ll /etc/cron.daily
总用量 16
-rwxr-xr-x. 1 root root 434 8月  16 2018 0logwatch
-rwx------. 1 root root 219 4月   1 2020 logrotate
-rwxr-xr-x. 1 root root 618 10月 30 2018 man-db.cron
-rwx------. 1 root root 208 4月  11 2018 mlocate

这样每天就会自动发送日志分析报告了,如果要立即手动运行:

[root@xyz ~]# /etc/cron.daily/0logwatch

然后就可以使用邮箱查看分析报告了:

[root@xyz ~]# mail
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/root": 4 messages 1 new
    1 user@localhost.icexm  Mon Aug  9 16:42 2180/148073 "[abrt] kernel: WARNING: CPU: 0 PID: 2640 at drivers/scsi/scsi_lib.c:2857"
    2 pro1@xyz.icexmoon.ce  Sat Aug 21 16:41  17/688   "*** SECURITY information for xyz.icexmoon.centos ***"
    3 root                  Wed Aug 25 16:01  21/627   "test at"
>N  4 logwatch@xyz.icexmoo  Sat Sep  4 19:57 129/4416  "Logwatch for xyz.icexmoon.centos (Linux)"
& 4
Message  4:
From root@xyz.icexmoon.centos  Sat Sep  4 19:57:42 2021
Return-Path: <root@xyz.icexmoon.centos>
X-Original-To: root
Delivered-To: root@xyz.icexmoon.centos
To: root@xyz.icexmoon.centos
From: logwatch@xyz.icexmoon.centos
Subject: Logwatch for xyz.icexmoon.centos (Linux)
Auto-Submitted: auto-generated
Precedence: bulk
...省略

鸟哥的日志分析工具

《鸟哥的私房菜》作者提供了一个日志分析工具:

[root@xyz ~]# cd ~icexmoon/
[root@xyz icexmoon]# wget http://linux.vbird.org/linux_basic/0570syslog/logfile_centos7.tar.gz
--2021-09-04 20:06:19--  http://linux.vbird.org/linux_basic/0570syslog/logfile_centos7.tar.gz
正在解析主机 linux.vbird.org (linux.vbird.org)... 140.116.44.180
正在连接 linux.vbird.org (linux.vbird.org)|140.116.44.180|:80... 已连接。
...省略
[root@xyz icexmoon]# tar -xzvf logfile_centos7.tar.gz -C /
etc/cron.d/vbirdlogfile
root/bin/logfile/
root/bin/logfile/function/
root/bin/logfile/function/samba
...省略
[root@xyz icexmoon]# cat /etc/cron.d/vbirdlogfile
10 0 * * * root /bin/bash /root/bin/logfile/logfile.sh &> /dev/null
[root@xyz icexmoon]# sh /root/bin/logfile/logfile.sh
/sbin/restorecon:  Warning no default label for /dev/shm/logfile/logfile_mail.txt
grep: /etc/postfix/body_checks: No such file or directory
cat: /dev/shm/logfile//postlog.1: No such file or directory
[root@xyz icexmoon]# mail

以上就是系统日志部分的全部内容,谢谢阅读。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: Linux syslog 系统日志
最后更新:2021年9月4日

魔芋红茶

加一点PHP,加一点Go,加一点Python......

点赞
< 上一篇
下一篇 >

文章评论

取消回复

*

code

COPYRIGHT © 2021 icexmoon.cn. ALL RIGHTS RESERVED.
本网站由提供CDN加速/云存储服务

Theme Kratos Made By Seaton Jiang

宁ICP备2021001508号

宁公网安备64040202000141号