认识Linux Rsyslog
2013-04-06 14:47:33 阿炯

rsyslog 是一个 syslogd 的多线程增强版。它支持数据使用插件、直接调用模板、异步写数据库等相对高级的功能,默认是被安装的,但只对本机开放。它使用udp方式的日志传输是基于灵活的插件实现的,很容易被使用。

现在Debian、Fedora、Ubuntu、Rhel6默认的日志系统都是rsyslog了。rsyslog负责写入日志,可以使用logrotate来负责备份和删除旧日志,以及更新日志文件。

看下系统中的进程:
# ps aux|grep rsyslog
root       911  0.0  0.1  27452  1600 ?        Sl   Apr05   0:00 /usr/sbin/rsyslogd -c4

从上面命令的输出结果看到rsyslog执行时使用的参数是'-c 4'。它的意思是指定rsyslog运行(兼容)的版本号,这个参数必须是第一个参数,当然也可以省略,默认为-c0 (命令行兼容sysklogd)。

这个参数是在文件'/etc/default/rsyslog'中指定。

主配置文件:/etc/rsyslogd.conf

# provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514

保存后执行/etc/rsyslogd restart 重启后,它就会监听514端口的udp请求。当然,它也支持TCP方式的监听,配置同样也是被注释了而已,可以按需开启。它的日志记录格式如下:
日志设备(类型).(连接符号)日志级别   日志处理方式(action)

详细的可以查看手册: man 3 syslog

连接符号
---------------
.xxx: 表示大于等于xxx级别的信息
.=xxx:表示等于xxx级别的信息
.!xxx:表示在xxx之外的等级的信息

Actions
1. 记录到普通文件或设备文件
*.* /var/log/file.log   # 绝对路径
*.* /dev/pts/0
测试: logger -p local3.info 'Message is testing the rsyslog and logger from freeoa.net'
logger 命令用于产生日志

2. 转发到远程
*.* @192.168.0.1 # 使用UDP协议转发到192.168.0.1的514(默认)端口
*.* @@192.168.0.1:10514 # 使用TCP协议转发到192.168.0.1的10514(默认)端口

3. 发送给用户(需要在线才能收到)
*.*   root
*.*   root,kadefor,up01     # 使用,号分隔多个用户
*.*   * # *号表示所有在线用户

4. 忽略,丢弃
local3.*   ~    # 忽略所有local3类型的所有级别的日志

5. 执行脚本
local3.*    ^/tmp/a.sh  # ^号后跟可执行脚本或程序的绝对路径
# 日志内容可以作为脚本的第一个参数.
# 可用来触发报警

增加一个日志纪录设备

默认的设备定义共有24个,建议使用local0(16)~local7(23)作为自定义的日志设备。默认情况下,debian的日志设备定义保存在/etc/rsyslog.d下。我们新建一个local1设备,默认存储路径'/var/log/freeoatest.log'方法如下:
vim /etc/rsyslog.d/90-local1.conf

local1.* /var/log/freeoatest.log
#local1.info /va/log/freeoatest.info.log

syslog共有从info到emerg总计7个等级,这里采用一个统配'*'代表所有报错等级,可以分别处理了。

rsyslog.conf中的配置简解:
#指明local2的日志存放位置
local2.info /var/log/login_info.log info级别日志
local2.debug /var/log/login_debug.log debug级别日志
local.* /var/log/login.log 所有级别日志

清空一个log内容的方法
# echo "" xx.log(文件大小被截为1字节)
# cat/dev/null > xx.log(文件大小被截为0字节)

经过配置后的rsyslog还可以接收远程交换机日志,在此不详述。


syslog配置文件/etc/rsyslog.conf讲解

配置文件定义格式为facility.priority  action

