Linux日志系统

工欲善其事,必先利其器。

文章目录


前言

服务器的调试和维护都需要一个专业的日志系统


一、日志系统体系结构

linux提供一个守护进程处理系统日志-syslogd,现在使用的基本都是rsyslogd。
rsyslogd守护进程既能接收用户输出日志,也能接收内核日志。
用户进程通过syslog系统调用生成系统日志,该日志输出到一个UNIX本地域socket类型的文件/dev/log中,rsyslog则监听该文件以获取用户进程的输出。

系统上是通过另外一个守护进程rklogd来管理的,rsyslogd利用额外的模块实现了相同的功能。内核日志由printk等函数打印至内核的环状缓存(ring buffer)中。环状缓存的内容直接映射到/proc/kmsg文件中。rsyslogd则通过读取该文件获得内核日志。rsyslogd守护进程在接收到用户进程或内核输入的日志后,会把它们输出至某些特定的日志文件。默认情况下,调试信息会保存至/var/log/debug文件,普通信息保存至/var/log/messages文件,内核消息则保存至/var/log/kern.log文件。不过,日志信息具体如何分发,可以在rsyslogd 的配置文件中设置。rsyslogd 的主配置文件是/etc/rsyslog.conf,其中主要可以设置的项包括:内核日志输入路径,是否接收UDP日志及其监听端口(默认是514,见 /etclservices文件),是否接收TCP日志及其监听端口,日志文件的权限,包含哪些子配置文件图7-1总结了Linux的系统日志体系

printk dmesg syslog 配置文件 内核 内核缓冲区 终端输出内核信息 /proc/kmsg syslogd 用户过程 /dev/log /var/log/*
sudo systemctl status syslog.service // 查看syslog服务状态
● rsyslog.service - System Logging Service
     Loaded: loaded (/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabl>
     Active: active (running) since Sat 2021-10-02 01:50:08 PDT; 3 days ago
TriggeredBy: ● syslog.socket
       Docs: man:rsyslogd(8)
             https://www.rsyslog.com/doc/
   Main PID: 732 (rsyslogd)
      Tasks: 4 (limit: 2273)
     Memory: 3.4M
     CGroup: /system.slice/rsyslog.service
             └─732 /usr/sbin/rsyslogd -n -iNONE

sudo systemctl status rsyslog.service // 查看rsyslog服务状态
● rsyslog.service - System Logging Service
     Loaded: loaded (/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabl>
     Active: active (running) since Sat 2021-10-02 01:50:08 PDT; 3 days ago
TriggeredBy: ● syslog.socket
       Docs: man:rsyslogd(8)
             https://www.rsyslog.com/doc/
   Main PID: 732 (rsyslogd)
      Tasks: 4 (limit: 2273)
     Memory: 3.4M
     CGroup: /system.slice/rsyslog.service
             └─732 /usr/sbin/rsyslogd -n -iNONE

二、日志相关函数

#include <syslog.h>

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

可变参数函数来结构化输出。priority参数是所谓的设施值与日志级别的按位或。设施值的默认值是LOG_USER,日志级别如下

#include <syslog.h>
#define LOG_EMERG 0 /* 系统不可用 */
#define LOG_ALERT 1 /* 报警,需要立即采取措施 */
#define LOG_CRIT  2 /* 非常严重的情况 */
#define LOG_ERR   3 /* 错误 */
#define LOG_WARNING 4 /* 警告 */
#define LOG_NOTICE 5 /* 通知 */
#define LOG_INFO 6 /* 信息 */ 
#define LOG_DEBUG 7 /* 调试 */

下面这个函数可以改变syslog的默认输出方式,进一步结构化日志

#include <syslog.h>

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

ident参数指定的字符串将被添加到日志消息的日期和时间之后,通常被设置为程序的名字。logopt参数对后序的syslog调用的参数进行配置,它可以去以下值的按位与。

#define	LOG_PID	0x01 /* 在消息日志中包含程序的pid */
#define LOG_CONS 0x02 /* 如果消息不能记录到日志文件,则打印至终端 */
#define LOG_ODELAY 0x04 /* 延迟打开日志功能直到第一次调用syslog */
#define LOG_NDELAY 0x08 /* 不延迟打开日志功能 */

此外,日志过滤也很重要,设置日志掩码,是日志级别大于日志掩码的日志信息被系统忽视,设置日志掩码的函数

#include <syslog.h>

int setlogmask(int mask);

mask是掩码的值。成功(始终成功的)该函数返回之前掩码的值。

关闭日志功能

#include <syslog.h>

void closelog(void);
上一篇:PLC衔接新方式UcAsp.Opc


下一篇:php输出日志