一. 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 日志的output格式
1. 如果配置好并运行了 syslogd 或 klogd,一般所有 log的信息也会追加到 /var/log/messages。并且kernel log信息被记录在/val/log/kern.log。
可以看到基本日志格式包含以下四列:
(1) 事件产生的时间(Jan 1 08:00:09)
(2) 发生事件的服务器的主机名 (cvitek)
(3) 产生事件的服务名或程序名 (kernel or local5)
(4) 事件的具体信息(…cif a0c2000.cif:..)
2.当开启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中。
#################
#### MODULES ####
#################
module(load="imuxsock") # provides support for local system logging ;加载提供对本地系统日志的支持
module(load="imklog") # provides kernel logging support;加载读取内核消息模块
#module(load="immark") # provides --MARK-- message capability
# provides UDP syslog reception (接收使用UDP 协议转发过来的日志,这里#注释掉了表示不启用)
#module(load="imudp")
#input(type="imudp" port="514") (允许514端口接收)
# provides TCP syslog reception (接收使用UDP 协议转发过来的日志)
#module(load="imtcp")
#input(type="imtcp" port="514")(允许514端口接收)
# Enable non-kernel facility klog messages
$KLogPermitNonKernelFacility on
###########################
#### GLOBAL DIRECTIVES ####
###########################
#
# Use traditional timestamp format.
# To enable high precision timestamps, comment out the following line.
#
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
# Filter duplicated messages
$RepeatedMsgReduction on
#
# Set the default permissions for all log files.
#
$FileOwner syslog
$FileGroup adm
$FileCreateMode 0640
$DirCreateMode 0755
$Umask 0022
$PrivDropToUser syslog
$PrivDropToGroup syslog
#
# Where to place spool and state files
#
$WorkDirectory /var/spool/rsyslog
(记录所有日志类型的info级别以及大于info级别的信息到/var/log/messages,但是mail邮件信息,authpriv验证方面的信息和cron时间任务相关的信息除外)
#*.info;mail.none;authpriv.none;cron.none /var/log/messages
# Include all config files in /etc/rsyslog.d/
#
$IncludeConfig /etc/rsyslog.d/*.conf (表示加载该目录中的所有配置)
1.2.2 rsyslog规则(/etc/rsyslog.d/*.conf)
rsyslog规则配置文件一般由以下3部分组成,每一行表示一个项目,格式为:facility.level action,分别表示日志类型,日志等级,日志输出路径。一般系统默认的规则定义在/etc/rsyslog.d/50-default.conf,
一般所有日志类型都会被追加在/val/log/messages。如:
*.info;mail.none;authpriv.none;cron.none /var/log/messages
facility日志类型:
- kern: 内核信息
- user: 用户进程相关信息
- mail: 电子邮件相关信息
- Local0- local7: 为本地使用预留的服务
- daemon: 后台进程相关信息
- syslog: 系统日志信息
level(按严重程度由低到高排序):
- none: 没有重要级
- debug: 调试信息
- info: 打印的信息
- notice: 具有重要信息的普通条件
- warning: 警告信息
- err: 错误信息
- crit: 阻止某些工具或子系统功能实现的错误条件
- alert: 需要立即被修改的条件
- emerg: 该系统不可用
action(表示log保存的位置)
那下面我也抄过来一份比较全面的规则定义示例供大家参考:
# 记录mail日志等级为error及以上日志
mail.err /var/log/mail_err.log
# 记录mail所有等级为warn级别的日志(仅记录warn级别)
mail.=warn /var/log/mail_err.log
# 记录kern所有日志
kern.* /var/log/kern.log
# 将mail的所有信息,除了info以外,其他的都写入/var/adm/mail
mail.*;mail.!=info /var/adm/mail
# 将日志等级为crit或更高的内核消息定向到远程主机finlandia
# 如果主机崩溃,磁盘出现不可修复的错误,可能无法读取存储的消息。如果有日志在远程主机上,可以尝试找出崩溃的原因。
kern.crit @finlandia
# 记录所有类型的warning等级及以上日志
*.warning /var/log/syslog_warn.log
# 记录mail的warning日志和kern的error日志,其他所有的info日志
*.info;mail.warning;kern.error /var/log/messages
# 记录kernel的info到warning日志
kern.info;kern.!err /var/adm/kernel-info
# 将mail和news的info级别日志写入/var/adminfo
mail,news.=info /var/adm/info
# 将所有系统中所有类型的info日志和notice日志存入/var/log/massages,mail的所有日志除外。
*.=info;*.=notice;
mail.none /var/log/messages
# 紧急消息(emerg级别)将使用wall显示给当前所有登录的用户,这里用等号表示只对emerg日志级别有效
*.=emerg *
# 该规则将所有alert以及更高级别的消息定向到操作员的终端,即登录的用户“root”和“joey”的终端。
*.alert root,joey
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中。
那么我们可以自定义规则如下:
syslogfacility-text:表示facility日志类型
syslogseverity-text:表示level日志级别
这里对aisdk.conf用local7日志类型产生的大于warn日志级别的log都将记录到/val/log/aisdk,
对kern.conf用kern类型产生的所有级别日志都记录到/val/log/kern,
Local5类型的日志记录到/val/log/middleware, 并且当日志级别等于或高于4(warn)时也会追加到console.
二. syslog()函数
用户空间也可以用syslog()函数来记录自己的进程的日志,所以用户进程可以自定义日志规则。
调用openlog是可选择的。如果不调用openlog,则在第一次调用syslog时,会自动调用openlog。
syslog的相关函数和宏定义一般在toolchain中都会有定义:
2.1 openlog函数
第1个参数为ident,该参数常用来表示信息的来源。ident信息会被固定地添加在每行日志的前面。
第2个参数 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定向到自己想要的地方,
方法1:修改rsyslog.conf:
将facility=user时的所有level级别的log重定向到/val/log/user.log, 重启rsyslog服务,
此时log将被写入到新配置的位置/val/log/user.log, 当然/val/log/syslog也会保留一份.(因为也符合/val/log/syslog这条规则)
方法2:修改code中的facility:
那这里的facility被设置成了local0, 那也会记录在/val/log/syslog.
2.4 设置log等级
1. 这里新增一个app.conf,然后自定义log路径:
当然还可以类似于这样子写, syslogfacility-text和syslogseverity-text是rsyslog自带的系统变量。
2. 重启rsyslog服务
3. 运行程序,查看log如下:
4. 那现在修改log等级为warn, 表示只有大于等于该等级的log才会记录。
5. 再次重启rsyslog服务,运行程序,可以看到"log debug"不再打印.
2.5 重定向log到console
再次重启rsyslog服务,运行程序,那么可以看到err级别的log打印在了console上,但是低于err级别还是会记录在/val/log/app。