[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或者其它进程,会发生一些莫名其妙的问题,比如突然挂掉了,比如突然重启等等.在软件上找不到问题所在,此时我们应该怀疑硬件或者内核的问题,此时我们就可以使用 ...
随机推荐
- 屏幕实时显示键盘鼠标操作软件keycastow,适合做视频教程
屏幕实时显示键盘鼠标操作软件keycastow,适合做视频教程 学习了:https://www.52pojie.cn/thread-535154-1-1.html 进行键盘按键的屏幕实时显示:
- 【canvas】三角光阑
代码: <!DOCTYPE html> <html lang="utf-8"> <meta http-equiv="Content-Type ...
- 工具篇:如何使用junit.jar进行测试
一.网上下载:junit.jar包 下载地址:https://sourceforge.net/projects/junit/?source=typ_redirect 二.导入指定项目中 三.在指定方法 ...
- Unity Web前端研究
原地址:http://blog.csdn.net/libeifs/article/details/7200630 开发环境 Window7 Unity3D 3.4.1 MB525defy Andro ...
- Map 和 WeakMap 数据结构
Map 和 WeakMap 是ES6 新增的数据结构 一.Map 它们本质与对象一样,都是键值对的集合,但是他们与 Object 对象主要的不同是,键可以是各种类型的数值,而Object 对象的键 只 ...
- 在MVC的cshtml视图页获取默认路由下的ID值的方法
<a href="/user/resume/index/11"> <span class="title bold">我的 @Reques ...
- Autofac3 在MVC4中的运用原理
这是一种新的开发模式,注入开发模式,或者叫它IOC模式,说起IOC你可以这样去理解它,它为你的某个实现流出一个注入点,你生产的对象,可以根据你之前的配置进行组合. IOC全称是Inversion o ...
- potplayer 网页调用potplayer播放本地视频
网页调用potplayer播放本地视频 CreateTime--2018年1月3日10:36:24 Author:Marydon 源码展示: <!DOCTYPE html> <h ...
- 【linux】查看内存和CPU使用情况
1.内存命令:free 解释:以上数据单位KB. 所以,上面的mem物理内存共1G 下面是对这些数值的解释: total:总计物理内存的大小. used:已使用多大. free:可用有多少. Shar ...
- 【LeetCode】73. Set Matrix Zeroes (2 solutions)
Set Matrix Zeroes Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do i ...