linux loglevel

本文深入探讨了Linux中的consoleloglevel与printk、dmesg知识,详细阐述了改变consoleloglevel的方法,以及如何利用syslog系统调用与模块进行日志级别的设置与控制。同时介绍了dmesg命令的功能与原理,以及ringbuffer的作用,为读者提供了一个全面的内核日志管理系统概览。

总结一下Linux中的console loglevel以及printk, dmesg知识。

只有当printk打印信息时的loglevel小于console loglevel的值(即:优先级高于console loglevel),这些信息才会被打印到console上。

改变console loglevel的方法有如下几种:
1.启动时Kernel boot option:loglevel=level
2.运行时Runtime: dmesg -n level
(注意:demsg -n level 改变的是console上的loglevel,dmesg命令仍然会打印出所有级别的系统信息。)
3.运行时Runtime: echo $level > /proc/sys/kernel/printk
4.运行时Runtime:写程序使用syslog系统调用(可以man syslog)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <unistd.h>
#include <sys/syscall.h>
 
static inline int syslog(int type, char *bufp, int len)
{
	return syscall(SYS_syslog, type, bufp, len);
}
 
int main()
{
	/* Set the console loglevel to 4 */
	syslog(8, 0, 4);
 
	return 0;
}

在kernel boot option中:

loglevel Set the default console log level.
loglevel=level
Specify the initial console log level. Any log messages with levels less than this (that is, of higher priority) will be printed to the console, whereas any messages with levels equal to or greater than this will not be displayed.
The console log level can also be changed by the klogd program, or by writing the specified level to the /proc/sys/kernel/printk file. (在2.6.32及之上kernel的Linux系统中,我没有找到klogd这个程序了,应该是有所变化了)

The kernel log levels are:
0 (KERN_EMERG)
The system is unusable.
1 (KERN_ALERT)
Actions that must be taken care of immediately.
2 (KERN_CRIT)
Critical conditions.
3 (KERN_ERR)
Noncritical error conditions.
4 (KERN_WARNING)
Warning conditions that should be taken care of.
5 (KERN_NOTICE)
Normal, but significant events.
6 (KERN_INFO)
Informational messages that require no action.
7 (KERN_DEBUG)
Kernel debugging messages, output by the kernel if the developer enabled debugging at compile time.

KERN_ERR, KERN_DEBUG等是一些宏定义,在$Linux_SRC/include/linux/printk.h中可以查看到。

dmesg是从kernel的ring buffer(环缓冲区)中读取信息的.
man dmesg得到如下信息:
dmesg is used to examine or control the kernel ring buffer.
The program helps users to print out their bootup messages. Instead of copying the messages by hand, the user need only: dmesg > dmesg.log

那什么是ring buffer呢?
在LINUX中,所有的系统信息(包内核信息)都会传送到ring buffer中。而内核产生的信息由printk()打印出来。系统启动时所看到的信息都是由该函数打印到屏幕中。printk()打出的信息往往以 <0>…<2>… 这的数字表明消息的重要级别。高于一定的优先级别(当前的console loglevel)就会打印到console上,否则只会保留在系统的缓冲区中(ring buffer)。
至于dmesg具体是如何从ring buffer中读取的,大家可以看dmesg.c源代码。$Linux-SRC/arch/m68k/tools/amiga/dmesg.c,很短,比较容易读懂。

默认的loglevel在kernel/printk.c中有定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* printk's without a loglevel use this.. */
#define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL
 
/* We show everything that is MORE important than this.. */
#define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */
#define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */
 
DECLARE_WAIT_QUEUE_HEAD(log_wait);
 
int console_printk[4] = {
        DEFAULT_CONSOLE_LOGLEVEL,       /* console_loglevel */
        DEFAULT_MESSAGE_LOGLEVEL,       /* default_message_loglevel */
        MINIMUM_CONSOLE_LOGLEVEL,       /* minimum_console_loglevel */
        DEFAULT_CONSOLE_LOGLEVEL,       /* default_console_loglevel */
};

