@@ -18,6 +18,7 @@ use bitcoin::secp256k1::PublicKey;
1818
1919use core:: cmp;
2020use core:: fmt;
21+ use core:: ops:: Deref ;
2122
2223use crate :: ln:: ChannelId ;
2324#[ cfg( c_bindings) ]
@@ -152,6 +153,39 @@ pub trait Logger {
152153 fn log ( & self , record : Record ) ;
153154}
154155
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+
155189/// Wrapper for logging a [`PublicKey`] in hex format.
156190///
157191/// 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
202236
203237#[ cfg( test) ]
204238mod 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 } ;
206242 use crate :: util:: test_utils:: TestLogger ;
207243 use crate :: sync:: Arc ;
208244
@@ -243,6 +279,41 @@ mod tests {
243279 wrapper. call_macros ( ) ;
244280 }
245281
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+
246317 #[ test]
247318 fn test_log_ordering ( ) {
248319 assert ! ( Level :: Error > Level :: Warn ) ;
0 commit comments