Skip to main content

Logger

Struct Logger 

Source
pub struct Logger { /* private fields */ }
Expand description

A named logger with a severity threshold and a set of Handlers.

Use Logger::get to obtain a shared logger by name (created once, then reused), or Logger::root for the ancestor logger. Messages below level are dropped before reaching any handler.

The level is stored in an AtomicU8 and handlers behind an RwLock, so a &Logger can be used concurrently from multiple threads.

Implementations§

Source§

impl Logger

Source

pub fn new(name: &'static str) -> Self

Builds a logger. The root logger starts empty at Level::Info; any other logger inherits a snapshot of root’s handlers and level at creation time.

Source

pub fn get(name: &'static str) -> Arc<Self>

Returns the shared logger registered under name, creating and registering it on first call.

Examples found in repository?
examples/quickstart.rs (line 17)
14fn main() {
15    // Get a named logger from the global registry. Calling `get` with the same
16    // name again anywhere in the program returns the same logger.
17    let logger = Logger::get("basic");
18
19    // Attach a handler that writes to stdout using a simple pattern.
20    // `%(level)` and `%(message)` are field placeholders.
21    logger
22        .add_handler(StreamHandler::with_pattern(
23            std::io::stdout(),
24            "%(level): %(message)",
25        ))
26        .expect("handler lock should not be poisoned at startup");
27
28    // Emit a few messages. The default level is `Info`, so `debug` is dropped.
29    logger.info("hello from a named logger");
30    logger.warning("something to keep an eye on");
31    logger.error("something went wrong");
32}
More examples
Hide additional examples
examples/colorized.rs (line 61)
36fn main() {
37    // 1. Build a formatter from a pattern.
38    //
39    //    `%(name)` is a field placeholder. A trailing spec like `-20` controls
40    //    width/alignment: a leading `-` left-aligns, the number is the minimum
41    //    width, and an optional `.N` truncates to N characters. So:
42    //      %(level)-8   -> left-aligned, padded to 8 ("INFO    ")
43    //      %(name).12   -> truncated to at most 12 chars
44    let mut formatter = Formatter::new("%(timestamp) [%(level)-8] %(name)-12 | %(message)");
45
46    // 2. Customize the timestamp rendering (chrono's strftime syntax).
47    formatter.set_time_format("%Y-%m-%d %H:%M:%S");
48
49    // 3. Post-process every rendered line (here: add color).
50    formatter.set_transformer(colorize);
51
52    // 4. Configure the ROOT logger once. Every logger created afterwards
53    //    inherits a snapshot of root's handlers and level, so you typically
54    //    set things up here and then just `Logger::get(...)` everywhere else.
55    let root = Logger::root();
56    root.add_handler(StreamHandler::new(formatter, std::io::stdout()))
57        .expect("root handler lock should not be poisoned at startup");
58    root.set_level(Level::Debug); // emit everything Debug and above
59
60    // 5. Grab a named logger and emit one message per level.
61    let logger = Logger::get("quickstart");
62    logger.debug("a debug message (gray)");
63    logger.info("an info message (blue)");
64    logger.warning("a warning message (yellow)");
65    logger.error("an error message (red)");
66    logger.critical("a critical message (deep red)");
67
68    // 6. Levels below a logger's threshold are dropped cheaply (before
69    //    formatting). Raise the bar and show that Debug/Info now vanish.
70    logger.set_level(Level::Warning);
71    logger.debug("you will NOT see this (below threshold)");
72    logger.info("you will NOT see this either");
73    logger.warning("but warnings still get through");
74}
Source

pub fn root() -> Arc<Self>

Returns the shared root logger, the ancestor whose handlers/level new loggers inherit.

Examples found in repository?
examples/colorized.rs (line 55)
36fn main() {
37    // 1. Build a formatter from a pattern.
38    //
39    //    `%(name)` is a field placeholder. A trailing spec like `-20` controls
40    //    width/alignment: a leading `-` left-aligns, the number is the minimum
41    //    width, and an optional `.N` truncates to N characters. So:
42    //      %(level)-8   -> left-aligned, padded to 8 ("INFO    ")
43    //      %(name).12   -> truncated to at most 12 chars
44    let mut formatter = Formatter::new("%(timestamp) [%(level)-8] %(name)-12 | %(message)");
45
46    // 2. Customize the timestamp rendering (chrono's strftime syntax).
47    formatter.set_time_format("%Y-%m-%d %H:%M:%S");
48
49    // 3. Post-process every rendered line (here: add color).
50    formatter.set_transformer(colorize);
51
52    // 4. Configure the ROOT logger once. Every logger created afterwards
53    //    inherits a snapshot of root's handlers and level, so you typically
54    //    set things up here and then just `Logger::get(...)` everywhere else.
55    let root = Logger::root();
56    root.add_handler(StreamHandler::new(formatter, std::io::stdout()))
57        .expect("root handler lock should not be poisoned at startup");
58    root.set_level(Level::Debug); // emit everything Debug and above
59
60    // 5. Grab a named logger and emit one message per level.
61    let logger = Logger::get("quickstart");
62    logger.debug("a debug message (gray)");
63    logger.info("an info message (blue)");
64    logger.warning("a warning message (yellow)");
65    logger.error("an error message (red)");
66    logger.critical("a critical message (deep red)");
67
68    // 6. Levels below a logger's threshold are dropped cheaply (before
69    //    formatting). Raise the bar and show that Debug/Info now vanish.
70    logger.set_level(Level::Warning);
71    logger.debug("you will NOT see this (below threshold)");
72    logger.info("you will NOT see this either");
73    logger.warning("but warnings still get through");
74}
Source

pub fn handlers(&self) -> Vec<Arc<dyn Handler>>

Returns a snapshot clone of this logger’s handlers.

Source

pub fn set_level(&self, level: Level)

Sets the minimum severity this logger will emit.

Examples found in repository?
examples/colorized.rs (line 58)
36fn main() {
37    // 1. Build a formatter from a pattern.
38    //
39    //    `%(name)` is a field placeholder. A trailing spec like `-20` controls
40    //    width/alignment: a leading `-` left-aligns, the number is the minimum
41    //    width, and an optional `.N` truncates to N characters. So:
42    //      %(level)-8   -> left-aligned, padded to 8 ("INFO    ")
43    //      %(name).12   -> truncated to at most 12 chars
44    let mut formatter = Formatter::new("%(timestamp) [%(level)-8] %(name)-12 | %(message)");
45
46    // 2. Customize the timestamp rendering (chrono's strftime syntax).
47    formatter.set_time_format("%Y-%m-%d %H:%M:%S");
48
49    // 3. Post-process every rendered line (here: add color).
50    formatter.set_transformer(colorize);
51
52    // 4. Configure the ROOT logger once. Every logger created afterwards
53    //    inherits a snapshot of root's handlers and level, so you typically
54    //    set things up here and then just `Logger::get(...)` everywhere else.
55    let root = Logger::root();
56    root.add_handler(StreamHandler::new(formatter, std::io::stdout()))
57        .expect("root handler lock should not be poisoned at startup");
58    root.set_level(Level::Debug); // emit everything Debug and above
59
60    // 5. Grab a named logger and emit one message per level.
61    let logger = Logger::get("quickstart");
62    logger.debug("a debug message (gray)");
63    logger.info("an info message (blue)");
64    logger.warning("a warning message (yellow)");
65    logger.error("an error message (red)");
66    logger.critical("a critical message (deep red)");
67
68    // 6. Levels below a logger's threshold are dropped cheaply (before
69    //    formatting). Raise the bar and show that Debug/Info now vanish.
70    logger.set_level(Level::Warning);
71    logger.debug("you will NOT see this (below threshold)");
72    logger.info("you will NOT see this either");
73    logger.warning("but warnings still get through");
74}
Source

pub fn level(&self) -> Level

Returns the logger’s current minimum severity.

Source

pub fn add_handler( &self, handler: impl Handler + 'static, ) -> Result<(), Box<dyn Error>>

Appends a handler. Returns an error only if the internal lock was poisoned by a panic in another thread.

Examples found in repository?
examples/quickstart.rs (lines 22-25)
14fn main() {
15    // Get a named logger from the global registry. Calling `get` with the same
16    // name again anywhere in the program returns the same logger.
17    let logger = Logger::get("basic");
18
19    // Attach a handler that writes to stdout using a simple pattern.
20    // `%(level)` and `%(message)` are field placeholders.
21    logger
22        .add_handler(StreamHandler::with_pattern(
23            std::io::stdout(),
24            "%(level): %(message)",
25        ))
26        .expect("handler lock should not be poisoned at startup");
27
28    // Emit a few messages. The default level is `Info`, so `debug` is dropped.
29    logger.info("hello from a named logger");
30    logger.warning("something to keep an eye on");
31    logger.error("something went wrong");
32}
More examples
Hide additional examples
examples/colorized.rs (line 56)
36fn main() {
37    // 1. Build a formatter from a pattern.
38    //
39    //    `%(name)` is a field placeholder. A trailing spec like `-20` controls
40    //    width/alignment: a leading `-` left-aligns, the number is the minimum
41    //    width, and an optional `.N` truncates to N characters. So:
42    //      %(level)-8   -> left-aligned, padded to 8 ("INFO    ")
43    //      %(name).12   -> truncated to at most 12 chars
44    let mut formatter = Formatter::new("%(timestamp) [%(level)-8] %(name)-12 | %(message)");
45
46    // 2. Customize the timestamp rendering (chrono's strftime syntax).
47    formatter.set_time_format("%Y-%m-%d %H:%M:%S");
48
49    // 3. Post-process every rendered line (here: add color).
50    formatter.set_transformer(colorize);
51
52    // 4. Configure the ROOT logger once. Every logger created afterwards
53    //    inherits a snapshot of root's handlers and level, so you typically
54    //    set things up here and then just `Logger::get(...)` everywhere else.
55    let root = Logger::root();
56    root.add_handler(StreamHandler::new(formatter, std::io::stdout()))
57        .expect("root handler lock should not be poisoned at startup");
58    root.set_level(Level::Debug); // emit everything Debug and above
59
60    // 5. Grab a named logger and emit one message per level.
61    let logger = Logger::get("quickstart");
62    logger.debug("a debug message (gray)");
63    logger.info("an info message (blue)");
64    logger.warning("a warning message (yellow)");
65    logger.error("an error message (red)");
66    logger.critical("a critical message (deep red)");
67
68    // 6. Levels below a logger's threshold are dropped cheaply (before
69    //    formatting). Raise the bar and show that Debug/Info now vanish.
70    logger.set_level(Level::Warning);
71    logger.debug("you will NOT see this (below threshold)");
72    logger.info("you will NOT see this either");
73    logger.warning("but warnings still get through");
74}
Source

pub fn log(&self, level: Level, message: &str)

Emits message at level to every handler, unless level is below the logger’s threshold. Builds one Record (message, level, timestamp, logger name, thread name) and hands it to each handler.

Source

pub fn debug(&self, message: &str)

Logs message at Level::Debug.

Examples found in repository?
examples/colorized.rs (line 62)
36fn main() {
37    // 1. Build a formatter from a pattern.
38    //
39    //    `%(name)` is a field placeholder. A trailing spec like `-20` controls
40    //    width/alignment: a leading `-` left-aligns, the number is the minimum
41    //    width, and an optional `.N` truncates to N characters. So:
42    //      %(level)-8   -> left-aligned, padded to 8 ("INFO    ")
43    //      %(name).12   -> truncated to at most 12 chars
44    let mut formatter = Formatter::new("%(timestamp) [%(level)-8] %(name)-12 | %(message)");
45
46    // 2. Customize the timestamp rendering (chrono's strftime syntax).
47    formatter.set_time_format("%Y-%m-%d %H:%M:%S");
48
49    // 3. Post-process every rendered line (here: add color).
50    formatter.set_transformer(colorize);
51
52    // 4. Configure the ROOT logger once. Every logger created afterwards
53    //    inherits a snapshot of root's handlers and level, so you typically
54    //    set things up here and then just `Logger::get(...)` everywhere else.
55    let root = Logger::root();
56    root.add_handler(StreamHandler::new(formatter, std::io::stdout()))
57        .expect("root handler lock should not be poisoned at startup");
58    root.set_level(Level::Debug); // emit everything Debug and above
59
60    // 5. Grab a named logger and emit one message per level.
61    let logger = Logger::get("quickstart");
62    logger.debug("a debug message (gray)");
63    logger.info("an info message (blue)");
64    logger.warning("a warning message (yellow)");
65    logger.error("an error message (red)");
66    logger.critical("a critical message (deep red)");
67
68    // 6. Levels below a logger's threshold are dropped cheaply (before
69    //    formatting). Raise the bar and show that Debug/Info now vanish.
70    logger.set_level(Level::Warning);
71    logger.debug("you will NOT see this (below threshold)");
72    logger.info("you will NOT see this either");
73    logger.warning("but warnings still get through");
74}
Source

pub fn info(&self, message: &str)

Logs message at Level::Info.

Examples found in repository?
examples/quickstart.rs (line 29)
14fn main() {
15    // Get a named logger from the global registry. Calling `get` with the same
16    // name again anywhere in the program returns the same logger.
17    let logger = Logger::get("basic");
18
19    // Attach a handler that writes to stdout using a simple pattern.
20    // `%(level)` and `%(message)` are field placeholders.
21    logger
22        .add_handler(StreamHandler::with_pattern(
23            std::io::stdout(),
24            "%(level): %(message)",
25        ))
26        .expect("handler lock should not be poisoned at startup");
27
28    // Emit a few messages. The default level is `Info`, so `debug` is dropped.
29    logger.info("hello from a named logger");
30    logger.warning("something to keep an eye on");
31    logger.error("something went wrong");
32}
More examples
Hide additional examples
examples/colorized.rs (line 63)
36fn main() {
37    // 1. Build a formatter from a pattern.
38    //
39    //    `%(name)` is a field placeholder. A trailing spec like `-20` controls
40    //    width/alignment: a leading `-` left-aligns, the number is the minimum
41    //    width, and an optional `.N` truncates to N characters. So:
42    //      %(level)-8   -> left-aligned, padded to 8 ("INFO    ")
43    //      %(name).12   -> truncated to at most 12 chars
44    let mut formatter = Formatter::new("%(timestamp) [%(level)-8] %(name)-12 | %(message)");
45
46    // 2. Customize the timestamp rendering (chrono's strftime syntax).
47    formatter.set_time_format("%Y-%m-%d %H:%M:%S");
48
49    // 3. Post-process every rendered line (here: add color).
50    formatter.set_transformer(colorize);
51
52    // 4. Configure the ROOT logger once. Every logger created afterwards
53    //    inherits a snapshot of root's handlers and level, so you typically
54    //    set things up here and then just `Logger::get(...)` everywhere else.
55    let root = Logger::root();
56    root.add_handler(StreamHandler::new(formatter, std::io::stdout()))
57        .expect("root handler lock should not be poisoned at startup");
58    root.set_level(Level::Debug); // emit everything Debug and above
59
60    // 5. Grab a named logger and emit one message per level.
61    let logger = Logger::get("quickstart");
62    logger.debug("a debug message (gray)");
63    logger.info("an info message (blue)");
64    logger.warning("a warning message (yellow)");
65    logger.error("an error message (red)");
66    logger.critical("a critical message (deep red)");
67
68    // 6. Levels below a logger's threshold are dropped cheaply (before
69    //    formatting). Raise the bar and show that Debug/Info now vanish.
70    logger.set_level(Level::Warning);
71    logger.debug("you will NOT see this (below threshold)");
72    logger.info("you will NOT see this either");
73    logger.warning("but warnings still get through");
74}
Source

pub fn warning(&self, message: &str)

Logs message at Level::Warning.

Examples found in repository?
examples/quickstart.rs (line 30)
14fn main() {
15    // Get a named logger from the global registry. Calling `get` with the same
16    // name again anywhere in the program returns the same logger.
17    let logger = Logger::get("basic");
18
19    // Attach a handler that writes to stdout using a simple pattern.
20    // `%(level)` and `%(message)` are field placeholders.
21    logger
22        .add_handler(StreamHandler::with_pattern(
23            std::io::stdout(),
24            "%(level): %(message)",
25        ))
26        .expect("handler lock should not be poisoned at startup");
27
28    // Emit a few messages. The default level is `Info`, so `debug` is dropped.
29    logger.info("hello from a named logger");
30    logger.warning("something to keep an eye on");
31    logger.error("something went wrong");
32}
More examples
Hide additional examples
examples/colorized.rs (line 64)
36fn main() {
37    // 1. Build a formatter from a pattern.
38    //
39    //    `%(name)` is a field placeholder. A trailing spec like `-20` controls
40    //    width/alignment: a leading `-` left-aligns, the number is the minimum
41    //    width, and an optional `.N` truncates to N characters. So:
42    //      %(level)-8   -> left-aligned, padded to 8 ("INFO    ")
43    //      %(name).12   -> truncated to at most 12 chars
44    let mut formatter = Formatter::new("%(timestamp) [%(level)-8] %(name)-12 | %(message)");
45
46    // 2. Customize the timestamp rendering (chrono's strftime syntax).
47    formatter.set_time_format("%Y-%m-%d %H:%M:%S");
48
49    // 3. Post-process every rendered line (here: add color).
50    formatter.set_transformer(colorize);
51
52    // 4. Configure the ROOT logger once. Every logger created afterwards
53    //    inherits a snapshot of root's handlers and level, so you typically
54    //    set things up here and then just `Logger::get(...)` everywhere else.
55    let root = Logger::root();
56    root.add_handler(StreamHandler::new(formatter, std::io::stdout()))
57        .expect("root handler lock should not be poisoned at startup");
58    root.set_level(Level::Debug); // emit everything Debug and above
59
60    // 5. Grab a named logger and emit one message per level.
61    let logger = Logger::get("quickstart");
62    logger.debug("a debug message (gray)");
63    logger.info("an info message (blue)");
64    logger.warning("a warning message (yellow)");
65    logger.error("an error message (red)");
66    logger.critical("a critical message (deep red)");
67
68    // 6. Levels below a logger's threshold are dropped cheaply (before
69    //    formatting). Raise the bar and show that Debug/Info now vanish.
70    logger.set_level(Level::Warning);
71    logger.debug("you will NOT see this (below threshold)");
72    logger.info("you will NOT see this either");
73    logger.warning("but warnings still get through");
74}
Source

pub fn error(&self, message: &str)

Logs message at Level::Error.

Examples found in repository?
examples/quickstart.rs (line 31)
14fn main() {
15    // Get a named logger from the global registry. Calling `get` with the same
16    // name again anywhere in the program returns the same logger.
17    let logger = Logger::get("basic");
18
19    // Attach a handler that writes to stdout using a simple pattern.
20    // `%(level)` and `%(message)` are field placeholders.
21    logger
22        .add_handler(StreamHandler::with_pattern(
23            std::io::stdout(),
24            "%(level): %(message)",
25        ))
26        .expect("handler lock should not be poisoned at startup");
27
28    // Emit a few messages. The default level is `Info`, so `debug` is dropped.
29    logger.info("hello from a named logger");
30    logger.warning("something to keep an eye on");
31    logger.error("something went wrong");
32}
More examples
Hide additional examples
examples/colorized.rs (line 65)
36fn main() {
37    // 1. Build a formatter from a pattern.
38    //
39    //    `%(name)` is a field placeholder. A trailing spec like `-20` controls
40    //    width/alignment: a leading `-` left-aligns, the number is the minimum
41    //    width, and an optional `.N` truncates to N characters. So:
42    //      %(level)-8   -> left-aligned, padded to 8 ("INFO    ")
43    //      %(name).12   -> truncated to at most 12 chars
44    let mut formatter = Formatter::new("%(timestamp) [%(level)-8] %(name)-12 | %(message)");
45
46    // 2. Customize the timestamp rendering (chrono's strftime syntax).
47    formatter.set_time_format("%Y-%m-%d %H:%M:%S");
48
49    // 3. Post-process every rendered line (here: add color).
50    formatter.set_transformer(colorize);
51
52    // 4. Configure the ROOT logger once. Every logger created afterwards
53    //    inherits a snapshot of root's handlers and level, so you typically
54    //    set things up here and then just `Logger::get(...)` everywhere else.
55    let root = Logger::root();
56    root.add_handler(StreamHandler::new(formatter, std::io::stdout()))
57        .expect("root handler lock should not be poisoned at startup");
58    root.set_level(Level::Debug); // emit everything Debug and above
59
60    // 5. Grab a named logger and emit one message per level.
61    let logger = Logger::get("quickstart");
62    logger.debug("a debug message (gray)");
63    logger.info("an info message (blue)");
64    logger.warning("a warning message (yellow)");
65    logger.error("an error message (red)");
66    logger.critical("a critical message (deep red)");
67
68    // 6. Levels below a logger's threshold are dropped cheaply (before
69    //    formatting). Raise the bar and show that Debug/Info now vanish.
70    logger.set_level(Level::Warning);
71    logger.debug("you will NOT see this (below threshold)");
72    logger.info("you will NOT see this either");
73    logger.warning("but warnings still get through");
74}
Source

pub fn critical(&self, message: &str)

Logs message at Level::Critical.

Examples found in repository?
examples/colorized.rs (line 66)
36fn main() {
37    // 1. Build a formatter from a pattern.
38    //
39    //    `%(name)` is a field placeholder. A trailing spec like `-20` controls
40    //    width/alignment: a leading `-` left-aligns, the number is the minimum
41    //    width, and an optional `.N` truncates to N characters. So:
42    //      %(level)-8   -> left-aligned, padded to 8 ("INFO    ")
43    //      %(name).12   -> truncated to at most 12 chars
44    let mut formatter = Formatter::new("%(timestamp) [%(level)-8] %(name)-12 | %(message)");
45
46    // 2. Customize the timestamp rendering (chrono's strftime syntax).
47    formatter.set_time_format("%Y-%m-%d %H:%M:%S");
48
49    // 3. Post-process every rendered line (here: add color).
50    formatter.set_transformer(colorize);
51
52    // 4. Configure the ROOT logger once. Every logger created afterwards
53    //    inherits a snapshot of root's handlers and level, so you typically
54    //    set things up here and then just `Logger::get(...)` everywhere else.
55    let root = Logger::root();
56    root.add_handler(StreamHandler::new(formatter, std::io::stdout()))
57        .expect("root handler lock should not be poisoned at startup");
58    root.set_level(Level::Debug); // emit everything Debug and above
59
60    // 5. Grab a named logger and emit one message per level.
61    let logger = Logger::get("quickstart");
62    logger.debug("a debug message (gray)");
63    logger.info("an info message (blue)");
64    logger.warning("a warning message (yellow)");
65    logger.error("an error message (red)");
66    logger.critical("a critical message (deep red)");
67
68    // 6. Levels below a logger's threshold are dropped cheaply (before
69    //    formatting). Raise the bar and show that Debug/Info now vanish.
70    logger.set_level(Level::Warning);
71    logger.debug("you will NOT see this (below threshold)");
72    logger.info("you will NOT see this either");
73    logger.warning("but warnings still get through");
74}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.