-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add customizable logging system #401
Conversation
1. Rename FilesystemLogger to LdkNodeLogger. 2. Make LdkNodeLogger technically customizable, retain default behavior. 3. Add customizable logging to configuration.
1. Remove left-over log_dir & log_file_path related fields from Config 2. Rename log_dir to log_file_path 3. Update the creation of new FileWriter to handle recursive parent directory 4. Fix integration tests
- Creates a LogWriter interface for different writers to write logs to their preferred destinations. These destinations could be either the filesystem or another logger (e.g. custom logger or any that implements log's facade. - The writer and formatter of LdkNodeLogger can be created by configurable options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for looking into this! Here is a first round of comments.
Generally, I would have preferred a clean start rather than basing it off #393, since, as discussed there, the chosen approach isn't really bindings compatible and breaks a few of our LDK Node-internal preexisting idioms. That said, happy to continue the work in this PR. However, please try to ensure to have commits be discrete changes that always compile, and if possible avoid touching parts of the code again in later commits as it makes reviewing and understanding whats going a lot harder. To this end, you might want to squash and then split out commits for the custom writer and log
parts.
|
||
pub(crate) struct FilesystemLogger { | ||
file_path: String, | ||
pub struct LdkNodeLogger { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's drop the LdkNode
prefix please, as we also don't prefix other objects. This could just be Logger
(although that would mean we'd need to refer to the upstream trait as LdkLogger
as we do with others, e.g., LdkFeeEstimator
), or find another suitable name that capture its properties.
src/logger.rs
Outdated
level: Level, | ||
formatter: Box<dyn Fn(&Record) -> String + Send + Sync>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if it's worth introducing a separate heap object for this. Let's just not for now, and re-add it if we really find use for it.
src/config.rs
Outdated
@@ -108,6 +109,9 @@ pub struct Config { | |||
/// If set to `None`, logs can be found in `ldk_node.log` in the [`Config::storage_dir_path`] | |||
/// directory. | |||
pub log_file_path: Option<String>, | |||
/// In the default configuration logs can be found in the `logs` subdirectory in | |||
/// [`Config::storage_dir_path`], and the log level is set to [`DEFAULT_LOG_LEVEL`]. | |||
pub logging_config: LoggingConfig, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned in the original PR, we can't do this as it likely won't be really compatible with bindings and also doesn't match how we handle other things.
Rather, we'd need to add three builder methods to allow configuring the three modes:
a) set_logger_file
/set_logger_filesystem
taking a FilesystemLogger
config object allowing to set loglevel and path (also exposed in the bindings builder)
b) set_logger_facade
to use the log
facade
c) set_logger_custom
taking an Arc<dyn LogWriter + Send + Sync>
(also exposed in the bindings builder)
That said, we'd likely want to keep something like LoggingConfig
as an internal config object, similar to ChainSourceConfig
, EntropySourceConfig
, etc.
That is, the API would be controlled by Builder
methods, but the 'state' is kept in that object and used to setup in Builder::build
.
src/config.rs
Outdated
@@ -108,6 +109,9 @@ pub struct Config { | |||
/// If set to `None`, logs can be found in `ldk_node.log` in the [`Config::storage_dir_path`] | |||
/// directory. | |||
pub log_file_path: Option<String>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be dropped/moved, too, as it only makes sense for the filesystem writer.
src/logger.rs
Outdated
level: Level, | ||
formatter: Box<dyn Fn(&Record) -> String + Send + Sync>, | ||
writer: Box<dyn Fn(&String) + Send + Sync>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to expose a LogWriter
trait that can be used for custom loggers exposed via bindings (see https://mozilla.github.io/uniffi-rs/0.27/udl/interfaces.html#exposing-traits-as-interfaces)
|
||
/// Log writer configuration type. | ||
#[derive(Debug, Clone)] | ||
pub enum WriterType { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this the internal config object mentioned above, but it should live in builder.rs
and should be named accordingly (e.g., LoggingConfig
, LogWriterConfig
, etc.).
impl FileWriterConfig { | ||
/// Creates a new configuration given the path to the log file | ||
/// and the log level. | ||
pub fn new(log_file_path: &str, level: Level) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't need a constructor.
#[derive(Debug, Clone)] | ||
pub struct CustomWriterConfig { | ||
/// Pointer to any custom log writer. | ||
pub inner: Arc<dyn LogWriter + Send + Sync>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't live in the public API config object, but just as a field in the (to be renamed) WriterType
.
/// Pointer to any custom log writer. | ||
pub inner: Arc<dyn LogWriter + Send + Sync>, | ||
/// Specifies the log level. | ||
pub level: Level, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't the custom writer decide how to filter for level? I.e., do we really need CustomWriterConfig
at all?
@@ -26,6 +26,7 @@ panic = 'abort' # Abort on panic | |||
|
|||
[features] | |||
default = [] | |||
log_relay = ["log"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't use any features in LDK Node so far (mostly to keep ~feature-parity of the Rust vs bindings API, for which everything needs to be configurable via the Builder
), so please drop this and just take a non-optional dependency on log
for now.
Closing this because, given the feedback, I also think it's best to have a clean slate. #407 addresses all the concerns here. |
Summary
This PR builds on #393 to add a customizable logging system.
What this PR does
Introduces a
LogWriter
interface, allowingWriter
variants to handle log output destinations. The supportedWriter
variants can now:log
Makes
Writer
variants configurable.Expose
LogWriter
to bindings (pending).Test logging to different destinations.
Related Issue
logger
interface #309