Linux中syslog日志函数扫盲式实例解析

来源:互联网 发布:淘宝黄山烧饼哪个牌子 编辑:程序博客网 时间:2024/05/16 05:17

由于近期项目的需要,想在AP上利用syslog机制来通告远程路由器一些链路信息。于是,我借此机会对syslog机制及用法进行了一个小小的整理。

一、SYSLOG机制简要概述

syslog是Linux中设置(或者用更形象的词“创建”)系统日志的一种工具。其包含了一系列的系统函数,其中最主要的三个函数有openlog, syslog, closelog。另外,还有一个vsyslog,暂且将其。vsyslog和yslog功能一样,只是参数格式不同。在Linux中有另外一种机制来处理函数变量数量/格式不定的问题,这种类型的函数一般情况下,函数名都是以v开头的,参数中一般包含“...”的参数。在函数实现中,一般都有va_list ap; va_start(ap, fmt); va_end(ap); 三个步骤,来定义不定参数ap的生存周期。

通常,syslog守护进程在启动时会读一个配置文件。一般来说,其文件名为/etc/syslog.conf,该文件决定了不同种类的消息应送向何处。例如,紧急消息可被送向系统管理员(若已登录),并在控制台上显示,而警告消息则可记录到一个文件中。该机制提供了syslog函数,其调用格式如下:
#include <syslog.h>
void openlog(char*ident,int option ,int facility);
void syslog(int priority,char*format,……)
void closelog();

调用openlog是可选择的。如果不调用openlog,则在第一次调用syslog时,自动调用openlog。调用closelog也是可选择的,它只是关闭被用于与syslog守护进程通信的描述符。调用openlog使我们可以指定一个ident,以后, 此ident 将被加至每则记录消息中。


二、函数详细介绍
下面我们对syslog相关的函数调用及参数使用做个详细说明,主要参看的是Linux的man手册,同时我们用实例来进行分析,达到学以会用。
(1)openlog函数及其参数:
void openlog(const char *ident, int option, int facility);
此函数用来打开一个到系统日志记录程序的连接,打开之后就可以用syslog或vsyslog函数向系统日志里添加信息了。
openlog的第一个参数ident将是一个标记,ident所表示的字符串将固定地加在每行日志的前面以标识这个日志,通常就写成当前程序的名称以作标记。也就是区分日志的一个标记字符,可以由我们自己来设定。

第二个参数option应该是日志消息格式内容的配置选项。是下列值取与运算的结果:LOG_CONS, LOG_NDELAY, LOG_NOWAIT, LOG_ODELAY, LOG_PERROR, LOG_PID,各值意义请参考man openlog手册:
       LOG_CONS
              Write directly to system console if there is an error while sending to system logger.

       LOG_NDELAY
              Open the connection immediately (normally, the connection is opened when the first message is logged).

       LOG_NOWAIT
              Don't  wait  for  child processes that may have been created while logging the message.  (The GNU C library does not create a
              child process, so this option has no effect on Linux.)

       LOG_ODELAY
              The converse of LOG_NDELAY; opening of the connection is delayed until syslog() is called.  (This is the  default,  and  need
              not be specified.)

       LOG_PERROR
              (Not in SUSv3.) Print to stderr as well.

       LOG_PID
              Include PID with each message.
 
第三个参数指明记录日志的程序的类型。个人感觉不重要,不知道有什么用。通常情况下,我们都只用LOG_LOCAL0 到 LOG_LOCAL7中的任意一个。可选的程序有很多,例如:
       LOG_DAEMON
              system daemons without separate facility value

       LOG_FTP
              ftp daemon

       LOG_KERN
              kernel messages

       LOG_LOCAL0 through LOG_LOCAL7
              reserved for local use

       LOG_LPR
              line printer subsystem

       LOG_MAIL
              mail subsystem

       LOG_NEWS
              USENET news subsystem

       LOG_SYSLOG
              messages generated internally by syslogd

       LOG_USER (default)
              generic user-level messages
除此之外,还有其他的类型,具体可以参考man openlog手册。

 

