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

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: klogd&syslogd与dmesg-嵌入式系统获取linux内核log

文章目录

概述

klogd&syslogd

klogd

dmesg

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

dmesg与x86中dmesg的区别

使用方法

内核log在klogd dmesg中的数据流

klogd和dmesg的共同点和区别

参考资料:


概述

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


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


klogd&syslogd

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服务所去取代。


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


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

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

dmesg与x86中dmesg的区别

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

使用方法

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


内核log在klogd dmesg中的数据流

20191219225403441.png

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/


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
6天前
|
Linux
Linux系统之whereis命令的基本使用
Linux系统之whereis命令的基本使用
50 23
Linux系统之whereis命令的基本使用
|
15天前
|
存储 前端开发 数据可视化
Grafana Loki,轻量级日志系统
本文介绍了基于Grafana、Loki和Alloy构建的轻量级日志系统。Loki是一个由Grafana Labs开发的日志聚合系统,具备高可用性和多租户支持,专注于日志而非指标,通过标签索引而非内容索引实现高效存储。Alloy则是用于收集和转发日志至Loki的强大工具。文章详细描述了系统的架构、组件及其工作流程,并提供了快速搭建指南,包括准备步骤、部署命令及验证方法。此外,还展示了如何使用Grafana查看日志,以及一些基本的LogQL查询示例。最后,作者探讨了Loki架构的独特之处,提出了“巨型单体模块化”的概念,即一个应用既可单体部署也可分布式部署,整体协同实现全部功能。
260 69
Grafana Loki,轻量级日志系统
|
2月前
|
存储 缓存 监控
Linux缓存管理:如何安全地清理系统缓存
在Linux系统中,内存管理至关重要。本文详细介绍了如何安全地清理系统缓存,特别是通过使用`/proc/sys/vm/drop_caches`接口。内容包括清理缓存的原因、步骤、注意事项和最佳实践,帮助你在必要时优化系统性能。
230 78
|
1月前
|
缓存 安全 Linux
Linux系统查看操作系统版本信息、CPU信息、模块信息
在Linux系统中,常用命令可帮助用户查看操作系统版本、CPU信息和模块信息
109 23
|
1月前
|
安全 Linux 测试技术
Intel Linux 内核测试套件-LKVS介绍 | 龙蜥大讲堂104期
《Intel Linux内核测试套件-LKVS介绍》(龙蜥大讲堂104期)主要介绍了LKVS的定义、使用方法、测试范围、典型案例及其优势。LKVS是轻量级、低耦合且高代码覆盖率的测试工具,涵盖20多个硬件和内核属性,已开源并集成到多个社区CICD系统中。课程详细讲解了如何使用LKVS进行CPU、电源管理和安全特性(如TDX、CET)的测试,并展示了其在实际应用中的价值。
|
1月前
|
Ubuntu Linux 开发者
Ubuntu20.04搭建嵌入式linux网络加载内核、设备树和根文件系统
使用上述U-Boot命令配置并启动嵌入式设备。如果配置正确,设备将通过TFTP加载内核和设备树,并通过NFS挂载根文件系统。
95 15
|
1月前
|
存储 安全 Java
Spring Boot 3 集成Spring AOP实现系统日志记录
本文介绍了如何在Spring Boot 3中集成Spring AOP实现系统日志记录功能。通过定义`SysLog`注解和配置相应的AOP切面,可以在方法执行前后自动记录日志信息,包括操作的开始时间、结束时间、请求参数、返回结果、异常信息等,并将这些信息保存到数据库中。此外,还使用了`ThreadLocal`变量来存储每个线程独立的日志数据,确保线程安全。文中还展示了项目实战中的部分代码片段,以及基于Spring Boot 3 + Vue 3构建的快速开发框架的简介与内置功能列表。此框架结合了当前主流技术栈,提供了用户管理、权限控制、接口文档自动生成等多项实用特性。
81 8
|
2月前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
121 13
|
Shell Linux
Android--Linux kernel log级别修改
在我们开发过程中,内核的信息一开机就会很多,然后一直打个不停,很烦人,也不好看调试信息,更不好在串口终端输入相关的命令进行调试。 那么有什么办法可以解决? 1、在kernel中修改log默认等级, kernel-3.18/include/linux/printk.h         static inline void console_verbose(void)函数中的    console_loglevel = CONSOLE_LOGLEVEL_MIN; //CONSOLE_LOGLEVEL_MOTORMOUTH;然后重新编译内核。
2235 0
|
3月前
|
Linux 网络安全 数据安全/隐私保护
Linux 超级强大的十六进制 dump 工具:XXD 命令,我教你应该如何使用!
在 Linux 系统中,xxd 命令是一个强大的十六进制 dump 工具,可以将文件或数据以十六进制和 ASCII 字符形式显示,帮助用户深入了解和分析数据。本文详细介绍了 xxd 命令的基本用法、高级功能及实际应用案例,包括查看文件内容、指定输出格式、写入文件、数据比较、数据提取、数据转换和数据加密解密等。通过掌握这些技巧,用户可以更高效地处理各种数据问题。
343 8