cat /proc/sys/kernel/printk
4 4 1 7
所得到的信息是$Linux_SRC/include/linux/printk.h中定义的宏:
#define console_loglevel (console_printk[0])
#define default_message_loglevel (console_printk[1])
#define minimum_console_loglevel (console_printk[2])
#define default_console_loglevel (console_printk[3])
依次分别为:
控制台日志级别:优先级高于该值的消息将被打印至控制台
缺省的消息日志级别:将用该优先级来打印没有优先级的消息
最低的控制台日志级别:控制台日志级别可被设置的最小值(最高优先级)
缺省的控制台日志级别:控制台日志级别的缺省值

为了下面我做的一个实验:
首先,需要一个module,我的loglevel.c代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <linux/module.h>       /* Needed by all modules */
#include <linux/kernel.h>       /* Needed for log level */
#include <linux/init.h>         /* Needed for the macros */
 
MODULE_AUTHOR("Jay, <Jay's email> ");
MODULE_DESCRIPTION("To test: console log level.");
MODULE_LICENSE("GPL");
MODULE_VERSION("Version-0.0.1");
 
static int __init hello_start(void)
{
printk(KERN_INFO "Loading loglevel module...\n");
printk(KERN_INFO "Hello, Jay.\n");
printk(KERN_EMERG "------------------------------------\n");
 
printk(KERN_EMERG "Hello, EMERG.\n");
printk(KERN_ALERT "Hello, ALERT.\n");
printk(KERN_CRIT "Hello, CRIT.\n");
printk(KERN_ERR "Hello, ERR.\n");
printk(KERN_WARNING"Hello, WARNING.\n");
printk(KERN_NOTICE "Hello, NOTICE.\n");
printk(KERN_INFO "Hello, INFO.\n");
printk(KERN_DEBUG "Hello, DEBUG.\n");
 
printk(KERN_EMERG "------------------------------------\n");
 
return 0;
}
 
static void __exit hello_end(void)
{
printk(KERN_INFO "Goodbye, Jay.\n");
}
 
module_init(hello_start);
module_exit(hello_end);

将这个module编译好之后,有了loglevel.ko这个module文件。

1
2
3
[root@vt-snb9 ~]# cat /proc/sys/kernel/printk
7      4       1       7
[root@vt-snb9 ~]# insmod /root/loglevel/loglevel.ko

console上打印的信息如下:
##注意DEBUG级别的信息没有打印在console上
Loading loglevel module…
Hello, Jay.
————————————
Hello, EMERG.
Hello, ALERT.
Hello, CRIT.
Hello, ERR.
Hello, WARNING.
Hello, NOTICE.
Hello, INFO.
————————————

改变console loglevel之后,

1
2
3
[root@vt-snb9 ~]# cat /proc/sys/kernel/printk
4      4       1       7
[root@vt-snb9 ~]# insmod /root/loglevel/loglevel.ko

##注意”Hello, Jay.”这样的INFO级别的就没有打印到console上
————————————
Hello, EMERG.
Hello, ALERT.
Hello, CRIT.
Hello, ERR.
————————————

在kernel启动项目中加入了debug,则启动后:

1
2
3
[root@vt-snb9 ~]# cat /proc/sys/kernel/printk
10      4       1       7
[root@vt-snb9 ~]# insmod /root/loglevel/loglevel.ko

##注意这次DEBUG等级的信息也被打印在console上了
Loading loglevel module…
Hello, Jay.
————————————
Hello, EMERG.
Hello, ALERT.
Hello, CRIT.
Hello, ERR.
Hello, WARNING.
Hello, NOTICE.
Hello, INFO.
Hello, DEBUG.
————————————

而dmesg始终都是可以打印出module所print出来的所有信息的,不管console loglevel为多少,当insmod loglevel之时,dmesg始终会打印如下信息:

Loading loglevel module...
Hello, Jay.
------------------------------------
Hello, EMERG.
Hello, ALERT.
Hello, CRIT.
Hello, ERR.
Hello, WARNING.
Hello, NOTICE.
Hello, INFO.
Hello, DEBUG.
------------------------------------

