Skip to main content

hickory_util/
lib.rs

1// Copyright 2015-2022 Benjamin Fry <benjaminfry@me.com>
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// https://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// https://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use std::env;
9
10use clap::Parser;
11use tracing::Level;
12use tracing::metadata::LevelFilter;
13use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt};
14
15fn get_levels(bin: &str, cli_level: Option<Level>) -> String {
16    let env_level = env::var("RUST_LOG").ok();
17
18    let Some(cli_level) = cli_level else {
19        return env_level.unwrap_or_default();
20    };
21
22    let level_str = format!(
23        "{bin}={level},hickory={level}",
24        level = cli_level.to_string().to_lowercase(),
25    );
26
27    match env_level {
28        Some(env_level) => format!("{level_str},{env_level}"),
29        None => level_str,
30    }
31}
32
33/// Setup the logging for the given Level of output and all hickory-dns crates
34///
35/// # Panic
36///
37/// This will panic if the tracing subscriber can't be registered
38pub fn logger(bin: &str, cli_level: Option<Level>) {
39    // Setup tracing for logging based on input
40    let subscriber = EnvFilter::builder()
41        .with_default_directive(LevelFilter::OFF.into())
42        .parse(get_levels(bin, cli_level))
43        .expect("failed to configure tracing/logging");
44
45    tracing_subscriber::registry()
46        .with(tracing_subscriber::fmt::layer().compact())
47        .with(subscriber)
48        .init();
49}
50
51/// Common CLI configuration for tracing log levels
52#[derive(Debug, Parser)]
53pub struct LogConfig {
54    /// Enable trace + debug + info + warning + error logging
55    #[clap(long)]
56    trace: bool,
57
58    /// Enable debug + info + warning + error logging
59    #[clap(long)]
60    debug: bool,
61
62    /// Enable info + warning + error logging
63    #[clap(long)]
64    info: bool,
65
66    /// Enable warning + error logging
67    #[clap(long)]
68    warn: bool,
69
70    /// Enable error logging
71    #[clap(long)]
72    error: bool,
73}
74
75impl LogConfig {
76    pub fn level(&self) -> Option<Level> {
77        Some(if self.trace {
78            Level::TRACE
79        } else if self.debug {
80            Level::DEBUG
81        } else if self.info {
82            Level::INFO
83        } else if self.warn {
84            Level::WARN
85        } else if self.error {
86            Level::ERROR
87        } else {
88            return None;
89        })
90    }
91}