foxy/logging/
config.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! Configuration for logging.
6
7use serde::{Deserialize, Serialize};
8use std::collections::HashMap;
9use crate::logging::structured::{LoggerConfig, LogFormat};
10
11/// Logging configuration
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct LoggingConfig {
14    /// Whether to use structured logging
15    #[serde(default = "default_false")]
16    pub structured: bool,
17    
18    /// Log format (terminal or json)
19    #[serde(default = "default_format")]
20    pub format: String,
21    
22    /// Log level
23    #[serde(default = "default_level")]
24    pub level: String,
25    
26    /// Include source code location
27    #[serde(default = "default_true")]
28    pub include_location: bool,
29    
30    /// Include thread ID
31    #[serde(default = "default_true")]
32    pub include_thread_id: bool,
33    
34    /// Include trace ID in logs
35    #[serde(default = "default_true")]
36    pub include_trace_id: bool,
37    
38    /// Propagate trace ID from request headers
39    #[serde(default = "default_true")]
40    pub propagate_trace_id: bool,
41    
42    /// Header name for trace ID
43    #[serde(default = "default_trace_header")]
44    pub trace_id_header: String,
45    
46    /// Static fields to include in all logs
47    #[serde(default)]
48    pub static_fields: HashMap<String, String>,
49}
50
51fn default_false() -> bool {
52    false
53}
54
55fn default_true() -> bool {
56    true
57}
58
59fn default_format() -> String {
60    "terminal".to_string()
61}
62
63fn default_level() -> String {
64    "info".to_string()
65}
66
67fn default_trace_header() -> String {
68    "X-Trace-ID".to_string()
69}
70
71impl Default for LoggingConfig {
72    fn default() -> Self {
73        Self {
74            structured: false,
75            format: default_format(),
76            level: default_level(),
77            include_location: true,
78            include_thread_id: true,
79            include_trace_id: true,
80            propagate_trace_id: true,
81            trace_id_header: default_trace_header(),
82            static_fields: HashMap::new(),
83        }
84    }
85}
86
87impl LoggingConfig {
88    /// Convert to logger config
89    pub fn to_logger_config(&self) -> LoggerConfig {
90        LoggerConfig {
91            format: match self.format.to_lowercase().as_str() {
92                "json" => LogFormat::Json,
93                _ => LogFormat::Terminal,
94            },
95            level: match self.level.to_lowercase().as_str() {
96                "trace" => slog::Level::Trace,
97                "debug" => slog::Level::Debug,
98                "info" => slog::Level::Info,
99                "warn" => slog::Level::Warning,
100                "error" => slog::Level::Error,
101                "critical" => slog::Level::Critical,
102                _ => slog::Level::Info,
103            },
104            include_location: self.include_location,
105            include_thread_id: self.include_thread_id,
106            static_fields: self.static_fields.clone(),
107        }
108    }
109}