Logging with slog
Expunge provides a painless and (relatively) foolproof way to log structs that may contain sensitive fields.
As long as your type implements serde::Serialize
, the slog
attribute will derive slog::SerdeValue
.
Internally the value will be expunged before logging.
Example
use expunge::Expunge;
use serde::{Serialize, Deserialize};
use slog::{info, o};
use slog::{Drain, Logger};
use std::sync::Mutex;
#[derive(Clone, Expunge, Deserialize, Serialize, PartialEq, Eq)] // must implement Serialize
#[expunge(slog)]
#[serde(rename_all = "snake_case")]
enum LocationType {
#[expunge(as = "<expunged>".to_string())]
City(String),
Address {
#[expunge(as = "line1".to_string())]
line1: String,
#[expunge(as = "line2".to_string())]
line2: String,
},
}
fn main() {
let buf = vec![];
let drain = Mutex::new(slog_json::Json::default(buf)).fuse();
let logger = Logger::root(drain, o!());
// Just log as is and it will be automatically expunged
let city = LocationType::City("New York".to_string());
info!(logger, "it should log city"; "location" => city);
let address = LocationType::Address{
line1: "101 Some street".to_string(),
line2: "Some Town".to_string(),
};
info!(logger, "it should log address"; "location" => address);
// {"msg":"it should log city","location":{"city":"<expunged>"},"level":"INFO","ts":"2024-02-04T12:55:28.627592Z"}
// {"msg":"it should log address","location":{"address":{"line1":"line1","line2":"line2"}},"level":"INFO","ts":"2024-02-04T12:55:28.627627Z"}
}