tracing_web_console/
layer.rs1use crate::api::logs::LogsState;
4use crate::storage::LogStorage;
5use crate::subscriber::LogCaptureLayer;
6use axum::routing::get;
7use axum::Router;
8use std::sync::Arc;
9use tower_http::cors::{Any, CorsLayer};
10use tracing_subscriber::layer::SubscriberExt;
11use tracing_subscriber::util::SubscriberInitExt;
12use tracing_subscriber::EnvFilter;
13
14#[derive(Clone)]
16pub struct TracingLayer {
17 router: Router,
18}
19
20impl TracingLayer {
21 pub fn new(base_path: &str) -> Self {
39 Self::with_capacity(base_path, 10_000)
40 }
41
42 pub fn with_capacity(base_path: &str, capacity: usize) -> Self {
49 let storage = LogStorage::with_capacity(capacity);
51
52 let env_filter = EnvFilter::try_from_default_env()
57 .unwrap_or_else(|_| EnvFilter::new("trace,tracing_web_console=off,log=off"));
58
59 let log_capture_layer = LogCaptureLayer::new(storage.clone());
61
62 tracing_subscriber::registry()
65 .with(env_filter)
66 .with(log_capture_layer)
67 .try_init()
68 .ok(); let logs_state = Arc::new(LogsState::new(storage.clone()));
72
73 let frontend_state = crate::frontend::FrontendState {
75 base_path: Arc::new(base_path.to_string()),
76 };
77
78 let frontend_router = Router::new()
80 .route("/", get(crate::frontend::serve_index))
81 .route("/assets/*path", get(crate::frontend::serve_static))
82 .with_state(frontend_state);
83
84 let api_router = crate::api::create_api_router(logs_state);
86
87 let inner_router = frontend_router.merge(api_router);
89
90 let cors = CorsLayer::new()
93 .allow_origin(Any)
94 .allow_methods(Any)
95 .allow_headers(Any);
96
97 let router = Router::new().nest(base_path, inner_router).layer(cors);
99
100 Self { router }
101 }
102
103 pub fn into_router(self) -> Router {
119 self.router
120 }
121}
122
123#[allow(dead_code)]
125pub struct TracingLayerBuilder {
126 base_path: String,
127 capacity: usize,
128 initial_filter: String,
129}
130
131impl TracingLayerBuilder {
132 #[allow(dead_code)]
134 pub fn new(base_path: &str) -> Self {
135 Self {
136 base_path: base_path.to_string(),
137 capacity: 10_000,
138 initial_filter: "trace".to_string(),
139 }
140 }
141
142 #[allow(dead_code)]
144 pub fn with_capacity(mut self, capacity: usize) -> Self {
145 self.capacity = capacity;
146 self
147 }
148
149 #[allow(dead_code)]
151 pub fn with_filter(mut self, filter: &str) -> Self {
152 self.initial_filter = filter.to_string();
153 self
154 }
155
156 #[allow(dead_code)]
158 pub fn build(self) -> TracingLayer {
159 TracingLayer::with_capacity(&self.base_path, self.capacity)
160 }
161}
162
163#[cfg(test)]
164mod tests {
165 use super::*;
166
167 #[test]
168 fn test_tracing_layer_creation() {
169 let _layer = TracingLayer::new("/tracing");
171 }
172
173 #[test]
174 fn test_builder_pattern() {
175 let builder = TracingLayerBuilder::new("/tracing")
176 .with_capacity(5000)
177 .with_filter("debug");
178
179 assert_eq!(builder.base_path, "/tracing");
180 assert_eq!(builder.capacity, 5000);
181 assert_eq!(builder.initial_filter, "debug");
182 }
183
184 #[test]
185 fn test_builder_defaults_to_trace() {
186 let builder = TracingLayerBuilder::new("/tracing");
187 assert_eq!(builder.initial_filter, "trace");
188 }
189}