syslog是UNIX系统中提供的一种日志记录方法(RFC3164),syslog本身是一个服务器,程序中凡是使用syslog记录的信息都会发送到该服务器,服务器根据配置决定此信息是否记录,是记录到磁盘文件还是其他地方,这样使系统内所有应用程序都能以统一的方式记录日志,为系统日志的统一审计提供了方便。
Rsyslog 是一个 syslogd 的多线程增强版。
centos 6以上的都是rsyslog。
syslog服务器的配置文件为/etc/rsyslog.conf,syslog( )函数把想记录的日志信息都发送给日志服务器,但此日志最终是否记录到文件或发送给远程服务器,则是由此配置文件来决定的,该配置文件就是告诉日志服务器要记录那些类型和级别的日志,如何记录等信息。配置文件/etc/rsyslog.conf大概分为三个部分
####MODULES####
这个部分是针对接收配置的,主要是指定接收日志的协议和端口。若要配置日志服务器,则需要将相应的配置项去掉注释。
####GLOBAL DIRECTIVES####
这个部分主要用来配置模板,模板的作用是指定你希望在日志文件中保存的日志格式。
#### RULES ####
这一部分是规则文件,每行配置分两个字段,第一字段是说明要记录哪类日志(包括消息类型和等级),第二字段是说明日志存放位置(action),可以是本地文件,也可以是远程服务器。filter action
rsyslog发现符合 filter 规则的日志后,会将日志发送到 action 指定的动作进行处理。
在rsyslog中,提供了三种方式的过滤器方法:
基于设施/优先级的过滤器是最常用的方法,语法如下:
FACILITY.PRIORITYFacility消息类型,指定 syslog 功能,主要包括:
kern 内核信息,首先通过 klogd 传递; user 用户进程; mail 邮件; daemon 后台进程; authpriv 授权信息; syslog 系统日志; lpr 打印信息; news 新闻组信息; uucp 由uucp生成的信息 cron 计划和任务信息。 mark syslog 内部功能用于生成时间戳 local0----local7 与自定义程序使用,例如使用 local5 做为 ssh 功能 * 通配符代表除了 mark 以外的所有功能
Priority消息级别,指定syslog优先级由高到低主要包括:
emerg 或 panic 该系统不可用(最紧急消息) alert 需要立即被修改的条件(紧急消息) crit 阻止某些工具或子系统功能实现的错误条件(重要消息) err 阻止工具或某些子系统部分功能实现的错误条件(出错消息) warning 预警信息(警告消息) notice 具有重要性的普通条件(普通但重要的消息) info 提供信息的消息(通知性消息) debug 不包含函数条件或问题的其他信息(调试级-信息量最多) none 没有重要级,通常用于排错(不记录任何日志消息) * 所有级别,除了none前置符号=表明只有该优先级的消息会被捕获,!表明除了该优先级的消息之外的优先级会被捕获。除了前置符号外,可以使用符号*
xxx: 表示大于等于xxx级别的信息 =xxx:表示等于xxx级别的信息 !xxx:表示在xxx之外的等级的信息
表示所有的设施或者优先级,对优先级部分使用none关键字会捕获所有没有指定优先级的消息。
定义多个设施或者优先级使用,分隔,如果是多个 filter 的话,则使用;进行分隔。
使用范例
kern.* # 选择所有优先级的内核日志 mail.crit # 选择所有mail 的优先级高于crit的日志 cron.!info,!debug # 选择除了 info 和 debug 优先级的 cron 日志基于属性的过滤器语法
:PROPERTY, [!]COMPARE_OPERATION, "STRING":PROPERTY是要比较的日志属性,COMPARE_OPERATION 为要执行的比较操作,这个的!表示取反的意思,"STRING"为比较的值。
可以使用的比较操作:
比较操作 描述 contains 匹配提供的字符串值是否是属性的一部分,如果不区分大小写,使用contains_i isequal 比较属性和值是否相等 startswith 属性是否以指定字符串开始(startswith_i) regex 正则表达式(POSIX BRE 基本正则)匹配 ereregex 正则表达式(POSIX ERE 扩展正则)匹配 isempty 判断属性是否为空,不需要 value使用范例:
:msg, contains, "error" :hostname, isequal, "host1" :msg, !regex, "fatal .* error"基于表达式的过滤器使用了rsyslog自定义的脚本语言RainerScript构建复杂的filter,这里暂时不对这种方法进行讲述。
Action定义了当匹配指定的 filter 的时候,执行什么操作。
如果要指定多个 ACTION, 使用 &连接多个 ACTION。 例如:
kern.=crit user1 & ^test-program;temp & @192.168.0.1这里的;temp指定了传递日志给 test-program 程序时( ^ 开头表明日志发送给该可执行文件),使用它 temp 模板格式化日志。
local3.* ^/tmp/a.sh # ^号后跟可执行脚本或程序的绝对路径
在 ACTION 后面追加;模板名称可以为指定的 action 使用该模板格式化日志。
语法:
FILTER PATH这里的 PATH 指定了日志要保存到的文件。例如 cron.* /var/log/cron.log 指定了所有的定时任务日志都写入到/var/log/cron.log文件。
默认情况下,每次生成 syslog 的时候,日志信息会同步到日志文件。可以在文件路径前使用 - 指定忽略同步(如果系统崩溃,会丢失日志,但是这样可以提高日志性能)。
除了上述方法记录日志(静态),也可以动态的生成日志文件。
FILTER ?DynamicFile这里的DynamicFile是预定义的输出路径模板。
rsyslog可以使用网络将日志消息发送或者接受日志,使用这个特性,可以实现使用单一的日志服务器统一管理多台服务器日志。
@[(zNUMBER)]HOST:[PORT]这里的@告诉syslog使用 UDP 协议发送日志,要使用 TCP 的话,使用 @@。可选值zNUMBER设置了是否允许使用zlib对日志压缩(压缩级别1-9)。
使用范例
*.* @192.168.0.1 # 使用 UDP 发送,默认端口514 *.* @@example.com:18 # 使用 TCP 发送到端口18, 默认10514 *.* @(z9)[2001:db8::1] # UDP, ipv6,使用zlib级别9压缩要丢弃日志消息,使用~动作。
FILTER ~例如:
cron.* ~任何rsyslog生成的日志都可以根据需要使用模板进行格式化,要创建模板,使用如下指令
$template TEMPLATE_NAME,"text %PROPERTY% more text", [OPTION]这里的$template指令表明了接下来的内容定义了一个模板,TEMPLATE_NAME是模板的名称,接下来双引号之间的内容为模板的内容。
这里还有一个 OPTION , 它指定了模板的功能,支持选项为sql和stdsql,在使用数据库存储的时候会用到。
模板可以用来生成动态文件名,就如之前所述,在使用动态文件名的时候,需要在 ACTION 中的模板名称前增加?表明该文件名是动态生成的。
例如:
$template DynamicFile,"/var/log/test_logs/%timegenerated%-test.log" *.* ?DynamicFiletimegenerated属性从日志信息中提取出消息的时间戳,这样可以为每个日志生成唯一文件名称。
在模板中使用的属性是在%之间的内容,使用属性可以访问日志消息中的内容。
%PROPERTY_NAME[:FROM_CHAR:TO_CHAR:OPTION]%可用的属性列表见man rsyslog.conf。
全局指令是rsyslogd守护进程的配置指令。所有的全局指令必须以$开始,每行只能有一个指令,例如:
$MainMsgQueueSize 50000在新的配置格式中(rsyslog v6),已经不在使用这种方式的指令,但是它们仍然是可用的。
如果不记录某级别的日志,在级别前加“!”,如:
auth.info;auth.!err #info及info级别以上但不包括err级别的auth类型日志
也可以是远程服务器端,格式是“@address”,“@”表示进行远程记录,将日志发送到远程的日志服务器,日志服务器的端口是UDP514,address可以是IP地址,也可以是域名:
kern.* @1.1.1.1 #将所有级别的内核日志发送到远程syslog服务器
//其中*是通配符,代表任何设备;none表示不对任何级别的信息进行记录。
*.info;mail.none;news.none;authpriv.none;cron.none /var/log/messages
//将authpriv的任何级别的信息记录到/var/log/secure文件中,这主要是一些和认、权限使用相关的信息。
authpriv.* /var/log/secure
//将mail设备中的任何级别的信息记录到/var/log/maillog文件中,这主要是和电子邮件相关的信息。
mail.* -/var/log/maillog
//将cron设备中的任何级别的信息记录到/var/log/cron文件中,这主要是和系统中定期执行的任务相关的信息。
cron.* /var/log/cron
//将任何设备的emerg级别的信息发送给所有正在系统上的用户。
*.emerg *
//将uucp和news设备的crit级别的信息记录到/var/log/spooler文件中。
uucp,news.crit /var/log/spooler
//将和系统启动相关的信息记录到/var/log/boot.log文件中。
local7.* /var/log/boot.log
//将发送所有的消息除了等级为info的消息。 mail.*;mail.!info /var/log/mail
//把syslog消息通过UDP发送到syslog服务器的514端口: *.err @192.168.0.1
//发生错误时,在控制台打屏: *.err /dev/console
syslog配置文件 -> /etc/syslog.conf
(1)内核信息 -> klogd -> syslogd -> /var/log/messages等文件
(2)其他信息 -> syslogd -> /var/log/messages等文件
syslogd 守护程序:
如果将要使用一个日志服务器,必须调用 syslogd -r。缺省情况下 syslog 不接受来自远程系统的信息。当指定 -r 选项,syslogd 将会监听从 514 端口上进来的 UDP 包。
如果还希望日志服务器能传送日志信息,可以使用 -h 标志。缺省时,syslogd 将忽略使其从一个远程系统传送日志信息到另一个系统的/etc/syslog.conf 输入项。
(1)编辑/etc/sysconfig/rsyslog文件
在“SYSLOGD_OPTIONS”行上加“-r”选项以允许接受外来日志消息。 如果因为关于其他机器的DNS记录项不够齐全或其他原因不想让中央日志服务器解析其他机器的FQDN,还可以加上“-x”选项。 此外,你或许还想把默认的时间戳标记消息(--MARK--)出现频率改成比较有实际意义的数值,比如240,表示每隔240分钟(每天6次)在日志文件里增加一行时间戳消息。日志文件里的“--MARK--”消息可以让你知道中央日志服务器上的 syslog守护进程没有停工偷懒。按照上面这些解释写出来的配置行应该是如下所示的样子:SYSLOGD_OPTIONS="-r-x-m240"
(2)编辑rsyslog配置文件,路径 /etc/rsyslog.conf,修改前最好先备份一份,修改后的文件内容如下
[root@opm log]# grep -v "^#" /etc/rsyslog.conf | grep -v "^$" $ModLoad imuxsock # provides support for local system logging (e.g. via logger command) $ModLoad imjournal # provides access to the systemd journal $ModLoad immark # provides --MARK-- message capability $ModLoad imudp $UDPServerRun 514 $WorkDirectory /var/lib/rsyslog $AllowedSender tcp, 192.168.0.0/24 $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat $template Remote,"/data/log/%fromhost-ip%/%fromhost-ip%_%$YEAR%-%$MONTH%-%$DAY%.log" :fromhost-ip, !isequal, "127.0.0.1" ?Remote $IncludeConfig /etc/rsyslog.d/*.conf $OmitLocalLogging on $IMJournalStateFile imjournal.state *.info;mail.none;authpriv.none;cron.none /data/log/messages authpriv.* /var/log/secure mail.* -/var/log/maillog cron.* /var/log/cron *.emerg :omusrmsg:* uucp,news.crit /var/log/spooler local7.* /var/log/boot.log
a.$AllowedSender udp, 192.168.0.0/24 允许 0.0网段内的主机以udp协议来传输
b.$template Remote,"/data/log/%fromhost-ip%/%fromhost-ip%_%$YEAR%-%$MONTH%-%$DAY%.log" 定义模板,接受日志文件路径,区分了不同主机的日志
c.:fromhost-ip, !isequal, "127.0.0.1" ?Remote 过滤server 本机的日志。
创建日志目录,尽量选择系统内比较大的区域创建,因为考虑到要存放很多服务器的日志文件。
# mkdir -pv /data/log 修改完成无误后,重启rsyslog服务,并查看监听端口,514 是否是tcp协议
[root@opm ~]# systemctl restart rsyslog [root@opm ~]# netstat -aulntp | grep rsyslog tcp 0 0 0.0.0.0:514 0.0.0.0:* LISTEN 20228/rsyslogd tcp6 0 0 :::514 :::* LISTEN 20228/rsyslogd udp 0 0 0.0.0.0:514 0.0.0.0:* 20228/rsyslogd udp6 0 0 :::514 :::* 20228/rsyslogd
如果验证失败的话,先检查selinux 是否关闭(如果没有关闭,则需要关闭)。后将udp 514 端口和tcp 514端口允许0网段访问即可,或者关闭iptables 服务。另外说明centos7上 默认防火墙是firewalld。该操作在每台机器上进行。
关闭selinux参考:点击打开链接
设置防火墙参考:CentOS7使用firewalld打开关闭防火墙与端口
为记录日志,通常用到3个函数,openlog( ),syslog( )和closelog( ),openlog( )和closelog( )不是必须的,没有openlog( )的话将用系统缺省的方式记录日志。 #include <syslog.h> void openlog( char *ident, int option, int facility) void syslog( int priority, char *format, ...) void closelog( void )
logopt参数
说 明
LOG_PID
在日志信息中包含进程标识符,这是系统分配给每个进程的一个唯一值
LOG_CONS
如果信息不能被记录到日志文件中,就把它们发送到控制台
LOG_ODELAY
在第一次调用syslog时才打开日志功能
LOG_NDELAY
立即打开日志功能,而不是等到第一次记录日志时
openlog函数会分配并打开一个文件描述符,并通过它来写日志。你可以使用closelog函数来关闭它。
第三个参数是说明日志类型的: LOG_AUTH LOG_AUTHPRIV LOG_CRON LOG_DAEMON LOG_KERN LOG_LOCAL0 - LOG_LOCAL7 (编程中用户自定义) LOG_LPR LOG_MAIL LOG_NEWS LOG_SYSLOG LOG_USER(default) LOG_UUCPsyslog()函数主要的是第一个参数priority,后面那些参数就是和printf( )函数用法一样了,priority值表示该条日志的级别,日志级别分8级,由高到低的顺序为:
优 先 级
说 明
LOG_EMERG
紧急情况
LOG_ALERT
高优先级故障,例如数据库崩溃
LOG_CRIT
严重错误,例如硬件故障
LOG_ERR
错误
LOG_WARNING
警告
LOG_NOTICE
需要注意的特殊情况
LOG_INFO
一般信息
LOG_DEBUG
调试信息
根据系统配 置,LOG_EMERG信息可能会广播给所有用户,LOG_ALERT信息可能会EMAIL给管理员,LOG_DEBUG信息可能会被忽略,而其他信息则 写入日志文件。当我们编写的程序需要使用日志记录功能时,只要在希望创建一条日志信息时简单的调用syslog函数即可。如果openlog( )时没有指定facility,是可以把facility的值或到priority中的,如(LOG_AUTH | LOG_INFO),已经设置了就可以不用或了。
closelog( )这个没啥好说的了,关闭日志记录。
实例:
//syslog.c #include <stdio.h> #include <syslog.h> int main(int argc, char **argv) { openlog("MyMsgMARK", LOG_CONS | LOG_PID, LOG_LOCAL0); syslog(LOG_EMERG, "This is a syslog test message generated by program '%s'/n", argv[0]); closelog(); return 0; }
通过logger命令记录日志
logger是一个shell命令接口,可以通过该接口使用Syslog的系统日志模块,还可以从命令行直接向系统日志文件写入一行信息。
----------------------------------------------------------
logger 语法 logger [options] [messages] **options (选项):** -d, --udp 使用数据报(UDP)而不是使用默认的流连接(TCP) -i, --id 逐行记录每一次logger的进程ID -f, --file file_name 记录特定的文件 -h, --help 显示帮助文本并退出 -n, --server 写入指定的远程syslog服务器,使用UDP代替内装式syslog的例程 -P, --port port_num 使用指定的UDP端口。默认的端口号是514 -p, --priority priority_level 指定输入消息的优先级,优先级可以是数字或者指定为 "facility.level" 的格式。比如:"-p local3.info " local3 这个设备的消息级别为info。默认级别是 "user.notice" -s, --stderr 输出标准错误到系统日志。 -t, --tag tag 指定标记记录 -u, --socket socket 写入指定的socket,而不是到内置系统日志例程。 -V, --version 现实版本信息并退出 **messages:**写入log文件的内容消息,可以与-f配合使用。 logger 以0退出表示成功,大于0表示失败。
示例: $ logger System Rebooted #往系统日志例程中写入“System Rebooted”可在/var/log/syslog中查看 写入到指定的log文件中。
示例: $ vim /etc/rsyslog.conf #在最后一行加入local3.* /var/log/my_test.log 意思是来自local3的所有消息都记录到/var/log/my_test.log中。
$ systemctl restart rsyslog #重启rsyslog服务
$ logger -i -t "my_test" -p local3.notice "test_info"
$ cat /var/log/my_test.log May 5 21:27:37 gino-virtual-machine my_test[3651]: test_info
-i 在每行都记录进程ID
-t my_test每行记录都加上“my_test”这个标签
-p local3.notice 设置记录的设备和级别
"test_info" 输出信息
SNMP Trap 参考文献:
浅谈 Linux 系统中的 SNMP Trap
参考文献:
Linux syslog介绍
Linux 之 rsyslog 系统日志转发
linux日志logger命令详解