APUE学习之日志系统

发布时间:2024年01月23日

目录

一、syslog概述

二、syslog协议标准

三、syslog函数

1、openlog()

2、syslog()

3、closelog()

4、演示代码

四、关于守护进程调用syslog,找不到/var/log/messages


一、syslog概述

? ? ? ? 以守护进程为例,该进程在后台默默运行,我们一般会关闭三个标准I/O,那么程序的运行状态信息该如何查看呢?让我们带这个这个疑问继续往下看吧!

? ? ? ? 对于这个问题,我们可以自己写函数把程序运行的相关信息记录到文件中,另一种方式就是使用Linux系统中自带的syslog日志机制。

? ? ? ? syslog是一种工业标准的协议,可以用来记录设备的日志。在UNIX系统中,路由器、交换机等网络设备中,系统日志(System Log)记录系统中任何时间发生的大小事件。管理者可以通过查看系统记录,随时掌握系统状况。UNIX的系统日志是通过syslogd这个进程记录系统有关事件的记录,也可以记录应用程序的运作事件。通过适当的配置,我们还可以实现运行syslog协议的机器间通信,通过分析这些网络行为日志,用以追踪掌握与设备和网络有关的状况。

二、syslog协议标准

? ? ? ? syslog协议是一种用来在互联网协议(TCP/IP)的网络中传递记录档信息的标准,完整的syslog日志中包含产生日志的程序模块(Facility)、严重性(Severity/Level)、时间、主机名/IP、进程名、进程ID和正文。在UNIX类操作系统上,能够按照Facility和Level的组合来决定什么样的日志消息是否需要记录,记录到什么地方,是否需要发送到一个接收syslog的服务器等。

具体协议如下图所示:

如上图所示,syslog消息主要分为priority、head以及message三个部分,priority是由两个部分组成的—facility、level。

(1)facility表明该日志消息是由谁产生的,是内核Kern?还是用户user?不同的facility对应不同的代号,可以通过?man 3 syslog来查看:

?(2)level表明该日志消息的重要程度,是导致系统不能正常使用了的紧急级别emerg?还是需要被及时处理的警告级别alert?又或是仅仅是需要调试的debug级别的信息?同样可通过??man 3 syslog查看:

三、syslog函数

????????Linux中提供了一套系统日志写入的接口—syslog库,syslog库可以将应用程序中的日志消息写入日志系统,主要涉及三个函数openlog、syslog、closelog,接下来我们主要介绍一下这三个Linux系统自带的日志系统函数:

1、openlog()

函数原型如下:

#include <syslog.h>

void openlog(const? char *ident, int? option, int? facility);

函数说明:

? ? ? ? 打开日志设备,以供读取和写入,与文件系统调用的open类似;调用openlog是可选择的。如果不调用openlog,则在第一次调用syslog时,自动调用openlog。

功能:

????????打开一个syslog连接:使用 openlog 函数来连接 syslogd 程序。?

参数说明:

(1)第一个参数ident:是一个标记,ident所表示的字符串将固定的加在每行日志的前面以标识这个日志,通常就写成当前程序的名称以作为标记。

(2)第二个参数option:指定openlog函数和接下来调用的syslog函数的控制标志。可以取以下值:

LOG_CONS如果将信息发送给syslogd守护进程时发生错误,直接将相关信息输出到终端
LOG_NDELAY立即打开与系统日志的连接(通常情况下,只有产生第一条日志信息的情况下才会打开与日志系统的连接)
LOG_ODELAY与系统日志的连接只有在syslog函数调用时才会创建
LOG_PERROR在将信息写入日志的同时,将信息发送到标准错误输出
LOG_PID每条日志信息中都包含进程号

(3)第三个参数facility:?指定记录消息程序的类型,与syslogd守护进程的配置文件syslog.conf中的facility对应。可取如下值:

