@@ -18,6 +18,7 @@ use bitcoin::secp256k1::PublicKey;
18
18
19
19
use core:: cmp;
20
20
use core:: fmt;
21
+ use core:: ops:: Deref ;
21
22
22
23
use crate :: ln:: ChannelId ;
23
24
#[ cfg( c_bindings) ]
@@ -152,6 +153,39 @@ pub trait Logger {
152
153
fn log ( & self , record : Record ) ;
153
154
}
154
155
156
+ /// Adds relevant context to a [`Record`] before passing it to the wrapped [`Logger`].
157
+ pub struct WithContext < ' a , L : Deref > where L :: Target : Logger {
158
+ /// The logger to delegate to after adding context to the record.
159
+ logger : & ' a L ,
160
+ /// The node id of the peer pertaining to the logged record.
161
+ peer_id : Option < PublicKey > ,
162
+ /// The channel id of the channel pertaining to the logged record.
163
+ channel_id : Option < ChannelId > ,
164
+ }
165
+
166
+ impl < ' a , L : Deref > Logger for WithContext < ' a , L > where L :: Target : Logger {
167
+ fn log ( & self , mut record : Record ) {
168
+ if self . peer_id . is_some ( ) {
169
+ record. peer_id = self . peer_id
170
+ } ;
171
+ if self . channel_id . is_some ( ) {
172
+ record. channel_id = self . channel_id ;
173
+ }
174
+ self . logger . log ( record)
175
+ }
176
+ }
177
+
178
+ impl < ' a , L : Deref > WithContext < ' a , L > where L :: Target : Logger {
179
+ /// Wraps the given logger, providing additional context to any logged records.
180
+ pub fn from ( logger : & ' a L , peer_id : Option < PublicKey > , channel_id : Option < ChannelId > ) -> Self {
181
+ WithContext {
182
+ logger,
183
+ peer_id,
184
+ channel_id,
185
+ }
186
+ }
187
+ }
188
+
155
189
/// Wrapper for logging a [`PublicKey`] in hex format.
156
190
///
157
191
/// This is not exported to bindings users as fmt can't be used in C
@@ -202,7 +236,9 @@ impl<T: fmt::Display, I: core::iter::Iterator<Item = T> + Clone> fmt::Display fo
202
236
203
237
#[ cfg( test) ]
204
238
mod tests {
205
- use crate :: util:: logger:: { Logger , Level } ;
239
+ use bitcoin:: secp256k1:: { PublicKey , SecretKey , Secp256k1 } ;
240
+ use crate :: ln:: ChannelId ;
241
+ use crate :: util:: logger:: { Logger , Level , WithContext } ;
206
242
use crate :: util:: test_utils:: TestLogger ;
207
243
use crate :: sync:: Arc ;
208
244
@@ -243,6 +279,41 @@ mod tests {
243
279
wrapper. call_macros ( ) ;
244
280
}
245
281
282
+ #[ test]
283
+ fn test_logging_with_context ( ) {
284
+ let logger = & TestLogger :: new ( ) ;
285
+ let secp_ctx = Secp256k1 :: new ( ) ;
286
+ let pk = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
287
+ let context_logger = WithContext :: from ( & logger, Some ( pk) , Some ( ChannelId ( [ 0 ; 32 ] ) ) ) ;
288
+ log_error ! ( context_logger, "This is an error" ) ;
289
+ log_warn ! ( context_logger, "This is an error" ) ;
290
+ log_debug ! ( context_logger, "This is an error" ) ;
291
+ log_trace ! ( context_logger, "This is an error" ) ;
292
+ log_gossip ! ( context_logger, "This is an error" ) ;
293
+ log_info ! ( context_logger, "This is an error" ) ;
294
+ logger. assert_log_context_contains (
295
+ "lightning::util::logger::tests" , Some ( pk) , Some ( ChannelId ( [ 0 ; 32 ] ) ) , 6
296
+ ) ;
297
+ }
298
+
299
+ #[ test]
300
+ fn test_logging_with_multiple_wrapped_context ( ) {
301
+ let logger = & TestLogger :: new ( ) ;
302
+ let secp_ctx = Secp256k1 :: new ( ) ;
303
+ let pk = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
304
+ let context_logger = & WithContext :: from ( & logger, None , Some ( ChannelId ( [ 0 ; 32 ] ) ) ) ;
305
+ let full_context_logger = WithContext :: from ( & context_logger, Some ( pk) , None ) ;
306
+ log_error ! ( full_context_logger, "This is an error" ) ;
307
+ log_warn ! ( full_context_logger, "This is an error" ) ;
308
+ log_debug ! ( full_context_logger, "This is an error" ) ;
309
+ log_trace ! ( full_context_logger, "This is an error" ) ;
310
+ log_gossip ! ( full_context_logger, "This is an error" ) ;
311
+ log_info ! ( full_context_logger, "This is an error" ) ;
312
+ logger. assert_log_context_contains (
313
+ "lightning::util::logger::tests" , Some ( pk) , Some ( ChannelId ( [ 0 ; 32 ] ) ) , 6
314
+ ) ;
315
+ }
316
+
246
317
#[ test]
247
318
fn test_log_ordering ( ) {
248
319
assert ! ( Level :: Error > Level :: Warn ) ;
0 commit comments