klogd&syslogd与dmesg-嵌入式系统获取linux内核log

    xiaoxiao2021-03-25  136

    概述

      有的时候运行linux内核的设备(现在市场上有很多智能设备运行android或GNU/Linux)发生了死机、挂起或其他不正常的行为,但是该设备并没有连接控制台串口,如何获取内核log就需要这些工具了,内核可能发生过oops,通过这些工具可以查看发生错误的具体内容,帮助进行问题诊断。

      下面简单介绍一下获取内核log工具的原理和使用。

    0x1 klogd&syslogd

    0x11 klogd

      klogd是一个专门截获并记录 Linux 内核消息的守护进程,可以指定输出到控制台,文件或syslogd守护进程等,常用情况是把内核消息输出到syslogd进程,由syslogd统一处理。

    0x12 syslogd

      syslogd负责记录系统中kenel或应用程序(邮件、新闻等)产生的各种log信息的工具。这些信息被写入到系统文件中,通常是/var/log目录下,或者是输出到远程server,让使用者进行故障排除、追踪尝试非法入侵的使用者等等。

      本文主要关注的是内核log,syslogd涉及到的log信息种类很多,并且都有对应等级描述,配置文件syslog.conf需要用规定的语法进行配置,内容比较多,这里不做过多介绍,要更详细了解syslogd及配置方法,请参考https://linux.die.net/man/8/syslogd。

      klogd获取内核log通过两种方式,一种是系统调用syslog(),glibc对应用程序的API是klogctl(),两个函数的原型分别为: int syslog(int type, char *bufp, int len); /* No wrapper provided in glibc */ /* The glibc interface */ #include <sys/klog.h> int klogctl(int type, char *bufp, int len);

      另一种方式是,通过/proc/kmsg,以正常打开文件形式,通过系统调用open、read、write去操作。

      klogd输出到syslogd的方法是通过glibc中的api,openlog 、syslog 、closelog,这几个函数的原型是: #include <syslog.h> void openlog(const char *ident, int option, int facility); void syslog(int priority, const char *format, ...); void closelog(void);

      内部操作都是通过socket实现,其中会在调用openlog的时候创建socket,调用syslog的时候实现发送,调用closelog关闭socket。需要了解更多,请参考glibc源码。

    0x14 利用klogd&syslogd保存内核log

      系统初始化时打开守护进程:   在/etc/inittab文件中指定控制台串口设备后添加如下指令:   # 启动klogd syslogd服务 null::respawn:/sbin/klogd -n null::respawn:/sbin/syslogd -n

      # 重启系统之前关闭 null::shutdown:/bin/killall klogd null::shutdown:/bin/killall syslogd

      注意: 在init控制klogd和syslogd的情况下-n参数一定要加,否则会执行完之后直接退出,init进程会反复重启这两个守护进程。   syslogd配置保存内核消息   syslogd的配置文件/etc/syslog.conf添加内核log的配置 kern.* -/var/log/kern.log   上面配置的解释:kern是内核log的关键字,表示需要处理内核log, *是表示要保存所有级别的log, -代表每次有log写入要同步文件到磁盘,/var/log/kern.log是保存log的路径名称。

    0x15 klogd在嵌入式系统中和PC中的区别

      通常在嵌入式系统中由busybox提供系统工具,klogd也在其中,它支持两个选项c 和n:   -c 设置控制台消息的默认等级,内核消息等级由0到7,定义在内核代码的kern_levels.h头文件中   -n 上面已经解释过,由init进程控制klogd时要加上   而PC端的klogd要强大很多,可以输出到文件、动态配置内核log来源、动态加载内核符号表等帮助分析内核错误,例如oops。但是现在很多PC端的GNU/Linux系统发行版中已经不用klogd和syslogd了,它们已经被功能更强大的rsyslog服务所去取代。

    0x2 dmesg

      打印或控制kernel ring buffer,默认的行为是显示所有保存在kernel ring buffer中的log信息。

    0x21 常用命令选项

      -c 清除log   当完成打印显示后清除kernel ring buffer的内容。   -s 定义缓冲区大小   定义指定大小的缓冲区用于查询kernel ring buffer。默认大小为 16392(内核3.16 log buffer大小是16384字节),如果你设置了一个大于默认值的缓冲区,那就可以用这来查看完整的kernel ring buffer内容,下限是4096字节,如果比这个值小则改为4096。   -n 设置log级别   设置控制台输出log级别。比如,-n 1或-n alert选项阻止了除了内核panic信息之外的其他所有信息在控制台打印。所有级别的log信息仍然可以通过/proc/kmsg文件中获取,因此,syslogd(8)同样可以用来对信息的输出进行控制。当使用-n选项时,dmesg不会打印和清除kernel ring buffer中的内容。    -r   打印原始数据,也就是不加消息级别前缀   要注意真正的原始数据依赖于读取内核日志的方法。/dev/kmsg与系统调用syslog()不同。为了向后兼容,dmesg返回syslog的数据格式。也可以通过/dev/kmsg读取,例如,使用命令:

    dd if=/dev/kmsg iflag=nonblock

    0x22 dmesg获取内核log以及输出原理

     dmesg 的内核消息来源有两个,其中一个是系统调用syslog,和klogd是相同的,调用glibc的klogctl接口实现。   另一个是通过设备文件/dev/kmsg获取,通过系统调用open、read、write去操作dmesg通过获取内核log后,通过fwrite函数输出到stdout。

    0x23 dmesg与x86中dmesg的区别

      1. busybox中只支持-c -n -s -r四个选项;   2. buxybox 日志缓冲区最小是16k,最大是16M, x86最小是4096+8,没有设置上限;   3. busybox只支持通过syslog系统调用读取内核日志,x86支持syslog系统调用和/dev/kmsg。

    0x24 使用方法

      终端命令行下输入命令 dmesg | less dmesg | grep keyword

    0x3 内核log在klogd dmesg中的数据流

                图 内核log输入输出流

    0x4 klogd和dmesg的共同点和区别

      共同点:   1. 都是获取内核消息到用户空间;   2. 都可以通过系统调用syslog获取内核log;   3. 它们通过所有方法获取的内核log都是kernel ring buffer中的内容。   区别:   klogd输出log信息到文件或syslogd进程中,比较适用于无人值守的情况,当系统发生过挂起,或设备发生过断电重启,log仍然可以完好的保存。   dmesg获取log后输出到stdout,也就是终端屏幕或控制台串口,比较适用于实时查看kenrel ring buffer中的内容,比如事先并没有连接控制台,或内核log优先级设置的数字很低(优先级很高),或是log早已被其他应用程序繁多的log所淹没的情况下(android系统log很多)使用,通过dmesg仍然看以查看内核log。当然现在的ubuntu发行版中也保存了dmesg信息到文件中,但是rsyslog已经保存了内核log,对这个行为表示不理解。

    参考资料:

    klogd http://www.linuxcommand.org/man_pages/klogd8.html http://baike.baidu.com/link?url=DNO3mDsSEUT7pju2ujw9-WxT–wmxp4yAwCHayIBQLjya_O4d1BiBj8cdyeUyuSNwXIhCJWC7l0XYj_LHPpgy_ syslogd https://linux.die.net/man/8/syslogd dmesg http://man7.org/linux/man-pages/man1/dmesg.1.html 内核源码地址: https://www.kernel.org/ linux工具源码地址: https://www.kernel.org/pub/linux/utils/util-linux/ glibc源码地址 http://ftp.gnu.org/gnu/glibc/ busybox源码地址 https://busybox.net/downloads/

    转载请注明原文地址: https://ju.6miu.com/read-5143.html

    最新回复(0)