Tina Linux syslog使用指南

tina linux syslog 使用指南 1 基本介绍 syslog 可以说是一套统一管理系统日志的机制,尤其常用于记录守护进程的输出信息上。因为守护进程不存在控制终端,它的打印不能简单地直接输出到stdin 或stderr。
使用syslog 时,一般需要关注两部分:syslog 守护进程与syslog 函数。
1.1 syslog 守护进程 syslog 守护进程用于统一管理日志。它一般会创建一个数据报(sock_dgram )类型的unix 域套接字(unix domain socket),将其捆绑到/dev/log (不同的
系统可能会有所不同)。如果支持网络功能,它可能还会创建一个udp 套接字,并捆绑到端口514。syslog 守护进程从这些套接字中读取日志信息,然后再输出到
设定的目标位置(文件、串口等)。
后面提到的ubox 的logd 、busybox 的syslogd 、syslog-ng 都是syslog 守护进程的不同实现。
1.2 syslog 函数 应用程序若想将打印信息发送到syslog 守护进程,就需要通过unix 域套接字将信息输出到syslog守护进程绑定的路径,标准的做法是通过调用syslog 函数:
#include
void openlog(const char *ident, int option, int facility);
void syslog(int priority, const char *format, ...);
void closelog(void);
syslog 函数被应用程序首次调用时,会创建一个unix 域套接字,并连接到syslog 守护进程的unix 域套接字绑定的路径名上。这个套接字会一直保持打开,直到进
程终止为止。应用程序也可以显式地调用openlog 和closelog (这两个函数都不是必须要调用的),如果不显式调用,在第一次调用syslog 函数时会自动隐式地调
用openlog ,进程结束后也会自动关闭与syslog 守护进程通信的文件描述符,相当于隐式调用closelog 。
以下是一些参数说明,更详细的请参考syslog 的man 手册。
1.2.1 openlog() • ident 参数会被添加到每一条日志信息中,一般为程序的名字。
• option 参数支持以下的值,可通过或操作(or)让其支持多个option :
option 说明
log_cons 若日志无法通过unix 域套接字送到syslog 守护进程,则将其输出到 console
log_ndelay 立即打开至syslog 守护进程unix 域套接字的连接,不要等到第一次调用 syslog 函数时才建立连接(通常情况下会在第一次调用syslog 时才建立连 接)
log_nowait 不要等待在将消息计入日志过程中可能已经创建的子进程(gnu c 库中不 会创建子进程,因此该选项在linux 中不会起作用)
log_odelaylog_ndelay 的相反,在第一次调用syslog 函数前不建立连接(这是默 认的行为,可以不显式指定该选项)
log_perror 将日志信息也输出到stderr
log_pid 在每条日志信息中添加上进程id
• facility 参数用于指定当前应用程序的设施类型,为后续的syslog 调用指定一个设施的默认值。
该参数的存在意义是让syslog 守护进程可以通过配置文件对不同设施类型的日志信息做区分处理。如果应用程序没有调用openlog ,或是调用时facility 参数为0,
可在调用syslog 时将facility 作为priority 参数的一部分传进去。
facility 说明
log_auth 安全/授权信息
log_authpriv 安全/授权信息(私用)
log_cron 定时相关的守护进程(cron 和at )
log_daemon 系统守护进程
log_ftp ftp 守护进程
log_kern 内核信息(无法通过用户空间的进程产生)
log_lpt 行式打印机系统
log_mail 邮件系统
log_news usenet 网络新闻系统
log_syslog 有syslog 守护进程内部产生的消息
log_user 任意的用户级消息(默认)
log_uucp uucp 系统
1.2.2 syslog() priority 参数可以是上面提到的facility 与下面的level 的组合。level 的优先级从高到低依次排序如下:
level 值 说明
log_emerg 0 紧急(系统不可用)(最高优先级)
log_alert 1 必须立即采取行动
log_crit 2 严重情况(如硬件设备出错)
log_err 3 出错情况
log_warning 4 警告情况
log_notice 5 正常但重要的情况(默认值)
log_info 6 通告信息
log_debug 7 调试信息(最低优先级)
1.3 rotate(转存/轮转) 很多时候都会让syslog 守护进程读取到的日志信息都写入到某个文件中,随着日志的增多,文件大小会不断增大。为了避免日志文件将存储空间占满,需要限制日
志文件的大小并删除过去的日志,该操作就称为rotate(转存/轮转)。
rotate 的实现一般如下:假设syslog 守护进程将日志写入到文件/var/run/messages,当messages 文件大小超过设定值时,会将messages 中的日志信息保存到
别的文件中(假设名字为messages.0),然后清空messages 的内容;当下一次messages 文件的大小又超过设定值时,会再一次将messages 中的内容保存为
messages.0,messages.0 中原有的内容则保存为messages.1。如此类推,若干次之后就会存在messages、messages.0、messages.1、… 、messages.n 几个
文件。一般会设置n 的最大值,超过该值的历史文件就会被删除,从而限制日志文件整体的大小。
我们可以自行编写脚本实现rotate,可以使用专门的工具logrotate,另外有一些syslog 守护进程的实现自带有rotate 的功能,如ubox 的logread 、busybox 的
syslogd 。
2 syslog 相关软件工具 2.1 ubox 的logd 与logread ubox 是openwrt 的工具箱,它的syslog 系统由logd 与logread 两个工具实现(此处的logread是ubox 自己的实现,与下文busybox 提供的logread 不是同一个
工具)。
因为这两个工具是openwrt 原生自带,它们在使用上有可能会依赖于procd 和ubus ,目前尚未测试过在非procd init 的环境下是否可用。
使用procd init 时,它们通过开机脚本/etc/init.d/log 自启动,具体如下:
#!/bin/sh /etc/rc.common
# copyright (c) 2013 openwrt.org
# start after and stop before networking
start=12
stop=89
pidcount=0
use_procd=1
prog=/sbin/logread
oom_adj=-17
validate_log_section()
{
    uci_validate_section system system ${1}
    'log_file:string'
    'log_size:uinteger'
    'log_ip:ipaddr'
    'log_remote:bool:1'
    'log_port:port:514'
    'log_proto:or(tcp, udp):udp'
    'log_trailer_null:bool:0'
    'log_prefix:string'
}
validate_log_daemon()
{
    uci_validate_section system system ${1}
    'log_size:uinteger:0'
    'log_buffer_size:uinteger:0'
}
start_service_daemon()
{
    local log_buffer_size log_size
    validate_log_daemon ${1}
    [ $log_buffer_size -eq 0 -a $log_size -gt 0 ] && log_buffer_size=$log_size
    [ $log_buffer_size -eq 0 ] && log_buffer_size=16
    procd_open_instance
    procd_set_param oom_adj $oom_adj
    procd_set_param command /sbin/logd
    procd_append_param command -s ${log_buffer_size}
    procd_set_param respawn
    procd_close_instance
}
start_service_file()
{
    pidcount=$(( ${pidcount} + 1))
    local pid_file=/var/run/logread.${pidcount}.pid
    local log_file log_size
    validate_log_section ${1} || {
        echo validation failed
        return 1
    }
    [ -z ${log_file} ] && return
    procd_open_instance
    procd_set_param command $prog -f -f $log_file -p $pid_file
    [ -n ${log_size} ] && procd_append_param command -s $log_size
    procd_close_instance
}
start_service_remote()
{
    pidcount=$(( ${pidcount} + 1))
    local pid_file=/var/run/logread.${pidcount}.pid
    local log_ip log_port log_proto log_prefix log_remote log_trailer_null
    validate_log_section ${1} || {
        echo validation failed
        return 1
    }
    [ ${log_remote} -ne 0 ] || return
    [ -z ${log_ip} ] && return
    procd_open_instance
    procd_set_param command $prog -f -r $log_ip ${log_port} -p $pid_file
    case ${log_proto} in
    udp) procd_append_param command -u;;
    tcp) [ ${log_trailer_null} -eq 1 ] && procd_append_param command -0;;
    esac
    [ -z ${log_prefix} ] || procd_append_param command -p ${log_prefix}
    procd_close_instance
}
service_triggers()
{
    procd_add_reload_trigger system
    procd_add_validation validate_log_section
}
start_service()
{
    config_load system
    config_foreach start_service_daemon system
    config_foreach start_service_file system
    config_foreach start_service_remote system
}
可见该脚本会通过config_load system 读取配置,然后将配置作为logd 和logread 的选项参数。具体的配置位于文件/etc/config/system 中。
更为详细的说明可参考openwrt 的官方文档runtime logging in openwrt 以及systemconfiguration /etc/config/system 。
2.1.1 logd logd 维护着一个固定大小的ring buffer(环形缓冲区),用于保存收集到的日志(包括内核的日志)。ring buffer 的大小通过-s 参数指定,可通过配
置/etc/config/system 中的log_buffer_size进行修改,单位为kb。
2.1.2 logread logread 用于读取logd 的ring buffer 的内容,并输出到文件或网络上的远程机器(通过tcp/udp 套接字)。它支持的选项有如下:
usage: logread [options]
options:
    -s path to ubus socket
    -l got only the last 'count' messages
    -e filter messages with a regexp
    -r stream message to a server
    -f log file
    -s log size
    -p pid file
    -h add hostname to the message
    -p prefix custom text to streamed messages
    -f follow log messages
    -u use udp as the protocol
    -0 use � instead of n as trailer when using tcp
