RSYSLOG 是一个高效的日志系统,也是目前 Ubuntu 和 CentOS 默认使用的日志系统。
LogAnalyzer 是一个 PHP 写成的 Web 前端,使用它可以分析和查看 RSYSLOG 生成的日志。
经过研究,我准备直接使用这两个系统。本文记录了我在配置这两个系统中遇到的问题。
rsyslog 配置简介
rsyslog 是负责收集 syslog 的程序,可以用来取代 syslogd 或 syslog-ng。 在这些 syslog 处理程序中,个人认为 rsyslog 是功能最为强大的。其特性包括: 支持输出日志到各种数据库,如 MySQL,PostgreSQL,MongoDB,ElasticSearch,等等; 通过 RELP + TCP 实现数据的可靠传输(基于此结合丰富的过滤条件可以建立一种 可靠的数据传输通道供其他应用来使用);精细的输出格式控制以及对消息的强大 过滤能力;高精度时间戳;队列操作(内存,磁盘以及混合模式等); 支持数据的加密和压缩传输等。
syslog 的相关 RFC 参考 RFC3164, RFC5424, RFC5425, RFC5426。
本文仅覆盖 rsyslog 的相关配置,其中配置指令的正确性以 官方文档为准, Wiki 作为参考。
配置文件 /etc/rsyslog.conf
配置文档官方文档请参考这里。http://www.rsyslog.com/doc/rsyslog_conf.html
rsyslog 的配置文件一般为 /etc/rsyslog.conf。模块相关的配置指定指定和功能仅在 相应的模块被加载($ModLoad)后才可用。配置行如果太长,可以在行尾使用 “\” 分割成多行。注释支持两种语法,一种以 # 开始到行尾,另一种为 C 语言格式。
指令的处理顺序为文件内容从始到末。
使用命令 rsyslogd -f /etc/rsyslog.conf -N1 测试配置文件检查。
# rsyslogd -f /etc/rsyslog.conf -N1
rsyslogd: version 7.4.4, config validation run (level 1), master config /etc/rsyslog.conf
rsyslogd: warning: ~ action is deprecated, consider using the 'stop' statement instead [try http://www.rsyslog.com/e/2307 ]
rsyslogd: immark: mark message period must not be 0, can not run
rsyslogd: End of config validation run. Bye.
日志的发送测试可以使用 logger 命令,该命令支持通过 UNIX Socket,UDP/TCP 等 发送 syslog。
下面仅对常用的配置指令 做一些说明,并主要以 legacy rsyslog 的格式来描述。官方文档目前大部分是以 RainerScript 的格式描述。 部分配置指令放在单独的章节里说明。
$ActionFileDefaultTemplate [templateName] # 定义文件动作的日志输出模板
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
Dec 30 17:16:58 linux-64 logger[16898]: test syslog
$ActionFileDefaultTemplate RSYSLOG_FileFormat
2013-12-30T17:19:50.926770+08:00 linux-64 logger[7757]: test syslog
$ActionForwardDefaultTemplate [templateName] # 定义缺省转发动作的日志输出模板
$ActionExecOnlyWhenPreviousIsSuspended [on/off] # 值为 on 时表示接下来的 动作仅在之前的动作被挂起(失败)时才执行。
文件系统相关配置
$DirCreateMode,$DirGroup, $DirOwner # 设置目录创建模式,属主和组
$FileCreateMode,$FileGroup,$FileOwner # 设置文件创建模式,属主和组
$Umask 0062 # 设置文件创建掩码,等价于 man 1 umask
$DynaFileCacheSize # 控制动态文件保持打开的个数,针对每个动作
$IncludeConfig # 导入其他文件到配置,等价于 C 中的 #include
$MainMsgQueueSize # 主消息队列大小
$MaxMessageSize # 日志最大大小,太大的值需要考虑传输协议,如 UDP
$ModLoad xxx # 模块加载
重复消息控制
$RepeatedMsgReduction on
$RepeatedMsgContainsOrigionalMsg on
日志接收率控制
Interval 设置率计算的时间间隔,0 表示关闭;Burst 设置该间隔内允许的日志数。 IMUXSock 针对通过 system log socket 接收的日志;SystemLog 针对其他输入源。
$SystemLogRateLimitInterval 0
$SystemLogRateLimitBurst 0
$IMUXSockRateLimitInterval 0
$IMUXSockRateLimitBurst 0
Dec 31 22:02:36 linux-64 rsyslogd-2039: imuxsock begins to drop messages from pid 6927 due to rate-limiting
Dec 31 22:02:39 linux-64 rsyslogd-2039: imuxsock lost 133250 messages from pid 6927 due to rate-limiting
模块
完整的模块列表在这里。 http://www.rsyslog.com/doc/v8-stable/configuration/modules/index.html
下面仅对常用的各类别模块做简单的介绍。
输入模块(im 前缀)
imfile - 转换文本文件为日志
imrelp - 通过 RELP 可靠的接收日志。
$ModLoad imrelp # 加载模块
$InputRELPServerRun 514 # 在 514 端口监听
imudp - 通过 UDP 接收日志
$ModLoad imudp
$UDPServerRun 514
imtcp - 通过 TCP 接收日志
$ModLoad imtcp
$InputTCPMaxSessions 500
$InputTCPServerRun 514
imptcp - 同 imtcp,但针对 Linux 做高性能定制
$ModLoad imptcp
$InputPTCPServerRun 514
immark - 周期性输出标记信息
设置为60,每分钟产生一个 mark 日志
$MarkMessagePeriod 60
imklog - 获取内核日志(通过 dmesg 也能看到相关信息)
imuxsock - UNIX socket
缺省情况下从 /dev/log 获取日志。
# netstat -nxp|grep /dev/log
unix 3 [ ] DGRAM 7439519 9074/rsyslogd /dev/log
$ModLoad imuxsock # needs to be done just once
$SystemLogRateLimitInterval 0 # turn off rate limiting
$InputUnixListenSocketCreatePath on # turn on for next socket
$InputUnixListenSocket /var/run/sshd/dev/log
$InputUnixListenSocketHostName jail1.example.net
$AddUnixListenSocket /jail/1/dev/log
$InputUnixListenSocketHostName jail2.example.net
$AddUnixListenSocket /jail/2/dev/log
impstats - rsyslog 内部数据周期统计
输出模块(om 前缀)
omfile - 输出到文件
支持静态文件;通过模板支持动态文件;
omfwd - 内置模块,转发
*.* @192.168.2.11:10514
*.* @@192.168.2.11:10514
omsnmp - SNMP trap 输出
$ModLoad omsnmp
$actionsnmptransport udp
$actionsnmptarget localhost
$actionsnmptargetport 162
$actionsnmpversion 1
$actionsnmpcommunity public
*.* :omsnmp:
omrelp - RELP output module
$ModLoad omrelp
*.* :omrelp:loghost.example.com:20514
omusrmsg - 内置模块,发送日志到指定用户
# Emergencies are sent to everybody logged in.
*.emerg :omusrmsg:*
omprog - 发送日志给程序处理
为方便程序解析,日志的输出最好采用 json 格式输出。
$ModLoad omprog
$ActionOMProgBinary /home/app/rtdatamq/save_log_data.py
:programname,startswith,"log4report" :omprog:;RSYSLOG_TraditionalFileFormat
ommail - 发送邮件
输出到数据库等
ommysql - MySQL
ompgsql - PostgreSQL
ommongodb - MongoDB
omlibdbi - 通用数据库模块
omhdfs - Hadoop's HDFS
omelasticsearch - ElasticSearch
其他模块
消息过滤(fm 前缀),消息解析(pm 前缀),字符串生成(sm 前缀),库模块,等。
规则
规则由过滤器和动作组成。
过滤器
基于设施/优先级的过滤器
格式如下:
<FACILITY>.<PRIORITY>
其中:
表示生成日志的子系统。取值范围为 auth,authpriv,cron, daemon,kern,lpr,mail,news,syslog,user,uucp,local0 到 local7, 参考 man 3 syslog。其对应的数值请参考 /usr/include/sys/syslog.h, 注意需要忽略移位操作。
表示日志的级别,取值范围为(从低到高,数值对应 7-0) debug,info,notice,warning,err,crit,alert,emerg。 参考 man 3 syslog。
在级别前可以增加相应的修饰符,例如加 = 表示仅选择该优先级的日志,加 ! 表示选择不等于优先级的所有日志,不加任何符号则表示选择该优先级及之上的日志。 * 可以用来表示所有的日志子系统和/或消息级别。关键字 none 表示未指定级别的日志。如果要定义多个设置/优先级,使用 , 分隔即可。 如果要定义多个过滤条件,则使用 ; 分隔。
示例如下:
kern.* # 选择所有级别的内核日志
mail.crit # 选择所有级别为 crit 及之上的邮件系统相关日志
cron.!info,!debug # 选择所有 cron 日志信息,排除优先级为 info 和 debug 的日志
*.=debug # 选择所有的调试级别日志
*.*;auth,authpriv.none # 选择所有级别的日志,以及认证相关无级别的日志
基于属性的过滤器
格式如下:
:<PROPERTY>, [!]<COMPARE_OPERATION>, "<STRING>"
其中 ! 表示对匹配结果取反。
该过滤器可以对所有日志的属性进行过滤(相对传统的 syslog 程序而言),例如: timegenerated 或者 syslogtag,所有的属性列表如下,完整的列表可以参考 这里的 Available Properties 节。部分属性如下:
属性名 说明
msg 日志正文
hostname 日志中的主机名
fromhost 从该主机接收到的消息,可能不是最开始的发送主机
fromhost-ip fromhost 的 IP
syslogtag 日志标签,如 named[12345]
programname 日志标签的静态部分,如 named
pri 日志的 PRI 部分
pri-text PRI 的文本表示,如 syslog.info
syslogfacility 日志类别
syslogfacility-text 日志类别的文本表示
syslogseverity 日志级别
syslogseverity-text 日志级别的文本表示
timegenerated 日志接收时间,或理解为 timereceived
timereported 日志内的报告时间,或生成时间
$now 当前时间,YYYY-MM-DD
$year 当前年,YYYY
$month 当前月,MM
$day 当前日志,DD
$hour 当前小时,24 小时格式,HH
$hhour 当前半小时,0-29 对应 0,30-59 对应 1
$qhour 当前1/4小时,0-3
$minute 当前分钟,MM
timegenerated 和 timereported 的差别请参考 What is the difference between timereported and timegenerated?
每一个属性可以使用下面的比较操作来和某一个指定的值进行从而定义过滤器。
操作符 说明
contains 属性包含指定的字符串
isequal 属性等于指定的字符串
startswith 属性由指定字符串开始
regex POSIX BRE 正则表达式
ereregex POSIX ERE 正则表达式
示例如下:
:msg,contains,"error" # 选择包含 error 的日志
:hostname,isequal, "host1" # 选择主机名为 host1 的日志
:msg,!regex,"fatal .* error" # 选择不匹配指定正则表达式的日志
基于RainerScript的过滤器
格式如下:
if <EXPRESSION> then <ACTION>
其中,<EXPRESSION> 表示表达式,例如: "$msg startswith 'DEVNAME' or $syslogfacility-text == 'local0'"。 如果表达式结果为真,则会执行相应的动作。
动作
保存日志到指定文件
例如:
cron.* -/var/log/cron.log
如果文件路径前有 “-” 则表示每次输出日志时不同步(fsync)指定日志文件。 文件路径既可以是静态文件也可以是动态文件。动态文件由模板前加 ? 定义。
通过网络发送日志
格式如下:
@[(<options>)]<HOST>:[<PORT>]
@ 表示使用 UDP 协议。@@ 表示使用 TCP 协议。<options> 可以为: z<NUMBER> 表示使用 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 级压缩
发送消息到特定用户
例如
:msg,contains,"error" liuzx
发送包含 error 的日志到用户 liuzx。多个用户则用 , 分隔,* 表示所有用户。用户 的 mesg (参考 man 1 mesg)权限需要设置为 y。
上面的写法随 rsyslog 版本不同,可能会有如下警告信息,最好做调整。
action 'liuzx' treated as ':omusrmsg:liuzx' - please change syntax, 'liuzx' will not be supported in the future
更多动作
参考输出模块的文档。例如 omprog 输出日志到指定程序的标准输入,ommysql 输出 到 MySQL 数据库,ompgsql 输出日志到 PostgreSQL, ...
丢弃日志
例如
cron.* ~
丢弃所有信息,即该配置之后的动作不会看到该日志。
随 rsyslog 版本不同,如果有如下警告信息,则将 ~ 修改为 stop。
warning: ~ action is deprecated, consider using the 'stop' statement instead [try http://www.rsyslog.com/e/2307 ]
对每一个过滤条件,可以指定多个动作,每个动作一行即可。这种情况下,也可以通过 “&” 来表示上一行的过滤体检。例如:
:msg,contains,"error" liuzx
& @192.168.1.1
包含 “error” 日志被同时发送给用户 liuzx 和通过 UDP 发送到 192.168.1.1。
日志输出模板
通过模板可以更具需要来控制日志输出的样式。格式如下:
$template <TEMPLATE_NAME>,"text %<PROPERTY>% more text", [<options>]
$template 为模板指令。<TEMPLATE_NAME> 为模板名。"" 之间的文本为模板格式。 被 % 包含的文本对应相关的属性。<options> 指定修改 模板功能的一些选项,例如 sql 或者 stdsql 会格式化文本为 SQL 查询。
动态文件输出
通过日志和/或系统属性决定输出文件名。
$template DynamicFile,"/var/log/test_logs/%timegenerated%-test.log"
*.* ?DynamicFile
使用 timegenerated 生成文件名,使用该模板则在前面加上 ?。
其他例子如下:
$template DailyPerHostLogs,"/var/log/syslog/%$YEAR%/%$MONTH%/%$DAY%/%HOSTNAME%/messages.log"
根据属性控制日志输出格式
使用下面的格式可以对模板之中的属性做各种修改操作从而定制日志的格式:
%<propname>[:<fromChar>:<toChar>:<options>]%
<propname> 属性名,可用的属性名参考上文。
<fromChar> 和 <toChar> 表示对属性值字符串的操作范围。 设置 <fromChar> 为 R,<toChar> 为正则表达式即可以通过正则 表达式定义范围。
<options> 则表示属性选项。完整的列表可以参考 这里的 Property Options 节。
一些示例如下:
%msg% # 日志的完整消息文本
%msg:1:2% # 日志消息文本的最开始两个字符
%msg:::drop-last-lf% # 日志的完整消息文本,移出最后的换行符
%timegenerated:1:10:date-rfc3339% # 时间戳的头10个字符并按 RFC3999 标准格式化
下面是一些模板例子。
输出日志的级别,类别,收到日志时的时间错,主机名,消息标签,消息正文, 加上换行符:
$template verbose,"%syslogseverity%,%syslogfacility%,%timegenerated%,%HOSTNAME%,%syslogtag%,%msg%\n"
输出日志来源,时间以及日志标签,正文,同时还有蜂鸣声(\7):
$template wallmsg,"\r\n\7Message from syslogd@%HOSTNAME% at %timegenerated% ...\r\n %syslogtag% %msg%\n\r"
格式化日志以便于直接进行 SQL 操作:
$template dbFormat,"insert into SystemEvents (Message, Facility,FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%',%syslogpriority%, '%timereported:::date-mysql%', '%timegenerated:::date-mysql%', %iut%, '%syslogtag%')",sql
以 json 格式输出,方便程序解析:
$template jsonFormat,"{\"message\":\"%msg:::json%\",\"fromhost\":\"%HOSTNAME:::json%\",\"facility\":\"%syslogfacility-text%\",\"priority\":\"%syslogpriority-text%\",\"timereported\":\"%timereported:::date-rfc3339%\",\"timegenerated\":\"%timegenerated:::date-rfc3339%\"}\n"
注意,message 的内容会在最前面多一个空格,其解释请参考这里。
rsyslog 也提供了一些预定义的模板(以 RSYSLOG_ 为前缀),参考 这里 的 Reserved Template Names 节,其定义如下:
RSYSLOG_FileFormat
"%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n\"
RSYSLOG_TraditionalFileFormat
"%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n\"
RSYSLOG_ForwardFormat
"<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%\"
RSYSLOG_TraditionalForwardFormat
"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%\"
使用这些模板,则在动作后附加 “;template_name” 即可,例如:
:programname,startswith,"cron" -/var/log/cron;RSYSLOG_TraditionalFileFormat
深入理解
队列是理解 rsyslog 内部原理和配置的重要基础, 参考 Understanding rsyslog Queues 和 Turning Lanes and Rsyslog Queues - an Analogy。 下图概要性的说明了 rsyslog 内的数据流图。
队列相关的配置指令:
$WorkDirectory /rsyslog/work # 中间文件存放路径
$ActionQueueType LinkedList # [FixedArray/LinkedList/Direct/Disk]
$ActionQueueFileName relpact # 定义队列文件名
$ActionResumeRetryCount -1 # 重试次数, -1 表示无限重试
$ActionQueueSaveOnShutdown on # rsyslog 关闭时将队列内容存盘,防止数据丢失
*.* :omrelp:172.19.2.10:2514
Syslog系统日志配置
Linux保存了系统中所发生事件的详细记录,这些记录称作日志文件或消息文件。可以查阅日志文件来确定系统当前状态,观察入侵者踪迹,寻找某特定程序(或事件)相关的数据。syslogd与klogd(监控linux内核提交的消息)守护进程负责记录,发送系统或工具产生的信息,二者的配置文件都是/etc/syslog.conf。当系统内核或工具产生信息时,通过调用相关函数将信息发送到syslogd或klogd守护进程。syslogd与klogd守护进程会根据/etc/syslog.conf中的配置信息,对消息的去向作出处理。syslog协议的详细描述在RFC3164中。
logrotate工具用来定期重命名、压缩、邮递系统日志文件,它可以保证日志文件不会占用太大的磁盘空间。
1、配置文件/etc/syslog.conf: syslog.conf是syslogd进程的配置文件,将在程序启动时读取,默认位置是/etc/syslog.conf。这个配置文件中的空白行和以"#"开头的行将被忽略。"facility.level"部分也被称为选择符(seletor)。 seletor和action之间使用一个或多个空白分隔。它指定了一系列日志记录规则。规则的格式如下:
facility.level action
选择符(seletor)由facility和level两部分组成,之间用一个句点(.)连接。
(1)facility:指定了产生日志的设备,可以是下面的关键字之一:
关键字 值 解释
kern 0 内核信息,首先通过klogd传递
user 1 由用户程序生成的信息
mail 2 与电子邮件有关的信息
daemon 3 与inetd守护进程有关的信息
auth 4 由pam_pwdb报告的认证活动
syslog 5 由syslog生成的信息
lpr 6 与打印服务有关的信息
news 7 来自新闻服务器的信息
uucp 8 由uucp生成的信息(uucp = unix to unix copy)
cron 9 与cron和at有关的信息
authpriv 10 包括私有信息(如用户名)在内的认证活动
ftp 11 与FTP有关的信息
12-15 系统保留
local0 ~ local7 16-23 由自定义程序使用,例如使用local5做为ssh功能
mark syslog内部功能,用于生成时间戳
* 通配符代表除了mark以外的所有功能
在大多数情况下,任何程序都可以通过任何facility发送日志消息,但是一般都遵守约定俗成的规则。比如,只有内核才能使用"kern"facility。注意syslog保留从“local0”到“local7”这几个设备号来接受从远程服务器和网络设备上发送过来的日志信息。路由器,交换机,防火墙和负载均衡器都很容易给它们各自配置一个独立的日志文件。
(2)level:指定了消息的优先级,可以是下面的关键字之一(降序排列,严重性越来越低):
关键字 值 解释
emerg 0 系统不可用
alert 1 需要立即被修改的条件
crit 2 (临界)阻止某些工具或子系统功能实现的错误条件
err 3 阻止工具或某些子系统部分功能实现的错误条件
warning 4 预警信息
notice 5 具有重要性的普通条件
info 6 提供信息的消息
debug 7 不包含函数条件或问题的其他信息
none (屏蔽所有来自指定设备的消息)没有优先级,通常用于排错
* 除了none之外的所有级别
facility部分可以是用逗号(,)分隔的多个设备,而多个seletor之间也可以通过分号(;)组合在一起。注意多个组合在一起的选择符,后面的会覆盖前面的,这样就允许从模式中排除一些优先级。默认将对指定级别以及更严重级别的消息进行操作,但是可以通过2个操作符进行修改。等于操作符(=)表示仅对这个级别的消息进行操作,不等操作符(!)表示忽略这个级别以及更严重级别的消息。这两个操作符可以同时使用,不过"!"必须出现在"="的前面。
(3)动作action:动作确定了syslogd与klogd守护进程将日志消息发送到什么地方去。有以下几种选择:
普通文件:使用文件的绝对路径来指明日志文件所在的位置,例如:/var/log/cron。
终端设备:终端可以是/dev/tty0~/dev/tty6,也可以为/dev/console。
用户列表:例如动作为“root hackbutter”,将消息写入到用户root与hackbutter的计算机屏幕上。
远程主机:将信息发往网络中的其他主机的syslogd守护进程,格式为“@hostname”。
(4)配置文件的语法说明:
*用作设备或优先级时,可以匹配所有的设备或优先级。
*用作动作时,将消息发送给所有的登录用户。
多个选择器可在同一行中,并使用分号分隔开,且后面的会覆盖前面的。如uucp,news.crit。
关键字none用作优先级时,会屏蔽所有来自指定设备的消息。
通过使用相同的选择器和不同的动作,同一消息可以记录到多个位置。
syslog.conf文件中后面的配置行不会覆盖前面的配置行,每一行指定的动作都独立的运作。
(5)我的Ubuntu中默认的/etc/syslog.conf内容:
# /etc/syslog.conf syslogd的配置文件
# 更多信息参考syslog.conf(5)
#
# 首先是一些标准的日志文件,消息由相应设备发送
#
# 认证活动auth,authpriv的日志消息发送到auth.log中
auth,authpriv.* /var/log/auth.log
# 除auth和authpriv之外的所有设备的所有消息都要发送到syslog中
*.*;auth,authpriv.none -/var/log/syslog
# cron及at的消息发送到cron.log
#cron.* /var/log/cron.log
# inetd的所有消息发送到daemon.log
daemon.* -/var/log/daemon.log
# 内核的所有消息(如klogd的消息)发送到kernlog
kern.* -/var/log/kern.log
# 打印服务的所有消息发送到lpr.log
lpr.* -/var/log/lpr.log
# 邮件的所有消息发送到mail.log
mail.* -/var/log/mail.log
# 用户程序的所有消息发送到user.log
user.* -/var/log/user.log
#
# 邮件系统的日志记录。分割成不同的文件,以便能够比较容易地写脚本来
# 解析这些文件
#
# 邮件的info或更高级别的消息发送到mail.info,warn更高级别的消息发送到mail.warn,
# err或更高级别的消息发送到mail.err
mail.info -/var/log/mail.info
mail.warn -/var/log/mail.warn
mail.err /var/log/mail.err
# INN新闻系统的日志记录:来自新闻服务器的消息
#
news.crit /var/log/news/news.crit
news.err /var/log/news/news.err
news.notice -/var/log/news/news.notice
#
# 一些捕捉用的日志文件
#
# 除auth,authpriv,news,mail之外的所有设备的debug级别消息都要发送到debug中
*.=debug;/
auth,authpriv.none;/
news.none;mail.none -/var/log/debug
# 除auth,authpriv,cron,daemon,mail,news之外的所有设备的info,notice,
# warn级别消息都要发送到messages中
*.=info;*.=notice;*.=warn;/
auth,authpriv.none;/
cron,daemon.none;/
mail,news.none -/var/log/messages
#
# 所有设备的emerg级别消息(系统无法使用)会发送给所有登录的用户
#
*.emerg *
#
# 希望一些消息显示在控制台,但只在虚拟控制台上:daemon,mail的任何消息;news的危险、
# 错误、通知消息;任何设备的调试、信息、通知、预警消息
#
#daemon,mail.*;/
# news.=crit;news.=err;news.=notice;/
# *.=debug;*.=info;/
# *.=notice;*.=warn /dev/tty8
# 命名管道/dev/xconsole用于xconsloe工具。为了使用它,你必须带-file选项来调用xconsole
# $ xconsole -file /dev/xconsole [...]
# 注意:调整下面的列表,否则如果你有一个相当繁忙的站点,你将变得发狂
daemon.*;mail.*;/
news.err;/
*.=debug;*.=info;/
*.=notice;*.=warn |/dev/xconsole
某些应用软件也会将自己的运行状况记录到特定的日志文件上,它不受syslog.conf文件的控制。如文件/var/log/apache2/access.log,目录/var/log/apache2, /var/log/cups, /var/log/gdm, /var/log/mysql, /var/log/samba等。
修改完/etc/syslog.conf后,可用service syslog restart重启syslog服务,Debian/Ubuntu中则用sudo /etc/init.d/sysklogd restart。查看日志文件里最新的记录可用tail -f /var/log/messages。
2、将日志信息记录到远程Linux服务器上: 将你的系统信息记录到远程服务器上将是一个很好的安全措施。如果把公司所有的服务器的日志信息都记录到一个集中的syslog服务器上,这将会方便你管理各个服务器中发生的相关事件。这也会使得掩盖错误和恶意攻击变得更困难,因为对各个日志文件的恶意删除在日志服务器上不能同时发生,特别是当你限制用户访问日志服务器时。
配置Syslog服务器:在默认情况下,syslog并不会接受远程客户端的信息,要激活它,RedHat/Fedora中需要修改/etc/sysconfig/syslog文件,在SYSLOGD_OPTIONS参数中增加-r选项,以允许记录远程机器的信息。Debian/Ubuntu中则是修改/etc/default/syslogd文件中的SYSLOGD参数,也可直接编辑syslog启动脚本/etc/init.d/sysklogd,将SYSLOGD的参数定义为“-r”。修改完后要重启syslog服务。
配置客户端:syslog服务器现在可以接受syslog信息了。你还要设置好远程linux客户端以向服务器发送信息。假设客户端主机名为smallfry,可通过编辑/etc/hosts文件来实现。
(1)确定远程服务器的IP地址和有效的域名。
(2)在客户端班机的/etc/hosts文件中加入远程服务器的描述:IP地址 完整域名 服务器名 “别名”,例如192.168.1.100 bigboy.my-site.com bigboy loghost,这样为服务器主机bigboy设置了一个别名loghost。
(3)编辑客户端的/etc/syslog.conf文件,使得syslog信息能发送到你新设置的日志服务器loghost上。
*.debug @loghost
*.debug /var/log/messages
重启syslog服务,现在你的机器将会将所有“调试”级别及以上级别的信息同时发送到服务器bigboy和本地文件/var/log/messeges上。你可以做个简单测试看看syslog服务器是否在接受你的信息了。比如重启一下lpd打印机守护进程,看看能否在服务器上看到相关日志消息。
3、配置文件/etc/logrotate.conf: 它是logrotate的一般性配置文件。你可以通过它设置哪个日志文件被循环重用以及多久重用一次。可以设定的循环参数有每周(weekly)或每天(daily)。rotate参数定义保留多少份日志文件备份,create参数指定在每轮循环后就新建空的日志文件。我的Ubuntu中默认的/etc/logrotate.conf内容为:
注意在Debian/Ubuntu系统中,/etc/cron.daily.sysklogd脚本将读取/etc/syslog.conf文件,并根据它轮转所有设定的日志文件。所以,对于一般的系统日志,你不必再在/etc/logrotate.d文件夹中重复设定了。因为在 /etc/cron.daily文件夹中它没24小时便运行一次。在Fedora/Redhat系统中,这个脚本被/etc/cron.daily/logrotate取代,而且它不读取syslog配置文件。所以,你必须在/etc/logrotate.d设置好。
对logrotate的设置只有在你使用logrotate -f命令时才会生效。如果你想让logrotate只读取特定的配置文件而不是所有,把配置文件名作为logrotate的参数运行即可,如logrotate -f /etc/logrotate.d/syslog。如果你的网页访问量比较高,那么日志文件将变得异常大。你可以通过编辑logrotate.conf文件加入压缩选项compress来实现对日志文件的压缩。这些日志文件将用gzip来压缩,所有的文件将会有一个.gz的扩展名。查看这些文件的内容依然很容易,因为你可以用zcat命令快速的将它们的内容显示在屏幕上。
Syslog服务器的一个缺点是没有把不良来源的消息过滤掉。因此,当你的的服务器位于一个不安全的网络时,使用TCP wrappers软件或防火墙来限制可以接受的消息来源是一个明智的举措。这将有助于限制拒绝服务攻击的成效,这种拒绝服务攻击的目的是填塞你的服务器的硬盘或加重其他系统资源负担,它有可能最终导致服务器崩溃。
现在使用越来越广泛的syslog-ng程序结合了logrotate和syslog的特性,它能给用户提供更多的自定义功能,从功能上也更加丰富了。如果你想使用它,可到www.balabit.com上去下载安装,其配置文件为/etc/syslog-ng/syslog-ng.conf。
我的系统配置:
CentOS 6.3
RSYSLOG 5.8.10
LogAnalyzer 4.1.1(v4-beta)
一、筛选日志到到独立的文件
在 git 和 server.git 和 serverctrl.git 两个库中,我使用了 Server-side hook(服务端钩子) 实现自动部署。这两个钩子程序会产生日志信息。
下面的设置,做了三件事:
将 FACILITY 为 local5 ,PRIORITY 为任意值的日志写入 all.log ;
将程序名称为 hhl-git-serverctrl 的日志写入 serverctrl.log ;
将程序名称为 hhl-git-server 的日志写入 server.log 。
-
local5.* /var/log/hhl/all.log
:programname,isequal,"hhl-git-serverctrl" /var/log/hhl/serverctrl.log
:programname,isequal,"hhl-git-server" /var/log/hhl/server.log
我将这些内容放在独立的配置文件中,存放在 /etc/rsyslog.d/ 文件夹下。它会在 rsyslogd 服务重启的时候被自动载入。
二、LogAnalyzer 不显示 FACILITY 和 PRIORITY
这是因为日志文件默认采用老的格式,而 LogAnalyzer 不完全支持这种格式。RSYSLOG WIKI 提供了解决方案。需要做下面几处修改:
1. 修改 /etc/rsyslog.conf 查找下面的内容:
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
将其替换成为:
$ActionFileDefaultTemplate RSYSLOG_SyslogProtocol23Format
这个操作将日志格式替换成了 RFC 5424 定义的格式。替换完毕记得重启 rsyslogd 。
2. 同上,将这个模版加入配置文件
$template TraditionalFormatWithPRI,"<%syslogpriority%>%syslogseverity% %timegenerated% %HOSTNAM E% %syslogtag%%msg:::drop-last-lf%\n"
3. 进入 LogAnalyzer 的 Admin Center 界面,修改 Source 使其使用 RSyslog Format23(RFC 5424) 。
三、使用 Python 写入日志
使用 Python 的 logging 包可以直接将日志写入 RSYSLOG 。在上面的配置文件中,我指定 FACILITY 是 local5 ,因此这里给出了相同的值。
还要注意 Formatter 第一个参数的第二段就是程序名称,RSYSLOG 可以依赖这个名称来筛选日志,写入到不同的文件。
#!/usr/bin/env python
import logging
from logging.handlers import SysLogHandler
log = logging.getLogger('git')
log.setLevel(logging.DEBUG)
log_hdlr = SysLogHandler(facility=SysLogHandler.LOG_LOCAL5, address='/dev/log')
log_format = logging.Formatter(
'%(asctime)s hhl-%(name)s-server[%(process)d]: %(message)s:', '%b %e %H:%M:%S')
log_hdlr.setFormatter(log_format)
log.addHandler(log_hdlr)
如果希望同时加上 print 效果,加入 StreamHandler 即可。
#!/usr/bin/env python
log_hdlr2 = logging.StreamHandler(sys.stdout)
log_hdlr2.setFormatter(log_format)
log.addHandler(log_hdlr2)