1 syslogd简介#
syslogd不仅仅是记录kernel log的服务,还能记录user space中的日志。
syslogd是Linux下的一个记录日志文件服务。新版本叫做rsyslogd。
syslogd有一系列的子服务,例如mail、auth、cron、kern等等,这些子服务提供日志记录的功能,。当程序要记录log时,可以直接调用这些子服务将日志记录到设定的地方。
syslogd是一个守护进程,配置这整个守护进程以及其子服务的地方就是/etc/syslog.conf这个文件。可以从https://www.rsyslog.com/doc/master/获取官方文档。
1.1 日志格式#
如果配置好并运行了 syslogd 或 klogd,一般所有 log的信息也会追加到 /var/log/messages
。并且kernel log信息被记录在/val/log/kern.log
。
可以看到基本日志格式包含以下四列:
- 事件产生的时间(Jan 1 08:00:09)
- 发生事件的服务器的主机名 (cvitek)
- 产生事件的服务名或程序名 (kernel or local5)
- 事件的具体信息(…cif a0c2000.cif:..)
当开启rsyslogd后,不能透过/proc/kmsg来查看kernel log。
1.2 /etc/syslog.conf服务配置#
- /etc/rsyslog.conf 是rsyslog服务的总配置文件
- /etc/rsyslog.d 该目录是单独配置的rsyslog配置文件
1.2.1 总配置/etc/syslog.conf#
rsyslog记录哪些日志,到底记录了什么样的日志,是通过这个/etc/rsyslog.conf
配置文件来决定的,先分析一下rsyslogd的总配置文件:
默认规则会定义在/etc/rsyslog.d/50-default.conf
中:
1 | ################# |
1.2.2 rsyslog规则(/etc/rsyslog.d/*.conf)#
rsyslog规则配置文件一般由以下3部分组成,每一行表示一个项目,格式为:facility.level action,分别表示日志类型,日志等级,日志输出路径。一般系统默认的规则定义在/etc/rsyslog.d/50-default.conf
:
一般所有日志类型都会被追加在/val/log/messages
。如:
1 | *.info;mail.none;authpriv.none;cron.none /var/log/messages |
1.2.2.1 facility-日志类型#
- kern: 内核信息
- user: 用户进程相关信息
- mail: 电子邮件相关信息
- Local0- local7: 为本地使用预留的服务
- daemon: 后台进程相关信息
- syslog: 系统日志信息
1.2.2.2 level-按严重程度由低到高排序#
- none: 没有重要级
- debug: 调试信息
- info: 打印的信息
- notice: 具有重要信息的普通条件
- warning: 警告信息
- err: 错误信息
- crit: 阻止某些工具或子系统功能实现的错误条件
- alert: 需要立即被修改的条件
- emerg: 该系统不可用
1.2.2.3 action-表示log保存的位置#
那下面我也抄过来一份比较全面的规则定义示例供大家参考:
1 | # 记录mail日志等级为error及以上日志 |
1.3 程序如何配置syslog子服务(自定义rsyslog规则)#
问题:进程如何发送消息给rsyslog守护进程,rsyslog守护进程是如何对各种日志区分开来的?
像/usr/sbin/sshd、/usr/bin/login、/usr/bin/su
这些进程,它们是调用一个叫syslog的系统调用, syslog系统调用是一个用于向rsyslog守护进程发送消息的的系统函数。/usr/sbin/sshd,/usr/bin/login、/usr/bin/su
这些进程专门执行登录验证时,它们在调用syslog系统函数会一般会传入LOG_AUTH
这个常量。
而/usr/bin/crond和/usr/bin/at
这些在调用syslog系统调用会传入LOG_CRON
这个常量(具体请看**syslog()**函数),日志归类规则如下:
所以如果用LOG_AUTH
的syslog()函数调用,那么会归类到了/val/log/secure
。
如果用LOG_CRON
的syslog()调用则归类到了/val/log/cron
。而kernel等其他log被记录在了/val/log/messages
中。
那么我们可以自定义规则如下:
1 | syslogfacility-text:表示facility日志类型 |
注意busybox要开启使能syslog.conf解析:/etc/syslog.conf
解析,CONFIG_FEATURE_SYSLOGD_CFG=y
2 syslog()函数#
用户空间也可以用syslog()函数来记录自己的进程的日志,所以用户进程可以自定义日志规则。
调用openlog是可选择的。如果不调用openlog,则在第一次调用syslog时,会自动调用openlog。
syslog的相关函数和宏定义一般在toolchain中都会有定义:
1 |
|
2.1 openlog函数#
第1个参数为ident,该参数常用来表示信息的来源。ident信息会被固定地添加在每行日志的前面:
第2个参数 option控制标志:
option控制标志 | 作用 |
---|---|
LOG_CONS | 如果将信息发送给syslogd守护进程时发生错误,直接将相关信息输出到终端 |
LOG_PID | 每条日志信息中都包括进程号 |
第3个参数为facility:
facility参数 | syslog.conf中对应的facility取值 |
---|---|
LOG_KERN | kern |
LOG_USER | user |
LOG_MAIL | |
LOG_DAEMON | daemon |
LOG_AUTH | auth |
LOG_SYSLOG | syslog |
LOG_LPR | lpr |
LOG_NEWS | news |
LOG_UUCP | uucp |
LOG_CRON | cron |
LOG_AUTHPRIV | authpriv |
LOG_FTP | ftp |
LOG_LOCAL0~LOG_LOCAL7 | local0~local7 |
2.2 syslog函数#
第一个参数priority表示日志级别:
priority参数 | syslog.conf中对应的level取值 |
---|---|
LOG_EMERG | emerg |
LOG_ALERT | alert |
LOG_CRIT | crit |
LOG_ERR | err |
LOG_WARNING | warning |
LOG_NOTICE | notice |
LOG_INFO | info |
LOG_DEBUG | debug |
下面是具体的例子:
这里printf("%m")等价于printf("%s",strerror(errno));
它表示把errno用string形式打印出来。
由于我这里facility为user时,是记录在/val/log/syslog中的:
因此打印log如下:
2.3 重定向log#
我们也可以把log定向到自己想要的地方。
2.3.1 方法1-修改rsyslog.conf#
将facility=user
时的所有level级别的log重定向到/val/log/user.log
, 重启rsyslog服务:
此时log将被写入到新配置的位置/val/log/user.log, 当然/val/log/syslog也会保留一份.(因为也符合/val/log/syslog这条规则)
2.3.2 方法2-修改code中的facility#
那这里的facility被设置成了local0, 那也会记录在/val/log/syslog
:
2.4 设置log等级#
- 这里新增一个app.conf,然后自定义log路径:
当然还可以类似于这样子写, syslogfacility-text和syslogseverity-text是rsyslog自带的系统变量。
重启rsyslog服务
这里切成4个文件,每个文件记录1024k。
运行程序,查看log如下:
那现在修改log等级为warn, 表示只有大于等于该等级的log才会记录。
再次重启rsyslog服务,运行程序,可以看到”log debug”不再打印:
2.5 重定向log到console#
再次重启rsyslog服务,运行程序,那么可以看到err级别的log打印在了console上,但是低于err级别还是会记录在/val/log/app。
3 dup函数介绍#
用来将标准输出重定向到文件:
1 | static int dup_fd; |