breez_sdk_liquid/
logger.rs1use std::fs::OpenOptions;
2use std::io::Write;
3
4use anyhow::{anyhow, Result};
5use chrono::Local;
6use log::{LevelFilter, Metadata, Record};
7
8use crate::model::LogEntry;
9
10pub(crate) struct GlobalSdkLogger {
11 pub(crate) logger: env_logger::Logger,
13 pub(crate) log_listener: Option<Box<dyn log::Log>>,
15}
16impl log::Log for GlobalSdkLogger {
17 fn enabled(&self, metadata: &Metadata) -> bool {
18 metadata.level() <= log::Level::Trace
19 }
20
21 fn log(&self, record: &Record) {
22 if self.enabled(record.metadata()) {
23 self.logger.log(record);
24
25 if let Some(s) = &self.log_listener.as_ref() {
26 if s.enabled(record.metadata()) {
27 s.log(record);
28 }
29 }
30 }
31 }
32
33 fn flush(&self) {}
34}
35
36pub(super) fn init_logging(log_dir: &str, app_logger: Option<Box<dyn log::Log>>) -> Result<()> {
37 let target_log_file = Box::new(
38 OpenOptions::new()
39 .create(true)
40 .append(true)
41 .open(format!("{log_dir}/sdk.log"))
42 .map_err(|e| anyhow!("Can't create log file: {e}"))?,
43 );
44 let logger = env_logger::Builder::new()
45 .target(env_logger::Target::Pipe(target_log_file))
46 .parse_filters(
47 r#"
48 debug,
49 breez_sdk_liquid=debug,
50 breez_sdk_liquid::swapper::boltz_status_stream=info,
51 electrum_client::raw_client=warn,
52 lwk_wollet=info,
53 rustls=warn,
54 rustyline=warn,
55 ureq=info,
56 tungstenite=warn
57 "#,
58 )
59 .format(|buf, record| {
60 writeln!(
61 buf,
62 "[{} {} {}:{}] {}",
63 Local::now().format("%Y-%m-%d %H:%M:%S%.3f"),
64 record.level(),
65 record.module_path().unwrap_or("unknown"),
66 record.line().unwrap_or(0),
67 record.args()
68 )
69 })
70 .build();
71
72 let global_logger = GlobalSdkLogger {
73 logger,
74 log_listener: app_logger,
75 };
76
77 log::set_boxed_logger(Box::new(global_logger))
78 .map_err(|e| anyhow!("Failed to set global logger: {e}"))?;
79 log::set_max_level(LevelFilter::Trace);
80
81 Ok(())
82}
83
84pub trait Logger: Send + Sync {
85 fn log(&self, l: LogEntry);
86}