Skip to content

Commit c920e55

Browse files
committed
feat(logger): implement configurable log writer with filesystem support
* Add flexible log writer interface for multiple destinations * Implement filesystem writing capability via FilesystemLogger * Prefix LDK-based objects with 'Ldk' for consistency * Add configuration options for log file path and log level
1 parent c08c3d5 commit c920e55

24 files changed

+255
-211
lines changed

bindings/ldk_node.udl

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@ namespace ldk_node {
55

66
dictionary Config {
77
string storage_dir_path;
8-
string? log_file_path;
98
Network network;
109
sequence<SocketAddress>? listening_addresses;
1110
NodeAlias? node_alias;
1211
sequence<PublicKey> trusted_peers_0conf;
1312
u64 probing_liquidity_limit_multiplier;
14-
LogLevel log_level;
1513
AnchorChannelsConfig? anchor_channels_config;
1614
SendingParameters? sending_parameters;
1715
};
@@ -27,6 +25,20 @@ dictionary EsploraSyncConfig {
2725
u64 fee_rate_cache_update_interval_secs;
2826
};
2927

28+
enum LdkLevel {
29+
"Gossip",
30+
"Trace",
31+
"Debug",
32+
"Info",
33+
"Warn",
34+
"Error",
35+
};
36+
37+
dictionary FilesystemLoggerConfig {
38+
string log_file_path;
39+
LdkLevel level;
40+
};
41+
3042
interface Builder {
3143
constructor();
3244
[Name=from_config]
@@ -41,6 +53,7 @@ interface Builder {
4153
void set_gossip_source_rgs(string rgs_server_url);
4254
void set_liquidity_source_lsps2(SocketAddress address, PublicKey node_id, string? token);
4355
void set_storage_dir_path(string storage_dir_path);
56+
void set_filesystem_logger(FilesystemLoggerConfig fs_config);
4457
void set_network(Network network);
4558
[Throws=BuildError]
4659
void set_listening_addresses(sequence<SocketAddress> listening_addresses);
@@ -505,15 +518,6 @@ interface MaxDustHTLCExposure {
505518
FeeRateMultiplier ( u64 multiplier );
506519
};
507520

508-
enum LogLevel {
509-
"Gossip",
510-
"Trace",
511-
"Debug",
512-
"Info",
513-
"Warn",
514-
"Error",
515-
};
516-
517521
interface NetworkGraph {
518522
sequence<u64> list_channels();
519523
ChannelInfo? channel(u64 short_channel_id);

src/builder.rs

Lines changed: 52 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
// accordance with one or both of these licenses.
77

88
use crate::chain::{ChainSource, DEFAULT_ESPLORA_SERVER_URL};
9-
use crate::config::{default_user_config, Config, EsploraSyncConfig, WALLET_KEYS_SEED_LEN};
9+
use crate::config::{
10+
default_user_config, Config, EsploraSyncConfig, FilesystemLoggerConfig, WALLET_KEYS_SEED_LEN,
11+
};
1012

1113
use crate::connection::ConnectionManager;
1214
use crate::event::EventQueue;
@@ -16,7 +18,7 @@ use crate::io::sqlite_store::SqliteStore;
1618
use crate::io::utils::{read_node_metrics, write_node_metrics};
1719
use crate::io::vss_store::VssStore;
1820
use crate::liquidity::LiquiditySource;
19-
use crate::logger::{log_error, log_info, FilesystemLogger, Logger};
21+
use crate::logger::{log_error, log_info, LdkLogger, Logger};
2022
use crate::message_handler::NodeCustomMessageHandler;
2123
use crate::payment::store::PaymentStore;
2224
use crate::peer_store::PeerStore;
@@ -27,8 +29,8 @@ use crate::types::{
2729
};
2830
use crate::wallet::persist::KVStoreWalletPersister;
2931
use crate::wallet::Wallet;
32+
use crate::Node;
3033
use crate::{io, NodeMetrics};
31-
use crate::{LogLevel, Node};
3234

3335
use lightning::chain::{chainmonitor, BestBlock, Watch};
3436
use lightning::io::Cursor;
@@ -106,6 +108,17 @@ impl Default for LiquiditySourceConfig {
106108
}
107109
}
108110

111+
#[derive(Debug)]
112+
enum LogWriterConfig {
113+
File(FilesystemLoggerConfig),
114+
}
115+
116+
impl Default for LogWriterConfig {
117+
fn default() -> Self {
118+
Self::File(FilesystemLoggerConfig::default())
119+
}
120+
}
121+
109122
/// An error encountered during building a [`Node`].
110123
///
111124
/// [`Node`]: crate::Node
@@ -182,6 +195,7 @@ pub struct NodeBuilder {
182195
chain_data_source_config: Option<ChainDataSourceConfig>,
183196
gossip_source_config: Option<GossipSourceConfig>,
184197
liquidity_source_config: Option<LiquiditySourceConfig>,
198+
log_writer_config: Option<LogWriterConfig>,
185199
}
186200

187201
impl NodeBuilder {
@@ -197,12 +211,14 @@ impl NodeBuilder {
197211
let chain_data_source_config = None;
198212
let gossip_source_config = None;
199213
let liquidity_source_config = None;
214+
let log_writer_config = None;
200215
Self {
201216
config,
202217
entropy_source_config,
203218
chain_data_source_config,
204219
gossip_source_config,
205220
liquidity_source_config,
221+
log_writer_config,
206222
}
207223
}
208224

@@ -298,9 +314,9 @@ impl NodeBuilder {
298314
self
299315
}
300316

301-
/// Sets the log file path if the log file needs to live separate from the storage directory path.
302-
pub fn set_log_file_path(&mut self, log_dir_path: String) -> &mut Self {
303-
self.config.log_file_path = Some(log_dir_path);
317+
/// Configures the [`Node`] instance to write logs to the filesystem.
318+
pub fn set_filesystem_logger(&mut self, fs_config: FilesystemLoggerConfig) -> &mut Self {
319+
self.log_writer_config = Some(LogWriterConfig::File(fs_config));
304320
self
305321
}
306322

@@ -333,12 +349,6 @@ impl NodeBuilder {
333349
Ok(self)
334350
}
335351

336-
/// Sets the level at which [`Node`] will log messages.
337-
pub fn set_log_level(&mut self, level: LogLevel) -> &mut Self {
338-
self.config.log_level = level;
339-
self
340-
}
341-
342352
/// Builds a [`Node`] instance with a [`SqliteStore`] backend and according to the options
343353
/// previously configured.
344354
pub fn build(&self) -> Result<Node, BuildError> {
@@ -391,7 +401,10 @@ impl NodeBuilder {
391401
) -> Result<Node, BuildError> {
392402
use bitcoin::key::Secp256k1;
393403

394-
let logger = setup_logger(&self.config)?;
404+
let writer = LogWriterConfig::default();
405+
let log_writer_config =
406+
if let Some(config) = &self.log_writer_config { config } else { &writer };
407+
let logger = setup_logger(&log_writer_config)?;
395408

396409
let seed_bytes = seed_bytes_from_config(
397410
&self.config,
@@ -456,7 +469,10 @@ impl NodeBuilder {
456469
pub fn build_with_vss_store_and_header_provider(
457470
&self, vss_url: String, store_id: String, header_provider: Arc<dyn VssHeaderProvider>,
458471
) -> Result<Node, BuildError> {
459-
let logger = setup_logger(&self.config)?;
472+
let writer = LogWriterConfig::default();
473+
let log_writer_config =
474+
if let Some(config) = &self.log_writer_config { config } else { &writer };
475+
let logger = setup_logger(&log_writer_config)?;
460476

461477
let seed_bytes = seed_bytes_from_config(
462478
&self.config,
@@ -488,7 +504,11 @@ impl NodeBuilder {
488504

489505
/// Builds a [`Node`] instance according to the options previously configured.
490506
pub fn build_with_store(&self, kv_store: Arc<DynStore>) -> Result<Node, BuildError> {
491-
let logger = setup_logger(&self.config)?;
507+
let writer = LogWriterConfig::default();
508+
let log_writer_config =
509+
if let Some(config) = &self.log_writer_config { config } else { &writer };
510+
let logger = setup_logger(&log_writer_config)?;
511+
492512
let seed_bytes = seed_bytes_from_config(
493513
&self.config,
494514
self.entropy_source_config.as_ref(),
@@ -610,9 +630,9 @@ impl ArcedNodeBuilder {
610630
self.inner.write().unwrap().set_storage_dir_path(storage_dir_path);
611631
}
612632

613-
/// Sets the log file path if logs need to live separate from the storage directory path.
614-
pub fn set_log_file_path(&self, log_file_path: String) {
615-
self.inner.write().unwrap().set_log_file_path(log_file_path);
633+
/// Configures the [`Node`] instance to write logs to the filesystem.
634+
pub fn set_filesystem_logger(&self, fs_config: FilesystemLoggerConfig) {
635+
self.inner.write().unwrap().set_filesystem_logger(fs_config);
616636
}
617637

618638
/// Sets the Bitcoin network used.
@@ -635,11 +655,6 @@ impl ArcedNodeBuilder {
635655
self.inner.write().unwrap().set_node_alias(node_alias).map(|_| ())
636656
}
637657

638-
/// Sets the level at which [`Node`] will log messages.
639-
pub fn set_log_level(&self, level: LogLevel) {
640-
self.inner.write().unwrap().set_log_level(level);
641-
}
642-
643658
/// Builds a [`Node`] instance with a [`SqliteStore`] backend and according to the options
644659
/// previously configured.
645660
pub fn build(&self) -> Result<Arc<Node>, BuildError> {
@@ -734,7 +749,7 @@ fn build_with_store_internal(
734749
config: Arc<Config>, chain_data_source_config: Option<&ChainDataSourceConfig>,
735750
gossip_source_config: Option<&GossipSourceConfig>,
736751
liquidity_source_config: Option<&LiquiditySourceConfig>, seed_bytes: [u8; 64],
737-
logger: Arc<FilesystemLogger>, kv_store: Arc<DynStore>,
752+
logger: Arc<Logger>, kv_store: Arc<DynStore>,
738753
) -> Result<Node, BuildError> {
739754
// Initialize the status fields.
740755
let is_listening = Arc::new(AtomicBool::new(false));
@@ -1231,23 +1246,22 @@ fn build_with_store_internal(
12311246
})
12321247
}
12331248

1234-
/// Sets up the node logger, creating a new log file if it does not exist, or utilizing
1235-
/// the existing log file.
1236-
fn setup_logger(config: &Config) -> Result<Arc<FilesystemLogger>, BuildError> {
1237-
let log_file_path = match &config.log_file_path {
1238-
Some(log_dir) => String::from(log_dir),
1239-
None => format!("{}/{}", config.storage_dir_path.clone(), "ldk_node.log"),
1240-
};
1249+
/// Sets up the node logger.
1250+
fn setup_logger(config: &LogWriterConfig) -> Result<Arc<Logger>, BuildError> {
1251+
match config {
1252+
LogWriterConfig::File(fs_logger_config) => {
1253+
let log_file_path = &fs_logger_config.log_file_path;
12411254

1242-
Ok(Arc::new(
1243-
FilesystemLogger::new(log_file_path, config.log_level)
1244-
.map_err(|_| BuildError::LoggerSetupFailed)?,
1245-
))
1255+
Ok(Arc::new(
1256+
Logger::new_fs_writer(log_file_path.to_string(), fs_logger_config.level)
1257+
.map_err(|_| BuildError::LoggerSetupFailed)?,
1258+
))
1259+
},
1260+
}
12461261
}
12471262

12481263
fn seed_bytes_from_config(
1249-
config: &Config, entropy_source_config: Option<&EntropySourceConfig>,
1250-
logger: Arc<FilesystemLogger>,
1264+
config: &Config, entropy_source_config: Option<&EntropySourceConfig>, logger: Arc<Logger>,
12511265
) -> Result<[u8; 64], BuildError> {
12521266
match entropy_source_config {
12531267
Some(EntropySourceConfig::SeedBytes(bytes)) => Ok(bytes.clone()),
@@ -1269,7 +1283,7 @@ fn seed_bytes_from_config(
12691283
}
12701284

12711285
fn derive_vss_xprv(
1272-
config: Arc<Config>, seed_bytes: &[u8; 64], logger: Arc<FilesystemLogger>,
1286+
config: Arc<Config>, seed_bytes: &[u8; 64], logger: Arc<Logger>,
12731287
) -> Result<Xpriv, BuildError> {
12741288
use bitcoin::key::Secp256k1;
12751289

src/chain/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::fee_estimator::{
2121
ConfirmationTarget, OnchainFeeEstimator,
2222
};
2323
use crate::io::utils::write_node_metrics;
24-
use crate::logger::{log_bytes, log_error, log_info, log_trace, FilesystemLogger, Logger};
24+
use crate::logger::{log_bytes, log_error, log_info, log_trace, LdkLogger, Logger};
2525
use crate::types::{Broadcaster, ChainMonitor, ChannelManager, DynStore, Sweeper, Wallet};
2626
use crate::{Error, NodeMetrics};
2727

@@ -112,13 +112,13 @@ pub(crate) enum ChainSource {
112112
esplora_client: EsploraAsyncClient,
113113
onchain_wallet: Arc<Wallet>,
114114
onchain_wallet_sync_status: Mutex<WalletSyncStatus>,
115-
tx_sync: Arc<EsploraSyncClient<Arc<FilesystemLogger>>>,
115+
tx_sync: Arc<EsploraSyncClient<Arc<Logger>>>,
116116
lightning_wallet_sync_status: Mutex<WalletSyncStatus>,
117117
fee_estimator: Arc<OnchainFeeEstimator>,
118118
tx_broadcaster: Arc<Broadcaster>,
119119
kv_store: Arc<DynStore>,
120120
config: Arc<Config>,
121-
logger: Arc<FilesystemLogger>,
121+
logger: Arc<Logger>,
122122
node_metrics: Arc<RwLock<NodeMetrics>>,
123123
},
124124
BitcoindRpc {
@@ -131,7 +131,7 @@ pub(crate) enum ChainSource {
131131
tx_broadcaster: Arc<Broadcaster>,
132132
kv_store: Arc<DynStore>,
133133
config: Arc<Config>,
134-
logger: Arc<FilesystemLogger>,
134+
logger: Arc<Logger>,
135135
node_metrics: Arc<RwLock<NodeMetrics>>,
136136
},
137137
}
@@ -140,7 +140,7 @@ impl ChainSource {
140140
pub(crate) fn new_esplora(
141141
server_url: String, sync_config: EsploraSyncConfig, onchain_wallet: Arc<Wallet>,
142142
fee_estimator: Arc<OnchainFeeEstimator>, tx_broadcaster: Arc<Broadcaster>,
143-
kv_store: Arc<DynStore>, config: Arc<Config>, logger: Arc<FilesystemLogger>,
143+
kv_store: Arc<DynStore>, config: Arc<Config>, logger: Arc<Logger>,
144144
node_metrics: Arc<RwLock<NodeMetrics>>,
145145
) -> Self {
146146
let mut client_builder = esplora_client::Builder::new(&server_url);
@@ -170,7 +170,7 @@ impl ChainSource {
170170
host: String, port: u16, rpc_user: String, rpc_password: String,
171171
onchain_wallet: Arc<Wallet>, fee_estimator: Arc<OnchainFeeEstimator>,
172172
tx_broadcaster: Arc<Broadcaster>, kv_store: Arc<DynStore>, config: Arc<Config>,
173-
logger: Arc<FilesystemLogger>, node_metrics: Arc<RwLock<NodeMetrics>>,
173+
logger: Arc<Logger>, node_metrics: Arc<RwLock<NodeMetrics>>,
174174
) -> Self {
175175
let bitcoind_rpc_client =
176176
Arc::new(BitcoindRpcClient::new(host, port, rpc_user, rpc_password));
@@ -1123,7 +1123,7 @@ impl Filter for ChainSource {
11231123

11241124
fn periodically_archive_fully_resolved_monitors(
11251125
channel_manager: Arc<ChannelManager>, chain_monitor: Arc<ChainMonitor>,
1126-
kv_store: Arc<DynStore>, logger: Arc<FilesystemLogger>, node_metrics: Arc<RwLock<NodeMetrics>>,
1126+
kv_store: Arc<DynStore>, logger: Arc<Logger>, node_metrics: Arc<RwLock<NodeMetrics>>,
11271127
) -> Result<(), Error> {
11281128
let mut locked_node_metrics = node_metrics.write().unwrap();
11291129
let cur_height = channel_manager.current_best_block().height;

0 commit comments

Comments
 (0)