@@ -12,27 +12,48 @@ use std::{env, str};
12
12
pub use tokio_trace:: tasks:: TaskList ;
13
13
use tokio_trace:: tasks:: TasksLayer ;
14
14
use tracing:: Dispatch ;
15
- use tracing_subscriber:: { fmt:: format, prelude:: * } ;
15
+ use tracing_subscriber:: {
16
+ fmt:: format:: { self , DefaultFields } ,
17
+ layer:: Layered ,
18
+ prelude:: * ,
19
+ reload, EnvFilter ,
20
+ } ;
21
+
22
+ type Registry =
23
+ Layered < reload:: Layer < EnvFilter , tracing_subscriber:: Registry > , tracing_subscriber:: Registry > ;
16
24
17
25
const ENV_LOG_LEVEL : & str = "LINKERD2_PROXY_LOG" ;
18
26
const ENV_LOG_FORMAT : & str = "LINKERD2_PROXY_LOG_FORMAT" ;
19
27
20
28
const DEFAULT_LOG_LEVEL : & str = "warn,linkerd=info" ;
21
29
const DEFAULT_LOG_FORMAT : & str = "PLAIN" ;
22
30
31
+ #[ derive( Debug , Default ) ]
32
+ pub struct Settings {
33
+ filter : Option < String > ,
34
+ format : Option < String > ,
35
+ is_test : bool ,
36
+ }
37
+
38
+ #[ derive( Clone ) ]
39
+ pub struct Handle ( Inner ) ;
40
+
41
+ #[ derive( Clone ) ]
42
+ enum Inner {
43
+ Disabled ,
44
+ Enabled {
45
+ level : level:: Handle ,
46
+ tasks : TaskList ,
47
+ } ,
48
+ }
49
+
23
50
/// Initialize tracing and logging with the value of the `ENV_LOG`
24
51
/// environment variable as the verbosity-level filter.
25
52
pub fn init ( ) -> Result < Handle , Error > {
26
- let log_level = env:: var ( ENV_LOG_LEVEL ) . unwrap_or_else ( |_| DEFAULT_LOG_LEVEL . to_string ( ) ) ;
27
- if let "OFF" = log_level. to_uppercase ( ) . trim ( ) {
28
- return Ok ( Handle ( Inner :: Disabled ) ) ;
29
- }
30
-
31
- let log_format = env:: var ( ENV_LOG_FORMAT ) . unwrap_or_else ( |_| DEFAULT_LOG_FORMAT . to_string ( ) ) ;
32
- let ( dispatch, handle) = Settings :: default ( )
33
- . filter ( log_level)
34
- . format ( log_format)
35
- . build ( ) ;
53
+ let ( dispatch, handle) = match Settings :: from_env ( ) {
54
+ Some ( s) => s. build ( ) ,
55
+ None => return Ok ( Handle ( Inner :: Disabled ) ) ,
56
+ } ;
36
57
37
58
// Set the default subscriber.
38
59
tracing:: dispatcher:: set_global_default ( dispatch) ?;
@@ -57,110 +78,104 @@ pub fn init_log_compat() -> Result<(), Error> {
57
78
Ok ( ( ) )
58
79
}
59
80
60
- #[ derive( Debug , Default ) ]
61
- pub struct Settings {
62
- filter : Option < String > ,
63
- format : Option < String > ,
64
- test : bool ,
65
- }
81
+ // === impl Settings ===
66
82
67
83
impl Settings {
68
- pub fn from_env ( ) -> Self {
69
- let mut settings = Settings :: default ( ) ;
70
- if let Ok ( filter) = env:: var ( ENV_LOG_LEVEL ) {
71
- settings = settings. filter ( filter) ;
72
- }
73
- if let Ok ( format) = env:: var ( ENV_LOG_FORMAT ) {
74
- settings = settings. format ( format) ;
84
+ pub fn from_env ( ) -> Option < Self > {
85
+ let filter = std:: env:: var ( ENV_LOG_LEVEL ) . ok ( ) ;
86
+ if let Some ( level) = filter. as_ref ( ) {
87
+ if level. to_uppercase ( ) . trim ( ) == "OFF" {
88
+ return None ;
89
+ }
75
90
}
76
- settings
91
+
92
+ Some ( Self {
93
+ filter,
94
+ format : std:: env:: var ( ENV_LOG_FORMAT ) . ok ( ) ,
95
+ is_test : false ,
96
+ } )
77
97
}
78
98
79
- pub fn filter ( self , filter : impl Into < String > ) -> Self {
99
+ fn for_test ( filter : String , format : String ) -> Self {
80
100
Self {
81
- filter : Some ( filter. into ( ) ) ,
82
- ..self
101
+ filter : Some ( filter) ,
102
+ format : Some ( format) ,
103
+ is_test : true ,
83
104
}
84
105
}
85
106
86
- pub fn format ( self , format : impl Into < String > ) -> Self {
87
- Self {
88
- format : Some ( format . into ( ) ) ,
89
- .. self
90
- }
107
+ fn format ( & self ) -> String {
108
+ self . format
109
+ . as_deref ( )
110
+ . unwrap_or ( DEFAULT_LOG_FORMAT )
111
+ . to_uppercase ( )
91
112
}
92
113
93
- pub fn test ( self , test : bool ) -> Self {
94
- Self { test, ..self }
114
+ fn mk_registry ( & self ) -> ( Registry , level:: Handle ) {
115
+ let log_level = self . filter . as_deref ( ) . unwrap_or ( DEFAULT_LOG_LEVEL ) ;
116
+ let ( filter, level) = reload:: Layer :: new ( EnvFilter :: new ( log_level) ) ;
117
+ let reg = tracing_subscriber:: registry ( ) . with ( filter) ;
118
+ ( reg, level:: Handle :: new ( level) )
95
119
}
96
120
97
- pub fn build ( self ) -> ( Dispatch , Handle ) {
98
- let filter = self . filter . unwrap_or_else ( || DEFAULT_LOG_LEVEL . to_string ( ) ) ;
99
- let format = self
100
- . format
101
- . unwrap_or_else ( || DEFAULT_LOG_FORMAT . to_string ( ) ) ;
121
+ fn mk_json ( & self , registry : Registry ) -> ( Dispatch , TaskList ) {
122
+ let ( tasks, tasks_layer) = TasksLayer :: < format:: JsonFields > :: new ( ) ;
123
+ let registry = registry. with ( tasks_layer) ;
102
124
103
- // Set up the subscriber
104
125
let fmt = tracing_subscriber:: fmt:: format ( )
105
126
. with_timer ( Uptime :: starting_now ( ) )
106
- . with_thread_ids ( !self . test ) ;
107
- let filter = tracing_subscriber:: EnvFilter :: new ( filter) ;
108
- let ( filter, level) = tracing_subscriber:: reload:: Layer :: new ( filter) ;
109
- let level = level:: Handle :: new ( level) ;
110
- let registry = tracing_subscriber:: registry ( ) . with ( filter) ;
111
-
112
- let ( dispatch, tasks) = match format. to_uppercase ( ) . as_ref ( ) {
113
- "JSON" => {
114
- let ( tasks, tasks_layer) = TasksLayer :: < format:: JsonFields > :: new ( ) ;
115
- let fmt = fmt
116
- // Configure the formatter to output JSON logs.
117
- . json ( )
118
- // Output the current span context as a JSON list.
119
- . with_span_list ( true )
120
- // Don't output a field for the current span, since this
121
- // would duplicate information already in the span list.
122
- . with_current_span ( false ) ;
123
- let fmt = tracing_subscriber:: fmt:: layer ( )
124
- // Use the JSON event formatter.
125
- . event_format ( fmt)
126
- // Since we're using the JSON event formatter, we must also
127
- // use the JSON field formatter.
128
- . fmt_fields ( format:: JsonFields :: default ( ) ) ;
129
- let registry = registry. with ( tasks_layer) ;
130
- let dispatch = if self . test {
131
- registry. with ( fmt. with_test_writer ( ) ) . into ( )
132
- } else {
133
- registry. with ( fmt) . into ( )
134
- } ;
135
- ( dispatch, tasks)
136
- }
137
- _ => {
138
- let ( tasks, tasks_layer) = TasksLayer :: < format:: DefaultFields > :: new ( ) ;
139
- let registry = registry. with ( tasks_layer) ;
140
- let fmt = tracing_subscriber:: fmt:: layer ( ) . event_format ( fmt) ;
141
- let dispatch = if self . test {
142
- registry. with ( fmt. with_test_writer ( ) ) . into ( )
143
- } else {
144
- registry. with ( fmt) . into ( )
145
- } ;
146
- ( dispatch, tasks)
147
- }
127
+ . with_thread_ids ( !self . is_test )
128
+ // Configure the formatter to output JSON logs.
129
+ . json ( )
130
+ // Output the current span context as a JSON list.
131
+ . with_span_list ( true )
132
+ // Don't output a field for the current span, since this
133
+ // would duplicate information already in the span list.
134
+ . with_current_span ( false ) ;
135
+
136
+ let fmt = tracing_subscriber:: fmt:: layer ( )
137
+ // Use the JSON event formatter.
138
+ . event_format ( fmt)
139
+ // Since we're using the JSON event formatter, we must also
140
+ // use the JSON field formatter.
141
+ . fmt_fields ( format:: JsonFields :: default ( ) ) ;
142
+
143
+ let dispatch = if self . is_test {
144
+ registry. with ( fmt. with_test_writer ( ) ) . into ( )
145
+ } else {
146
+ registry. with ( fmt) . into ( )
148
147
} ;
149
148
150
- ( dispatch, Handle ( Inner :: Enabled { level , tasks } ) )
149
+ ( dispatch, tasks)
151
150
}
152
- }
153
151
154
- #[ derive( Clone ) ]
155
- pub struct Handle ( Inner ) ;
152
+ fn mk_plain ( & self , registry : Registry ) -> ( Dispatch , TaskList ) {
153
+ let ( tasks, tasks_layer) = TasksLayer :: < DefaultFields > :: new ( ) ;
154
+ let registry = registry. with ( tasks_layer) ;
156
155
157
- #[ derive( Clone ) ]
158
- enum Inner {
159
- Disabled ,
160
- Enabled {
161
- level : level:: Handle ,
162
- tasks : TaskList ,
163
- } ,
156
+ let fmt = tracing_subscriber:: fmt:: format ( )
157
+ . with_timer ( Uptime :: starting_now ( ) )
158
+ . with_thread_ids ( !self . is_test ) ;
159
+ let fmt = tracing_subscriber:: fmt:: layer ( ) . event_format ( fmt) ;
160
+ let dispatch = if self . is_test {
161
+ registry. with ( fmt. with_test_writer ( ) ) . into ( )
162
+ } else {
163
+ registry. with ( fmt) . into ( )
164
+ } ;
165
+
166
+ ( dispatch, tasks)
167
+ }
168
+
169
+ pub fn build ( self ) -> ( Dispatch , Handle ) {
170
+ let ( registry, level) = self . mk_registry ( ) ;
171
+
172
+ let ( dispatch, tasks) = match self . format ( ) . as_ref ( ) {
173
+ "JSON" => self . mk_json ( registry) ,
174
+ _ => self . mk_plain ( registry) ,
175
+ } ;
176
+
177
+ ( dispatch, Handle ( Inner :: Enabled { level, tasks } ) )
178
+ }
164
179
}
165
180
166
181
// === impl Handle ===
0 commit comments