Skip to content

Instantly share code, notes, and snippets.

@swsnr
Created May 29, 2021 11:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save swsnr/a2f63c6daa11fabec764caeb8a65dd00 to your computer and use it in GitHub Desktop.
Save swsnr/a2f63c6daa11fabec764caeb8a65dd00 to your computer and use it in GitHub Desktop.
Filter loggers with env_logger
// Copyright Sebastian Wiesner <sebastian@swsnr.de>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//! Logging.
use env_logger::filter::Filter;
use log::{Log, Metadata, Record};
/// A logger which is filtered.
pub struct FilteredLog<T: Log> {
log: T,
filter: Filter,
}
impl<T: Log> FilteredLog<T> {
/// Create a new filtered logger.
pub fn new(filter: Filter, log: T) -> Self {
Self { log, filter }
}
}
impl<T: Log> Log for FilteredLog<T> {
/// Whether this logger is enabled for the given `metadata`.
///
/// Returns true if the filter allows the given metadata and
/// if the underlying logger is enabled for the given metadata.
fn enabled(&self, metadata: &Metadata) -> bool {
self.filter.enabled(metadata) && self.log.enabled(metadata)
}
/// Log the given `record`.
///
/// Check if the filter matches the given `record`; if so log
/// the record with the underlying logger, otherwise do nothing.
fn log(&self, record: &Record) {
if self.filter.matches(record) {
self.log.log(record)
}
}
/// Flush the underlying logger.
fn flush(&self) {
self.log.flush()
}
}
/// Where to log to.
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum LogDestination {
/// Standard output.
Stdout,
/// The systemd journal.
Journal,
}
/// Setup logging for the given `destination`.
///
/// The default level is "info".
///
/// The level and module filters can be configured with `$RUST_LOG`, and the styling of messages for
/// standard output is read from `$RUST_LOG_STYLE`.
///
/// See [env_logger](https://docs.rs/env_logger/) for more information.
/// The maximum level is set to "info", unless the `$LOG_DEBUG` environment variable is set in which case it's "debug".
pub fn setup_logging(destination: LogDestination) {
let default_filter = "info";
match destination {
LogDestination::Journal => {
let filter = env_logger::filter::Builder::new()
.parse(
std::env::var(env_logger::DEFAULT_FILTER_ENV)
.as_ref()
.map_or(default_filter, |f| &f),
)
.build();
log::set_max_level(filter.filter());
log::set_boxed_logger(Box::new(FilteredLog::new(
filter,
systemd_journal_logger::JournalLog,
)))
.expect("Failed to initialize journal logging");
}
LogDestination::Stdout => {
env_logger::Builder::from_env(
env_logger::Env::default().default_filter_or(default_filter),
)
.init();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment