slog

Macro log

Source
macro_rules! log {
    (2 @ { $($fmt:tt)* }, { $($kv:tt)* },  $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr) => { ... };
    (2 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr,) => { ... };
    (2 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr;) => { ... };
    (2 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr, $($args:tt)*) => { ... };
    (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr, $k:ident = $v:expr) => { ... };
    (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr, $k:ident = $v:expr;) => { ... };
    (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr, $k:ident = $v:expr,) => { ... };
    (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr, $k:ident = $v:expr; $($args:tt)*) => { ... };
    (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr, $k:ident = $v:expr, $($args:tt)*) => { ... };
    (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr,) => { ... };
    (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr) => { ... };
    (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr, ; $($args:tt)*) => { ... };
    (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr; $($args:tt)*) => { ... };
    (1 @ { $($fmt:tt)* }, { $($kv:tt)* }, $l:expr, $lvl:expr, $tag:expr, $msg_fmt:expr, $f:tt $($args:tt)*) => { ... };
    ($l:expr, $lvl:expr, $tag:expr, $($args:tt)*) => { ... };
}
Expand description

Log message a logging record

Use wrappers error!, warn! etc. instead

The max_level_* and release_max_level* cargo features can be used to statically disable logging at various levels. See slog notable details

Use version with longer name if you want to prevent clash with legacy log crate macro names.

§Supported invocations

§Simple

#[macro_use]
extern crate slog;

fn main() {
    let drain = slog::Discard;
    let root = slog::Logger::root(
        drain,
        o!("key1" => "value1", "key2" => "value2")
    );
    info!(root, "test info log"; "log-key" => true);
}

Note that "key" => value part is optional:

#[macro_use]
extern crate slog;

fn main() {
    let drain = slog::Discard;
    let root = slog::Logger::root(
        drain, o!("key1" => "value1", "key2" => "value2")
    );
    info!(root, "test info log");
}

§Formatting support:

#[macro_use]
extern crate slog;

fn main() {
    let drain = slog::Discard;
    let root = slog::Logger::root(drain,
        o!("key1" => "value1", "key2" => "value2")
    );
    info!(root, "formatted {num_entries} entries of {}", "something", num_entries = 2; "log-key" => true);
}

Note:

  • ; is used to separate message arguments and key value pairs.
  • message behaves like format!/format_args!
  • Named arguments to messages will be added to key-value pairs as well!

"key" => value part is optional:

#[macro_use]
extern crate slog;

fn main() {
    let drain = slog::Discard;
    let root = slog::Logger::root(
        drain, o!("key1" => "value1", "key2" => "value2")
    );
    info!(root, "formatted: {}", 1);
}

Use formatting support wisely. Prefer named arguments, so the associated data is not “lost” by becoming an untyped string in the message.

§Tags

All above versions can be supplemented with a tag - string literal prefixed with #.

#[macro_use]
extern crate slog;

fn main() {
    let drain = slog::Discard;
    let root = slog::Logger::root(drain,
        o!("key1" => "value1", "key2" => "value2")
    );
    let ops = 3;
    info!(
        root,
        #"performance-metric", "thread speed"; "ops_per_sec" => ops
    );
}

See Record::tag() for more information about tags.

§Own implementations of KV and Value

List of key value pairs is a comma separated list of key-values. Typically, a designed syntax is used in form of k => v where k can be any type that implements Value type.

It’s possible to directly specify type that implements KV trait without => syntax.

#[macro_use]
extern crate slog;

use slog::*;

fn main() {
    struct MyKV;
    struct MyV;

    impl KV for MyKV {
       fn serialize(&self,
                    _record: &Record,
                    serializer: &mut Serializer)
                   -> Result {
           serializer.emit_u32("MyK", 16)
       }
    }

    impl Value for MyV {
       fn serialize(&self,
                    _record: &Record,
                    key : Key,
                    serializer: &mut Serializer)
                   -> Result {
           serializer.emit_u32("MyKV", 16)
       }
    }

    let drain = slog::Discard;

    let root = slog::Logger::root(drain, o!(MyKV));

    info!(
        root,
        "testing MyV"; "MyV" => MyV
    );
}

§fmt::Display and fmt::Debug values

Value of any type that implements std::fmt::Display can be prefixed with % in k => v expression to use its text representation returned by format_args!("{}", v). This is especially useful for errors. Not that this does not allocate any String since it operates on fmt::Arguments. You can also use the #% prefix to use the “alternate” form of formatting, represented by the {:#} formatting specifier.

Similarly to use std::fmt::Debug value can be prefixed with ?, or pretty-printed with #?.

#[macro_use]
extern crate slog;
use std::fmt::Write;

fn main() {
    let drain = slog::Discard;
    let log  = slog::Logger::root(drain, o!());

    let mut output = String::new();

    if let Err(e) = write!(&mut output, "write to string") {
        error!(log, "write failed"; "err" => %e);
    }
}