@@ -60,18 +60,16 @@ pub(super) fn sqlite_logger_make_span(request: &Request<Body>) -> Span {
60
60
let host = get_header ( headers, "host" ) . unwrap_or ( "" ) ;
61
61
let user_agent = get_header ( headers, "user-agent" ) . unwrap_or ( "" ) ;
62
62
let referer = get_header ( headers, "referer" ) . unwrap_or ( "" ) ;
63
- let client_ip = InsecureClientIp :: from ( headers, request. extensions ( ) )
64
- . map ( |ip| ip. 0 . to_string ( ) )
65
- . unwrap_or_else ( |_| "" . to_string ( ) ) ;
66
- // let extensions = request.extensions().get::<ConnectInfo<SocketAddr>>();
63
+ let client_ip = InsecureClientIp :: from ( headers, request. extensions ( ) ) . map ( |ip| ip. 0 . to_string ( ) ) ;
67
64
65
+ // NOTE: "%" means print using fmt::Display, and "?" means fmt::Debug.
68
66
let span = tracing:: info_span!(
69
67
"request" ,
70
68
method = %request. method( ) ,
71
69
uri = %request. uri( ) ,
72
70
version = ?request. version( ) ,
73
71
host,
74
- client_ip,
72
+ client_ip = %client_ip . as_ref ( ) . map_or ( "" , |s| s . as_str ( ) ) ,
75
73
user_agent,
76
74
referer,
77
75
) ;
@@ -84,24 +82,26 @@ pub(super) fn sqlite_logger_on_request(_req: &Request<Body>, _span: &Span) {
84
82
// request related information into the span
85
83
}
86
84
85
+ #[ inline]
87
86
fn as_millis_f64 ( d : & Duration ) -> f64 {
88
87
const NANOS_PER_MILLI : f64 = 1_000_000.0 ;
89
88
const MILLIS_PER_SEC : u64 = 1_000 ;
90
- return d. as_secs_f64 ( ) * ( MILLIS_PER_SEC as f64 ) + ( d. as_nanos ( ) as f64 ) / ( NANOS_PER_MILLI ) ;
89
+ return ( d. as_secs ( ) as f64 ) * ( MILLIS_PER_SEC as f64 )
90
+ + ( d. subsec_nanos ( ) as f64 ) / ( NANOS_PER_MILLI ) ;
91
91
}
92
92
93
93
pub ( super ) fn sqlite_logger_on_response (
94
94
response : & Response < Body > ,
95
95
latency : Duration ,
96
96
_span : & Span ,
97
97
) {
98
- let length = get_header ( response. headers ( ) , "content-length" ) . unwrap_or ( "-1" ) ;
98
+ let length = get_header ( response. headers ( ) , "content-length" ) ;
99
99
100
100
tracing:: info!(
101
101
name: "response" ,
102
102
latency_ms = as_millis_f64( & latency) ,
103
103
status = response. status( ) . as_u16( ) ,
104
- length = length. parse:: <i64 >( ) . unwrap ( ) ,
104
+ length = length. and_then ( |l| l . parse:: <i64 >( ) . ok ( ) ) ,
105
105
) ;
106
106
}
107
107
@@ -123,89 +123,71 @@ impl SqliteLogLayer {
123
123
// TODO: We could use recv_many() and batch insert.
124
124
fn write_log ( & self , log : Log ) -> Result < ( ) , trailbase_sqlite:: Error > {
125
125
return self . conn . call_and_forget ( move |conn| {
126
- let result = conn. execute (
126
+ let mut stmt = match conn. prepare_cached (
127
127
r#"
128
128
INSERT INTO
129
129
_logs (type, level, status, method, url, latency, client_ip, referer, user_agent)
130
130
VALUES
131
131
($1, $2, $3, $4, $5, $6, $7, $8, $9)
132
132
"# ,
133
- rusqlite:: params!(
134
- log. r#type,
135
- log. level,
136
- log. status,
137
- log. method,
138
- log. url,
139
- log. latency,
140
- log. client_ip,
141
- log. referer,
142
- log. user_agent
143
- ) ,
144
- ) ;
145
-
146
- if let Err ( err) = result {
133
+ ) {
134
+ Ok ( stmt) => stmt,
135
+ Err ( err) => {
136
+ warn ! ( "Logs stmt failed: {err}" ) ;
137
+ return ;
138
+ }
139
+ } ;
140
+
141
+ if let Err ( err) = stmt. execute ( rusqlite:: params!(
142
+ log. r#type,
143
+ log. level,
144
+ log. status,
145
+ log. method,
146
+ log. url,
147
+ log. latency,
148
+ log. client_ip,
149
+ log. referer,
150
+ log. user_agent
151
+ ) ) {
147
152
warn ! ( "logs writing failed: {err}" ) ;
148
153
}
149
154
} ) ;
150
155
}
151
156
}
152
157
158
+ const BUG_TEXT : & str = "Span not found, this is a bug" ;
159
+
153
160
impl < S > Layer < S > for SqliteLogLayer
154
161
where
155
162
S : tracing:: Subscriber ,
156
163
S : for < ' lookup > tracing_subscriber:: registry:: LookupSpan < ' lookup > ,
157
164
{
158
165
fn on_new_span ( & self , attrs : & Attributes < ' _ > , id : & Id , ctx : Context < ' _ , S > ) {
159
- let span = ctx. span ( id) . unwrap ( ) ;
160
-
161
- // let mut fields = BTreeMap::new();
162
- // attrs.record(&mut JsonVisitor(&mut fields));
163
- // span.extensions_mut().insert(CustomFieldStorage(fields));
166
+ let span = ctx. span ( id) . expect ( BUG_TEXT ) ;
164
167
165
168
let mut storage = LogFieldStorage :: default ( ) ;
166
169
attrs. record ( & mut LogJsonVisitor ( & mut storage) ) ;
167
170
span. extensions_mut ( ) . insert ( storage) ;
168
171
}
169
172
170
173
fn on_record ( & self , id : & Id , values : & Record < ' _ > , ctx : Context < ' _ , S > ) {
171
- // Get a mutable reference to the data we created in new_span
172
- let span = ctx. span ( id) . unwrap ( ) ;
173
- let mut extensions_mut = span. extensions_mut ( ) ;
174
+ let span = ctx. span ( id) . expect ( BUG_TEXT ) ;
174
175
175
- // And add to using our old friend the visitor!
176
- // let custom_field_storage = extensions_mut.get_mut::<CustomFieldStorage>().unwrap();
177
- // values.record(&mut JsonVisitor(&mut custom_field_storage.0));
178
-
179
- let log_field_storage = extensions_mut. get_mut :: < LogFieldStorage > ( ) . unwrap ( ) ;
180
- values. record ( & mut LogJsonVisitor ( log_field_storage) ) ;
176
+ let mut extensions = span. extensions_mut ( ) ;
177
+ if let Some ( storage) = extensions. get_mut :: < LogFieldStorage > ( ) {
178
+ values. record ( & mut LogJsonVisitor ( storage) ) ;
179
+ }
181
180
}
182
181
183
182
fn on_event ( & self , event : & tracing:: Event < ' _ > , ctx : Context < ' _ , S > ) {
184
- let mut request_storage: Option < LogFieldStorage > = None ;
185
-
186
- let scope = ctx. event_scope ( event) . unwrap ( ) ;
187
- for span in scope. from_root ( ) {
188
- // TODO: we should be merging here to account for multiple spans. Maybe we should have a json
189
- // span representation in the data field.
190
- let extensions = span. extensions ( ) ;
191
- if let Some ( storage) = extensions. get :: < LogFieldStorage > ( ) {
192
- request_storage = Some ( storage. clone ( ) ) ;
193
- }
194
- }
183
+ let Some ( span) = ctx. event_span ( event) else {
184
+ return ;
185
+ } ;
186
+
187
+ let mut extensions = span. extensions_mut ( ) ;
188
+ if let Some ( s) = extensions. get_mut :: < LogFieldStorage > ( ) {
189
+ let mut storage = std:: mem:: take ( s) ;
195
190
196
- // The fields of the event
197
- // let mut fields = BTreeMap::new();
198
- // event.record(&mut JsonVisitor(&mut fields));
199
- // let output = json!({
200
- // "target": event.metadata().target(),
201
- // "name": event.metadata().name(),
202
- // "level": format!("{:?}", event.metadata().level()),
203
- // "fields": fields,
204
- // "spans": spans,
205
- // });
206
- // println!("{}", serde_json::to_string_pretty(&output).unwrap());
207
-
208
- if let Some ( mut storage) = request_storage {
209
191
event. record ( & mut LogJsonVisitor ( & mut storage) ) ;
210
192
211
193
let log = Log {
@@ -222,7 +204,13 @@ where
222
204
client_ip : storage. client_ip ,
223
205
referer : storage. referer ,
224
206
user_agent : storage. user_agent ,
225
- data : Some ( json ! ( storage. fields) ) ,
207
+ data : {
208
+ if storage. fields . is_empty ( ) {
209
+ None
210
+ } else {
211
+ Some ( json ! ( storage. fields) )
212
+ }
213
+ } ,
226
214
} ;
227
215
228
216
if let Err ( err) = self . write_log ( log) {
@@ -259,77 +247,69 @@ struct LogFieldStorage {
259
247
length : i64 ,
260
248
261
249
// All other fields.
262
- fields : BTreeMap < String , serde_json:: Value > ,
250
+ fields : BTreeMap < & ' static str , serde_json:: Value > ,
263
251
}
264
252
265
253
struct LogJsonVisitor < ' a > ( & ' a mut LogFieldStorage ) ;
266
254
267
255
impl tracing:: field:: Visit for LogJsonVisitor < ' _ > {
268
256
fn record_f64 ( & mut self , field : & Field , double : f64 ) {
269
- let name = field. name ( ) ;
270
- match name {
257
+ match field. name ( ) {
271
258
"latency_ms" => self . 0 . latency_ms = double,
272
- _ => {
273
- self . 0 . fields . insert ( name. to_string ( ) , json ! ( double) ) ;
259
+ name => {
260
+ self . 0 . fields . insert ( name, json ! ( double) ) ;
274
261
}
275
262
} ;
276
263
}
277
264
278
265
fn record_i64 ( & mut self , field : & Field , int : i64 ) {
279
- let name = field. name ( ) ;
280
- match name {
266
+ match field. name ( ) {
281
267
"length" => self . 0 . length = int,
282
- _ => {
283
- self . 0 . fields . insert ( name. to_string ( ) , json ! ( int) ) ;
268
+ name => {
269
+ self . 0 . fields . insert ( name, json ! ( int) ) ;
284
270
}
285
271
} ;
286
272
}
287
273
288
274
fn record_u64 ( & mut self , field : & Field , uint : u64 ) {
289
- let name = field. name ( ) ;
290
- match name {
275
+ match field. name ( ) {
291
276
"status" => self . 0 . status = uint,
292
- _ => {
293
- self . 0 . fields . insert ( name. to_string ( ) , json ! ( uint) ) ;
277
+ name => {
278
+ self . 0 . fields . insert ( name, json ! ( uint) ) ;
294
279
}
295
280
} ;
296
281
}
297
282
298
283
fn record_bool ( & mut self , field : & Field , b : bool ) {
299
- self . 0 . fields . insert ( field. name ( ) . to_string ( ) , json ! ( b) ) ;
284
+ self . 0 . fields . insert ( field. name ( ) , json ! ( b) ) ;
300
285
}
301
286
302
287
fn record_str ( & mut self , field : & Field , s : & str ) {
303
- let name: & str = field. name ( ) ;
304
- match name {
288
+ match field. name ( ) {
305
289
"client_ip" => self . 0 . client_ip = s. to_string ( ) ,
306
290
"host" => self . 0 . host = s. to_string ( ) ,
307
291
"referer" => self . 0 . referer = s. to_string ( ) ,
308
292
"user_agent" => self . 0 . user_agent = s. to_string ( ) ,
309
293
name => {
310
- self . 0 . fields . insert ( name. to_string ( ) , json ! ( s) ) ;
294
+ self . 0 . fields . insert ( name, json ! ( s) ) ;
311
295
}
312
296
} ;
313
297
}
314
298
315
299
fn record_debug ( & mut self , field : & Field , dbg : & dyn std:: fmt:: Debug ) {
316
- let name = field. name ( ) ;
317
300
let v = format ! ( "{:?}" , dbg) ;
318
- match name {
301
+ match field . name ( ) {
319
302
"method" => self . 0 . method = v,
320
303
"uri" => self . 0 . uri = v,
321
304
"version" => self . 0 . version = v,
322
305
name => {
323
- self . 0 . fields . insert ( name. to_string ( ) , json ! ( v) ) ;
306
+ self . 0 . fields . insert ( name, json ! ( v) ) ;
324
307
}
325
308
} ;
326
309
}
327
310
328
311
fn record_error ( & mut self , field : & Field , err : & ( dyn std:: error:: Error + ' static ) ) {
329
- self
330
- . 0
331
- . fields
332
- . insert ( field. name ( ) . to_string ( ) , json ! ( err. to_string( ) ) ) ;
312
+ self . 0 . fields . insert ( field. name ( ) , json ! ( err. to_string( ) ) ) ;
333
313
}
334
314
}
335
315
0 commit comments