Crate slog_derive [] [src]

Custom derives for working with the slog crate.

The KV Derive

Say you've got a struct like this,

pub struct Config {
  width: f64,
  height: f64,
  output_file: PathBuf,
}

Sometimes you'll want to log the struct's contents in your application, for example when you've just started and want to record the configuration details for debugging purposes. Usually you'd need to do something like this:

debug!(logger, "Loaded Config";
    "width" => cfg.width,
    "height" => cfg.height,
    "output-file" => cfg.output_file.display());

This is where the KV trait comes in. Implementing it lets you translate the previous log statement into something like this:

debug!(logger, "Loaded Config"; cfg);

This crate provides a custom derive which will implement KV for you. It'll just iterate over each field in your struct and invoke Value::serialize() on each.

#[derive(KV)]
pub struct Config {
  width: f64,
  height: f64,
  output_file: String,
}

You can also skip fields using the #[skip] attribute, this is useful when you don't want to log complex data structures or the particular field doesn't implement Value.

#[derive(KV)]
pub struct Config {
  width: f64,
  height: f64,
  #[slog(skip)]
  output_file: PathBuf,
}

The SerdeValue Derive

Implementing the SerdeValue is usually trivial and tedious so it also has a custom derive.

extern crate slog;
#[macro_use]
extern crate slog_derive;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate erased_serde;

use std::path::PathBuf;

#[derive(Clone, SerdeValue, Serialize, Deserialize)]
pub struct Config {
  width: f64,
  height: f64,
  output_file: PathBuf,
}

This will require enabling slog's nested-values feature flag, as well as implementing (or deriving) serde::Serialize for your type. You will also need to pull in the erased_serde crate because it's part of the SerdeValue signature.

For convenience this will also generate a Value impl for your type (to implement SerdeValue you must also implement Value). This impl simply calls Serializer::emit_serde(), but if you want to write your own Value implementation you can add the #[slog(no_value_impl)] attribute.

extern crate slog;
#[macro_use]
extern crate slog_derive;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate erased_serde;

use std::path::PathBuf;
use slog::{Key, Record, Serializer, Value};

#[derive(Clone, SerdeValue, Serialize)]
#[slog(no_value_impl)]
pub struct Config {
  width: f64,
  height: f64,
  output_file: PathBuf,
}

impl Value for Config {
    fn serialize(&self, _record: &Record, key: Key, ser: &mut Serializer) -> slog::Result {
        unimplemented!()
    }
}

Functions

derive_kv
derive_serde_value