3
3
4
4
use std:: convert:: From ;
5
5
use std:: fmt;
6
- use std:: io:: LineWriter ;
6
+ use std:: fs:: OpenOptions ;
7
+ use std:: io:: { BufWriter , LineWriter } ;
7
8
use std:: os:: unix:: fs:: OpenOptionsExt ;
9
+ use std:: path:: PathBuf ;
8
10
use std:: str:: FromStr ;
9
11
use std:: sync:: atomic:: AtomicBool ;
10
12
use std:: sync:: atomic:: Ordering :: SeqCst ;
@@ -107,7 +109,7 @@ impl FromStr for LevelFilter {
107
109
#[ serde( deny_unknown_fields) ]
108
110
pub struct LoggerConfig {
109
111
/// Named pipe or file used as output for logs.
110
- pub log_path : Option < std :: path :: PathBuf > ,
112
+ pub log_path : Option < PathBuf > ,
111
113
// TODO Deprecate this API argument.
112
114
/// The level of the Logger.
113
115
pub level : Option < LevelFilter > ,
@@ -117,6 +119,8 @@ pub struct LoggerConfig {
117
119
pub show_log_origin : Option < bool > ,
118
120
/// Filter components. If this is `Some` it overrides `self.level`.
119
121
pub filter : Option < FilterArgs > ,
122
+ /// Named pipe or file used as output for profile.
123
+ pub profile_path : Option < PathBuf > ,
120
124
}
121
125
122
126
/// Error type for [`LoggerConfig::init`].
@@ -186,17 +190,24 @@ type FmtHandle<F, G> = tracing_subscriber::reload::Handle<
186
190
> ,
187
191
> ;
188
192
193
+ /// An alias for the specific [`tracing_flame::FlushGuard`] used to flush the
194
+ /// [`tracing_flame::FlameLayer`].
195
+ pub type FlameGuard = tracing_flame:: FlushGuard < BufWriter < std:: fs:: File > > ;
196
+
189
197
impl LoggerConfig {
190
198
/// Initializes the logger.
191
199
///
192
200
/// Returns handles that can be used to dynamically re-configure the logger.
193
201
pub fn init (
194
202
self ,
195
203
) -> Result <
196
- LoggerHandles <
197
- impl Fn ( & tracing:: Metadata < ' _ > ) -> bool ,
198
- impl Fn ( & tracing:: Metadata < ' _ > ) -> bool ,
199
- > ,
204
+ (
205
+ LoggerHandles <
206
+ impl Fn ( & tracing:: Metadata < ' _ > ) -> bool ,
207
+ impl Fn ( & tracing:: Metadata < ' _ > ) -> bool ,
208
+ > ,
209
+ Option < FlameGuard > ,
210
+ ) ,
200
211
InitLoggerError ,
201
212
> {
202
213
// Update default filter to match passed arguments.
@@ -243,7 +254,7 @@ impl LoggerConfig {
243
254
// consuming the message that is flushed to the two pipes, we are opening it
244
255
// with `O_NONBLOCK` flag. In this case, writing to a pipe will start failing
245
256
// when reaching 64K of unconsumed content.
246
- let file = std :: fs :: OpenOptions :: new ( )
257
+ let file = OpenOptions :: new ( )
247
258
. custom_flags ( libc:: O_NONBLOCK )
248
259
. read ( true )
249
260
. write ( true )
@@ -264,19 +275,37 @@ impl LoggerConfig {
264
275
ReloadLayer :: new ( fmt_subscriber)
265
276
} ;
266
277
267
- Registry :: default ( )
268
- . with ( filter)
269
- . with ( fmt)
270
- . try_init ( )
271
- . map_err ( InitLoggerError :: Init ) ?;
278
+ // Setup flame layer
279
+ let flame_guard = if let Some ( profile_path) = self . profile_path {
280
+ let writer = OpenOptions :: new ( ) . write ( true ) . open ( profile_path) . unwrap ( ) ;
281
+ let buffer = BufWriter :: new ( writer) ;
282
+ let flame_layer = tracing_flame:: FlameLayer :: new ( buffer) ;
283
+ let guard = flame_layer. flush_on_drop ( ) ;
284
+
285
+ Registry :: default ( )
286
+ . with ( filter)
287
+ . with ( fmt)
288
+ . with ( flame_layer)
289
+ . try_init ( )
290
+ . map_err ( InitLoggerError :: Init ) ?;
291
+
292
+ Some ( guard)
293
+ } else {
294
+ Registry :: default ( )
295
+ . with ( filter)
296
+ . with ( fmt)
297
+ . try_init ( )
298
+ . map_err ( InitLoggerError :: Init ) ?;
299
+ None
300
+ } ;
272
301
273
302
tracing:: error!( "Error level logs enabled." ) ;
274
303
tracing:: warn!( "Warn level logs enabled." ) ;
275
304
tracing:: info!( "Info level logs enabled." ) ;
276
305
tracing:: debug!( "Debug level logs enabled." ) ;
277
306
tracing:: trace!( "Trace level logs enabled." ) ;
278
307
279
- Ok ( LoggerHandles { fmt : fmt_handle } )
308
+ Ok ( ( LoggerHandles { fmt : fmt_handle } , flame_guard ) )
280
309
}
281
310
/// Updates the logger using the given handles.
282
311
pub fn update (
@@ -292,7 +321,7 @@ impl LoggerConfig {
292
321
// message that is flushed to the two pipes, we are opening it with `O_NONBLOCK` flag.
293
322
// In this case, writing to a pipe will start failing when reaching 64K of unconsumed
294
323
// content.
295
- let file = std :: fs :: OpenOptions :: new ( )
324
+ let file = OpenOptions :: new ( )
296
325
. custom_flags ( libc:: O_NONBLOCK )
297
326
. read ( true )
298
327
. write ( true )
0 commit comments