Syslog配置详解及编程实例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zyy617532750/article/details/74942090

1.背景

syslog是UNIX系统中提供的一种日志记录方法(RFC3164),syslog本身是一个服务器,程序中凡是使用syslog记录的信息都会发送到该服务器,服务器根据配置决定此信息是否记录,是记录到磁盘文件还是其他地方,这样使系统内所有应用程序都能以统一的方式记录日志,为系统日志的统一审计提供了方便。


2. 日志格式

syslog记录的日志格式为:
月  日  时:分:秒  主机名  标志  日志内容

3. syslog配置文件

Rsyslog 是一个 syslogd 的多线程增强版。

centos 6以上的都是rsyslog。

syslog服务器的配置文件为/etc/rsyslog.conf,syslog( )函数把想记录的日志信息都发送给日志服务器,但此日志最终是否记录到文件或发送给远程服务器,则是由此配置文件来决定的,该配置文件就是告诉日志服务器要记录那些类型和级别的日志,如何记录等信息。
 

配置文件/etc/rsyslog.conf大概分为三个部分

####MODULES####

这个部分是针对接收配置的,主要是指定接收日志的协议和端口。若要配置日志服务器,则需要将相应的配置项去掉注释。

####GLOBAL DIRECTIVES####

这个部分主要用来配置模板,模板的作用是指定你希望在日志文件中保存的日志格式。

#### RULES ####

扫描二维码关注公众号,回复: 3721012 查看本文章
这一部分是规则文件,每行配置分两个字段,第一字段是说明要记录哪类日志(包括消息类型和等级),第二字段是说明日志存放位置(action),可以是本地文件,也可以是远程服务器。


filter        action

rsyslog发现符合 filter 规则的日志后,会将日志发送到 action 指定的动作进行处理。

Filter

rsyslog中,提供了三种方式的过滤器方法:

(1) 基于设施/优先级的过滤器 (Facility/Priority-based filters)

基于设施/优先级的过滤器是最常用的方法,语法如下:

FACILITY.PRIORITY

Facility消息类型,指定 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 日志
(2) 基于属性的过滤器

基于属性的过滤器语法

: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"
(3) 基于表达式的过滤器

基于表达式的过滤器使用了rsyslog自定义的脚本语言RainerScript构建复杂的filter,这里暂时不对这种方法进行讲述。

Action

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是预定义的输出路径模板。

通过网络发送syslog

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 , 它指定了模板的功能,支持选项为sqlstdsql,在使用数据库存储的时候会用到。

生成动态文件名

模板可以用来生成动态文件名,就如之前所述,在使用动态文件名的时候,需要在 ACTION 中的模板名称前增加?表明该文件名是动态生成的。

例如:

$template DynamicFile,"/var/log/test_logs/%timegenerated%-test.log"
*.* ?DynamicFile

timegenerated属性从日志信息中提取出消息的时间戳,这样可以为每个日志生成唯一文件名称。

属性

在模板中使用的属性是在%之间的内容,使用属性可以访问日志消息中的内容。

%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



4.linux日志管理工作流程:

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 输入项。


5.实际搭建流程:

5.1 搭建Syslog服务器

(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     

5.2 搭建Syslog客户端

打开配置文件,老样子,先备份下在进行修改 /etc/rsyslog.conf,修改完记得要重启程序
$ModLoad imuxsock # provides support for local system logging (e.g. via logger command)
$ModLoad imjournal # provides access to the systemd journal
$WorkDirectory /var/lib/rsyslog
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
$template myFormat,"%timestamp% %fromhost-ip% %msg%\n"
$ActionFileDefaultTemplate myFormat
$IncludeConfig /etc/rsyslog.d/*.conf
$OmitLocalLogging on
$IMJournalStateFile imjournal.state
*.info;mail.none;authpriv.none;cron.none                @192.168.0.100
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

5.3 验证

在客户端上在命令行里输入 logger “this is test ” 发送消息,server上进行查看下在服务器上进到 /data/log 目录下,查看是否有客户端的内容

[root@admin ~]# tail -1f /data/log/192.168.0.101/192.168.0.101_2017-07-12.log 
Jul 12 16:05:12 localhost iie: this is test

 

如果验证失败的话,先检查selinux 是否关闭(如果没有关闭,则需要关闭)。后将udp 514 端口和tcp 514端口允许0网段访问即可,或者关闭iptables 服务。另外说明centos7上 默认防火墙是firewalld。该操作在每台机器上进行。

关闭selinux参考:点击打开链接

设置防火墙参考:CentOS7使用firewalld打开关闭防火墙与端口


 

6. Syslog编程

为记录日志,通常用到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 )
 

6.1 openlog( )函数

openlog()函数有三个参数:
第一个参数是标志字符串,也就是日志中的第5个字段(前4个字段分别是月、日、时:分:秒、主机名),不设的话缺省取程序名称;
第二个参数是选项,是下面一些标志位的组合,如(LOG_PID | LOG_CONS):

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_UUCP

6.2 syslog()函数

syslog()函数主要的是第一个参数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),已经设置了就可以不用或了。


6.3 closelog()函数

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;  
} 



7 logger命令

通过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命令详解









猜你喜欢

转载自blog.csdn.net/zyy617532750/article/details/74942090
今日推荐