• 直接执行logread 会将当前ring buffer 中的日志全打印出来(类似于dmesg )。 • 加上-f 则会持续地运行着,并输出ring buffer 中新的日志。 • 使用-f $log_file 可指定将日志输出到哪一个文件中,-s $log_size 可指定文件的大小,其中log_file 和log_size 都可在/etc/config/system 中进行设置。(实测发现其自带有rotate 的功能,当log_file 的大小超过log_size 时,会加上“.0” 后缀转存到同一个目录下,默认只保存一份历史文件。暂未发现是否可配置保存超过一份的历史转存文件。)
2.2 busybox 的syslogd、klogd 与logread busybox 自带有一些syslog 工具,一般用到的主要为syslogd 、klogd 和logread (此处的logread与上文的ubox 的logread 不是同一个工具),均位于它
menuconfig 的“system loggingutilities” 下。
后文busybox 相关的内容均基于1.27.2 版本进行阐述。
2.2.1 syslogd busybox 的syslogd 用于读取/dev/log 中的日志,并决定将其发送到文件、共享内存中的circular buffer 或网络等位置,且其自带有简单的rotate 功能。
它支持的特性可在menuconfig 中进行配置,将所有特性都选上后它支持的选项如下:
usage: syslogd [options]
system logging utility
    -n run in foreground
    -r host[:port] log to host:port (default port:514)
    -l log locally and via network (default is network only if -r)
    -c[size_kb] log to shared mem buffer (use logread to read it)
    -k log to kernel printk buffer (use dmesg to read it)
    -o file log to file (default: /var/log/messages, stdout if -)
    -s size max size (kb) before rotation (default 200kb, 0=off)
    -b n n rotated logs to keep (default 1, max 99, 0=purge)
    -l n log only messages more urgent than prio n (1-8)
    -s smaller output
    -d drop duplicates
    -f file use file as config (default:/etc/syslog.conf)
