@@ -7,9 +7,15 @@ use std::{
77 fs:: File ,
88 net:: SocketAddr ,
99 path:: { Path , PathBuf } ,
10- sync:: Arc ,
10+ sync:: { Arc , OnceLock } ,
11+ } ;
12+ use tracing:: level_filters:: LevelFilter ;
13+ use tracing_subscriber:: {
14+ filter:: Targets ,
15+ fmt:: writer:: MakeWriterExt ,
16+ layer:: { Layered , SubscriberExt } ,
17+ util:: SubscriberInitExt ,
1118} ;
12- use tracing_subscriber:: fmt:: writer:: MakeWriterExt ;
1319use utoipa:: ToSchema ;
1420
1521fn tls_cert ( ) -> String {
@@ -238,6 +244,20 @@ nestify::nest! {
238244pub const FORBIDDEN_PATHS : & [ & str ] = & [ "api.token" ] ;
239245
240246pub type ConfigSnapshot = arc_swap:: Guard < Arc < InnerConfig > > ;
247+ type ReloadHandle =
248+ tracing_subscriber:: reload:: Handle < Targets , Layered < LevelFilter , tracing_subscriber:: Registry > > ;
249+
250+ fn log_filter ( debug : bool ) -> Targets {
251+ let crate_level = if debug {
252+ LevelFilter :: DEBUG
253+ } else {
254+ LevelFilter :: INFO
255+ } ;
256+
257+ Targets :: new ( )
258+ . with_default ( LevelFilter :: INFO )
259+ . with_target ( "db_agent" , crate_level)
260+ }
241261
242262#[ allow( dead_code) ]
243263pub struct LogGuard (
@@ -247,6 +267,7 @@ pub struct LogGuard(
247267
248268pub struct Config {
249269 inner : ArcSwap < InnerConfig > ,
270+ log_reload_handle : OnceLock < ReloadHandle > ,
250271 pub path : String ,
251272 pub disk_check_semaphore : ArcSwap < tokio:: sync:: Semaphore > ,
252273}
@@ -270,6 +291,7 @@ impl Config {
270291
271292 Ok ( Arc :: new ( Self {
272293 inner : ArcSwap :: from_pointee ( inner) ,
294+ log_reload_handle : OnceLock :: new ( ) ,
273295 path : path. to_string ( ) ,
274296 disk_check_semaphore,
275297 } ) )
@@ -347,25 +369,40 @@ impl Config {
347369 let ( stdout_writer, stdout_guard) = tracing_appender:: non_blocking ( std:: io:: stdout ( ) ) ;
348370 let ( file_writer, file_guard) = tracing_appender:: non_blocking ( rolling) ;
349371
350- tracing_subscriber:: fmt ( )
351- . with_max_level ( if debug {
352- tracing:: Level :: DEBUG
353- } else {
354- tracing:: Level :: INFO
355- } )
372+ let ( reload_layer, reload_handle) =
373+ tracing_subscriber:: reload:: Layer :: new ( log_filter ( debug) ) ;
374+
375+ let fmt_layer = tracing_subscriber:: fmt:: layer ( )
356376 . with_writer ( stdout_writer. and ( file_writer) )
357- . with_target ( false )
377+ . with_target ( false ) ;
378+
379+ tracing_subscriber:: registry ( )
380+ . with ( LevelFilter :: DEBUG )
381+ . with ( reload_layer)
382+ . with ( fmt_layer)
358383 . init ( ) ;
359384
385+ let _ = self . log_reload_handle . set ( reload_handle) ;
386+
360387 Ok ( LogGuard ( file_guard, stdout_guard) )
361388 }
362389
363390 pub fn replace ( & self , new : InnerConfig ) -> anyhow:: Result < ( ) > {
391+ let old_debug = self . load ( ) . debug ;
392+ let new_debug = new. debug ;
364393 let old_concurrency = self . load ( ) . disk_check_concurrency . max ( 1 ) ;
365394 let new_concurrency = new. disk_check_concurrency . max ( 1 ) ;
366395 Self :: save_to ( & self . path , & new) ?;
367396 self . inner . store ( Arc :: new ( new) ) ;
368397
398+ if old_debug != new_debug
399+ && let Some ( handle) = self . log_reload_handle . get ( )
400+ {
401+ handle
402+ . modify ( |filter| * filter = log_filter ( new_debug) )
403+ . context ( "failed to reload tracing level filter" ) ?;
404+ }
405+
369406 if new_concurrency != old_concurrency {
370407 self . disk_check_semaphore
371408 . store ( Arc :: new ( tokio:: sync:: Semaphore :: new ( new_concurrency) ) ) ;
0 commit comments