@@ -12,19 +12,50 @@ use lightning::util::logger::{Level, Record};
1212
1313use chrono:: Utc ;
1414
15+ use std:: fmt:: Debug ;
1516use std:: fs;
1617use std:: io:: Write ;
1718#[ cfg( not( target_os = "windows" ) ) ]
1819use std:: os:: unix:: fs:: symlink;
1920use std:: path:: Path ;
21+ use std:: sync:: Mutex ;
2022
21- pub ( crate ) struct LdkNodeLogger {
22- file_path : String ,
23+ pub struct LdkNodeLogger {
2324 level : Level ,
25+ formatter : Box < dyn Fn ( & Record ) -> String + Send + Sync > ,
26+ writer : Box < dyn Fn ( & String ) + Send + Sync > ,
2427}
2528
2629impl LdkNodeLogger {
27- pub ( crate ) fn new ( log_dir : String , level : Level ) -> Result < Self , ( ) > {
30+ pub fn new (
31+ level : Level , formatter : Box < dyn Fn ( & Record ) -> String + Send + Sync > ,
32+ writer : Box < dyn Fn ( & String ) + Send + Sync > ,
33+ ) -> Result < Self , ( ) > {
34+ Ok ( Self { level, formatter, writer } )
35+ }
36+ }
37+
38+ impl Debug for LdkNodeLogger {
39+ fn fmt ( & self , f : & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
40+ write ! ( f, "LdkNodeLogger level: {}" , self . level)
41+ }
42+ }
43+
44+ impl Logger for LdkNodeLogger {
45+ fn log ( & self , record : Record ) {
46+ if record. level < self . level {
47+ return ;
48+ }
49+ ( self . writer ) ( & ( self . formatter ) ( & record) )
50+ }
51+ }
52+
53+ pub ( crate ) struct FilesystemLogWriter {
54+ log_file : Mutex < fs:: File > ,
55+ }
56+
57+ impl FilesystemLogWriter {
58+ pub fn new ( log_dir : String ) -> Result < Self , ( ) > {
2859 let log_file_name =
2960 format ! ( "ldk_node_{}.log" , chrono:: offset:: Local :: now( ) . format( "%Y_%m_%d" ) ) ;
3061 let log_file_path = format ! ( "{}/{}" , log_dir, log_file_name) ;
@@ -53,29 +84,33 @@ impl LdkNodeLogger {
5384 }
5485 }
5586
56- Ok ( Self { file_path : log_file_path, level } )
57- }
58- }
59- impl Logger for LdkNodeLogger {
60- fn log ( & self , record : Record ) {
61- if record. level < self . level {
62- return ;
63- }
64- let raw_log = record. args . to_string ( ) ;
65- let log = format ! (
66- "{} {:<5} [{}:{}] {}\n " ,
67- Utc :: now( ) . format( "%Y-%m-%d %H:%M:%S" ) ,
68- record. level. to_string( ) ,
69- record. module_path,
70- record. line,
71- raw_log
87+ let log_file = Mutex :: new (
88+ fs:: OpenOptions :: new ( )
89+ . create ( true )
90+ . append ( true )
91+ . open ( log_file_path. clone ( ) )
92+ . map_err ( |e| eprintln ! ( "ERROR: Failed to open log file: {}" , e) ) ?,
7293 ) ;
73- fs:: OpenOptions :: new ( )
74- . create ( true )
75- . append ( true )
76- . open ( self . file_path . clone ( ) )
77- . expect ( "Failed to open log file" )
94+ Ok ( Self { log_file } )
95+ }
96+
97+ pub fn write ( & self , log : & String ) {
98+ self . log_file
99+ . lock ( )
100+ . expect ( "log file lock poisoned" )
78101 . write_all ( log. as_bytes ( ) )
79102 . expect ( "Failed to write to log file" )
80103 }
81104}
105+
106+ pub ( crate ) fn default_format ( record : & Record ) -> String {
107+ let raw_log = record. args . to_string ( ) ;
108+ format ! (
109+ "{} {:<5} [{}:{}] {}\n " ,
110+ Utc :: now( ) . format( "%Y-%m-%d %H:%M:%S" ) ,
111+ record. level. to_string( ) ,
112+ record. module_path,
113+ record. line,
114+ raw_log
115+ )
116+ }
0 commit comments