forked from paradigmxyz/reth
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathformatter.rs
92 lines (84 loc) · 3.36 KB
/
formatter.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use crate::layers::BoxedLayer;
use clap::ValueEnum;
use std::{fmt, fmt::Display};
use tracing_appender::non_blocking::NonBlocking;
use tracing_subscriber::{EnvFilter, Layer, Registry};
/// Represents the logging format.
///
/// This enum defines the supported formats for logging output.
/// It is used to configure the format layer of a tracing subscriber.
#[derive(Debug, Copy, Clone, ValueEnum, Eq, PartialEq)]
pub enum LogFormat {
/// Represents JSON formatting for logs.
/// This format outputs log records as JSON objects,
/// making it suitable for structured logging.
Json,
/// Represents logfmt (key=value) formatting for logs.
/// This format is concise and human-readable,
/// typically used in command-line applications.
LogFmt,
/// Represents terminal-friendly formatting for logs.
Terminal,
}
impl LogFormat {
/// Applies the specified logging format to create a new layer.
///
/// This method constructs a tracing layer with the selected format,
/// along with additional configurations for filtering and output.
///
/// # Arguments
/// * `filter` - An `EnvFilter` used to determine which log records to output.
/// * `color` - An optional string that enables or disables ANSI color codes in the logs.
/// * `file_writer` - An optional `NonBlocking` writer for directing logs to a file.
///
/// # Returns
/// A `BoxedLayer<Registry>` that can be added to a tracing subscriber.
pub fn apply(
&self,
filter: EnvFilter,
color: Option<String>,
file_writer: Option<NonBlocking>,
) -> BoxedLayer<Registry> {
let ansi = if let Some(color) = color {
std::env::var("RUST_LOG_STYLE").map(|val| val != "never").unwrap_or(color != "never")
} else {
false
};
let target = std::env::var("RUST_LOG_TARGET")
// `RUST_LOG_TARGET` always overrides default behaviour
.map(|val| val != "0")
.unwrap_or_else(|_|
// If `RUST_LOG_TARGET` is not set, show target in logs only if the max enabled
// level is higher than INFO (DEBUG, TRACE)
filter.max_level_hint().is_none_or(|max_level| max_level > tracing::Level::INFO));
match self {
Self::Json => {
let layer =
tracing_subscriber::fmt::layer().json().with_ansi(ansi).with_target(target);
if let Some(writer) = file_writer {
layer.with_writer(writer).with_filter(filter).boxed()
} else {
layer.with_filter(filter).boxed()
}
}
Self::LogFmt => tracing_logfmt::layer().with_filter(filter).boxed(),
Self::Terminal => {
let layer = tracing_subscriber::fmt::layer().with_ansi(ansi).with_target(target);
if let Some(writer) = file_writer {
layer.with_writer(writer).with_filter(filter).boxed()
} else {
layer.with_filter(filter).boxed()
}
}
}
}
}
impl Display for LogFormat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Json => write!(f, "json"),
Self::LogFmt => write!(f, "logfmt"),
Self::Terminal => write!(f, "terminal"),
}
}
}