11use slog:: o;
22use slog:: Drain ;
33
4+ use super :: app_config:: AppConfig ;
45use super :: error:: Result ;
6+ use super :: types:: LogLevel ;
57
68pub fn setup_logging ( ) -> Result < slog_scope:: GlobalLoggerGuard > {
79 // Setup Logging
@@ -15,9 +17,11 @@ pub fn default_root_logger() -> Result<slog::Logger> {
1517 // Create drains
1618 let drain = slog:: Duplicate ( default_discard ( ) ?, default_discard ( ) ?) . fuse ( ) ;
1719
18- // TODO: Link logging to config
1920 // Merge drains
20- //let drain = slog::Duplicate(default_term_drain().unwrap_or(default_discard()?), drain).fuse();
21+ let drain = slog:: Duplicate ( default_term_drain ( ) . unwrap_or ( default_discard ( ) ?) , drain) . fuse ( ) ;
22+
23+ // Filter drain
24+ let drain = LevelFilter { drain } . fuse ( ) ;
2125
2226 // Create Logger
2327 let logger = slog:: Logger :: root ( drain, o ! ( "who" => "pyroscope-cli" ) ) ;
@@ -34,10 +38,52 @@ fn default_discard() -> Result<slog_async::Async> {
3438
3539// term drain: Log to Terminal
3640fn default_term_drain ( ) -> Result < slog_async:: Async > {
37- let plain = slog_term:: PlainSyncDecorator :: new ( std :: io :: stdout ( ) ) ;
38- let term = slog_term:: FullFormat :: new ( plain ) ;
41+ let decorator = slog_term:: TermDecorator :: new ( ) . build ( ) ;
42+ let term = slog_term:: FullFormat :: new ( decorator ) ;
3943
4044 let drain = slog_async:: Async :: default ( term. build ( ) . fuse ( ) ) ;
4145
4246 Ok ( drain)
4347}
48+
49+ struct LevelFilter < D > {
50+ drain : D ,
51+ }
52+
53+ impl < D > Drain for LevelFilter < D >
54+ where
55+ D : Drain ,
56+ {
57+ type Ok = Option < D :: Ok > ;
58+ type Err = Option < D :: Err > ;
59+
60+ fn log (
61+ & self , record : & slog:: Record , values : & slog:: OwnedKVList ,
62+ ) -> std:: result:: Result < Self :: Ok , Self :: Err > {
63+ // Discard logs if no_logging flag is set
64+ let logging = AppConfig :: get :: < bool > ( "no_logging" ) . unwrap_or ( false ) ;
65+ if logging {
66+ return Ok ( None ) ;
67+ }
68+
69+ // TODO: This is probably expensive (and should be cached)
70+ let log_level = AppConfig :: get :: < LogLevel > ( "log_level" ) . unwrap_or ( LogLevel :: Info ) ;
71+
72+ // convert log level to slog level
73+ let current_level = match log_level {
74+ LogLevel :: Trace => slog:: Level :: Trace ,
75+ LogLevel :: Debug => slog:: Level :: Debug ,
76+ LogLevel :: Info => slog:: Level :: Info ,
77+ LogLevel :: Warn => slog:: Level :: Warning ,
78+ LogLevel :: Error => slog:: Level :: Error ,
79+ LogLevel :: Critical => slog:: Level :: Critical ,
80+ } ;
81+
82+ // check if log level is above current level
83+ if record. level ( ) . is_at_least ( current_level) {
84+ self . drain . log ( record, values) . map ( Some ) . map_err ( Some )
85+ } else {
86+ Ok ( None )
87+ }
88+ }
89+ }
0 commit comments