@@ -43,6 +43,7 @@ use tracing_subscriber::filter::{Directive, EnvFilter, LevelFilter};
4343use tracing_subscriber:: fmt:: FmtContext ;
4444use tracing_subscriber:: fmt:: format:: { self , FormatEvent , FormatFields } ;
4545use tracing_subscriber:: layer:: SubscriberExt ;
46+ use tracing_subscriber:: { Layer , Registry } ;
4647
4748/// The values of all the environment variables that matter for configuring a logger.
4849/// Errors are explicitly preserved so that we can share error handling.
@@ -72,6 +73,36 @@ impl LoggerConfig {
7273
7374/// Initialize the logger with the given values for the filter, coloring, and other options env variables.
7475pub fn init_logger ( cfg : LoggerConfig ) -> Result < ( ) , Error > {
76+ init_logger_with_additional_layer ( cfg, || Registry :: default ( ) )
77+ }
78+
79+ /// Trait alias for the complex return type of `build_subscriber` in
80+ /// [init_logger_with_additional_layer]. A [Registry] with any composition of [tracing::Subscriber]s
81+ /// (e.g. `Registry::default().with(custom_layer)`) should be compatible with this type.
82+ /// Having an alias is also useful so rustc_driver_impl does not need to explicitly depend on
83+ /// `tracing_subscriber`.
84+ pub trait BuildSubscriberRet :
85+ tracing:: Subscriber + for < ' span > tracing_subscriber:: registry:: LookupSpan < ' span > + Send + Sync
86+ {
87+ }
88+
89+ impl <
90+ T : tracing:: Subscriber + for < ' span > tracing_subscriber:: registry:: LookupSpan < ' span > + Send + Sync ,
91+ > BuildSubscriberRet for T
92+ {
93+ }
94+
95+ /// Initialize the logger with the given values for the filter, coloring, and other options env variables.
96+ /// Additionally add a custom layer to collect logging and tracing events via `build_subscriber`,
97+ /// for example: `|| Registry::default().with(custom_layer)`.
98+ pub fn init_logger_with_additional_layer < F , T > (
99+ cfg : LoggerConfig ,
100+ build_subscriber : F ,
101+ ) -> Result < ( ) , Error >
102+ where
103+ F : FnOnce ( ) -> T ,
104+ T : BuildSubscriberRet ,
105+ {
75106 let filter = match cfg. filter {
76107 Ok ( env) => EnvFilter :: new ( env) ,
77108 _ => EnvFilter :: default ( ) . add_directive ( Directive :: from ( LevelFilter :: WARN ) ) ,
@@ -124,7 +155,7 @@ pub fn init_logger(cfg: LoggerConfig) -> Result<(), Error> {
124155 Err ( _) => { } // no wraptree
125156 }
126157
127- let subscriber = tracing_subscriber :: Registry :: default ( ) . with ( filter ) . with ( layer ) ;
158+ let subscriber = build_subscriber ( ) . with ( layer . with_filter ( filter ) ) ;
128159 match cfg. backtrace {
129160 Ok ( backtrace_target) => {
130161 let fmt_layer = tracing_subscriber:: fmt:: layer ( )
0 commit comments