另外,最后见说一下syslogd吧(或者新的叫做rsyslogd进程)。 在比较新的系统(比如RHEL6.1)中,syslogd已经存在了,取而代之的是rsyslogd,功能是差不多的,配置文件在/etc/rsyslogd.conf
syslogd这个守护进程根据/etc/syslog.conf,将不同的服务产生的Log记录到不同的文件中.
LINUX系统启动后,由/etc/init.d/sysklogd先后启动klogd,syslogd两个守护进程。
其中klogd会通过syslog()系统调用或者读取/proc/kmsg文件来从系统缓冲区(ring buffer)中得到由内核printk()发出的信息.而syslogd是通过klogd来读取系统内核信息.
(1)所有系统信息是输出到ring buffer中去的,dmesg所显示的内容也是从ring buffer中读取的.
(2)LINUX系统中/etc/init.d/sysklogd会启动2个守护进程:Klogd, Syslogd
(3)klogd是负责读取内核信息的,有2种方式:
syslog()系统调用(这个函数用法比较全,大家去MAN一下看看);
直接的对/proc/kmsg进行读取(再这提一下,/proc/kmsg是专门输出内核信息的地方)
(4)Klogd的输出结果会传送给syslogd进行处理,syslogd会根据/etc/syslog.conf的配置把log信息输出到/var/log/下的不同文件中.

可以将printk与syslog接合使用, 用在内核开发方面很不错的应用:
修改/etc/syslog.conf (或者是/etc/rsyslogd.conf)
kern.* /tmp/my_kernel_debug.txt
就可将kernel的信息输出到文件中了,这样更方便查看。

日志文件详细地记录了系统每天发生的各种各样的事件。用户可以通过日志文件检查错误产生的原因,或者在受到攻击和黑客入侵时追踪攻击者的踪迹。日志的两个比较重要的作用是:审核和监测。
Linux系统的日志主要分为两种类型:
1.进程所属日志
由用户进程或其他系统服务进程自行生成的日志,比如服务器上的access_log与error_log日志文件。
2.syslog消息 【syslogd, klogd协同作用,前面以及提及,新版本中都没了klogd了】
系统syslog记录的日志,任何希望记录日志的系统进程或者用户进程都可以给调用syslog来记录日志。
日志系统可以划分为三个子系统:
1.连接时间日志–由多个程序执行,把纪录写入到/var/log/wtmp和/var/run/utmp,login等程序更新wtmp和utmp文件,使系统管理员能够跟踪谁在何时登录到系统。
2.进程统计–由系统内核执行。当一个进程终止时,为每个进程往进程统计文件(pacct或acct)中写一个纪录。进程统计的目的是为系统中的基本服务提供命令使用统计。
3.错误日志–由syslogd(8)执行。各种系统守护进程、用户程序和内核通过syslog(3)向文件/var/log/messages报告值得注意的事件。

