Unix/Linux编程:syslog进程与日志输出_OceanStar的学习笔记的博客-CSDN博客
man syslog 看帮助手册
linux操作系统自带的守护进程syslog配置文件等现在在 /etc/rsyslog.conf
linux操作系统现在rsyslogd取代了原先的syslogd服务,rsyslog 是一个 syslogd 的多线程增强版,其配置语法与syslogd的配置文件一致。
当使用 syslog.h 记录日志时,大致流程如下:
- 打开系统日志。使用 openlog() 函数打开系统日志,需要传入三个参数:标识符(可为空),选项(可选),设备(可选)。
#include <syslog.h>
void openlog(const char *ident, int option, int facility);
-
1)ident 参数是一个指向字符串的指针:
- syslog()输出的每条消息都会包含这个字符串,这个参数的取值通常是程序名。
- 注意 openlog()仅仅是复制了这个指针的值。只要应用程序后面会继续调用 syslog(),那么就应该确保不会修改所引用的字符串
(2)传入 openlog()的 log_options 参数是一个位掩码,它是下面几个常量之间的 OR 值
- LOG_CONS : 当向系统日志发送消息发生错误时将消息写入到系统控制台(/dev/console)。
- LOG_NDELAY :
- 立即打开到日志系统的连接(即底层的 UNIX domain socket, /dev/log)
- 在默认情况下(LOG_ODELAY),只有在首次使用 syslog()记录消息的时候才会打开连接。
- O_NDELAY 标记对于那些需要精确控制何时为/dev/log 分配文件描述符的程序来讲是比较有用的,如调用chroot()的程序就有这样的要求。在调用 chroot()之后,/dev/log 路径名将不再可见,因此在chroot()之前需要调用一个指定了 LOG_NDELAY 的 openlog()。
- LOG_NOWAIT
- 不要wait()被创建来记录日志消息的子进程
- 在那些创建子进程来记录日志消息的实现上,当调用者创建并等待子进程时就需要使用 LOG_NOWAIT 了,这样 syslog()就不会试图等待已经被调用者销毁的子进程。
- 在 Linux 上,LOG_NOWAIT 不起任何作用,因为在记录日志消息时不会创建子进程
- LOG_ODELAY
- 这个标记的作用与 LOG_NDELAY 相反——连接到日志系统的操作会被延迟至记录第一条消息时。
- 这是默认行为,因此无需指定这个标记
- LOG_PERROR :
- 将消息写入标准错误和系统日志。
- 通常,daemon进程会关闭标志错误或者将其重定向到/dev/null,这样 LOG_PERROR 就没有用了
- LOG_PID :
- 在每条消息中加上调用者的进程 ID。
- 在一个创建多个子进程的服务器中使用 LOG_PID有助于区分哪个进程记录了某条特定的消息
(3)第三个参数facility是用来指定记录消息程序的类型。它让指定的配置文件,将以不同的方式来处理来自不同方式的消息。
- LOG_AUTH ——认证系统:login、su、getty等
- LOG_AUTHPRIV ——同LOG_AUTH,但只登录到所选择的单个用户可读的文件中
- LOG_CRON ——cron守护进程
- LOG_DAEMON ——其他系统守护进程,如routed
- LOG_FTP ——文件传输协议:ftpd、tftpd
- LOG_KERN ——内核产生的消息
- LOG_LPR ——系统打印机缓冲池:lpr、lpd
- LOG_MAIL ——电子邮件系统
- LOG_NEWS ——网络新闻系统
- LOG_SYSLOG ——由syslogd(8)产生的内部消息
- LOG_USER ——随机用户进程产生的消息
- LOG_UUCP ——UUCP子系统
- LOG_LOCAL0~LOG_LOCAL7 ——为本地使用保留
-
记录日志。使用 syslog() 函数记录日志,需要传入三个参数:优先级,格式化字符串,可变参数列表。
void syslog(int priority, const char *format, ...);
syslog函数中
(1)priority是level(级别) + facility(设置)的组合 用|起来
level如下:
-
LOG_EMERG——紧急情况
-
LOG_ALERT——应该被立即改正的问题,如系统数据库破坏
-
LOG_CRIT——重要情况,如硬盘错误
-
LOG_ERR——错误
-
LOG_WARNING——警告信息
-
LOG_NOTICE——不是错误情况,但是可能需要处理
-
LOG_INFO——情报信息
-
LOG_DEBUG——包含情报的信息,通常旨在调试一个程序时使用
(2) format:们与传入 printf()中的参数是一样的,但与 printf()不同的是这里的格式字符串不需要包含一个换行字符3.关闭系统日志。使用 closelog() 函数关闭系统日志。
当完成日志记录之后可以调用 closelog()来释放分配给/dev/log socket 的文件描述符
void closelog(void);
4.通过setlogmask设置日志掩码将级别大于掩码的日志信息被系统过滤掉
默认的掩码值允许记录所有的严重性级别。
int setlogmask(int mask);
宏 LOG_MASK()创建一个能过滤特定级别的所有消息的位掩码。如下为丢弃除优先级为 LOG_ERR 以及LOG_CRIT之外的消息
setlogmask(LOG_MASK(LOG_ERR) | LOG_MASK(LOG_CRIT));
LOG_UPTO()宏创建一个能过滤特定级别以及以上的所有消息的位掩码。如下为丢弃除优先级为 LOG_ERR 以及以上之外的消息
setlogmask(LOG_UPTO(LOG_ERR))
#include<stdio.h>
#include<syslog.h>
#include<unistd.h>
#include<stdlib.h>
void info(char* argv[])
{
openlog("sys",LOG_CONS | LOG_PID,LOG_USER);
setlogmask(LOG_UPTO(LOG_NOTICE));
syslog(LOG_INFO,"this is info log%s\n",argv[0]);
syslog(LOG_ERR,"this is err%s\n",argv[0]);
closelog();
return;
}
void err(char*argv[])
{
openlog("sys",LOG_CONS | LOG_PID,LOG_USER);
setlogmask(LOG_MASK(LOG_CRIT));
syslog(LOG_INFO,"this is info log%s\n",argv[0]);
syslog(LOG_ERR,"this is err log %s\n",argv[0]);
closelog();
return;
}
int main(int argc,char* argv[])
{
info(argv);
printf("------\n");
err(argv);
return 0;
}
user.* /var/log/logp.log