内核日志为例的日志级别划分

Don’t Live with Broken Windows.

1. 日志级别和使用实例

日志级别如下,逐渐提升:

  • Trace: 帮助debug内核的信息,但是通常过于冗长,一般情况下不显示
    • 调度器switch日志
    • IRQ中断日志
  • Debug: 开发者关系的信息
    • 页表地址
  • Info: 内核用户关心的信息
    • 系统中内存数量
    • 内核初始化状态
  • Warn: 表明一些非预期的错误情况
    • 内存用尽
    • 来自用户程序的未知异常
  • Error: 表明内核正常执行情况下从不应该发生的情况
    • 违反Debug断言
    • 内核中发生的未知异常

2. 实现

首先要引入log crate,这个crate提供的是抽象的api,需要自己给出logger的实现。

1
log = "0.4"

对应提供了下面这些宏

  • trace!()
  • debug!()
  • info!()
  • warn!()
  • error!()

然后实现具体的logger,并为它实现Logtrait。这里当然就是直接用kprintln格式化打印一句话就好了(见log()方法)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
use log::{LevelFilter, Metadata, Record};

use crate::console::kprintln;

struct KernelLogger;

static LOGGER: KernelLogger = KernelLogger;

impl log::Log for KernelLogger {
    fn enabled(&self, _metadata: &Metadata) -> bool {
        true
    }

    fn log(&self, record: &Record) {
        if self.enabled(record.metadata()) {
            kprintln!("[{}] {}", record.level(), record.args());
        }
    }

    fn flush(&self) {}
}

2.1. 配置日志显示级别

当然logger还有一个重要功能是配置日志的显示级别,如下函数,在logger初始化的时候调用,根据环境变量是否设置了VERBOSE_BUILD环境变量,配置显示级别:

1
2
3
4
5
6
7
8
9
10
11
pub unsafe fn init_logger() {
    log::set_logger_racy(&LOGGER)
        .map(|()| {
            log::set_max_level(if let Some(_) = option_env!("VERBOSE_BUILD") {
                LevelFilter::Trace
            } else {
                LevelFilter::Debug
            })
        })
        .expect("Failed to initialize the logger");
}

2.2. 结果

不开启trace情况下的输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[INFO] text beg: 0000000000080000, end: 00000000000a34f8
[INFO] bss  beg: 00000000000a34c0, end: 00000000000a34f8
[INFO] Welcome to EOS :) by LJR
[INFO] mem_allocator: init
[INFO] heap beg: a34f8, end: 3c000000
[INFO] mem_allocator: assign 0x10000000B mem at 0x10000000
[INFO] mem_allocator: assign 0x10000000B mem at 0x20000000
[INFO] mem_allocator: assign 0x8000000B mem at 0x30000000
[INFO] mem_allocator: assign 0x4000000B mem at 0x38000000
[INFO] mem_allocator: init succeed
[INFO] filesystem: init
[INFO] filesystem: sd driver init succeed
[INFO] filesystem: vfat init succeed
[INFO] filesystem: init succeed
[INFO] vmm: kern pt init
[INFO] vmm: kern pt init succeed
[INFO] scheduler: init
[INFO] process: start
[INFO] process: timer_interrupt init
[INFO] process: timer_interrupt init succeed
[INFO] process: create first process
[INFO] process: user program load succeed
[INFO] scheduler: init succeed

开启verbose之后,除了上面显示的还有:

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
[TRACE] syscall 14 triggered
text_beg: [TRACE] exception happened: Info {
    source: LowerAArch64,
    kind: Synchronous,
}
[TRACE] current sp: 0x381ffc40
[TRACE] syscall 14 triggered
ffffffffc0000000[TRACE] exception happened: Info {
    source: LowerAArch64,
    kind: Synchronous,
}
[TRACE] current sp: 0x381ffc40
[TRACE] syscall 14 triggered
, text_end: [TRACE] exception happened: Info {
    source: LowerAArch64,
    kind: Synchronous,
}
[TRACE] current sp: 0x381ffc40
[TRACE] syscall 14 triggered
ffffffffc00090a0[TRACE] exception happened: Info {
    source: LowerAArch64,
    kind: Synchronous,
}
[TRACE] current sp: 0x381ffc40
[TRACE] syscall 14 triggered

[TRACE] exception happened: Info {
    source: LowerAArch64,
    kind: Synchronous,
}
[TRACE] current sp: 0x381ffc40
[TRACE] syscall 14 triggered
heap_beg: [TRACE] exception happened: Info {
    source: LowerAArch64,
    kind: Synchronous,
}
[TRACE] current sp: 0x381ffc40
[TRACE] syscall 14 triggered
18446744072635875328[TRACE] exception happened: Info {
    source: LowerAArch64,
    kind: Synchronous,
}
[TRACE] current sp: 0x381ffc40
[TRACE] syscall 8 triggered
[TRACE] process 0 scheduled out
[TRACE] process 0 begin to run
[TRACE] process 0 scheduled out
[TRACE] process 0 begin to run
[TRACE] process 0 scheduled out
[TRACE] process 0 begin to run
[TRACE] process 0 scheduled out
[TRACE] process 0 begin to run
[TRACE] process 0 scheduled out
[TRACE] process 0 begin to run
[TRACE] process 0 scheduled out
[TRACE] process 0 begin to run
...

3. 参考