Linux 日志系统
1. 实验介绍
1.1 实验内容
日志数据可以是有价值的信息宝库,也可以是毫无价值的数据泥潭。它可以记录下系统产生的所有行为,并按照某种规范表达出来。我们可以使用日志系统所记录的信息为系统进行排错,优化系统的性能,或者根据这些信息调整系统的行为。收集你想要的数据,分析出有价值的信息,可以提高系统、产品的安全性,还可以帮助开发完善代码,优化产品。日志会成为在事故发生后查明“发生了什么”的一个很好的“取证”信息来源。日志可以为审计进行审计跟踪。
1.2 实验知识点
- 日志文件
- rsyslog 系统日志
- 日志文件的转储
1.3 推荐阅读
2. 日志文件
2.1 常见日志文件
注意开头的 $ 符号不用输入。
$ sudo service rsyslog start
$ ll /var/log
常见日志文件
日志名称 | 信息说明 |
---|---|
alternatives.log | 系统的更新替代信息 |
apport.log | 应用程序崩溃信息记录 |
apt/history.log | 使用 apt-get 时的具体操作 |
auth.log | 登录认证的 log 信息 |
boot.log | 系统启动时的日志信息 |
btmp | 记录所有失败启动信息 |
dmesg | 内核缓冲信息,在系统启动时,显示屏幕上的与硬件有关的信息 |
dpkg.log | 安装或 dpkg 命令清除软件包的日志 |
kern.log | 内核产生的日志,有助于在定制内核时解决问题 |
lastlog | 记录所有用户的最近信息。这不是一个 ASCII 文件,因此需要用 lastlog 命令查看内容 |
faillog | 用户登录失败信息。此外,错误登录命令也会记录在本文件中 |
wtmp | 包含登录信息。使用 wtmp 可以找出谁正在登录进入系统,谁使用命令显示这个文件或信息等 |
syslog | 系统信息记录 |
apt/term.log | 使用 apt-get 时的具体操作 |
注:本实验环境中没有 apport.log 是因为 apport 这个应用程序需要读取一些内核的信息来收集判断其他应用程序的信息,从而记录应用程序的崩溃信息。而在本实验环境中的我们没有这个权限,所以将 apport 从内置应用值剔除,自然而然就没有它的日志信息了。
2.2 日志格式
日志内容的一般格式
- 事件发生的时间
- 发生的主机名
- 启动的服务名称
- 实际信息内容
我们通过 cat 命令来查看一下几个常见日志文件的格式:
$ cat /var/log/alternatives.log
update-alternatives 2016-08-18 18:03:40: run with --quiet --install /usr/bin/c++ c++ /usr/bin/clang++ 10
update-alternatives 2016-08-18 18:03:40: run with --quiet --install /usr/bin/cc cc /usr/bin/clang 10
......
从 alternatives.log 中得到信息有程序作用,日期,命令,成功与否的返回码等信息。
$ cat /var/log/dpkg.log
2016-08-18 18:02:10 startup archives unpack
2016-08-18 18:02:12 install gcc-6-base:amd64 <none> 6.1.1-3ubuntu11~14.0
4.1
2016-08-18 18:02:12 status half-installed gcc-6-base:amd64 6.1.1-3ubuntu
11~14.04.1
2016-08-18 18:02:12 status unpacked gcc-6-base:amd64 6.1.1-3ubuntu11~14.
04.1
2016-08-18 18:02:12 status unpacked gcc-6-base:amd64 6.1.1-3ubuntu11~14.
04.1
2016-08-18 18:02:13 startup packages configure
......
从 dpkg.log 文件中可以知道 dpkg 命令安装或清除软件包的时间、安装包版本等日志信息。
在 apt 文件夹中的日志信息,其中有两个日志文件 history.log 与 term.log,两个日志文件的区别在于 history.log 主要记录了进行了什么操作,相关的依赖有哪些,而 term.log 则是较为具体的一些操作,主要就是下载包,打开包,安装包等等的细节操作。
先来看 history.log 文件:
$ cat /var/log/apt/history.log
Start-Date: 2016-08-18 18:02:09
Commandline: apt-get install -y --force-yes --no-install-recommends gcc-
4.9 gcc-5 g++-4.9 g++-5 clang-3.4 python3-pip libicu-dev python3.5 tree
Install: libisl15:amd64 (0.15-3~14.04, automatic),
......
libitm1:amd64 (4.8.4-
2ubuntu1~14.04.3, 6.1.1-3ubuntu11~14.04.1), gcc-4.9-base:amd64 (4.9.3-0u
buntu4, 4.9.3-8ubuntu2~14.04)
End-Date: 2016-08-18 18:03:48
从 apt/history.log 中能够知道一些历史信息。由于本实验环境是刚启动的环境,所以日志中的信除了环境的一些历史信息以外就没有其他信息。
然后来看 term.log 文件:
$ sudo cat /var/log/apt/term.log
Log started:2016-08-18 18:02:09
Log ended:2016-08-18 18:03:48
也是除了环境安装的历史信息,没有其他任何日志信息。
我们可以试着安装一个软件包测试一下
$ sudo apt-get install figlet
查看历史日志,可以看到最后出现了安装软件的历史日志记录了:
$ less /var/log/apt/history.log
同样,查看 term.log 文件也能到
$ sudo less /var/log/apt/term.log
像上面几个日志的格式内容大部分都是时间,操作这样。不过还有有两个比较特殊的日志,它们的查看的方式也比较与众不同,因为这连个日志并不是 ASCII 文件 而是被编码成了 二进制文件,所以不能直接使用 less、cat、more 这样的工具命令来查看,这两个日志文件是 wtmp,lastlog。
查看的方法是使用 last 和 lastlog 工具来提取其中的信息。
- last
$ last
- lastlog
$ lastlog --help
用法:lastlog [选项]
选项:
-b, --before DAYS 仅打印早于 DAYS 的最近登录记录
-h, --help 显示此帮助信息并推出
-R, --root CHROOT_DIR chroot 到的目录
-t, --time DAYS 仅打印晚于 DAYS 的最近登录记录
-u, --user LOGIN 打印 LOGIN 用户的最近登录记录
$ last
$ lastlog -u shiyanlou
提示:lastlog 是查看用户以类似 ssh 方式登录的记录,而桌面这种方式并未统计,而途中的效果是使用字符界面操作得来,不切换至字符界面以 ssh localhost(密码在右边工具栏中的 SSH直连)方式登录自己也可以达到相同的效果。
3. rsyslog 系统日志
3.1 rsyslog 系统日志概述
日志产生的方式一般存在两种方式:
- 一种是由软件开发商自己来自定义日志格式指定输出日志位置;
- 一种方式就是 Linux 提供的日志服务程序,而我们这里系统日志是通过 syslog 来实现,提供日志管理服务。
syslog 是一个系统日志记录程序,在早期的大部分 Linux 发行版都是内置 syslog,让其作为系统的默认日志收集工具,较新的 Ubuntu,Fedora 等等都是默认使用 rsyslog 作为系统的日志收集工具。
rsyslog 的全称是 rocket-fast system for log,它提供了高性能,高安全功能和模块化设计。rsyslog 能够接受从各种各样的来源,将其输入、输出的结果到不同的目的地。
其默认的 rsyslog 配置文件是:
- /etc/rsyslog.conf 文件:该配置文件主要决定需要加载的模块、文件所属者等
- /etc/rsyslog.d/50-default.conf。该文件主要是配置 Filter Conditions,详细内容后续会涉及。)
3.2 reyslog 的结构框架
先通过一个简单的流程图来了解一下 rsyslog 的结构框架和数据流走向。
通过上面的图片可以看出 rsyslog 主要是由
- Input
- Output
- Parser
三个模块构成的。
其流程是首先通过 Input module 来收集消息,然后将得到的消息传给 Parser module,通过分析模块的层层处理,将真正需要的消息传给 Output module,然后便输出至日志文件中。
官方的 Rsyslog 架构如图中所示,rsyslog 还有一个核心的功能模块是 Queue,便是它的存在使得 rsyslog 高并发 优势的突出:
Input 模块: 主要功能就是从各种各样的来源收集 messages,通过这些接口实现:
接口名 | 作用 |
---|---|
im3195 | RFC3195 Input Module |
imfile | Text File Input Module |
imgssapi | GSSAPI Syslog Input Module |
imjournal | Systemd journal Input Module |
imklog | Kernel Log Input Module |
imkmsg | /dev/kmsg Log Input Module |
impstats | Generate Periodic Statistics of Internal Counters |
imptcp | Plain TCP Syslog |
imrelp | RELP Input Module |
imsolaris | Solaris Input Module |
imtcp | TCP Syslog Input Module |
imudp | UDP Syslog Input Module |
imuxsock | Unix Socket Input |
Output 模块,也有许多可用分的接口来实现。
Output 也被称为 actions。一个组操作内容都是预先加载的(比如输出文件编写器,几乎在每个 rsyslog.conf 中都使用)。
通过 action(type="type"…)对象调用一个动作。Type 是强制性的,并且必须包含要调用的插件的名称(例如 "omfile" 或 "ommongodb")。其他参数可能存在。他们的类型和使用取决于问题的输出插件。
补充:这些模块接口的都需要通过 $ModLoad 指令来加载,在下文中会为大家展示 /etc/rsyslog.conf 的内容,大家可以注意前两行,其意思就是默认加载了 imklog、imuxsock 这两个模块。
在配置中 rsyslog 支持三种配置语法格式:
- sysklogd
- legacy rsyslog
- RainerScript
sysklogd 是比较老的简单格式,一些新的语法特性不支持。
legacy rsyslog 是以 dollar 符($)开头的语法,在 v6 及以上的版本还支持,如上文所说的 $ModLoad 还有一些插件的特性只在此语法下支持。而以 $ 开头的指令是全局指令,全局指令是 rsyslogd 守护进程的配置指令,每行只能有一个指令。(解析公式失败)
RainnerScript 是最新的语法。在官网上 rsyslog 大多推荐这个语法格式来配置。
注:老的语法格式(sysklogd & legacy rsyslog)是以行为单位。新的语法格式(RainnerScript)可以分割多行。
注释有两种语法:
- 井号 #
- C-style /*..*/
执行顺序:指令在 rsyslog.conf 文件中是从上到下的顺序执行的。
对于 rsyslog 环境的配置文件想要深入了解的朋友可以参看一下 官方文档
3.3 配置文件内容
$ cat /etc/rsyslog.conf
3.4 rsyslog 系统日志的配置
3.4.1 查看系统中的配置
$ vim /etc/rsyslog.d/50-default.conf
配置文件格式说明
日志设备(类型).(连接符号)日志级别 日志处理方式
日志设备(类型)
设备 | 说明 |
---|---|
auth | pam 产生的日志 |
authpriv | ssh,ftp 等登录信息的验证信息,即权限系统 |
cron | 时间任务相关,计划安排 |
kern | 内核消息 |
lpr | 打印 |
邮件系统消息 | |
mark(syslog) | rsyslog 服务内部的信息,时间标识 |
news | 新闻组消息 |
user | 用户程序产生的相关信息 |
uucp | unix 主机之间相关的通讯 |
local 1~7 | 自定义的日志设备 |
日志级别
从上到下,日志级别由高到低,记录的信息越来越少。
priority取值 | 值 | 说明 |
---|---|---|
emerge | 0 | 发生严重事件,并有导致系统崩溃的潜在危险。报告软件或者硬件问题 |
alert | 1 | 严重错误消息,会导致程序关闭并可能影响其他程序 |
crit | 2 | 错误消息,可能会导致程序关闭的时间重 |
err | 3 | 程序中存在错误的通告 |
warning | 4 | 程序中存在潜在问题的警告消息 |
notice | 5 | 程序运行中产生了值得注意的事件 |
info | 6 | 关于程序当前状态的报告信息 |
debug | 7 | 编程人员或测试人员使用调试信息 |
注:基本上,info,notice,warn 这三个讯息都是在告知一些基本信息,应该还不至于造成一些系统运作困扰。
- 优先级(priority)可参照 syslog 命令手册
连接符号
- .xx:表示大于等于 xx 级别的信息
- .=xx:表示等于 xx 级别的信息
- .!xx:表示在 xx 之外的等级的信息
可以从上面的文件中看到几项系统配置:
# `auth` 与 `authpriv` 的所有优先级的信息全都输出于 `/var/log/auth.log` 日志中
auth,authpriv.* /var/log/auth.log
# kern 的所有优先级信息异步写入 /var/log/kern.log 日志中
kern.* -/var/log/kern.log
:q
(`- `代表异步写入,也就是说日志写入时不需要等待系统缓存的同步,即日志还在内存中缓存也可以继续写入无需等待完全写入硬盘后再写入。通常用于写入数据比较大时使用)
举例
通过命令行向日志文件写入信息:
# 首先将syslog启动起来
sudo service rsyslog start
# 向 syslog 写入数据
ping 127.0.0.1 | logger -it logger_test -p local3.notice &
# 查看是否有数据写入
sudo tail -f /var/log/syslog
按 ctrl + c 退出
从结果上可以看出已经成功的将 ping 的信息写入了 syslog 中,格式也就是使用的 rsyslog 的默认模板
4. 日志文件的转储
4.1 logrotate 管理日志文件
在本地的机器中每天都会有成百上千条日志被写入文件,而服务器中每天更是有数十兆甚至更多的日志信息被写入文件中,那么每天日志文件都会不断膨胀,就会占用许多的空间,这个时候 logrotate 的出现正好就解决了这样一个问题。
logrotate 程序是一个日志文件管理工具。用来把旧的日志文件删除,然后创建新的日志文件。可以根据日志文件的大小,也可以根据其天数来切割日志、管理日志,这个过程又叫做“转储”。
大多数 Linux 发行版使用 logrotate 或 newsyslog对日志进行管理。logrotate 程序不但可以压缩日志文件,减少存储空间,还可以将日志发送到指定 E-mail,方便管理员及时查看日志。
其中 logrotate 是基于 CRON 来运行的,脚本是 /etc/cron.daily/logrotate;同时配置文件在 /etc/logrotate.conf 和 /etc/logrotate.d 中找到。
首先,我们一起来看看 /etc/logrotate.conf 这个文件中的内容。
$ cat /etc/logrotate.conf
# see "man logrotate" for details //可以查看帮助文档
# rotate log files weekly
weekly //设置每周转储一次(daily、weekly、monthly当然可以使用这些参数每天、星期,月 )
# keep 4 weeks worth of backlogs
rotate 4 //最多转储4次
# create new (empty) log files after rotating old ones
create //当转储后文件不存在时创建它
# uncomment this if you want your log files compressed
compress //通过gzip压缩方式转储(nocompress可以不压缩)
# RPM packages drop log rotation information into this directory
include /etc/logrotate.d //其他日志文件的转储方式配置文件,包含在该目录下
# no packages own wtmp -- we'll rotate them here
/var/log/wtmp { //设置/var/log/wtmp日志文件的转储参数
monthly //每月转储
create 0664 root utmp //转储后文件不存在时创建它,文件所有者为root,所属组为utmp,对应的权限为0664
rotate 1 //最多转储一次
}
4.2 logrotate 日志转储
logrotate 的配置文件是 /etc/logrotate.conf,是一个只读文件,通常不需要对它进行修改。而日志文件的转储设置在独立的配置文件中,放在 /etc/logrotate.d/目录下。
我们先通过 cat 命令来简单查看一下实验环境中已经配置的一些文件。
$ ll /etc/logrotate.d/
$ cat /etc/logrotate.d/apt
$ cat /etc/logrotate.d/dpkg
我们再举一个例子来详细说明一下日志是怎么进行转储的。
首先创建一个日志文件,然后快速生成文件在其中填入一个 10MB 的随机比较流数据。
$ sudo touch /var/log/log-file
$ sudo chmod 777 /var/log/log-file
$ sudo head -c 10M </dev/urandom > /var/log/log-file
然后,我们为这个文件创建一个配置文件
$ sudo touch /etc/logrotate.d/log-file
$ sudo vim /etc/logrotate.d/log-file
/var/log/log-file {
monthly
rotate 5
compress
delaycompress
missingok
notifempty
postrotate
/usr/bin/killall -HUP rsyslogd
endscript
}
说明:
- monthly : 日志文件按月转储。可以换成 daily,weekly 或者 yearly 。
- rotate 5 : 一次转储 5 个归档日志。
- compress : 在转储任务完成后,已转储的日志将使用 gzip 进行压缩。
- delaycompress : 和 compress 选项一起使用,delaycompress 表示 logrotate 不会将最近的压缩,压缩将在下一次转储周期进行。
- missingok : 在日志转储的时候,任何错误将被忽略,例如“文件无法找到”之类的错误。
- notifempty : 如果日志文件为空,转储不会进行。
- create 644 root root : 以指定的权限创建全新的日志文件,同时 logrotate 也会重命名原始日志文件。
- postrotate/endscript : 在所有其它指令完成后,postrotate 和 endscript 里面指定的命令将被执行。rsyslogd 进程将立即再次读取其配置并继续运行。
上面的配置比较的全面,可以当做一个模板,在实际中的配置参数根据你的需求来进行调整。
例如,当文件满足 10M 就转储一个日志文件。
$ sudo vim /etc/logrotate.d/log-file
/var/log/log-file{
su root root
size=10M
rotate 5
create 644 root root
postrotate
/usr/bin/killall -HUP rsyslogd
endscript
}
在配置文件的开始部分 su root root 来指定进行转储的用户,否则会报错:“parent directory has insecure permissions (It's world writable or writable by group which is not "root") Set "su" directive in config file to tell logrotate which user/group should be used for rotation.”。
保存退出后,通过 logrotate 命令来调用日志。
注:编写的配置文件的权限必须为:-rw-r--r-- ,否则logrotate 就无法正常工作。执行时就会提示:Ignoring mosquitto because of bad filemode。
$ sudo su root
# logrotate -d /etc/logrotate.d/log-file
使用 -d 选项是以预演方式运行 logrotate。不用实际转储任何日志文件,可以模拟演练日志轮循并显示其输出。
注:即使轮循环条件没有满足,也可以通过使用 -f 选项来强制 logrotate 轮循日志文件,-v 参数提供了详细的输出。
下面我们对所有配置文件进行转储操作。并且通过输出日志信息查看错误日志信息等。
# logrotate /etc/logrotate.d/
通过 ll /var/log 来查看转储的情况
最后,大家可以使用 man logrotate 命令来查看具体的参数说明,如按文件大小转储,按当前时间格式命名等等参数配置。
5. 总结
通过本节实验我们了解了日志文件结构,以及常用的日志,通过对系统日志 rsyslog 的配置和使用 logrotate 来对日志进行转储操作,进一步加深对系统日志的运用的理解。