[kernel]内核日志及printk结构分析
一直都知道内核printk分级机制,但是没有去了解过,前段时间和一个同事聊到开机启动打印太多,只需要设置一下等级即可;另外今天看驱动源码,也看到类似于Printk(KERN_ERR "....")的打印信息,以前用都是直接printk("...."),今晚回来就把printk这个机制熟悉一下。
转自:http://blog.csdn.net/tangkegagalikaiwu/article/details/8572365
另外/var/log下20个Linux日志文件详解
http://h2appy.blog.51cto.com/609721/781281/
一、printk概述
- 函数名
- 能够更早地工作(输出信息)
- 她有自己的小缓存(一般为512B)
- 一次性输出到硬件设备,不再以ring buffer的形式保留信息。
二、printk的使用
(1)日志等级
#define KERN_EMERG "<0>" /* 系统不可使用 */
#define KERN_ALERT "<1>" /* 需要立即采取行动 */
#define KERN_CRIT "<2>" /* 严重情况 */
#define KERN_ERR "<3>" /* 错误情况 */
#define KERN_WARNING "<4>" /* 警告情况 */
#define KERN_NOTICE "<5>" /* 正常情况, 但是值得注意 */
#define KERN_INFO "<6>" /* 信息型消息 */
#define KERN_DEBUG "<7>" /* 调试级别的信息 */
/* 使用默认内核日志级别 */
#define KERN_DEFAULT "<d>"
/*
* 标注为一个“连续”的日志打印输出行(只能用于一个
* 没有用 \n封闭的行之后). 只能用于启动初期的 core/arch 代码
* (否则续行是非SMP的安全).
*/
#define KERN_CONT "<c>"
/* printk's without a loglevel use this.. */
#define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL
printk(KERN_EMERG "log_level:%s\n", KERN_EMERG);
printk( "<0>" "log_level:%s\n", KERN_EMERG);
kern_levels.h printk.h printk.c 几个文件里面分别定义了printk和console的printk显示等级
echo 8 > /proc/sys/kernel/printk设置console的loglevel
- 一种选择是保持终端的默认记录等级不变,给所有调试信息KERN CRIT或更低的等级以保证信息一定会被输出。
- 另一种方法则相反,给所有调试信息KERN DEBUG等级,而调整终端的默认记录等级为7,也可以输出所有调试信息。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
//#define __LIBRARY__ /* _syscall3 and friends are only available through this */
//#include <linux/unistd.h>
/* define the system call, to override the library function */
//_syscall3(int, syslog, int, type, char *, bufp, int, len);
int main(int argc, char **argv)
{
int level;
if (argc == ) {
level = atoi(argv[]); /* the chosen console */
} else {
fprintf(stderr, "%s: need a single arg\n", argv[]);
exit();
}
if (klogctl(, NULL, level) < ) {
fprintf(stderr, "%s: syslog(setlevel): %s\n",
argv[], strerror(errno));
exit();
}
exit();
}
(2)相关辅助宏
#ifndef pr_fmt
#define pr_fmt(fmt) fmt
#endif
#define pr_emerg(fmt, ...) \
printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__)
#define pr_alert(fmt, ...) \
printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)
#define pr_crit(fmt, ...) \
printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)
#define pr_err(fmt, ...) \
printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
#define pr_warning(fmt, ...) \
printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
#define pr_warn pr_warning
#define pr_notice(fmt, ...) \
printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
#define pr_info(fmt, ...) \
printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
#define pr_cont(fmt, ...) \
printk(KERN_CONT fmt, ##__VA_ARGS__)
/* 除非定义了DEBUG ,否则pr_devel()不产生任何代码 */
#ifdef DEBUG
#define pr_devel(fmt, ...) \
printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
#else
#define pr_devel(fmt, ...) \
no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
#endif
/* 如果你在写一个驱动,请使用dev_dbg */
#if defined(DEBUG)
#define pr_debug(fmt, ...) \
printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
#elif defined(CONFIG_DYNAMIC_DEBUG)
/* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */
#define pr_debug(fmt, ...) \
dynamic_pr_debug(fmt, ##__VA_ARGS__)
#else
#define pr_debug(fmt, ...) \
no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
#endif
(3)输出速率控制
在调试的时候,有时某些部分可能printk会产生大量输出, 导致系统无法正常工作,并可能使系统日志ring buffer溢出(旧的信息被快速覆盖)。特别地,当使用一个慢速控制台设备(如串口), 过量输出也能拖慢系统。这样反而难于发现系统出问题的地方。所以你应当非常注意:正常操作时不应当打印任何东西,打印的输出应当是指示需要注意的异常,并小心不要做过头。
#define printk_ratelimit() __printk_ratelimit(__func__)
这个函数应当在你认为打印一个可能会出现大量重复的消息之前调用,如果这个函数返回非零值, 继续打印你的消息, 否则跳过它。典型的调用如这样:
if (printk_ratelimit())
printk(KERN_NOTICE "The printer is still on fire\n");
- /proc/sys/kern/printk_ratelimit( 可以看作一个监测周期,在这个周期内只能发出下面的控制量的信息)
- /proc/sys/kernel/printk_ratelimit_burst(以上周期内的最大消息数,如果超过了printk_ratelimit()返回0)
(4)最后特别提醒
三、printk的内核实现
static char __log_buf[__LOG_BUF_LEN];
/*
* 在指向log_buf时并没有用log_buf_len做限制 - 所以他们
* 在作为下标使用前必须用掩码处理(去除CONFIG_LOG_BUF_SHIFT以上的高位)
*/
static unsigned log_start; /* log_buf中的索引: 指向由syslog()读取的下一个字符 */
static unsigned con_start; /* log_buf中的索引: 指向发送到console的下一个字符 */
static unsigned log_end; /* log_buf中的索引:最近写入的字符地址 + 1 */
四、用户空间访问内核日志
- 通过glibc的klogctl函数接口调用内核的syslog系统调用
- 通过fs/proc/kmsg.c内核模块中导出的procfs接口:/proc/kmsg文件。

[kernel]内核日志及printk结构分析的更多相关文章
- [linux-内核][转]内核日志及printk结构浅析
这段时间复习了一下内核调试系统,注意看了一下printk的实现以及内核日志的相关知识,这里做一下总结. 1.问题的引出: 做DPDK项目时,调试rte_kni.ko时,发现printk并不会向我们想想 ...
- 内核日志及printk结构浅析
作者:tekkamanninja 鸣谢:感谢ChinaUnix技术社区的tekkamanninja提供稿件 ,如需转载,请注明出处. 这段时间复习了一下内核调试系统,注意看了一下printk的实现 ...
- ECS实例中的应用偶尔出现丢包现象并且内核日志(dmesg)存在“kernel: nf_conntrack: table full, dropping packet”的报错信息
问题描述 连接ECS实例中的应用时偶尔出现丢包现象.经排查,ECS实例的外围网络正常,但内核日志(dmesg)中存在"kernel: nf_conntrack: table full, dr ...
- Linux内核日志开关
Linux内核日志开关 1.让pr_debug能输出 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -59,7 +59,7 ...
- 深入linux kernel内核配置选项
============================================================================== 深入linux kernel内核配置选项 ...
- tiny4412 串口驱动分析八 --- log打印的几个阶段之内核启动阶段(printk tiny4412串口驱动的注册)
作者:彭东林 邮箱:pengdonglin137@163.com 开发板:tiny4412ADK+S700 4GB Flash 主机:Wind7 64位 虚拟机:Vmware+Ubuntu12_04 ...
- Ubuntu系统---系统驱动丢失、Kernel内核卸载、禁止更新
Ubuntu系统---系统驱动丢失.Kernel内核卸载.禁止更新 一早开机发现,ubuntu字体异常,字体很大,直接反应是驱动坏了.一查,确实丢失英伟达驱动,为什么呢?莫名的消失.想知道:1.英伟达 ...
- linux内核源码目录结构分析
原文地址 /arch.arch是architecture的缩写.arch目录下是好多个不同架构的CPU的子目录,譬如arm这种cpu的所有文件都在arch/arm目录下,X86的CPU的所有文件都在a ...
- Linux 内核日志——dmesg
有时Linux系统或者系统上运行的mysqld或者其它进程,会发生一些莫名其妙的问题,比如突然挂掉了,比如突然重启等等.在软件上找不到问题所在,此时我们应该怀疑硬件或者内核的问题,此时我们就可以使用 ...
随机推荐
- 转:Eclipse ADT的Custom debug keystore所需证书规格
转:http://blog.k-res.net/archives/1229.html Eclipse ADT的Custom debug keystore所需证书规格 三月 8, 2013 | Po ...
- Cognos TM1_10.1.1服务端配置
场景:本文继Cognos TM1_10.1.1服务端安装 之后,简单的说一下本人对简单配置的拙见,确保服务端在安装过程一切正常,成功安装. 1:进入TM的Cognos Configuration 2: ...
- Html中的次方符号怎么写
代码: <p>1.01<sup>365</sup>=37.783,0.99<sup>365</sup>=0.025</p> 效果 ...
- vue - 页面跳转
HTML:a 小程序:navigator Vue:router-link 1. router-link => a标签 2. javascript标签跳转页面 2.1 2.2 3. 常用方法之 ...
- windows下flv视频网站进度条随意拖放[转]
网站中视频都转换成flv格式,奈何flv格式无法拖拽,此问题纠结了好久,最终得以解决.现将解决思路记录下来,大多数源于网上找到的. 视频拖拽满足要求 1.播放器要支持 2.flv视频要有关键帧和met ...
- Window上python开发--4.Django的用户登录模块User
Android系统开发交流群:484966421 OSHome. 微信公众号:oshome2015 在搭建站点和web的应用程序时,用户的登录和管理是差点儿是每一个站点都必备的. 今天主要从一个实例了 ...
- Vue 源码 基础知识点
1.数据类型判断 const _toString = Object.prototype.toString function toRawType(value) { return _toString.ca ...
- openerp在ubuntu中查看日志
sudo su - openerp -s /bin/bash less /var/log/openerp/openerp-server.log
- XMPP协议实现即时通讯底层书写 (二)-- IOS XMPPFramework Demo+分析
我希望,This is a new day! 在看代码之前,我认为你还是应该先整理一下心情,来听我说几句: 首先,我希望你是在早上边看这篇blog,然后一边開始动手操作,假设你仅仅是看blog而不去自 ...
- Windows7下搭建Android开发环境
以后工作中要用到android开发,所以想搭建好开发环境,笔记本装的是win7 准备文件: 1 下载Android SDK http://code.google.com/android/downloa ...