引用自:http://blog.chinaunix.net/uid-26675482-id-3130583.html
守护进程日志的实现
syslogd守护进程用于解决守护进程的日志记录问题,而日志信息保存的位置和记录的信息级别是在syslogd守护进程的配置文件中设定的。守护进程 日志主要涉及3个函数,分别是openlog、syslog和closelog函数。表8.4所示为这3个函数的具体信息。
表8.4 openlog、syslog和closelog函数
头文件 |
|
||
函数形式 |
void openlog(const char *ident, int option, int facility); void syslog(int priority, const char *format, ...); void closelog(void); |
||
|
|
|
|
说明:调 用openlog是可选择的。如果不调用openlog,则在第一次调用syslog时,自动调用openlog。调用closelog也是可选择的,它 只是关闭被用于与syslog守护进程通信的描述符。调用openlog 使我们可以指定一个ident,以后, 此ident 将被加至每则记录消息中。ident 一般是程序的名称(例如 ,cron ,ine 等)
openlog函数中的第1个参数为ident,该参数常用来表示信息的来源。ident指向的字符信息会被固定地添加在每行日志的前面。第2个参数 option用于指定openlog函数和接下来调用的syslog函数的控制标志。option的取值情况如表8.5所示,可以单独取其中的某个值,也 可以通过与运算来获得多种特性。第3个参数为facility,这个要与syslogd守护进程的配置文件对应,日志信息会写入syslog.conf文 件指定的位置。
表8.5 openlong函数中的option取值表
参 数 |
说 明 |
LOG_CONS |
如果将信息发送给syslogd守护进程时发生错误,直接将相关信息输出到终端 |
LOG_NDELAY |
立即打开与系统日志的连接(通常情况下,只有在产生第一条日志信息的情况下才会打开与日志系统的连接) |
LOG_NOWAIT |
在记录日志信息时,不等待可能的子进程的创建 |
LOG_ODELAY |
类似于LOG_NDELAY参数,与系统日志的连接只有在syslog函数调用时才会创建 |
参 数 |
说 明 |
LOG_PERROR |
在将信息写入日志的同时,将信息发送到标准错误输出(POSIX.1-2001不支持该参数) |
LOG_PID |
每条日志信息中都包括进程号 |
参数facility的取值如表8.6所示。这些值与前面syslog.conf中的facility是存在对应关系的。
表8.6 openlog函数参数facility取值
facility参数 |
syslog.conf中对应的facility取值 |
LOG_KERN |
kern |
LOG_USER |
user |
LOG_MAIL |
|
LOG_DAEMON |
daemon |
LOG_AUTH |
auth |
LOG_SYSLOG |
syslog |
LOG_LPR |
lpr |
LOG_NEWS |
news |
LOG_UUCP |
uucp |
LOG_CRON |
cron |
LOG_AUTHPRIV |
authpriv |
LOG_FTP |
ftp |
LOG_LOCAL0~LOG_LOCAL7 |
local0~local7 |
syslog函数中的第一个参数priority表示消息的级别。与openlog函数中的facility参数类似,priority参数与level也存在对应的关系。priority取值和对应关系如表8.7所示。
表8.7 syslog函数参数priority取值
priority参数 |
syslog.conf中对应的level取值 |
LOG_EMERG |
emerg |
LOG_ALERT |
alert |
LOG_CRIT |
crit |
LOG_ERR |
err |
LOG_WARNING |
warning |
LOG_NOTICE |
notice |
LOG_INFO |
info |
LOG_DEBUG |
debug |
syslog函数的第二个参数为消息的格式,之后是格式对应的参数。函数的使用类似于printf函数。
参考代码如下:
点击(此处)折叠或打开
- #include <syslog.h>
-
- int main(int argc, char **argv)
- {
- syslog(LOG_ERR|LOG_USER,"test - %m/n");
- openlog("SyslogTest", LOG_CONS | LOG_PID, 0);
- syslog(LOG_DEBUG,"This is a syslog test message generated by program '%s'/n",argv[0]);
- closelog();
- return 0;
- }
执行结果:#cat /var/log/syslog
1. BSD syslogd的组成结构:
从上图可以看到相关的日志文件主要来源于三种途径:
(1) 内核:
许多内核例程调用log函数产生log消息,另外klogd守护进程能够监听并得到内核消息,并发送给syslogd进程。
(2) 许多用户进程直接调用syslog函数产生日志消息。
(3) 来自于TCP/IP网络连接的日志消息。该消息可能来自于自身的某个用户进程或者其它网络主机上的一个用户进程。端口是514.
我们主要讨论第二种情况下产生的日志消息。跟syslog相关的主要以下三个函数:
openlog:
ident主要被用于加在日志消息中,一般是用某个程序名来代替。如cron, inetd等。
option则是许多选项的位屏蔽,常见的选项见下表:
facility参数设置的目的是可以通过配置文件对不同设施的消息将以不同的方式进行处理。常见的facility见下表:
openlog(“dhcp6c”, LOG_NDELAY|LOG_PID, LOG_DAEMON);
syslog:
priority参数可以是facility与level的组合,其中level可取的值如下表:
syslog(LOG_ERR, “open error for %s: %m”, filename)
syslog(LOG_ERR|LOG_LPR, “open error for %s: %m”, filename)
format则是格式化的出错消息字符串。
setlogmask: 用来设置记录日志的优先级,即只记录指定优先级的日志消息。
setlogmask(LOG_ERR) ----- 仅仅记录ERR级别的日志消息
setlogmask(LOG_UPTO(LOG_ERR))----- 记录ERR以及之前的所有日志消息
syslogd配置文件:(/etc/syslog.conf)
主要用来控制如何处理facility|priority的log消息,如存放到某个指定的文件中,或者发送到指定的log服务器,
2. 内核消息日志的显示以及printk函数的日志级别:
从前面的图2-1中可以看到,函数printk先将消息打印到环形缓冲区_logbuf中,并将消息传给控制台进行显示,控制台驱动程序然后根据控制台的日志级别显示日志消息。
常见的日志级别如下表:(数字越低,代表级别越高!)
跟日志级别相关的几个常量:
#defineconsole_loglevel (console_printk[0]) 控制台的日志级别,凡是优先级高于这个值的消息将在控制台上显示。它的初始值是default_console_loglevel,这个值可以通过 klogd –cn(n为设置的级别)进行修改,不过要注意的是在修改之前,必须先杀掉klogd进程。 #define default_message_loglevel (console_printk[1]) 默认消息日志级别,当printk没定义优先级时使用这个值 #define minimum_console_loglevel (console_printk[2]) 最小控制台日志级别,控制台日志级别可被设置的最小值 #define default_console_loglevel (console_printk[3]) 默认的控制台日志级别,这个值可以通过sys_syslog系统调用进行修改。 Ps:这四个常量值可以通过/proc/sys/kernel/printk文件进行查看和修改。可以通过以下方式修改当前的日志级别: echo 8 > /proc/sys/kernel/printk