@@ -3,22 +3,27 @@ use core::sync::atomic::{AtomicBool, Ordering};
33use core:: time:: Duration ;
44
55use anstyle:: AnsiColor ;
6+ use hermit_sync:: OnceCell ;
67use log:: { Level , LevelFilter , Metadata , Record } ;
78
89pub static KERNEL_LOGGER : KernelLogger = KernelLogger :: new ( ) ;
10+ const ARENA_SIZE : usize = 4096 ;
11+ static mut ARENA : [ u8 ; ARENA_SIZE ] = [ 0 ; _] ;
912
1013const TIME_SEC_WIDTH : usize = 5 ;
1114const TIME_SUBSEC_WIDTH : usize = 6 ;
1215
1316/// Data structure to filter kernel messages
1417pub struct KernelLogger {
1518 time : AtomicBool ,
19+ filter : OnceCell < env_filter:: Filter > ,
1620}
1721
1822impl KernelLogger {
1923 pub const fn new ( ) -> Self {
2024 Self {
2125 time : AtomicBool :: new ( false ) ,
26+ filter : OnceCell :: new ( ) ,
2227 }
2328 }
2429
@@ -45,6 +50,23 @@ impl log::Log for KernelLogger {
4550 return ;
4651 }
4752
53+ let target = record. target ( ) ;
54+ let ( crate_, modules) = target. split_once ( "::" ) . unwrap_or ( ( target, "" ) ) ;
55+ let ( _modules, module) = modules. rsplit_once ( "::" ) . unwrap_or ( ( "" , modules) ) ;
56+ let target = if !module. is_empty ( ) && crate_ == "hermit" {
57+ module
58+ } else {
59+ crate_
60+ } ;
61+
62+ if self . filter . get ( ) . is_some_and ( |filter| {
63+ // We want the target that we match against to match the target we display.
64+ let record = record. to_builder ( ) . target ( target) . build ( ) ;
65+ !filter. matches ( & record)
66+ } ) {
67+ return ;
68+ }
69+
4870 let format_time = if self . time ( ) {
4971 let time = Duration :: from_micros ( crate :: processor:: get_timer_ticks ( ) ) ;
5072 format_args ! (
@@ -58,14 +80,6 @@ impl log::Log for KernelLogger {
5880 let core_id = crate :: arch:: core_local:: core_id ( ) ;
5981 let level = ColorLevel ( record. level ( ) ) ;
6082
61- let target = record. target ( ) ;
62- let ( crate_, modules) = target. split_once ( "::" ) . unwrap_or ( ( target, "" ) ) ;
63- let ( _modules, module) = modules. rsplit_once ( "::" ) . unwrap_or ( ( "" , modules) ) ;
64- let target = if !module. is_empty ( ) && crate_ == "hermit" {
65- module
66- } else {
67- crate_
68- } ;
6983 let format_target = format_args ! ( " {target:<10}" ) ;
7084
7185 let args = record. args ( ) ;
@@ -101,29 +115,29 @@ fn no_color() -> bool {
101115}
102116
103117pub unsafe fn init ( ) {
118+ #[ cfg( target_os = "none" ) ]
119+ unsafe {
120+ crate :: mm:: ALLOCATOR
121+ . lock ( )
122+ . claim ( ( & raw mut ARENA ) . cast ( ) , ARENA_SIZE )
123+ . unwrap ( )
124+ } ;
125+
104126 log:: set_logger ( & KERNEL_LOGGER ) . expect ( "Can't initialize logger" ) ;
105127 // Determines LevelFilter at compile time
106128 let log_level: Option < & ' static str > = option_env ! ( "HERMIT_LOG_LEVEL_FILTER" ) ;
107- let mut max_level = LevelFilter :: Info ;
108-
109- if let Some ( log_level) = log_level {
110- max_level = if log_level. eq_ignore_ascii_case ( "off" ) {
111- LevelFilter :: Off
112- } else if log_level. eq_ignore_ascii_case ( "error" ) {
113- LevelFilter :: Error
114- } else if log_level. eq_ignore_ascii_case ( "warn" ) {
115- LevelFilter :: Warn
116- } else if log_level. eq_ignore_ascii_case ( "info" ) {
117- LevelFilter :: Info
118- } else if log_level. eq_ignore_ascii_case ( "debug" ) {
119- LevelFilter :: Debug
120- } else if log_level. eq_ignore_ascii_case ( "trace" ) {
121- LevelFilter :: Trace
122- } else {
123- error ! ( "Could not parse HERMIT_LOG_LEVEL_FILTER, falling back to `info`." ) ;
124- LevelFilter :: Info
125- } ;
126- }
129+ let max_level = if let Some ( log_level) = log_level {
130+ let filter = env_filter:: Builder :: new ( )
131+ // The default. It may get overwritten by the parsed filter if it has a global level.
132+ . filter_level ( LevelFilter :: Info )
133+ . parse ( log_level)
134+ . build ( ) ;
135+ let max_level = filter. filter ( ) ;
136+ KERNEL_LOGGER . filter . set ( filter) . unwrap ( ) ;
137+ max_level
138+ } else {
139+ LevelFilter :: Info
140+ } ;
127141
128142 log:: set_max_level ( max_level) ;
129143}
0 commit comments