facility是指哪个facility来源产生的日志;priority是指拿个级别的日志;action是指产生日志怎么办是保存在文件中还是其他。facility可以理解为日志的来源或设备或选择条件,目前常用的facility有以下几种:
auth #认证相关的
authpriv #权限,授权相关的
cron #任务计划相关的
daemon #守护进程相关的
kern  #内核相关的
lpr  #打印相关的
mail  #邮件相关的
mark  #标记相关的
news  #新闻相关的
security #安全相关的,与auth类似
syslog #syslog自己的
user #用户相关的
uucp#unix to unix cp相关的
local0到local7 #用户自定义使用
*  #*表示所有的facility

priority(log level)日志优先级的级别,一般分为以下几种级别(从低到高)

注:级别越低记录的越详细
debug  #程序或系统的调试信息
info #一般信息
notice  #不影响正常的功能,需要提醒用户的重要事件
warning/warn  #可能影响系统功能,需要提醒用户的重要事件
err/error  #错误信息
crit   #比较严重的
alert  #必须马上处理的
emerg/canic  #会导致系统不可用的
*  #表示所有的日志级别
none    #跟*相反,表示什么也没有

action(动作)日志记录的位置

系统上的绝对路径      #普通文件 如:/var/log/file
|  #管道 通过管道送给其他的命令出来
终端  #终端 如:/dev/console
@host  #远程主机  如@10.1.1.1
用户  #系统用户 如:root
* #登录到系统上的所有用户,一般emerg级别的日志是这样定义的

定义格式列子:
mail.info  /var/log/mail.log   #表示将mail相关的,级别为info及info以上级别的信息记录到/var/log/mail.log文件中

auth.=info  @10.1.1.1#表示将auth相关的,级别为info的信息记录到10.1.1.1主机上去,前提是10.1.1.1要能接收其主机发来的日志信息

user.!=error    #表示记录user相关的,不包括error级别的信息

user.!error   #表示user.error相反

*.info  #表示记录所有的日志信息的info级别

mail.*  #表示记录所有mail相关的所有级别的信息

*.*       #表示记录所有的日志信息的所有的日志级别

cron.info;mail.info      #多个日志来源可以用“ ; ”隔开

cron,mail.info #与cron.info;mail.info        是同一个意思

mail.*;mail.!=info        #表示记录mail相关的所有级别的信息,但是不包括info级别的信息



Rsyslog 使用详解

配置

rsyslog的配置文件有多种书写方法:
sysklogd(一些结构不兼容新特性),
legacy rsyslog(以"$"开头的写法,如:$ModLoad imtcp.so),
RainerScript(一种新的格式,是最推荐使用的一种,尤其是需要做复杂的配置时)。

在本文中的配置都比较简单,就采用了legacy rsyslog的配置书写方法,更多详情参考这里

配置文件简单实例

$ less /etc/rsyslog.conf
#rsyslog v3 config file

# if you experience problems, check
# http://www.rsyslog.com/troubleshoot for assistance

#### MODULES ####

$ModLoad imuxsock.so    # provides support for local system logging (e.g. via logger command)
$ModLoad imklog.so      # provides kernel logging support (previously done by rklogd)
#$ModLoad immark.so     # provides --MARK-- message capability

# Provides UDP syslog reception
#$ModLoad imudp.so
#$UDPServerRun 514

# Provides TCP syslog reception
#$ModLoad imtcp.so  
#$InputTCPServerRun 514


#### GLOBAL DIRECTIVES ####

# Use default timestamp format
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat

# File syncing capability is disabled by default. This feature is usually not required,
# not useful and an extreme performance hit
#$ActionFileEnableSync on


#### RULES ####

# Log all kernel messages to the console.
# Logging much else clutters up the screen.
#kern.*                                                 /dev/console

# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none;cron.none  /var/log/messages

# The authpriv file has restricted access.
authpriv.*  /var/log/secure

# Log all the mail messages in one place.
mail.*  -/var/log/maillog


# Log cron stuff
cron.*  /var/log/cron

# Everybody gets emergency messages
*.emerg  *

# Save news errors of level crit and higher in a special file.
uucp,news.crit  /var/log/spooler

