转自:http://blog.csdn.net/henni386/article/details/7439142
当在linux中工作时,我们发现,提到linux中的日志(log)信息,就会想到syslog,printk中的内核日志,dmesg等等,但却对它们地关系有时候并不清楚。
笔者在接触到Linux的几年中,曾经就被这些log搞得昏头转向,不知道该去哪里找自己需要的log,为了弄清楚这个问题,决定花力气把这个问题搞清楚。
下面的图清楚地表达出了linux中的各种日志,以及日志相关的函数命令的关系。
从上面的图片中可以看出,linux系统的的log主要分成下面几个部分:
(1)syslogd
(2)klogd
(3)/etc/syslog.conf
(4)用户空间log写log接口,logger/syslog()
(5)内核空间log接口,printk/Log_buf
(6)用户空间对内核空间log的访问接口klogctl()/do_syslog()
在接下来的章节中,将详细的介绍这几个部分。
sysklogd RPM包中一般包含syslogd,klogd两个守护进程,它们分别用来完成对系统和内核日志信息的管理。
Syslogd
功能
syslogd负责接收系统中的每个进程发送过来的日志消息,然后根据消息的Priority和/ect/syslogd.conf的配置,进行分类存储或者转发。
日志存储格式
syslogd记录的每条消息都按照下面的格式进行存储。
时间:Host : Task_name: XXXXX
日志的优先级
syslog支持日志信息的优先级,它的优先级主要由两个因素构成:
(1)Facility,即日志的分类,主要有下面几种
LOG_AUTH
LOG_AUTHPRIV
LOG_CRON
LOG_DAEMON
LOG_FTP
LOG_KERN
LOG_LOCAL0
LOG_LOCAL1
LOG_LOCAL2
LOG_LOCAL3
LOG_LOCAL4
LOG_LOCAL5
LOG_LOCAL6
LOG_LOCAL7
LOG_LPR
LOG_MAIL
LOG_NEWS
LOG_SYSLOG
LOG_USER(default)
LOG_UUCP
(2)level: 消息的重要性
LOG_EMERG
LOG_ALERT
LOG_CRIT
LOG_ERR
LOG_WARNING
LOG_NOTICE
LOG_INFO
LOG_DEBUG
syslogd.conf 配置
syslogd的配置信息一般存储在/etc/syslogd.conf文件中。
每个配置项包括两个域,selector和action。如下图所示:
selector
selector是facility和level在一起。
selector中可以使用*,!,-等通配符
Name | Facility | level |
* | 任何一个 | 任何一个 |
= | X | 只有该level才可log |
! | X | 除了该level的log信息才能log |
None | X | 不存储任何level的消息 |
action
action主要是当log信息满足selector的需求时,该日志消息怎么处理,一般分为三种方式:
(1)存储到普通文件中
(2)写入到管道中
(3)远程转发到其它主机上
常规文件 | 管道文件 | 远程转发 |
普通的文件名:/xx/bb
| |文件名 | @hostname |
内核日志:
内核日志的存储
1. 地址
内核的日志存在log_buf指向的内存缓冲区中。
大小在新的内核是可配置的,CONFIG_LOG_BUF_SHIFT=xx
2. 格式
<level>xxxxxx
API
(1) printk:内核代码中常见的日志输出方式
(2)do_syslog/syslog: 内核提供的系统调用,用来操作log_buf
(3)klogctl:C库中提供的函数,用来使用上面的系统调用。
syslog系统调用支持下面的命令:
* 0 -- Close the log. Currently a NOP.
* 1 -- Open the log.Currently a NOP.
* 2 -- Read from the log.
* 3 -- Read all messages remaining in the ring buffer.
* 4 -- Read and clear allmessages remaining in the ring buffer
* 5 -- Clear ring buffer.
* 6 -- Disable printk toconsole
* 7 -- Enable printk toconsole
* 8 -- Set level of messagesprinted to console
* 9 -- Return number ofunread characters in the log buffer
* 10 -- Return size of the logbuffer
Tool
在shell中可以使用下面的方法直接操作内核log日志
(1) dmesg:用来查看log_buf中的数据;
(2) cat /proc/kmsg :也可用来读取log_buf中的数据
klogd与syslogd的交互:
问题
由于内核log_buf的大小受限,而内核随着时间的运行,其日志信息会越来越多,当过多时,log_buf中的日志信息就会被循环覆盖。
为了解决这个问题, 在用户空间就开发了klogd守护进程。它通过klogctl()将log_buf中的日志信息读取出来,然后发给syslogd()。
syslogd的接口
(1) 命令接口, logger
logger [-isd] [-f file] [-p pri] [-t tag] [-usocket] [message ...]
上面是logger使用方法,具体的参数含义可以man 1 logger
(2) API接口,openlog()/syslog()/closelog()
openlog()建立syslogd的连接;
void openlog(const char *ident, int option,int facility)
syslog()向syslogd发送log信息
void syslog(int priority, const char*format, ...);
closelog()断开与syslogd的连接
void closelog(void);
至此,Linux系统中的日志机制就介绍完毕了。