(2)syslog函数及参数
syslog函数用于把日志消息发给系统程序syslogd去记录,此函数原型是:
void syslog(int priority, const char *format, ...);
第一个参数是消息的紧急级别,可以对日志设置级别,然后跟系统级别相比,如果级别不够,则不予显示。例如,我们可以查看debug模式和非debug模式的两种系统日志。

如果openlog() 时没有指定facility,是可以把facility的值或到priority中的,如(LOG_AUTH | LOG_INFO),已经设置了就可以不用或了。

 

第二个参数是消息的格式,之后是格式对应的参数。就是printf函数一样使用。

如果我们的程序要使用系统日志功能,只需要在程序启动时使用openlog函数来连接syslogd程序,后面随时用syslog函数写日志就行了。


(3)closelog函数及参数
closelog 用来关闭正在使用写系统日志的描述符,没有参数。


三、实例分析
到此为止,从理论上对syslog进行了描述,也许还是云里雾里的,下面通过一个实例来分析。

程序的用法示例代码如下:

#include <syslog.h>
int main(int argc, char **argv)
{
    openlog("NGIRC—AP", LOG_CONS | LOG_PID, 0);
    syslog(LOG_INFO,
           "This is a syslog info generated by program: '%s'\n",
           argv[0]);
    closelog();
    return 0;
}
 
编译生成可执行程序后,运行一次程序将向/var/log/message文件添加一行,我们可以直接查看message文件,或者使用logread/logwatch来查看我们的系统日志信息。例如,我们的程序的日志信息如下:
Apr 28 10:47:11 IMS NGIRC—AP[21514]: This is a syslog info generated by program: './mylogger'

下面我们通过抽样更改函数的参数,来观察日志结果,并对结果进行简要说明。

【变更一】
openlog("NGIRC—AP", LOG_CONS|LOG_PID,LOG_MAEDON);
syslog(LOG_DEBUG,"This is a syslog info generated by program: '%s'\n",argv[0]);

结果:
none

说明:
因为我的系统设定的日志显示级别是LOG_INFO,LOG_DEBUG在LOG_INFO之下,所以没有进行打印。

【变更二】
openlog("NGIRC—AP", LOG_CONS|LOG_PID,LOG_MAEDON);
syslog(LOG_INFO,"This is a syslog info generated by program: '%s'\n",argv[0]);

结果:
Apr 28 10:47:11 IMS NGIRC—AP[21514]: This is a syslog info generated by program: './mylogger'

说明:
级别是LOG_INFO,所以会打印。OPTION是LOG_CONS|LOG_PID,所以会打印出标识符和进程号:NGIRC—AP[21514]。

【变更三】
openlog("NGIRC—AP", LOG_CONS,LOG_MAEDON);
syslog(LOG_INFO,"This is a syslog info generated by program: '%s'\n",argv[0]);

结果:
Apr 28 10:56:41 IMS NGIRC—AP: This is a syslog info generated by program: './mylogger'

说明:
OPTION是LOG_CONS,所以只会打印出标识符,不打印进程号:NGIRC—AP。

【变更四】
openlog("NGIRC—AP", LOG_CONS,0);
syslog(LOG_INFO,"This is a syslog info generated by program: '%s'\n",argv[0]);

结果:
Apr 28 11:18:05 IMS NGIRC—AP: This is a syslog info generated by program: './mylogger'

说明:
Facility 是 0,在消息内容上没能体现区别,但通过抓取数据包的前缀中提供相关的信息。


【变更五】
openlog("NGIRC—AP", LOG_CONS,LOG_LOCAL7);
syslog(LOG_INFO,"This is a syslog info generated by program: '%s'\n",argv[0]);

结果:
Apr 28 11:20:32 IMS NGIRC—AP: This is a syslog info generated by program: './mylogger'

说明:
Facility 是 LOG_LOCAL7,在消息内容上没有区别,但通过抓取数据包的前缀中提供相关的信息。

【变更六】
openlog("NGIRC—AP", 0,LOG_LOCAL7);
syslog(LOG_INFO,"This is a syslog info generated by program: '%s'\n",argv[0]);

结果:
Apr 28 11:23:26 IMS NGIRC—AP: This is a syslog info generated by program: './mylogger'

说明:
OPTION 是 0,在消息内容上,没有区别,但通过抓取数据包的前缀中提供相关的信息。

原创粉丝点击