# Save boot messages also to boot.log
local7.*  /var/log/boot.log


配置文件模块

配置文件查看less /etc/rsyslog.conf,Rsyslog的配置主要有以下模块:
modules,模块,配置加载的模块,如:ModLoad imudp.so配置加载UDP传输模块

global directives,全局配置,配置ryslog守护进程的全局属性,比如主信息队列大小(MainMessageQueueSize)

rules,规则(选择器+动作),每个规则行由两部分组成,selector部分和action部分,这两部分由一个或多个空格或tab分隔,selector部分指定源和日志等级,action部分指定对应的操作

模板(templates)

输出(outputs)

常用的modules

imudp,传统方式的UDP传输,有损耗

imtcp,基于TCP明文的传输,只在特定情况下丢失信息,并被广泛使用

imrelp,RELP传输,不会丢失信息,但只在rsyslogd 3.15.0及以上版本中可用


规则(rules)

规则的选择器(selectors)

selector也由两部分组成,设施和优先级,由点号.分隔。第一部分为消息源或称为日志设施,第二部分为日志级别。多个选择器用;分隔,如:*.info;mail.none。

日志设施有:
auth(security), authpriv: 授权和安全相关的消息
kern: 来自Linux内核的消息
mail: 由mail子系统产生的消息
cron: cron守护进程相关的信息
daemon: 守护进程产生的信息
news: 网络消息子系统
lpr: 打印相关的日志信息
user: 用户进程相关的信息
local0 to local7: 保留,本地使用

日志级别有(升序):
debug:包含详细的开发情报的信息,通常只在调试一个程序时使用。
info:情报信息,正常的系统消息,比如骚扰报告,带宽数据等,不需要处理。
notice: 不是错误情况,也不需要立即处理。
warning: 警告信息,不是错误,比如系统磁盘使用了85%等。
err:错误,不是非常紧急,在一定时间内修复即可。
crit:重要情况,如硬盘错误,备用连接丢失。
alert:应该被立即改正的问题,如系统数据库被破坏,ISP连接丢失。
emerg:紧急情况,需要立即通知技术人员。

日志设施的配置:
. 代表比后面还要高的消息等级都会记录下来
.= 代表只有后面的这个消息等级会被记录下来
.! 代表除了后面的这个消息等级,其他的都会被记录下来,我在rsyslogd 4.6.2中失败了不知道为啥。。

对于多个选择器可以用;分隔。
local0.=debug  /home/freeoa/applogs/app-name/debug.log
local0.err;local0.warning;local0.info  /home/freeoa/applogs/app-name/info.log
local0.err  /home/freeoa/applogs/app-name/error.log

动作(action)

action是规则描述的一部分,位于选择器的后面,规则用于处理消息。总的来说,消息内容被写到一种日志文件上,但也可以执行其他动作,比如写到数据库表中或转发到其他主机。

在前面的实例中的是写到本地文件中的:
# The authpriv file has restricted access.
authpriv.*    /var/log/secure

也可以写到mysql数据库中,
# modules, 要将日志写到mysql中需要加载ommysql模块
$ModLoad ommysql
# rule, send to mysql
#*.*       :ommysql:database-server,database-name,database-userid,database-password
*.*       :ommysql:127.0.0.1,Syslog,syslogwriter,topsecret

关于配置发送消息到数据库的更多类容可以参考这里

action的配置:
保存到文件,cron.* -/var/log/cron.log如果路径前有-则表示每次输出日志时不同步(fsync)指定日志文件。 文件路径既可以是静态文件也可以是动态文件。动态文件由模板前加 ? 定义。

通过网络发送日志 格式如下: @[()]:[] @ 表示使用 UDP 协议。@@ 表示使用 TCP 协议。 可以为: z 表示使用 zlib 压缩,NUMBER 表示压缩级别。多个选项 使用 , 分隔。 例如: . @192.168.0.1 # 使用 UDP 发送日志到 192.168.0.1 .@@example.com:18 # 使用 TCP 发送到 "example.com" 的 18 端口 . @(z9)[2001::1] # 使用 UDP 发送消息到 2001::1,启用 zlib 9 级压缩

