10
10
//! ´´´
11
11
//!
12
12
13
- use std:: sync:: Once ;
13
+ use std:: io;
14
+ use std:: sync:: { Arc , Mutex , Once } ;
14
15
15
16
use tracing:: level_filters:: LevelFilter ;
17
+ use tracing_subscriber:: fmt:: MakeWriter ;
16
18
17
19
#[ allow( dead_code) ]
18
20
pub static INIT : Once = Once :: new ( ) ;
@@ -28,3 +30,92 @@ pub fn tracing_stderr_init(filter: LevelFilter) {
28
30
29
31
tracing:: info!( "Logging initialized" ) ;
30
32
}
33
+
34
+ #[ allow( dead_code) ]
35
+ pub fn tracing_init_with_capturer ( filter : LevelFilter , log_capturer : Arc < Mutex < LogCapturer > > ) {
36
+ let writer = LogCapturerWrapper :: new ( log_capturer) ;
37
+
38
+ let builder = tracing_subscriber:: fmt ( )
39
+ . with_max_level ( filter)
40
+ . with_ansi ( true )
41
+ . with_writer ( writer) ;
42
+
43
+ builder. pretty ( ) . with_file ( true ) . init ( ) ;
44
+
45
+ tracing:: info!( "Logging initialized" ) ;
46
+ }
47
+
48
+ pub struct LogCapturerWrapper {
49
+ inner : Arc < Mutex < LogCapturer > > ,
50
+ }
51
+
52
+ impl LogCapturerWrapper {
53
+ pub fn new ( inner : Arc < Mutex < LogCapturer > > ) -> Self {
54
+ Self { inner }
55
+ }
56
+ }
57
+
58
+ impl < ' a > tracing_subscriber:: fmt:: MakeWriter < ' a > for LogCapturerWrapper {
59
+ type Writer = LogCapturerGuard ;
60
+
61
+ fn make_writer ( & ' a self ) -> Self :: Writer {
62
+ LogCapturerGuard {
63
+ inner : self . inner . clone ( ) ,
64
+ }
65
+ }
66
+ }
67
+
68
+ pub struct LogCapturerGuard {
69
+ inner : Arc < Mutex < LogCapturer > > ,
70
+ }
71
+
72
+ impl io:: Write for LogCapturerGuard {
73
+ fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
74
+ let mut capturer = self . inner . lock ( ) . unwrap ( ) ;
75
+ capturer. write ( buf)
76
+ }
77
+
78
+ fn flush ( & mut self ) -> io:: Result < ( ) > {
79
+ let mut capturer = self . inner . lock ( ) . unwrap ( ) ;
80
+ capturer. flush ( )
81
+ }
82
+ }
83
+
84
+ #[ derive( Debug , Default ) ]
85
+ pub struct LogCapturer {
86
+ output : String ,
87
+ }
88
+
89
+ impl LogCapturer {
90
+ pub fn new ( ) -> Self {
91
+ Self :: default ( )
92
+ }
93
+
94
+ pub fn contains ( & self , message : & str ) -> bool {
95
+ self . output . contains ( message)
96
+ }
97
+ }
98
+
99
+ impl io:: Write for LogCapturer {
100
+ fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
101
+ let out_str = String :: from_utf8_lossy ( buf) ;
102
+
103
+ print ! ( "{out_str}" ) ;
104
+
105
+ self . output . push_str ( & out_str) ;
106
+
107
+ Ok ( buf. len ( ) )
108
+ }
109
+
110
+ fn flush ( & mut self ) -> io:: Result < ( ) > {
111
+ Ok ( ( ) )
112
+ }
113
+ }
114
+
115
+ impl < ' a > MakeWriter < ' a > for LogCapturer {
116
+ type Writer = Self ;
117
+
118
+ fn make_writer ( & ' a self ) -> Self :: Writer {
119
+ Self :: default ( )
120
+ }
121
+ }
0 commit comments