• 特性“rotate message files”(feature_rotate_logfile)即为rotate 功能,对应 -s 指定日志文件的限制大小以及-b 指定保存多少份历史的转存文件。 • 特性“remote log support”(feature_remote_log)即为网络功能的支持,对应-r和-l 选项。 • 特性“support -d (drop dups) option”(feature_syslogd_dup)对应-d 选项,会丢弃掉内容相同的重复日志。判断日志是否相同不光看其主体信息,时间戳等附加的信息也会考虑在内,如“jan 1 08:00:00 root: foobar” 和“jan 1 08:00:01 root: foobar” 会被认为是两条不同的日志,只有完全相同的日志才会被丢弃掉。 • 特性“support syslog.conf”(feature_syslogd_cfg)支持使用配置文件,默认为/etc/syslog.conf ,也可通过-f 指定其他的文件。可在配置文件中根据facility 与level 将日志输出到不同的目标位置,例子如下:
# 将所有日志输出到文件/var/log/messages

*.* /var/log/messages

# 将所有日志输出到console
*.* /dev/console
# 将facility 为log_kern 的日志输出到/var/log/kernel
kern.* /var/log/kernel
# 将facility 为log_user 且level 高于log_notice 的日志输出到/var/log/user
user.notice /var/log/user
• 特性“read buffer size in bytes”(feature_syslogd_read_buffer_size)用于设置syslogd 从/dev/log 中读取内容时的buffer 大小,它规定了单条日志消息的最大长度,超出的部分会被截断丢弃掉。 • 特性“circular buffer support”(feature_ipc_syslog)对应-c[size_kb] 选项,用于将日志送至共享内存的circular buffer 中, 可以通过logread 读取出来。circular buffer 的大小可通过“circular buffer size in kbytes (minimum 4kb)”(feature_ ipc_syslog_buffer_size)进行设置。 • 特性“linux kernel printk buffer support”(feature_kmsg_syslog)对应-k 选项,用于将日志输出到linux 内核的printk buffer 中,可通过dmesg 读取出来。 • 剩余的一些选项:-o 用于指定直接将日志输出到哪个文件;-s 用于精简日志消息,去除hostname、facility、level 等内容,只保留时间戳、进程名字以及消息的内容部分。
注意:当前版本的syslogd 中-f 、-c 、-o 几个选项对应的功能是冲突的,无法同时使用。相关部分的代码如下(位于busybox/sysklogd/syslogd.c 的timestamp_and_log 函数中):
/* log message locally (to file or shared mem) */
#if enable_feature_syslogd_cfg
    {
        bool match = 0;
        logrule_t *rule;
        uint8_t facility = log_fac(pri);
        uint8_t prio_bit = 1 enabled_facility_priomap[facility] & prio_bit) {
            log_locally(now, g.printbuf, rule->file);
            match = 1;
        }
    }
    if (match)
        return;
    }