cron.* ~ 丢弃所有信息,即该配置之后的动作不会看到该日志。 随 rsyslog 版本不同,如果有如下警告信息,则将 ~ 修改为 stop。


模板(templates)

模板允许你指定日志信息的格式,也可用于生成动态文件名,或在规则中使用。其定义如下所示,其中TEMPLATE_NAME是模板的名字,PROPERTY是rsyslog本身支持的一些属性参数。

$template TEMPLATE_NAME,"text %PROPERTY% more text", [OPTION]

使用例子:
$template DynamicFile,"/var/log/test_logs/%timegenerated%-test.log"
$template DailyPerHostLogs,"/var/log/syslog/%$YEAR%/%$MONTH%/%$DAY%/%HOSTNAME%/messages.log"

*.info ?DailyPerHostLogs
*.* ?DynamicFile

在模板中我们用到的properties可以参考官方文档说明,例子中用到的timegenerated是指接收到消息时的时间戳。

输出(outputs)

输出频道为用户可能想要的输出类型提供了保护,在规则中使用前要先定义.其定义如下所示,其中NAME指定输出频道的名称,FILE_NAME指定输出文件,MAX_SIZE指定日志文件的大小,单位是bytes,ACTION指定日志文件到达MAX_SIZE时的操作。
$outchannel NAME, FILE_NAME, MAX_SIZE, ACTION

在规则中使用输出频道按照如下的格式:
selectors :omfile:$NAME

例子:
$outchannel log_rotation, /var/log/test_log.log, 104857600, /home/joe/log_rotation_script

*.* :omfile:$log_rotation

配置的验证

通过下面命令可以校验配置文件是否配置正确:
rsyslogd -f /etc/rsyslog.conf -N4

其中 -N后面的数值代表rsyslog启动时-c 后指定的版本。通过下面命令可以手动发送日志信息:
logger -p local0.info "hello world"

日志文件Rotating

随着日志文件越来越大,这不仅会带来性能问题,同时对日志的管理也非常棘手。当一个日志文件被rotated,会创建一个新的日志文件,同时旧的日志文件会被重命名。这些文件在一段时间内被保留,一旦产生一定数量的旧的日志,系统就会删除一部分旧的日志。

logrotate配置文件实例

logrotate是通过cron任务调用的,在安装的时候就自动创建了,所以通过ps命令看不到logrotate,可查看定时任务调用:cat /etc/cron.daily/logrotate:
#!/bin/sh
/usr/sbin/logrotate /etc/logrotate.conf >/dev/null 2>&1
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
    /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0

cron.daily下的文件执行都是通过/etc/crontab配置的:
$cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed

0 0 * * * root run-parts /etc/cron.daily #定时执行cron.daily

logrotate的配置文件为/etc/logrotate.conf,下面给一个例子:
# see "man logrotate" for details
# rotate log files weekly
weekly

# keep 4 weeks worth of backlogs
rotate 4

# create new (empty) log files after rotating old ones
create

# uncomment this if you want your log files compressed
#compress

# packages drop log rotation information into this directory
include /etc/logrotate.d

# no packages own wtmp, or btmp -- we'll rotate them here
/var/log/syslog
{
    rotate 7
    daily
    missingok
    notifempty
    delaycompress
    compress
    postrotate
        invoke-rc.d rsyslog reload > /dev/null
    endscript
}
/var/log/cron.log
/var/log/debug
/var/log/messages
{
    rotate 4
    weekly
    missingok
    notifempty
    compress
    delaycompress
    sharedscripts
    postrotate
        invoke-rc.d rsyslog reload > /dev/null
    endscript
}
# system-specific logs may be configured here

