Skip to content
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

Closed

Conversation

enigbe
Copy link
Contributor

@enigbe enigbe commented Nov 12, 2024

Summary

This PR builds on #393 to add a customizable logging system.

What this PR does

  • Introduces a LogWriter interface, allowing Writer variants to handle log output destinations. The supported Writer variants can now:

    • Write logs to the filesystem,
    • Optionally forward to log
    • Relay logs to a custom logger.
  • Makes Writer variants configurable.

  • Expose LogWriter to bindings (pending).

  • Test logging to different destinations.

Related Issue

domZippilli and others added 4 commits November 12, 2024 08:11
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.
@enigbe enigbe changed the title feat: customizable logging system feat: add customizable logging system Nov 12, 2024
Copy link
Collaborator

@tnull tnull left a 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 {
Copy link
Collaborator

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>,
Copy link
Collaborator

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,
Copy link
Collaborator

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>,
Copy link
Collaborator

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>,
Copy link
Collaborator

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 {
Copy link
Collaborator

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 {
Copy link
Collaborator

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>,
Copy link
Collaborator

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,
Copy link
Collaborator

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"]
Copy link
Collaborator

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.

@enigbe enigbe mentioned this pull request Nov 20, 2024
8 tasks
@enigbe
Copy link
Contributor Author

enigbe commented Nov 20, 2024

Closing this because, given the feedback, I also think it's best to have a clean slate. #407 addresses all the concerns here.

@enigbe enigbe closed this Nov 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants