背景:需求来自于一个客户想将服务器的日志转发到自己的日志服务器上,所以希望我们能提供这个转发的功能,同时还要满足syslog协议。
一、什么是syslog协议
1、介绍(略)
2、syslog标准协议如下图
这里的facility为模块,serverity为等级,由这两个信息共同计算出一个PRI头部。HEADER部分包含了时间和主机名。在HEADER和MSG之间有一个空格,MSG是需要记录的日志部分(日志消息体)。
这里也就是说,理论上使用这种格式构造的字符串发送,接收方就能解析出来。实际上根据实验,我使用了UDP发送,接收方syslog日志服务器能正确解析。
这里需要注意的是,如果使用了程序的库,比如:python的syslog库(同样c++也有相似的库),那么就不再需要关注PRI和HEADER部分,只要将相关的参数(facility,severity,time,ip)传入函数,调用发送就可以,不必自己构造字符串。对服务端来说,接收到的是整个消息,但通常来讲,比如使用linux默认的rsyslog作为接收服务端的话,是不能看到除MSG之外的部分。所看到的消息跟接收端配置有关,这个在下面有具体的讲。
3、以下是各级别及对应的数字代码
Facility:有0-23种设备可选,在python的syslog库中有一部分缺失
0 kernel messages
1 user-level messages
2 mail system
3 system daemons
4 security/authorization messages
5 messages generated internally by syslogd
6 line printer subsystem
7 network news subsystem
8 UUCP subsystem
9 clock daemon
10 security/authorization messages
11 FTP daemon
12 NTP subsystem
13 log audit
14 log alert
15 clock daemon
16-23 local0 - local7
Severity:日志等级
0 Emergency
1 Alert
2 Critical
3 Error
4 Warning
5 Notice
6 Informational
7 Debug
这里结合等级再详细讲一下syslog协议:
Priority(优先级) = facility * 8 + severity值。比如说,一个核心信息(facility=0)和一个Emergency的severity将会产生优先级为0。同样, 一个“local use 4”信息(facility=20)和一个Notice的severity(severity=5)将会产生165的优先级。
标题(HEADER)部分由称为TIMESTAMP和HOSTNAME的两个域组成,PRI结尾的“>”会马上跟着一个 TIMESTAMP,任何一个TIMESTAMP或者HOSTNAME域后面都必须跟着一个空格字符。HOSTNAME包含主机的名称,若无主机名或无法 识别则显示IP地址。如果一个主机有多个IP地址,它通常会使用它传送信息的那个IP地址。TIMESTAMP是本机时间,采用的格式是“Mmm dd hh:mm:ss”表示月日时分秒。HOSTNAME域仅仅能够包括主机名称,Ipv4地址或者是信息产生者的Ipv6地址。
MSG部分是Syslog数据包剩下的部分。这通常包含了产生信息进程的额外信息,以及信息的文本部分。MSG部分有两个域,分别为TAG域和 CONTENT域,TAG域的值是产生信息的程序或者进程的名称,CONTENT包含了这个信息的详细内容。传统上来说,这个域的格式较为自由,并且给出 一些时间的具体信息。TAG是一个不许超过32个字符的字母数字字符串,任何一个非字母数字字符都将会终止TAG域,并且被假设是CONTENT域的开 始。在大多数情况下,表示TAG结束的CONTENT域的第一个字符用左大括号( [ ],分号( : )或者是空格来表示。
下面是一个使用socket实现syslog日志的py脚本,大家可以参考,加深理解syslog协议