一些日志相关的笔记

Published: 2022年12月06日

In Basic.

自己的博客嘛,那不就是想到啥写啥,你happy,我不happy,有人高兴有人哭泣~今天被它洗脑了...


今天写的都是什么狗屁玩意儿啊?好骂!

经常遇到syslog但从来没有认真了解过它的机制,今天有空就来学学并记下来...

Syslog Monitoring

提到syslog,有三个与之相关的软件,syslog是最初代的版本,从它开始了有了syslog协议,rsyslog是其增强,它们配置挺像的,还有个syslog-ng也是其增强但配置语法差挺大,这里就不列出它们的优缺点了不重要都在进步嘛,本文会先记syslog,之后遇到其他的再记。

注意虽然通常Linux上都有它们但它们并不属于Linux内核,因此那里面是找不到相关代码滴!

syslog

它是cs架构,syslogd监听端口或unix socket来接收其他程序发来的日志,这里先看客户端怎么发日志,syslog有对应的协议标准,任何实现协议的客户端都可以提交日志,这里主要关注C语言的,如glibc就提供了如下接口可用:

void openlog (const char *ident, int option, int facility);   // 打开log功能
void syslog(int priority, const char *fmt, ...);                            // 写日志
void vsyslog (int priority, const char *fmt, va_list ap);          // 写日志
void closelog (void);                                                                                    // 关闭日志功能
int setlogmask(int mask);                                                                           // 设置日志掩码

首先是openlog,如果不显式调用该函数,也会在第一次调syslog时隐式调它,但首先调用它可以进行一些自定义,即这三个参数的功能:

1.ident是一个标志字符串,通常使用程序名或功能名,便于在日志中定位属于该程序的日志

2.option是设置选项,每一位代表一个option,如LOG_PID表示在日志中添加进程ID,LOG_ODELAY表示直到第一次调用syslog才真正打开它,所有的类型与值可见源码

3.facility用于设置日志的来源(faclility),如LOG_MAIL表示这是和邮件相关的程序发出的日志,LOG_KERN表示是内核中的日志,程序应该根据其作用设置正确的参数,以在正确的位置清晰有序的查询日志,若不设置默认是LOG_USER

接下来是syslogvsyslog它们都是写日志时用的,只是传参形式不同这里不在意,主要看第一个参数priority表示优先级,即日志等级,如LOG_EMERG/LOG_DEBUG等,最终它会和facility异或(即它们会合并由一个整数表示,低3位为优先级,高位为类别因此其实可以混用这两个地方的值(打咩)),至于setlogmask就是用于设置哪些级别的消息会被发送到syslogd,类似于其他语言里配置日志级别,默认所有消息会被发送,最后的closelog没参数没啥说的了,来个例子:

#include <stdio.h>
#include <unistd.h>
#include <syslog.h>
/* 只发送高于LOG_NOTICE级别的日志 */
setlogmask (LOG_UPTO (LOG_NOTICE));
int main() {
    /* 日志里每行会添加bm-syslog-learn [pid] 立即打开,并且来源(日志类型)为LOG_LOCAL0,这是保留的,由用户自定义用途的一种 */
    openlog("bm-syslog-learn", LOG_PID | LOG_NDELAY, LOG_LOCAL0); 
        /* 输出日志,优先级为LOG_INFO */
    syslog(LOG_INFO, "hello, my pid is %d", getuid());
    /* 关闭日志 */
    closelog();
    return 0;
}

客户端结束了,上面的默认会发送到/dev/log这个unix socket,它由syslogd服务监听,这里也只关心它的配置,其位于/etc/syslog.conf下,格式如下:

# 格式
[selectors]   [action]
# 
user.debug;mail.info        /var/log/userdebug
*.info                                          /var/log/syslog
*.emerg                     @arpa.berkeley.edu
authpriv.*                                  betamao                         

其中selectors为一个或多个选择器组合,它们间用;分割,单个选择其由facility.priority组成,facility和priority就是上面那个两个东东,它们以.连接表示当优先级大于或等于时则匹配,还可以用=精确匹配,用*匹配所有,用!反向排除,详见文档,接着是action表示匹配后的操作,其中<path>表示日志写到这个文件里面,-<path>表示不要在每次写日志后都同步,这有助于提高性能,@<addr>表示转发到其他位置的syslog服务,<user>[,<user>]表示发给已登录的指定用户等。

其实还有syslog协议需要了解下,但是一眼顶针这里就不记了,知道这些就能在分析程序时很轻松的开启日志,定位到日志位置了,over!

syslogd主要用于用户态,而内核还有个klogd来处理日志。