Linux日志系统解析

来源:互联网 发布:java中static修饰变量 编辑:程序博客网 时间:2024/06/08 14:21

前言

对于守护进程,因为它没有控制终端,所以不能往标准出错上面打印。
在很多工作站上,控制台设备运行一个窗口系统,我们不希望所有守护进程都写到控制台设备上。
我们也不希望每个守护进程都单独的写到一个文件里面。
对系统管理员来说,如果要去各个守护进程的文件中查看日志,将是一件很头疼的事情。
所以,我们需要集中的管理守护进程的出错信息。
因此Linux使用syslogd将所有的日志信息集中的管理起来。
整体架构如图所示:
这里写图片描述

从上面可以看到日志有3个来源:
1. 内核中的日志信息被klogd daemon程序读取,然后转发给syslogd daemon程序。
2. 应用程序调用syslog函数来产生日志信息。
3. 本地主机的应用程序或者来自网络上的其它程序,可以向端口514发送UDP报文来产生日志信息。

syslogd守护进程会处理上面3种类型的日志信息。
syslogd守护进程在启动时候,通常会去读/etc/syslog.conf配置文件,该文件决定了不同类型的消息应该怎么处理。
例如:紧急消息可发给系统管理员,并在控制台上面显示出来,而警告消息则可记录在文件中。

应用程序日志

相关函数如下

#include <syslog.h>/** * 初始化log相关的属性 * @param ident    log的标志,一般指定为程序的名字,将会出现在每一条log中。 * @param option  设置一些可选的配置信息。所有可选的配置说明见表13-1. * @param facility  指定日志的类型。所有的类型说明见表13-2. */void openlog(const char *ident, int option, int facility);

表13-1

表13-2

/** * 产生日志消息 * @param priority 日志的类型和级别。所有的级别见表13-3。 * @param format  日志的内容。format中的每一个%m会被替换为strerror(errno)对应的字符串。 */void syslog(int priority, const char *format, ...);

表13-3

/** * 关闭所有syslog打开的描述符 */void closelog(void);/** * 设置进程优先级屏蔽字,返回调用之前的屏蔽字。 * @param  maskpri 新的掩码 * @return        返回上一次的掩码 */int setlogmask(int maskpri);

调用openlog是可选的,如果不调用openlog,那么在第一次调用syslog时会自动调用openlog。
调用closelog也是可选的。它只是关闭用于与syslogd守护进程通信的文件描述符。

实 例
在一个行式打印机中,可能存在如下的log输出函数:

openlog("lpd", LOG_PID, LOG_LPR);syslog(LOG_ERR, "open error for %s: %m", filename);

openlog将ident设置为程序的名字lpd,option指定每一次都输出进程的pid,facility指定为行式打印机系统。
syslog指定输出级别为LOG_ERR,然后跟上输出的内容。其中%m被替换为strerror(errno)对应的字符串。
若不调用openlog,直接调用syslog形式可能是:

syslog(LOG_ERR | LOG_LPR, "open error for %s: %m", filename);

在syslog的priority中同时指定打印级别和类型。

除了syslog很多平台还提供一种变体处理可变参数列表的方法。

#include <syslog.h>#include <stdarg.h>void syslog(int priority, const char *format, va_list arg);

内核日志

内核使用printk产生日志消息,比如:

printk("<5>This is kernel log message");或者printk(KERN_NOTICE "This is kernel log message");

其中的<5>和KERN_NOTICE表示日志的级别,在klogd中会去解析日志级别,做不同的处理。
在Linux 2.6.39中的include/linux/printk.h中定义了日志的级别。

#define KERN_EMERG    "<0>"    /* system is unusable            */#define KERN_ALERT    "<1>"    /* action must be taken immediately    */#define KERN_CRIT    "<2>"    /* critical conditions            */#define KERN_ERR    "<3>"    /* error conditions            */#define KERN_WARNING    "<4>"    /* warning conditions            */#define KERN_NOTICE    "<5>"    /* normal but significant condition    */#define KERN_INFO    "<6>"    /* informational            */#define KERN_DEBUG    "<7>"    /* debug-level messages            */

klogd源码

klogd源码

syslogd源码

syslogd源码

openlog,syslog,closelog实现

openlog,syslog,closelog源码