soph_tracing/config/
mod.rs

1use serde::{Deserialize, Serialize};
2use serde_variant::to_variant_name;
3use soph_config::support::default;
4
5#[derive(Debug, Deserialize, Serialize)]
6pub struct Tracing {
7    #[serde(default)]
8    pub channel: Channel,
9
10    #[serde(default)]
11    pub env_filter: Option<String>,
12
13    #[serde(default)]
14    pub level: Level,
15
16    #[serde(default)]
17    pub format: Format,
18
19    #[serde(default = "default_with_ansi")]
20    pub with_ansi: bool,
21
22    #[serde(default)]
23    pub with_target: bool,
24
25    #[serde(default)]
26    pub with_file: bool,
27
28    #[serde(default)]
29    pub with_line_number: bool,
30
31    #[serde(default = "default_with_level")]
32    pub with_level: bool,
33
34    #[serde(default)]
35    pub with_thread_ids: bool,
36
37    #[serde(default)]
38    pub with_thread_names: bool,
39
40    #[cfg(feature = "file-appender")]
41    #[serde(default)]
42    pub rotation: Rotation,
43
44    #[cfg(feature = "file-appender")]
45    #[serde(default = "default_filename_prefix")]
46    pub filename_prefix: String,
47
48    #[cfg(feature = "file-appender")]
49    #[serde(default = "default_filename_suffix")]
50    pub filename_suffix: String,
51
52    #[cfg(feature = "file-appender")]
53    #[serde(default = "default_max_log_files")]
54    pub max_log_files: usize,
55
56    #[cfg(feature = "file-appender")]
57    #[serde(default = "default_directory")]
58    pub directory: String,
59}
60
61#[derive(Debug, Default, Deserialize, Serialize)]
62pub enum Channel {
63    #[serde(rename = "stdout")]
64    #[default]
65    Stdout,
66    #[cfg(feature = "file-appender")]
67    #[serde(rename = "file")]
68    File,
69}
70
71impl std::fmt::Display for Channel {
72    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73        to_variant_name(self).expect("only enum supported").fmt(f)
74    }
75}
76
77impl Default for Tracing {
78    fn default() -> Self {
79        default::<Self>().expect("Failed to get default value")
80    }
81}
82
83fn default_with_ansi() -> bool {
84    true
85}
86
87fn default_with_level() -> bool {
88    true
89}
90
91#[cfg(feature = "file-appender")]
92fn default_filename_prefix() -> String {
93    "soph".to_string()
94}
95
96#[cfg(feature = "file-appender")]
97fn default_filename_suffix() -> String {
98    "log".to_string()
99}
100
101#[cfg(feature = "file-appender")]
102fn default_max_log_files() -> usize {
103    14
104}
105
106#[cfg(feature = "file-appender")]
107fn default_directory() -> String {
108    "storage/logs".to_string()
109}
110
111#[derive(Clone, Debug, Default, Deserialize, Serialize)]
112pub enum Rotation {
113    #[serde(rename = "minutely")]
114    Minutely,
115    #[serde(rename = "hourly")]
116    Hourly,
117    #[default]
118    #[serde(rename = "daily")]
119    Daily,
120    #[serde(rename = "never")]
121    Never,
122}
123
124#[cfg(feature = "file-appender")]
125impl From<Rotation> for tracing_appender::rolling::Rotation {
126    fn from(rotation: Rotation) -> Self {
127        match rotation {
128            Rotation::Minutely => tracing_appender::rolling::Rotation::MINUTELY,
129            Rotation::Hourly => tracing_appender::rolling::Rotation::HOURLY,
130            Rotation::Daily => tracing_appender::rolling::Rotation::DAILY,
131            Rotation::Never => tracing_appender::rolling::Rotation::NEVER,
132        }
133    }
134}
135
136#[derive(Clone, Debug, Default, Deserialize, Serialize)]
137pub enum Level {
138    #[serde(rename = "trace")]
139    Trace,
140    #[serde(rename = "debug")]
141    Debug,
142    #[serde(rename = "info")]
143    #[default]
144    Info,
145    #[serde(rename = "warn")]
146    Warn,
147    #[serde(rename = "error")]
148    Error,
149}
150
151impl From<Level> for tracing::Level {
152    fn from(level: Level) -> Self {
153        match level {
154            Level::Trace => tracing::Level::TRACE,
155            Level::Debug => tracing::Level::DEBUG,
156            Level::Info => tracing::Level::INFO,
157            Level::Warn => tracing::Level::WARN,
158            Level::Error => tracing::Level::ERROR,
159        }
160    }
161}
162
163impl std::fmt::Display for Level {
164    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
165        to_variant_name(self).expect("only enum supported").fmt(f)
166    }
167}
168
169#[derive(Clone, Debug, Default, Deserialize, Serialize)]
170pub enum Format {
171    #[serde(rename = "compact")]
172    #[default]
173    Compact,
174    #[serde(rename = "pretty")]
175    Pretty,
176    #[serde(rename = "json")]
177    Json,
178}
179
180impl std::fmt::Display for Format {
181    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
182        to_variant_name(self).expect("only enum supported").fmt(f)
183    }
184}