Skip to main content

Formatter

Struct Formatter 

Source
pub struct Formatter {
    pub time_format: &'static str,
    /* private fields */
}
Expand description

Renders a Record into a string according to a pattern.

The pattern is parsed once (at construction) into a list of [Segment]s, so format does no parsing per call. Patterns mix literal text with field placeholders of the form %(name) optionally followed by a format spec (alignment/width), e.g. "[%(level)-8] %(message)".

Fields§

§time_format: &'static str

The chrono strftime format used to render the timestamp field (e.g. "%Y-%m-%d %H:%M:%S").

Implementations§

Source§

impl Formatter

Source

pub fn new(pattern: &str) -> Self

Creates a formatter from a pattern string, parsing it into segments now so that format is allocation-light per call.

Examples found in repository?
examples/colorized.rs (line 44)
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 add_field(&mut self, name: &str, resolve: fn(&str) -> &str) -> &mut Self

Registers a transform for a field name. When a %(name) placeholder is rendered, the raw record value is passed through resolve before alignment/width is applied. Returns &mut Self for chaining.

Source

pub fn format(&self, record: &Record<'_>) -> String

Renders record into a string, substituting each %(name) placeholder with the record’s value (or "" if absent), applying any registered field transform and the placeholder’s spec. A trailing newline is appended. If a transformer is set, it post-processes the whole line.

Source

pub fn set_transformer( &mut self, transformer: impl Fn(&Record<'_>, &String) -> String + Send + Sync + 'static, )

Installs a post-processing hook that receives the record and the fully rendered line and returns the final string (e.g. to add ANSI colors).

Examples found in repository?
examples/colorized.rs (line 50)
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 set_time_format(&mut self, time_format: &'static str)

Sets the chrono strftime format used to render the timestamp field.

Examples found in repository?
examples/colorized.rs (line 47)
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.