EDA365电子论坛网
标题:
Linux下printk()函数的使用
[打印本页]
作者:
uperrua
时间:
2021-2-20 10:33
标题:
Linux下printk()函数的使用
3 u1 U% D8 P$ Z$ W: |
在使用printk()函数中使用日志级别为的是使编程人员在编程过程中自定义地进行信息的输出,更加容易地掌握系统当前的状况。对程序的调试起到了很重要的作用。(下文中的日志级别和控制台日志控制级别是一个意思)printk(日志级别 "消息文本");这里的日志级别通俗的说指的是对文本信息的一种输出范围上的指定。日志级别一共有8个级别,printk的日志级别定义如下(在linux26/includelinux/kernel.h中):
) m _$ @6 n. A& w
! [9 f/ u; c4 F: m1 A
5 x8 x0 J! g0 N6 m# _) F
0 _+ i8 L8 t5 ]5 R1 H
#defineKERN_EMERG"<0>"
+ f0 y! Y5 ]& J. |
#defineKERN_ALERT"<1>"
1 t' p. |, D8 {5 n
#defineKERN_CRIT"<2>"
* @9 O+ F* W7 c9 p% b. S
#defineKERN_ERR"<3>"
3 T f) Q1 y3 z& K
#defineKERN_WARNING"<4>"
/ ^3 [/ G6 Y1 `* k
#defineKERN_NOTICE"<5>"
! S- T' N- H/ _ k: |1 d; i
#defineKERN_INFO"<6>"
" O% ]3 d5 |; E9 e! n7 \' ^. Y+ c
#defineKERN_DEBUG"<7>"
- m/ u) B- u0 J4 W- W. f
5 \5 n. R. _% k- l. j
& p% D+ `1 r' @. F8 b9 Z' Q
5 E% P2 Y5 ]6 b; W! Z) k
没有指定日志级别的printk语句默认采用的级别是DEFAULT_ MESSAGE_LOGLEVEL(这个默认级别一般为<4>,即与KERN_WARNING在一个级别上),其定义在linux26/kernel/printk.c中可以找到。
_' w/ B5 |/ D: o- z; s4 \* {) ?5 r
下面是一个比较简单的使用printk(KERN_INFO "INFO\n"); //这里可以使用数字代替 KERN_INFO,即可以写成printk(<6> "INFO\n");
7 F2 H6 W& r& m- K" l5 `$ \
在这个格式的定义中,日志级别和信息文本之间不能够使用逗号隔开,因为系统在进行编译的时候,将日志级别转换成字符串于后面的文本信息进行连接。
0 J/ D) }+ O6 @# p
# `0 J5 _% a9 A& z, Z
在对系统输出进行控制时,主要是讨论控制台和伪终端的输情况,以及系统日志等。
! ?% x# n. O7 R( ^ q& M8 H5 {
& a ?; s5 a; x+ A; N
下面是控制台日志级别的一些简要的介绍
' } ~: u# P: n- _2 y3 [& q! ?! ^
控制台相应的日志级别定义如下:
3 O9 M8 T( J3 a, F7 m P v; y
#define MINIMUM_CONSOLE_LOGLEVEL 1
' |. m5 |' L- U
#define DEFAULT_CONSOLE_LOGLEVEL 7
( v. \- {7 R: I, i, j5 n
5 n: m; W3 c- o& Q8 T; U+ ~
int console_printk[4] = {
/ W" ~( z. u& z' Y9 \
DEFAULT_CONSOLE_LOGLEVEL,
/ T) j+ ?! R" v: I) O4 _
7 m. @. p# ]' p5 k
DEFAULT_MESSAGE_LOGLEVEL,
7 N X2 B( a* i8 a6 [
1 `2 }5 v, x9 [9 R4 q
MINIMUM_CONSOLE_LOGLEVEL,
: H: ]4 ]* C. W7 q. U0 `$ X
DEFAULT_CONSOLE_LOGLEVEL,
/ ? l5 g( f$ l. c9 [- n' |6 l- U
};
; n ]' c T$ S6 `5 G
在进行查看的时候,可以使用命令 cat /proc/sys/kernel/printk来查看这四个值
& c( v: |& K3 p+ F; ^5 E
可以通过修改文件/proc/sys/kernel/printk中的第一个值来更改当前的控制台日志级别。
9 a& W/ U% k) D5 M. C. l7 u% p) D
3 g2 ?8 a+ j) ]+ M$ [6 e% D
(声明:在下面的模块函数中控制台所使用的日志级别均为KERN_WARNING级别)当日志级别高于console_loglevel(控制台日志级别)时,消息才能在控制台显示出来。
1 b$ A5 _$ `. n- o, ~+ H* v. i
假如我们写了一个如下的模块函数:
8 s* G6 o. f+ e I1 I
1 #include
0 _# U5 K; f- o. }4 H0 |# o- Y4 J% R
2 #include
/ f5 W) p2 w9 [* p0 O+ U
3 MODULE_LICENSE("Dual BSD/GPL");
( K& F, N; z( h) m
4 static int book_init(void)
, H0 O4 n/ j# r; s! X8 o+ ^& M
5 {
2 A, } I6 [* @% F0 J
6 printk(KERN_EMERG "EMERG\n");
+ R1 c* h# [0 o' A$ v" t q/ |- w
7 printk(KERN_ALERT "ALERT\n");
1 S' g9 L3 z7 w2 k. Q; R
8 printk(KERN_CRIT " CRIT\n");
% S; _" { H! |4 Z9 x8 j( `2 Z& j
9 printk(KERN_ERR " ERR\n");
* V- E9 j% S0 j0 r/ Q) k
10 printk(KERN_WARNING ""WARNING\n");
u( m' z, h- I8 A: f
11 printk(KERN_NOTICE "NOTICE\n");
, e ?) R8 m) [- r \) ^9 {
12 printk(KERN_INFO "INFO\n");
$ }' f: Y" n# I$ A0 J
13 printk(KERN_DEBUG "DEBUG\n");
# F$ I) |; r7 b. ~2 j+ R, A. @
14 return 0;
2 o! q* s) i- H! Y3 i) R h/ X
}
+ ]/ ?0 R, h/ F' c
15static void book_exit(void)
( x" t/ \* U( u9 k
16{
9 b! H' c4 `# y# f7 b( O' S
17 printk(KERN_ALERT "Book module exit\n");
% f/ M h" }% n; K, S
}
6 ]9 j) ]" X* P" s$ {0 f9 j/ F; d
18 module_init(book_init);
, o( ^& }2 f5 S: i( k
19 module_exit(book_exit);
$ H/ {* m' T, l$ J) X
. n8 `& X+ G* ?
在控制台(这里指的是虚拟终端 Ctrl+Alt+(F1~F6))加载模块以后,控制台给出的信息为6~9行中要求输出的信息,我们在伪终端(如果对伪终端不是很清楚可以看相关的内容)上运行命令tail -n 10 /var/log/messages查看日志文件刚才得到的运行记录
' d% {8 g& Q) G/ V2 W/ _
可以发现messages中的值为KERN_WARNING级别之后所要求输出到信息值。而如果我们在文件syslog和kern-log中查看系统日志文件,一般情况下可以得到所有的输出信息
. Z( F. N5 o" ]$ K
7 X5 A2 o) e/ s b6 d$ g
Jul 18 11:44:19 xiyoulinux-desktop kernel: [16100.637057] INFO
9 Y% n! s+ x8 \3 X" B
Jul 18 11:44:19 xiyoulinux-desktop kernel: [16100.637063] CRIT
; Z% d8 J: e/ _' ^$ ]
Jul 18 11:44:19 xiyoulinux-desktop kernel: [16100.637066] WARNING
/ Z$ d7 N+ w6 j: r3 E
Jul 18 11:44:19 xiyoulinux-desktop kernel: [16100.637068] ERR
/ Z0 k4 \7 S+ N' q, v
Jul 18 11:44:19 xiyoulinux-desktop kernel: [16100.637069] ALERT
2 G' I4 C' s4 K# H$ o8 v5 p' J
Jul 18 11:44:19 xiyoulinux-desktop kernel: [16100.637070] EMERG
* k1 q+ ~# v3 ?
Jul 18 11:44:19 xiyoulinux-desktop kernel: [16100.637071] NOTICE
& W( [2 I6 O& E, H
Jul 18 11:44:19 xiyoulinux-desktop kernel: [16100.637072] DEBUG
9 Y5 i3 j% x2 u( K/ x7 I
(不过在有些机器上运行得到的结果并不是这样的)
# V. f( n' s3 @7 Z1 n# D- T! J
即一般情况下,syslog和kern.log两个文件中记录的内容从编程这个角度来看是基本一致的。
' m6 G& _0 C5 E
在目录/var/log/下有一下四个文件可以查看日志
y7 s$ _, q% I" M8 r; ^& [% h! t
syslog ,kern.log,messages ,DEBUG 。
3 [# F1 k* q6 S5 g6 X3 |) }$ d
syslog和kern.log一般情况下可以得到所有的系统输出值,而messages得到的是比控制台日志级别低的输出值,DEBUG得到的仅仅是DEBUG级别的
) x. K0 m3 z- r8 f, u" @
输出值。
4 D+ |8 D1 M8 p5 j( L
一般情况下,优先级高于控制台日志级别的消息将被打印到控制台。优先级低于控制台日志级别的消息将被打印到messages日志文件中,而在伪终端下不打印任何的信息。
5 ~4 X* Z$ U# k) g; d
我们在进行有关编程的时候,若使用到printk()这个函数,一般查看信息是在messages和虚拟终端下进行查看,而对于syslog和kern.log下是用来检验所有信息的输出情况。
作者:
younicp
时间:
2021-2-20 13:24
Linux下printk()函数的使用
欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/)
Powered by Discuz! X3.2