LOG_AUTH认证系统(login、su、getty等)
LOG_AUTHPRIV同LOG_AUTH但只登陆到所选择的单个用户可读的文件中
LOG_CRONcron守护进程
LOG_DREAM其他系统守护进程,如routed
LOG_FTP文件传输协议:ftpd、tftpd
LOG_KERN内核产生的消息
LOG_LPR系统打印机缓冲池:Ipr、Ipd
LOG_MAIL电子邮件系统

LOG_NEWS

网络新闻系统
LOG_SYSLOG由syslogd(8)产生的内部消息
LOG_USER随机用户进程产生的消息
LOG_UUCPUUCP子系统
LOG_LOCALL0-LOG_LOCALL7本地使用保留

2、syslog()

函数原型如下:

#include <syslog.h>

void syslog(int? priority, const? char *format, ...);

函数说明:

? ? ? ? 写入日志,与文件系统调用printf使用方法类似,但在前面指定日志级别。

功能:

????????产生一条日志消息以特定的规则分发出去。

参数说明:

(1)第一个参数priority:表示消息的级别,与syslogd守护进程的配置文件syslog.conf中的level对应。可取如下值:

LOG_EMERG紧急情况
LOG_ALERT应该被立即改正的问题,如系统数据库破坏
LOG_CRIT重要情况,如硬盘错误
LOG_ERR错误
LOG_WARNING警告信息
LOG_NOTICE不是错误情况,但是可能需要处理
LOG_INFO情报错误
LOG_DEBUG包含情报的信息,通常指在调试一个程序时使用

(2)第二个参数fomat:格式化输出,类似于printf函数中的format参数。

3、closelog()

函数原型如下:

#include <syslog.h>

void closelog(void);

函数说明:

? ? ? ? 关闭日志设备,与文件系统调用的close类似;调用closelog也是可选择的,它只是关闭被用于与syslog守护进程通信的描述符。

功能:

????????关闭用来写日志记录的文件描述符。

4、演示代码

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <libgen.h>

int main(int argc,char *argv[])
{

        char    *progname = basename(argv[0]);

        if(daemon(0,0) < 0)
        {
                printf("Programe daemon() failure:%s\n",strerror(errno));
                return -1;
        }

        openlog("daemon",LOG_CONS|LOG_PID,0);
        syslog(LOG_NOTICE,"Program '%s' start running\n",progname);
        syslog(LOG_WARNING,"Program '%s' running with a warning message\n",progname);
        syslog(LOG_EMERG,"Programe '%s' running with a emergency message\n",progname);

        while(1)
        {
                printf("1\n");
        }
        syslog(LOG_NOTICE,"Program '%s' stop running\n",progname);
        closelog();

        return 0;
}
                  

???????所有程序(包括Linux内核)调用syslog()函数的输出相关信息都会记录到/var/log/messages日志文件中,因为该文件中记录了所有的信息,这也意味着当前程序记录的消息容易被别的程序冲刷掉,所以我们在做项目写网络程序的时候,一般会使用标准IO库(fopen、fwrite()等)自己实现日志系统,而不是直接调用该函数。

四、关于守护进程调用syslog,找不到/var/log/messages

? ? ? ? 最后,和大家聊一下我在实战中遇到的问题。相信有些小伙伴在运行上面的代码,发现/var/log/messages没有输出,这是为什么呢?其实主要就是随着系统更新,Linux的机制也发生了变化。那怎么办呢?

解决办法:

? ? ?(1)? ?首先你需要拥有sudo权限,我用的是自己的VMware虚拟机。

? ? ?(2)然后在终端输入命令? sudo? ?vim? ?/etc/rsyslog.d/50-default.conf

? ? ?(3)? ?找到文件的第33-41行,删掉原本的注释,处理完如下图所示:

? ? ? ? (4)在终端输入命令service syslog restart重启服务

????????(5)重新运行程序./daemon,在输入tail -5?/var/log/messages就可以看见程序的输出了,如下图所示:

到这里问题就已经成功解决啦!?

文章来源:https://blog.csdn.net/m0_65292176/article/details/135728494
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。