2.1.2 syslog系统构架

先介绍klogd是因为当一开始写入/var/log/message时,klogd所记录的信息会比syslogd 的顺序优先,原因是klogd所记录的是尚未进入操作系统的信息,但其实一开始的这些信息并不是由klogd所记录的,而是自加载kernel 时,就已经开始记录的。在系统尚未进入操作系统阶段,还在加载kernel及执行initrd时,会将信息先记录在/proc/kmsg文件中(因为在 initrd阶段没有实体硬盘可供记录),等进入操作系统执行完klogd后,klogd再将/proc/kmsg的所有内容全数填入/var/log /message文件中,这也是为何在/var/log/message文件的一开始,依然可以看到刚开机在加载kernel以及initrd阶段的信息 (如图5-13中连CPU的启用都看得到,信息中也注明了是kernel的信息)。

 

在klogd填入所有kernel加载及initrd阶段的信息之后,就进入下面介绍klogd时所描述的行为。

 

from << Linux安全体系分析与编程 >>   倪继利

2.1.2  syslog系统构架

内核和任何程序都可通过syslog系统记录事件消息,并将消息写入到一个文件或设备中,还可以通过网络进行传送。syslog系统构架如图2-1 所示。

在图2-1中,klogd后台进程监听和得到内核信息,并发送到syslogd后台进程。syslogd监听和处理来自syslog库API的所有 消息,并输出到控制台或指定文件中。

在内核,函数printk将消息写入到一个长度为LOG_BUF_LEN字节的循环缓冲区中。如果循环缓冲区填满了,printk就绕回缓冲区的开 始处填写新数据,klogd后台进程读取循环缓冲区中内核消息,并分发到syslogd。

1.系统调用sys_syslog

头文件sys/klog.h提供了系统调用sys_syslog,它从内核的printk环形缓冲区读取的消息。当环形缓冲区为空时,它会阻塞等 待。

2.后台进程klogd

后台进程klogd调用sys syslog读取内核的消息。klogd允许内核消息打印在系统终端上,优先级小于7的任何消息都可在终端上打印。优先级为7的消息是调试消息,不能出现 在终端上,将由syslogd后台定向到文件中。

由内部错误条件引发的消息是非常重要的,开发者需要分析这些消息来判定出错的原因。错误消息以原始数据出现,需要通过符号表映射文件转换成可读的符 号信息。程序编译时会产生符号表映射文件,它列出了重要变量和函数的地址位置。内核编译产生的符号映射文件为system.map,后台进程klogd通 过system.map文件将原始数据转成符号信息;然后,在系统终端打印或通过syslog库函数传递给syslogd后台。

如果没有运行klogd,数据将保留在循环缓冲区中,直到某个进程读取或缓冲区溢出为止。

还可通过读取/proc/kmesg文件获得调试信息。对/proc/kmesg进行读操作时,日志缓冲区中被读取的数据就不再保留,而sys syslog系统调用却能随意地返回日志数据,并保留这些数据以便其他进程也能使用。

klogd指定-f (file)选项,可将消息保存到某个特定的文件中,还可修改/etc/syslog.conf来设置消息存放地点。

3.syslog库API

syslog库API在syslog.h文件中定义,它提供了函数openlog、syslog和closelog用来将应用程序中的日志消息写入 日志系统。例如:应用程序su的打印日志消息函数列出如下:

#include 

#include "system.h"

# include



static void log_su (struct passwd const *pw, bool successful)

{

const char *new_user, *old_user, *tty;



new_user = pw->pw_name;

old_user = getlogin ();//通过日志文件utmp得到登录的用户

if (!old_user) //如果没得到用户名,就通过uid获取

{

struct passwd *pwd = getpwuid (getuid ());

old_user = (pwd ? pwd->pw_name : "");

}

tty = ttyname (STDERR_FILENO);//通过标准描述符STDERR_FILENO得到控制台名

if (!tty)

tty = "none";



 // base_name (program_name)表示用程序的基本名字作为消息标签头

openlog (base_name (program_name), 0 , LOG_AUTH ); // LOG_AUTH表示安全或授权消息

 //打印消息

syslog (LOG_NOTICE,//消息优先级

"%s(to %s) %s on %s",

successful ? "" : "FAILED SU ",

new_user,

old_user, tty);

closelog (); //关闭

}

4.后台进程syslogd

后台进程syslogd根据配置文件/etc/syslog.conf将消息输出到指定存放地点。配置文件syslog.conf定义每类消息的存 放地点。通常情况下,syslog信息写入到/var/adm或/var/log目录下的信息文件(messages.*)中。一个典型的syslog记 录包括生成程序的名字和一个文本信息。

syslog.conf文件的每一行对每类消息都提供一个选择域和一个动作域,由tab隔开;选择域指明消息的类型和优先级,动作域指明 syslogd执行的动作。

例如,下面配置表示所有邮件消息记录到一个文件中:

#Log all the mail messages in one place 

mail.* /var/log/maillog

下面配置表示将alert消息写入到root和tiger的个人账号中:

#Root and Tiger get alert and higher messages 

*.alert root,tiger

下面配置表示将内核消息记录到设置/dev/console中:

#Log all kernel messages to the console 

#Logging much else clutters up the screen

kern.* /dev/console

下面配置表示将UUCP和news设备产生的错误消息写入到指定的日志文件中:

# Save news errors of level crit and higher in a special file. 

uucp,news.crit /var/log/spooler

你可能感兴趣的:(linux,struct,api,user,include,终端)