设计一个企业网站多少钱,网页美术设计主要学什么,网站百度收录删除,怀孕单子图片在线制作目录 前言一、/proc/kmsg1、简介2、如何修改内核日志缓冲区3、dmesgklogctl 函数#xff08;来源于 man 手册#xff09; 4、扩展阅读 二、 /proc/sys/kernel/printk_xxx三、/dev/kmsg 前言 本篇文章将为大家介绍与 Linux 内核日志相关的一些控制文件#xff0c;共同学习来源于 man 手册 4、扩展阅读 二、 /proc/sys/kernel/printk_xxx三、/dev/kmsg 前言 本篇文章将为大家介绍与 Linux 内核日志相关的一些控制文件共同学习
一、/proc/kmsg
1、简介 /proc/kmsg 是一个特殊的文件它提供了内核消息缓冲区的访问这个缓冲区包含了内核产生的所有消息包括各种调试和错误信息如内核的启动打印。/proc/kmsg 文件通常只能被 root 用户或具有相应权限的用户读取。这个文件通常被用于调试和故障排除因为它可以提供关于内核发生事件的详细信息。 注意这是一个缓冲区所以其内的数据是会被刷新覆盖的 一般情况下你可以使用以下方式来使用 /proc/kmsg 文件
1、读取内核消息你可以使用命令行工具如 cat 或 dmesg 来查看和读取/proc/kmsg文件
中的内核消息。例如使用以下命令可以显示最近的内核消息cat /proc/kmsg
这样做可以帮助你查看内核启动时的各种信息、硬件错误、系统调试等。需要注意的是/proc/kmsg 文件一般只能被 root 用户或具有相应权限的用户访问因此在使用
时请确保你有足够的权限。此外了解内核消息的解释和上下文对正确理解和利用 /proc/kmsg 中
的信息非常重要。2、如何修改内核日志缓冲区 有时候我们发现dmesg看到的日志信息缺少了很多或者存储的很少这个是因为内核日志缓冲区设置的较小无法存储更多的内容可以适当调整该缓冲区的大小。 建议不要调整的过大正常的产品使用128KB即可若是自己调试排查问题可以设置的大一点比如2MB根据自己的物理内存资源合理设置。
3、dmesg /proc/kmsg 文件和 dmesg 命令之间有着紧密的关系。 /proc/kmsg 文件提供了对内核消息缓冲区的直接访问通过读取该文件可以查看最近的内核消息。dmesg 命令是一个通用命令行工具主要用于显示和控制内核环缓冲区。使用 dmesg 命令可以更方便地查看内核日志消息包括从开机到当前时间内的所有内核日志消息。 实际上dmesg 命令背后的实现原理也是通过读取 /proc/kmsg 文件来获取内核消息的。当我们在终端中执行 dmesg 命令时它会读取 /proc/kmsg 文件的内容并将其显示在终端上。 因此可以说 /proc/kmsg 文件是 dmesg 命令的底层实现之一。在使用 dmesg 命令的时候实际上是在调用 /proc/kmsg 文件提供的接口来获取内核日志。
以下文件来自busybox源码busybox\util-linux\dmesg.c
/* vi: set sw4 ts4: */
/*** dmesg - display/control kernel ring buffer.** Copyright 2006 Rob Landley roblandley.net* Copyright 2006 Bernhard Reutner-Fischer rep.nopaon.at** Licensed under GPLv2, see file LICENSE in this source tree.*/
//config:config DMESG
//config: bool dmesg (3.7 kb)
//config: default y
//config: select PLATFORM_LINUX
//config: help
//config: dmesg is used to examine or control the kernel ring buffer. When the
//config: Linux kernel prints messages to the system log, they are stored in
//config: the kernel ring buffer. You can use dmesg to print the kernels ring
//config: buffer, clear the kernel ring buffer, change the size of the kernel
//config: ring buffer, and change the priority level at which kernel messages
//config: are also logged to the system console. Enable this option if you
//config: wish to enable the dmesg utility.
//config:
//config:config FEATURE_DMESG_PRETTY
//config: bool Pretty output
//config: default y
//config: depends on DMESG
//config: help
//config: If you wish to scrub the syslog level from the output, say Y here.
//config: The syslog level is a string prefixed to every line with the form
//config: #.
//config:
//config: With this option you will see:
//config: # dmesg
//config: Linux version 2.6.17.4 .....
//config: BIOS-provided physical RAM map:
//config: BIOS-e820: 0000000000000000 - 000000000009f000 (usable)
//config:
//config: Without this option you will see:
//config: # dmesg
//config: 5Linux version 2.6.17.4 .....
//config: 6BIOS-provided physical RAM map:
//config: 6 BIOS-e820: 0000000000000000 - 000000000009f000 (usable)//applet:IF_DMESG(APPLET(dmesg, BB_DIR_BIN, BB_SUID_DROP))//kbuild:lib-$(CONFIG_DMESG) dmesg.o//usage:#define dmesg_trivial_usage
//usage: [-c] [-n LEVEL] [-s SIZE]
//usage:#define dmesg_full_usage \n\n
//usage: Print or control the kernel ring buffer\n
//usage: \n -c Clear ring buffer after printing
//usage: \n -n LEVEL Set console logging level
//usage: \n -s SIZE Buffer size
//usage: \n -r Print raw message buffer#include sys/klog.h
#include libbb.hint dmesg_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int dmesg_main(int argc UNUSED_PARAM, char **argv)
{int len, level;char *buf;unsigned opts;enum {OPT_c 1 0,OPT_s 1 1,OPT_n 1 2,OPT_r 1 3};opts getopt32(argv, cs:n:r, len, level);if (opts OPT_n) {if (klogctl(8, NULL, (long) level))bb_simple_perror_msg_and_die(klogctl);return EXIT_SUCCESS;}if (!(opts OPT_s))len klogctl(10, NULL, 0); /* read ring buffer size */if (len 16*1024)len 16*1024;if (len 16*1024*1024)len 16*1024*1024;buf xmalloc(len);len klogctl(3 (opts OPT_c), buf, len); /* read ring buffer */if (len 0)bb_simple_perror_msg_and_die(klogctl);if (len 0)return EXIT_SUCCESS;if (ENABLE_FEATURE_DMESG_PRETTY !(opts OPT_r)) {int last \n;int in 0;/* Skip [0-9] at the start of lines */while (1) {if (last \n buf[in] ) {while (buf[in] ! in len);} else {last buf[in];putchar(last);}if (in len)break;}/* Make sure we end with a newline */if (last ! \n)bb_putchar(\n);} else {full_write(STDOUT_FILENO, buf, len);if (buf[len-1] ! \n)bb_putchar(\n);}if (ENABLE_FEATURE_CLEAN_UP) free(buf);return EXIT_SUCCESS;
}#define EXTERNALLY_VISIBLE __attribute__(( visibility(default) ))
#define MAIN_EXTERNALLY_VISIBLE EXTERNALLY_VISIBLEEXTERNALLY_VISIBLE 是一个宏定义用于通过 __attribute__((visibility(default)))
属性将声明的符号设置为外部可见。__attribute__((visibility(default))) 是 GNU C 编译器的语法扩展可以用于指定符号
的可见性。可见性标记是用于控制符号在链接阶段的可见性即决定符号是否能够被其他目标文件或
动态链接库访问。通常情况下默认可见性会被应用于所有的符号。然而如果我们想将符号标记为外部可见即在其他
目标文件或动态链接库中可用就需要使用 __attribute__((visibility(default))) 属性
来指定这一可见性。在这个宏定义中EXTERNALLY_VISIBLE 用于将一个声明设置为外部可见这意味着其他源文件或
程序可以访问该声明。这样做的一个常见原因是要提供一个公共的接口使得其他模块或库可以使用它
。在使用这个宏定义时通常会将它与函数、变量或类型声明一起使用如下所示EXTERNALLY_VISIBLE int my_function();
EXTERNALLY_VISIBLE extern int my_variable;这样一来通过 EXTERNALLY_VISIBLE 宏定义这些声明就会被设置为外部可见可以在其他源文
件或程序中使用和访问。对于符号的可见性有几个不同的级别其中包括 default默认hidden隐藏protected
受保护和 internal内部等。default默认可见性是指符号在链接过程中会被默认导出可以被其他目标文件或动态链接库访问
。这是最常见的可见性级别。hidden隐藏可见性是指符号在链接过程中不会被导出只能在定义它的目标文件内部使用。其他
目标文件或动态链接库无法直接访问该符号。protected受保护可见性介于 default 和 hidden 之间在某些情况下限制了符号的可见性
但又允许共享库之间的访问。internal内部可见性是 GNU C 扩展中的一个特殊级别用于指定符号只能在同一编译单元内
可见。这意味着该符号只能在定义它的源文件内部使用。klogctl 函数来源于 man 手册
klogctl 函数用于控制内核消息日志头文件为 #include sys/klog.h。它有以下原型
int syslog(int type, char *bufp, int len);/* No wrapper provided in glibc */
int klogctl(int type, char *buf, int len);type指定要执行的操作类型。它可以是以下值之一
类型参数确定此函数所执行的操作。下面的列表指定了类型的值。符号名称在内核源代码中定义但不
导出到用户空间您要么使用数字或者自己实现宏定义。SYSLOG_ACTION_CLOSE (0)Close the log. Currently a NOP.SYSLOG_ACTION_OPEN (1)Open the log. Currently a NOP.SYSLOG_ACTION_READ (2)从日志中读取。该调用等待直到内核日志缓冲区为非空然后将最多len字节读取到bufp指向的
缓冲区中。该调用返回读取的字节数。从日志中读取的字节从日志缓冲区中消失信息只能读取一次。
这是当用户程序读取/proc/kmsg时内核执行的函数。SYSLOG_ACTION_READ_ALL (3)读取环形缓冲区中剩余的所有消息将它们放在bufp指向的缓冲区中。该调用从日志缓冲区读取
最后一个len字节非破坏性但读取的字节数不会超过自上次“清除环形缓冲区”命令以来写入缓冲
区的字节数请参阅下面的命令5。该调用返回读取的字节数SYSLOG_ACTION_READ_CLEAR (4)读取并清除环形缓冲区中剩余的所有消息。该调用与类型为3的调用完全相同但也执行“清除环
形缓冲区”命令。SYSLOG_ACTION_CLEAR (5)该调用仅执行“清除环形缓冲区”命令。bufp和len参数将被忽略。此命令并不能真正清除环形
缓冲区。相反它设置了一个内核记账变量用于确定命令3SYSLOG_ACTION_READ_ALL和 4
SYSLOG_ACTION_READ _CLEAR返回的结果。此命令对命令2SYSLOG_ACTION_READ和 9
SYSLOG_ACTION_SIZE_UNREAD没有影响。SYSLOG_ACTION_CONSOLE_OFF (6)该命令保存console_loglevel的当前值然后将console_log级别设置为
minimum_console_lowlevel这样就不会向控制台打印任何消息。在Linux 2.6.32之前该命令
只需将console_loglevel设置为minimum_console_longlevel。请参阅下面
对/proc/sys/kernel/printk的讨论。bufp和len参数将被忽略。SYSLOG_ACTION_CONSOLE_ON (7)如果执行了以前的SYSLOG_ACTION_CONSOLE_OFF命令则此命令会将CONSOLE_loglevel恢复
为该命令保存的值。在Linux 2.6.32之前此命令只需将console_loglevel设置为
default_console_loglevel。请参阅下面对/proc/sys/kernel/printk的讨论。bufp和len参数
将被忽略。SYSLOG_ACTION_CONSOLE_LEVEL (8)该调用将console_loglevel设置为len中给定的值该值必须是介于1和8之间包括1和8的
整数。内核静默地强制len的最小值minimum_console_loglevel。有关详细信息请参阅日志级别
部分。bufp参数被忽略。SYSLOG_ACTION_SIZE_UNREAD (9) (since Linux 2.4.10)该调用返回当前可通过命令2SYSLOG_ACTION_READ从内核日志缓冲区读取的字节数。bufp
和len参数将被忽略。SYSLOG_ACTION_SIZE_BUFFER (10) (since Linux 2.6.6)此命令返回内核日志缓冲区的总大小。bufp和len参数将被忽略。除3和10之外的所有命令都需要特权。在2.6.37之前的Linux内核中命令类型3和10被允许用于
非特权进程自Linux以来2.6.37只有当/proc/sys/kernel/dmesg_restrict的值为0时才允许
无特权进程使用这些命令。在Linux 2.6.37之前“特权”意味着呼叫者具有CAP_SYS_ADMIN能力。
从Linux 2.6.37开始“privileged”表示调用者具有CAP_SYS_ADMIN功能现在已弃用或新的
CAP_SYSLOG功能。buf用于读取或写入内核日志的缓冲区。len长度。 klogctl 函数允许您控制内核消息日志的操作例如打开或关闭日志记录读取最近的日志消息或将消息写入日志中。您可以使用相关的 type 值执行不同的操作并通过 buf 参数进行数据的读取或写入。需要注意的是klogctl 函数仅在 Linux 系统中可用且需要以管理员权限运行。 /proc/sys/kernel/printk /proc/sys/kernel/printk是一个可写文件包含四个整数值这些整数值在打印或记录错误
消息时会影响内核printk的行为。这四个值是console_loglevel只有日志级别低于此值的消息才会打印到控制台。该字段的默认值为default_CONSOLE_LOGLEVEL
7但如果内核命令行包含单词“quiet”则将其设置为4如果内核命令行将包含单词“debug”
则设置为10如果出现内核故障则设置至1510和15只是愚蠢的相当于8。console_loglevel
的值可以通过类型为8的syslog调用设置设置为1–8范围内的值。default_message_loglevel此值将用作没有显式级别的printk消息的日志级别。在Linux 2.6.38之前包括该版本
该字段的硬编码默认值为4KERN_WARNING自Linux 2.6.39以来默认值是由内核配置选项
CON-FIG_default_MESSAGE_LOGLEVEL定义的默认值为4。minimum_console_loglevel此字段中的值是可以设置console_loglevel的最小值。default_console_loglevel这是console_loglevel的默认值。内核日志的打印级别Kernel constant Level value MeaningKERN_EMERG 0 System is unusableKERN_ALERT 1 Action must be taken immediatelyKERN_CRIT 2 Critical conditions关键/临界条件KERN_ERR 3 Error conditionsKERN_WARNING 4 Warning conditionsKERN_NOTICE 5 Normal but significant conditionKERN_INFO 6 InformationalKERN_DEBUG 7 Debug-level messages返回值对于调用为2、3或4的类型成功调用syslog将返回读取的字节数。对于类型9syslog()
返回当前可在内核日志缓冲区上读取的字节数。对于类型10syslog返回内核日志缓冲区的总大
小。对于其他类型的值成功时返回0。如果出现错误则返回-1并设置errno以指示错误。错误码EINVAL错误的参数例如错误的类型或对于类型2、3或4buf为NULL或len小于零
或者对于类型8级别在1到8).ENOSYS此syslog系统调用不可用因为编译内核时禁用了CONFIG_PRINTK内核配置选项。EPERM没有足够权限的进程试图更改console_loglevel或清除内核消息环形缓冲区更准确地
说没有CAP_SYS_ADMIN或CAP_SYSLOG能力。ERESTARTSYS系统调用被信号中断什么也没读。这只能在跟踪过程中看到4、扩展阅读 linux日志syslogd和klogd及syslog
二、 /proc/sys/kernel/printk_xxx 这些是 Linux 内核的一些控制文件用于配置内核日志和打印设置。下面是对这些文件的详细解释 /proc/sys/kernel/printk 该文件用于控制内核日志的打印级别。它包含四个整数值以空格分隔分别表示控制台日志级别、默认控制台日志级别、启动日志级别和当前日志级别。 /proc/sys/kernel/printk_devkmsg 如果该文件的值为非零则内核日志将通过/dev/kmsg设备输出。如果为零则内核日志将不会输出到该设备。默认情况下它的值为非零。 /proc/sys/kernel/printk_delay 该文件用于设置内核日志的打印延迟时间以毫秒为单位。这个延迟时间用于合并相邻的日志消息以减少日志输出的开销。 /proc/sys/kernel/printk_ratelimit 该文件用于设置内核日志输出的限速即每秒打印的消息数量限制。默认情况下它的值为 5。 /proc/sys/kernel/printk_ratelimit_burst 该文件用于设置内核日志限速突发打印的数量。当达到限速后内核可以突发打印多少条日志消息。默认情况下它的值等于 10 * printk_ratelimit。 这些文件的值可以通过读取和写入这些文件来进行配置。例如要更改内核日志的打印级别可以使用以下命令
echo console_loglevel default_console_loglevel boot_loglevel current_loglevel /proc/sys/kernel/printk其中每个loglevel代表一个整数表示对应的日志级别。需要注意的是对这些控制文件的更改只对当前会话有效重新启动系统后会恢复为默认值。如果您希望在系统启动时保持更改的值可以在启动脚本中设置这些文件的值。
三、/dev/kmsg /dev/kmsg 是 Linux 操作系统中的一个特殊设备文件用于读取内核日志。它在内核中用于与用户空间的程序进行通信并提供了对内核消息缓冲区的访问。 通过读取 /dev/kmsg您可以获取内核在运行时生成的各种日志消息包括内核启动消息、驱动程序消息、错误消息等。这对于诊断系统问题、调试内核模块或了解系统运行状况非常有用。 为了访问 /dev/kmsg您可以使用标准的读取文件的方法例如使用 open 函数打开设备文件然后使用 read 函数读取其中的数据。示例代码如下
#include stdio.h
#include unistd.h
#include fcntl.h#define BUF_SIZE 1024int main()
{int fd open(/dev/kmsg, O_RDONLY);if (fd -1){perror(Failed to open /dev/kmsg);return 1;}char buffer[BUF_SIZE];ssize_t bytesRead;while ((bytesRead read(fd, buffer, BUF_SIZE - 1)) 0){buffer[bytesRead] \0;printf(%s, buffer);}close(fd);return 0;
}上述代码将打开 /dev/kmsg然后使用一个循环不断读取内核日志信息将其打印到标准输出上直至读取完毕。请注意读取 /dev/kmsg 通常需要 root 权限或者使用 sudo 运行程序。 需要注意的是读取 /dev/kmsg 的方式是阻塞的也就是说如果没有新的消息读取操作将会一直阻塞直到有新的消息到达。因此该方式通常用于长期运行或守护进程以便可以实时监控内核日志。 summary/proc/kmsg 是一个虚拟文件/dev/kmsg 是一个设备文件也用于读取内核日志消息。/proc 下的虚拟文件主要用于提供内核状态和动态信息而 /dev 下的设备文件主要用于与硬件设备进行交互。 欢迎大家指导和交流如果我有任何错误或遗漏请立即指正我愿意学习改进。期待与大家一起进步