1use std::{fmt::Display, path::PathBuf};
2
3use serde::{Deserialize, Deserializer, Serialize};
4use tracing_subscriber::{fmt::writer::BoxMakeWriter, EnvFilter};
5
6use crate::LogFormat;
7
8#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq)]
10#[serde(rename_all = "kebab-case")]
11pub struct Log {
12 #[serde(default)]
15 pub level: LogLevel,
16 #[serde(default)]
17 pub outputs: Vec<LogOutput>,
18 #[serde(default)]
19 pub format: LogFormat,
20}
21
22#[derive(Serialize, Deserialize, Debug, Default, Clone, Copy, PartialEq, Eq)]
24#[serde(rename_all = "lowercase")]
25pub enum LogLevel {
26 Trace,
27 Debug,
28 #[default]
29 Info,
30 Warn,
31 Error,
32 Fatal,
33}
34
35impl Display for LogLevel {
36 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 let level = match self {
38 LogLevel::Trace => "trace",
39 LogLevel::Debug => "debug",
40 LogLevel::Info => "info",
41 LogLevel::Warn => "warn",
42 LogLevel::Error => "error",
43 LogLevel::Fatal => "fatal",
44 };
45
46 write!(f, "{level}")
47 }
48}
49
50impl From<LogLevel> for EnvFilter {
51 fn from(value: LogLevel) -> Self {
52 EnvFilter::new(format!(
53 "warn,prover={value},aggkit={value},agglayer={value},pessimistic_proof={value}"
54 ))
55 }
56}
57
58#[derive(Serialize, Debug, Clone, Default, PartialEq, Eq)]
67pub enum LogOutput {
68 #[default]
69 Stdout,
70 Stderr,
71 File(PathBuf),
72}
73
74impl<'de> Deserialize<'de> for LogOutput {
75 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
76 where
77 D: Deserializer<'de>,
78 {
79 let s = String::deserialize(deserializer)?;
80 match s.as_str() {
83 "stdout" => Ok(LogOutput::Stdout),
84 "stderr" => Ok(LogOutput::Stderr),
85 _ => Ok(LogOutput::File(PathBuf::from(s))),
86 }
87 }
88}
89
90impl LogOutput {
91 pub fn as_make_writer(&self) -> BoxMakeWriter {
95 match self {
96 LogOutput::Stdout => BoxMakeWriter::new(std::io::stdout),
97 LogOutput::Stderr => BoxMakeWriter::new(std::io::stderr),
98 LogOutput::File(path) => {
99 let appender = tracing_appender::rolling::never(".", path);
100 BoxMakeWriter::new(appender)
101 }
102 }
103 }
104}