#endif
    if (log_pri(pri) /var/log/messages
4 其他一些的注意事项 4.1 unix 域套接字(unix domain socket)是可靠的 syslog 是靠unix 域套接字实现ipc(inter-process communication,进程间通信),协议族为af_local (或af_unix ),不管套接字的类型为字节流
(sock_stream )还是数据报(sock_dgram),它都是可靠的,在使用unix 域套接字通信的过程中,如果读操作一端阻塞且缓冲区满了,写操作的一端也同
样会阻塞,在此过程中不会有数据被丢弃。
因此,当syslog 守护进程因为某些原因阻塞或运行耗时变长时,若此时缓冲区已经满了,有可能会影响到调用syslog 函数的应用程序的性能。应用程序在设计时就
需要考虑syslog 函数可能的影响,不能无节制地使用syslog 函数进行打印,也不能认为它总会很快地就执行完。
关于缓冲区,应该跟内核的套接字设置有关。对于unix 域数据报套接字,从测试结果来看/proc/sys/net/unix/max_dgram_qlen 会影响其缓冲区大小,但具体的
机制还不清楚。它的默认值为10,可使用sysctl 进行修改:
sysctl -w net.unix.max_dgram_qlen=xx
5 在tina 中使用syslog 5.1 ubox 的logd 与logread 一般使用procd init 的方案都会默认选上这两个工具。
logd 由package_logd 提供,menuconfig 中的位置为:
make menuconfig --->    base system --->     logd

图5-1: logd 配置图

logread 由package_ubox 提供,menuconfig 中的位置为:
make menuconfig --->    base system --->     ubox

图5-2: ubox 配置图

它们的开机脚本/etc/init.d/log 由package_logd 提供;配置项位于文件/etc/config/system 中,默认由package_base-files 提供,若想修改默认的配置,可以在
target/allwinner//base-files/etc/config/ 目录下放置一份自定义的system 以覆盖默认的文件。
5.2 busybox 的syslogd、klogd 与logread busybox 的syslog 工具在menuconfig 中的位置为:
make menuconfig --->    base system --->        busybox --->            system logging utilities --->                [*] klogd                *** klogd should not be used together with syslog to kernel printk buffer ***                [*] use the klogctl() interface                [*] logger                [*] logread                [*] double buffering                [*] syslogd                [*] rotate message files                [ ] remote log support                [*] support -d (drop dups) option                [*] support syslog.conf                (256) read buffer size in bytes                [*] circular buffer support                (4) circular buffer size in kbytes (minimum 4kb)                [*] linux kernel printk buffer support
对应配置项的内容请参考前文的章节。
busybox 的syslog 工具没有自带开机脚本,若想开机自启需要自行编写, 在rc.final 增加开机自启动,如下:
#挂载sd卡 mount /dev/mmcblk0p1 /mnt/sdcard/ mkdir /mnt/sdcard/log #开启rotate功能,每个log大小问4m,最多记录10个 syslogd -s 4096 -b 10 & sleep 1 #同时记录kernel的log klogd &
创建/etc/syslog.conf 文件,把log 文件记录到sd 卡中,内容如下:
*.* /mnt/sdcard/log/message
5.3 syslog-ng syslog-ng 在menuconfig 中的位置为:
make menuconfig --->    administration --->     syslog-ng

图5-3: syslog-ng 配置图

它自带有一份procd 式的开机脚本(会自动拷贝到小机端)以及一份配置文件的范例(不会自动拷贝到小机端),均位于package/admin/syslog-ng/files 目录
下。可以参考配置文件范例syslog-ng.conf_example 自定义一份syslog-ng.conf 放到小机端的/etc 目录下。
5.4 logrotate logrotate 在menuconfig 中的位置为:
make menuconfig --->    utilities --->     logrotate

图5-4: logrotate 配置图

它自带有一份配置文件logrotate.conf ,位于package/utils/logrotate/files 目录下,会自动拷贝到小机端的/etc 目录下。
配置文件带有一些全局的配置项,并且会include /etc/logrotate.d ,因此自定义的配置可放置在小机端的/etc/logrotate.d 目录下,执行logrotate
/etc/logrotate.conf 时会被自动调用到(注意文件的权限需要为0644 或0444 )。


智能安防市场发展受到高度重视,门禁系统市场发展前景不可估量
ams天线放大技术解决NFC应用瓶颈
十六大优秀的人脸识别企业大盘点
FPGA/非挥发性存储器产品线收入增加 复旦微电上半年增收不增利
LiFi光通信技术
Tina Linux syslog使用指南
埃斯顿正式发布了2020年业绩快报与2021年Q1业绩预报
Astera Labs获5,000万美元C轮融资,以9.5亿美元的估值加速产品与客户发展势头
特斯拉车内信息娱乐系统有望使用AMD的Navi 23图形处理单元
怎样在计算机上播放DDR
解析高速压电陶瓷驱动电源的性能优势
LED植物照明代表未来农业发展方向 昕诺飞将加速推进植物照明未来发展
TP700多路数据记录仪在咖啡机的测试与应用
半导体封装工艺之模塑工艺类型
中国联通与其他运营商进行5G投资合作的两种思路介绍
神舟优雅X4今天送情人 送男友送女友怎样都好
AIoT&智能照明与驱动技术研讨会正式启动!
拼多多强迫商家二选一,大量订单无法发货
探索未来云计算,华为云耀云服务器 L 实例引领行业新动力
电流互感器安装方式介绍大全——电工必备知识