@@ -33,6 +33,27 @@ use std::time::SystemTime;
3333// Log level filter
3434// ====================================================================
3535
36+ /// Log severity level, ordered from least to most severe.
37+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , PartialOrd , Ord ) ]
38+ pub enum LogLevel {
39+ Debug = 0 ,
40+ Info = 1 ,
41+ // TODO: Add Progress between Info and Warn.
42+ Warn = 2 ,
43+ Error = 3 ,
44+ }
45+
46+ impl LogLevel {
47+ fn as_str ( self ) -> & ' static str {
48+ match self {
49+ LogLevel :: Debug => "DEBUG" ,
50+ LogLevel :: Info => "INFO" ,
51+ LogLevel :: Warn => "WARN" ,
52+ LogLevel :: Error => "ERROR" ,
53+ }
54+ }
55+ }
56+
3657/// Bitmask of allowed log levels for a stream.
3758///
3859/// Combine levels with `|`:
@@ -52,13 +73,12 @@ impl LevelFilter {
5273 pub const ERROR : LevelFilter = LevelFilter ( 0b1000 ) ;
5374 pub const ALL : LevelFilter = LevelFilter ( 0b1111 ) ;
5475
55- pub fn allows ( self , level : & str ) -> bool {
76+ pub fn allows ( self , level : LogLevel ) -> bool {
5677 let bit: u8 = match level {
57- "DEBUG" => 0b0001 ,
58- "INFO" => 0b0010 ,
59- "WARN" => 0b0100 ,
60- "ERROR" => 0b1000 ,
61- _ => 0 ,
78+ LogLevel :: Debug => 0b0001 ,
79+ LogLevel :: Info => 0b0010 ,
80+ LogLevel :: Warn => 0b0100 ,
81+ LogLevel :: Error => 0b1000 ,
6282 } ;
6383 self . 0 & bit != 0
6484 }
@@ -147,23 +167,23 @@ fn format_unix_timestamp(secs: u64, buf: &mut [u8; 19]) {
147167fn write_formatted < W : Write > (
148168 writer : & mut W ,
149169 format : & LogFormat ,
150- level : & str ,
170+ level : LogLevel ,
151171 msg : & str ,
152172) {
153173 match format {
154174 LogFormat :: Plain => match level {
155- "WARN" => {
175+ LogLevel :: Warn => {
156176 let _ = writeln ! ( writer, "Warning: {}" , msg) ;
157177 }
158- "ERROR" => {
178+ LogLevel :: Error => {
159179 let _ = writeln ! ( writer, "Error: {}" , msg) ;
160180 }
161181 _ => {
162182 let _ = writeln ! ( writer, "{}" , msg) ;
163183 }
164184 } ,
165185 LogFormat :: LevelPrefix => {
166- let _ = writeln ! ( writer, "[{}] {}" , level, msg) ;
186+ let _ = writeln ! ( writer, "[{}] {}" , level. as_str ( ) , msg) ;
167187 }
168188 LogFormat :: Timestamp => {
169189 let secs = SystemTime :: now ( )
@@ -173,7 +193,7 @@ fn write_formatted<W: Write>(
173193 let mut buf = [ 0u8 ; 19 ] ;
174194 format_unix_timestamp ( secs, & mut buf) ;
175195 let ts = std:: str:: from_utf8 ( & buf) . unwrap_or ( "0000-00-00 00:00:00" ) ;
176- let _ = writeln ! ( writer, "[{}] [{}] {}" , ts, level, msg) ;
196+ let _ = writeln ! ( writer, "[{}] [{}] {}" , ts, level. as_str ( ) , msg) ;
177197 }
178198 }
179199}
@@ -184,31 +204,11 @@ fn write_formatted<W: Write>(
184204
185205/// Trait for structured logging with zero-cost when disabled.
186206pub trait Logger {
187- // TODO: Get rid of this general method and force people to either
188- // create a new level, or reuse an existing one. We need to have a
189- // trade-off between flexibility and performance and simplicity,
190- // and I think the `log` method is simply too flexible and adds
191- // the cost of a string rather than a well defined enum that we
192- // can exhaustively match and ensure all cases are covered.
193- fn log ( & self , level : & str , msg : & str ) ;
194-
195- fn info ( & self , msg : & str ) {
196- self . log ( "INFO" , msg) ;
197- }
198-
207+ fn debug ( & self , msg : & str ) ;
208+ fn info ( & self , msg : & str ) ;
199209 // TODO: Add "progress" method between info and warn.
200-
201- fn warn ( & self , msg : & str ) {
202- self . log ( "WARN" , msg) ;
203- }
204-
205- fn error ( & self , msg : & str ) {
206- self . log ( "ERROR" , msg) ;
207- }
208-
209- fn debug ( & self , msg : & str ) {
210- self . log ( "DEBUG" , msg) ;
211- }
210+ fn warn ( & self , msg : & str ) ;
211+ fn error ( & self , msg : & str ) ;
212212}
213213
214214// ====================================================================
@@ -254,7 +254,7 @@ impl<W1: Write, W2: Write> DualStreamLogger<W1, W2> {
254254 }
255255
256256 /// Write a log message directly (used by the channel writer thread).
257- pub fn write_log ( & mut self , level : & str , msg : & str ) {
257+ pub fn write_log ( & mut self , level : LogLevel , msg : & str ) {
258258 if self . levels1 . allows ( level) {
259259 write_formatted ( & mut self . writer1 , & self . format1 , level, msg) ;
260260 }
@@ -274,7 +274,13 @@ pub struct NoOpLogger;
274274
275275impl Logger for NoOpLogger {
276276 #[ inline( always) ]
277- fn log ( & self , _level : & str , _msg : & str ) { }
277+ fn debug ( & self , _msg : & str ) { }
278+ #[ inline( always) ]
279+ fn info ( & self , _msg : & str ) { }
280+ #[ inline( always) ]
281+ fn warn ( & self , _msg : & str ) { }
282+ #[ inline( always) ]
283+ fn error ( & self , _msg : & str ) { }
278284}
279285
280286// ====================================================================
@@ -283,7 +289,7 @@ impl Logger for NoOpLogger {
283289
284290/// A log message sent through the channel.
285291struct LogMessage {
286- level : String ,
292+ level : LogLevel ,
287293 msg : String ,
288294}
289295
@@ -297,9 +303,30 @@ pub struct ChannelLogger {
297303}
298304
299305impl Logger for ChannelLogger {
300- fn log ( & self , level : & str , msg : & str ) {
306+ fn debug ( & self , msg : & str ) {
307+ let _ = self . sender . send ( LogMessage {
308+ level : LogLevel :: Debug ,
309+ msg : msg. to_owned ( ) ,
310+ } ) ;
311+ }
312+
313+ fn info ( & self , msg : & str ) {
314+ let _ = self . sender . send ( LogMessage {
315+ level : LogLevel :: Info ,
316+ msg : msg. to_owned ( ) ,
317+ } ) ;
318+ }
319+
320+ fn warn ( & self , msg : & str ) {
321+ let _ = self . sender . send ( LogMessage {
322+ level : LogLevel :: Warn ,
323+ msg : msg. to_owned ( ) ,
324+ } ) ;
325+ }
326+
327+ fn error ( & self , msg : & str ) {
301328 let _ = self . sender . send ( LogMessage {
302- level : level . to_owned ( ) ,
329+ level : LogLevel :: Error ,
303330 msg : msg. to_owned ( ) ,
304331 } ) ;
305332 }
@@ -358,7 +385,7 @@ where
358385 writer1, format1, levels1, writer2, format2, levels2,
359386 ) ;
360387 while let Ok ( msg) = receiver. recv ( ) {
361- backend. write_log ( & msg. level , & msg. msg ) ;
388+ backend. write_log ( msg. level , & msg. msg ) ;
362389 }
363390 } ) ;
364391
0 commit comments