<think> 首先,用户的问题是:“我想在Linux系统下查询loglevel的方法 请问Linux系统查询loglevel的方法”。我需要根据提供的引用来回答这个问题。 回顾引用: - 引用[1]提到了“四个数字的含义:当前的loglevel、默认loglevel、最小允许的loglevel、引导时的默认loglevel。”但没有具体说明如何查询。 - 引用[2]提到了“console_loglevel”,但没有直接给出查询方法。 - 引用[3]讨论了printk的使用和syslogd的问题,但也没有直接相关。 - 引用[4]是关于服务器性能优化的,似乎不相关。 用户指定的引用是站内引用,但我需要基于这些内容来回答。引用[1]提到了四个数字的含义,这暗示了可能有文件或命令来查询这些值。 在Linux中,loglevel通常与内核日志相关,特别是printk函数的日志级别。查询loglevel的方法通常涉及/proc或/sys文件系统。 从通用知识: - 当前控制台的日志级别可以通过`cat /proc/sys/kernel/printk`查询。这会输出四个数字,如引用[1]所述:当前级别、默认级别、最小允许级别、引导时默认级别。 - 另外,可以使用dmesg命令来查看内核日志,但dmesg本身不直接查询日志级别值;它显示日志消息。 引用[1]说:“四个数字的含义:当前的loglevel、默认loglevel、最小允许的loglevel、引导时的默认loglevel。”这对应于`/proc/sys/kernel/printk`的内容。 引用[2]提到了setlevel.c,这是一个程序来改变console_loglevel,但用户想查询,而不是设置。 引用[3]讨论了printk的影响,但不直接帮助查询。 所以,最直接的方法应该是查询`/proc/sys/kernel/printk`。 步骤: 1. 使用命令:`cat /proc/sys/kernel/printk` 2. 输出会是四个数字,例如:"7 4 1 7",含义如引用[1]所述。 用户可能还想知道如何查看当前日志级别或设置它,但问题明确是查询方法。 回答结构: - 用户的问题是中文的,所以我应该用中文回答。 - 系统指令要求使用中文回答,LaTeX语法正确,行内数学表达式用$...$,独立公式用$$...$$,但这里可能没有数学表达式。 - 生成相关问题。 - 在回答中引用的段落末尾添加引用标识,如[^1]。 引用标识: - 引用[1]描述了四个数字的含义,所以我可以在解释输出时引用它。 - 其他引用可能不直接相关,但如果需要,可以提及。 完整回答: - 解释如何查询:使用cat命令读取/proc/sys/kernel/printk。 - 解释输出格式。 - 可能简要说明如何设置,但用户只问查询,所以保持专注。 - 最后,生成相关问题。 生成相关问题: - 例如:如何设置日志级别?日志级别的不同值代表什么?等等。 确保回答真实可靠,基于知识。 最后,添加引用:当提到四个数字的含义时,添加[^1],因为引用[1]提供了这个信息。 </think>### Linux系统查询loglevel的方法 在Linux系统中,日志级别(loglevel)主要与内核日志机制相关,通过`printk`函数管理。查询日志级别最直接的方法是访问`/proc`文件系统,该文件系统提供了内核参数的实时信息。以下是查询方法的详细步骤: #### 1. **查询当前日志级别** - 使用`cat`命令读取`/proc/sys/kernel/printk`文件: ```bash cat /proc/sys/kernel/printk ``` - **输出示例**:四个数字,例如 `7 4 1 7`,其含义依次为: - **当前控制台日志级别**(console_loglevel):决定哪些级别的内核消息会输出到控制台。值越小,表示日志越紧急(如KERN_EMERG=0),值越大表示越详细(如KERN_DEBUG=7)。 - **默认消息日志级别**:未指定级别的`printk`消息使用的默认级别。 - **最小允许日志级别**:系统允许设置的最低日志级别。 - **引导时默认日志级别**:系统启动时使用的默认级别[^1]。 - 输出中的数字范围是0-7,对应不同的日志优先级,例如: - 0:KERN_EMERG(紧急) - 1:KERN_ALERT(警报) - 2:KERN_CRIT(严重) - 3:KERN_ERR(错误) - 4:KERN_WARNING(警告) - 5:KERN_NOTICE(通知) - 6:KERN_INFO(信息) - 7:KERN_DEBUG(调试) #### 2. **查看实时内核日志(辅助方法)** - 使用`dmesg`命令可以查看内核环形缓冲区中的消息,并结合`-l`选项过滤特定级别的日志: ```bash dmesg -l emerg,alert,crit,err,warn,notice,info,debug ``` - 例如,`dmesg -l err` 只显示错误级别的消息。 - 这不会直接显示日志级别数值,但能帮助确认当前日志输出行为。 #### 3. **注意事项** - **权限要求**:查询`/proc/sys/kernel/printk`通常需要`root`权限或具有`sudo`权限的用户。普通用户可能无法访问某些文件。 - **性能影响**:频繁使用`printk`或高日志级别(如DEBUG)可能拖慢系统,因为日志写入会触发磁盘同步操作[^3]。生产环境中建议保持较低级别(如默认值4)。 - **临时性**:`/proc`文件系统的值在系统重启后会重置。若要永久修改日志级别,需编辑`/etc/sysctl.conf`文件(例如添加`kernel.printk = 4 4 1 7`)。 #### 引用说明 - 日志级别的四个数字含义已在引用[1]中明确说明[^1]。 - 引用[3]提醒了高日志级别对性能的潜在影响[^3]。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值