syslog的日志文件每天被rotated,保留7份旧的日志,其他的日志文件每周进行一次rotate,并保留4份旧的日志。

logrotate配置项

我们可以通过man logrotate来获取所有的参数和详细描述。这里列出一部分:
daily 指定转储周期为每天
weekly 指定转储周期为每周
monthly 指定转储周期为每月
compress 通过gzip 压缩转储以后的日志
nocompress 不需要压缩时,用这个参数
copytruncate 用于还在打开中的日志文件,把当前日志备份并截断
nocopytruncate 备份日志文件但是不截断
missingok 如果文件不存在,继续下一个文件,不报异常
nomissingok 如果文件不存在,报异常(默认配置)
create mode(文件权限) owner(拥有者) group(组) 转储文件,使用指定的文件模式创建新的日志文件
nocreate 不建立新的日志文件
delaycompress 和 compress 一起使用时,转储的日志文件到下一次转储时才压缩
nodelaycompress 覆盖 delaycompress 选项,转储同时压缩。
errors address 转储时的错误信息发送到指定的Email 地址
ifempty 即使是空文件也转储,(logrotate 的缺省选项)
notifempty 如果是空文件的话,不转储
mail address 把转储的日志文件发送到指定的E-mail 地址
nomail 转储时不发送日志文件
olddir directory 转储后的日志文件放入指定的目录,必须和当前日志文件在同一个文件系统
noolddir 转储后的日志文件和当前日志文件放在同一个目录下
prerotate/endscript 在转储以前需要执行的命令可以放入这个对,这两个关键字必须单独成行
postrotate/endscript 在转储以后需要执行的命令可以放入这个对,这两个关键字必须单独成行
rotate count 指定日志文件删除之前转储的次数,0 指没有备份,5 指保留5 个备份
tabootext [+] LIST 让logrotate 不转储指定扩展名的文件,缺省的扩展名是:.rpm-orig, .rpmsave, v, 和 ~
size SIZE 当日志文件到达指定的大小时才转储,Size 可以指定 bytes (缺省)以及KB (sizek)或者MB (sizem)

实例参考

# vim /etc/rsyslog.conf
# Provides UDP syslog reception
$ModLoad imudp.so
$UDPServerRun 514

$template ipAndMsg,"[%fromhost-ip%]  %$now%%msg%\n"

local0.=debug                /home/freeoa/applogs/app-name/debug.log;ipAndMsg
local0.err;local0.warning;local0.info                /home/freeoa/applogs/app-name/info.log;ipAndMsg
local0.err                /home/freeoa/applogs/app-name/error.log;ipAndMsg

# service rsyslog restart

# service syslog/syslog-ng stop

sudo vim /etc/logrotate.conf
/home/freeoa/applogs/app-name/debug.log
/home/freeoa/applogs/app-name/info.log
/home/freeoa/applogs/app-name/error.log{
    daily
    create 0664 root root
    rotate 30
    missingok
    nocompress
    notifempty
    dateext
    postrotate
        /etc/init.d/rsyslog restart > /dev/null 2>&1
    endscript
}

注意,最后必须加上:
postrotate    /etc/init.d/rsyslog restart > /dev/null 2>&1
endscript

因为logrotate之后,即使已经移走了,但是rsyslog还是持有这个文件操作句柄,会继续往原文件(被rotate的文件)中写,即使已经被重命名了,所以需要 restart rsyslog 来 reopen 下 logrotate新创建的同名文件。

另外有一个可以不用重启的办法,但是会丢失部分数据,logrotate 提供了 copytruncate。默认的指令 create 做法,是 移动旧文件,创建新文件,然后用脚本reopen新文件;而 copytruncate 是采用的先拷贝再清空,先复制一份旧的日志,然后请客原文件,整个过程原来的文件句柄,并没有变化,所以不需要reopen,服务可以不中断,但是这个过程会导致部分数据丢失。




参考文档:
Gentoo-Rsyslog

RSyslog Documentation