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

Add configurable logging system #407

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

enigbe
Copy link
Contributor

@enigbe enigbe commented Nov 20, 2024

Overview

This PR introduces a flexible logging system for LDK Node by implementing a LogWriter interface that supports writing logs to different destinations.

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,
    • Forward to a log implementer,
    • Relay logs to a custom logger.
  • Exposes LogWriter to bindings.
  • Test logging to different destinations with:
    • In-memory log logger,
    • In-memory LogWriter logger.

Related Issue(s)

@enigbe enigbe mentioned this pull request Nov 20, 2024
7 tasks
@G8XSU G8XSU requested a review from tnull November 21, 2024 18:37
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.

Cool, thank you for looking into this! This already looks pretty good, but I have some comments after the first round of review.

@@ -27,6 +25,20 @@ dictionary EsploraSyncConfig {
u64 fee_rate_cache_update_interval_secs;
};

enum LdkLevel {
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 leave this as LogLevel. I don't think we want to start prefixing any of the types we expose in the API with Ldk. The prefix is really only used internally when we want to introduce a local type with the same name as an LDK type.


dictionary FilesystemLoggerConfig {
string log_file_path;
LdkLevel level;
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 also call the field here log_level.

@@ -28,13 +28,11 @@ class AndroidLibTest {
config1.storageDirPath = tmpDir1
config1.listeningAddresses = listOf(listenAddress1)
config1.network = Network.REGTEST
config1.logLevel = LogLevel.TRACE
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we still set TRACE level, just by the new means?

Cargo.toml Outdated
@@ -75,6 +75,7 @@ libc = "0.2"
uniffi = { version = "0.27.3", features = ["build"], optional = true }
serde = { version = "1.0.210", default-features = false, features = ["std", "derive"] }
serde_json = { version = "1.0.128", default-features = false, features = ["std"] }
log = { version = "0.4.22", features = ["std"]}
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 add default-features = false here and only include the features we really need.

src/builder.rs Outdated
let logger = setup_logger(&self.config)?;
let writer = LogWriterConfig::default();
let log_writer_config =
if let Some(config) = &self.log_writer_config { config } else { &writer };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should be able to just use unwrap_or_default() here.

src/logger.rs Outdated
pub(crate) enum Writer {
/// Writes logs to the file system.
FileWriter(FilesystemLogger),
/// Forwards logs to the `log` facade.
LogFacadeWriter(LogFacadeLogger),
/// Forwards logs to custom writer.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: s/custom writer/a custom writer/

}

/// Simple in-memory mock `log` logger for tests.
#[derive(Debug)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this Debug?

@@ -271,9 +274,18 @@ impl MockLogger {
}
}

/// [`MockLogger`] as `log` logger - destination for [`Writer::LogFacadeWriter`]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to belong in a different commit? Also, let's not add documents on trait implementations (internal ones in particular).

@@ -828,13 +831,16 @@ fn generate_bip21_uri() {
},
Err(e) => panic!("Failed to generate URI: {:?}", e),
}

assert!(mock_logger.retrieve_logs().last().unwrap().contains("Invoice created: lnbcrt"));
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 above: please avoid such potentially-flaky asserts. Also, we should really be testing the log facade separately instead of sprinkling in these asserts to unrelated testcases.

}

#[test]
fn unified_qr_send_receive() {
let (bitcoind, electrsd) = setup_bitcoind_and_electrsd();
let chain_source = TestChainSource::Esplora(&electrsd);

// Setup `log` facade logger.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same goes for arbitrary comments: please only add comments where they add to the context. Comments like this don't provide additional information over just reading the next line, they just increase the (visual) noise when reading code.

@tnull
Copy link
Collaborator

tnull commented Dec 9, 2024

@enigbe Is there any update on this? Please let me know if you're hitting any blockers.

This seems to need a minor rebase by now.

@enigbe
Copy link
Contributor Author

enigbe commented Dec 10, 2024

No blockers on this. I'll be pushing updates later today.

* 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
* Add support for user-provided custom logger to
  write logs to, allowing users to provide any logger
  that implements LogWriter
* Add test to cover this use case, implementing Log-
  Writer for the mock, in-memory MockLogger.
@enigbe enigbe force-pushed the 2024-11-configurable-logging-system branch from 1d57cab to d8eb0e1 Compare December 11, 2024 12:18
This commit includes several improvements aimed at simplifying code, improving readability, and optimizing performance:

- Inline enum struct fields to reduce indirection and clutter.
- Rename structs to improve clarity and better reflect their purpose.
- Enable specific feature flags in dependencies for a more streamlined build.
- Eliminate unnecessary data allocations to optimize memory usage.
- Correct minor grammatical error in documentation.
- allocates Strings only when necessary with `uniffi` feature,
  otherwise, keeps LogRecord fileds as lifetime references.
This commit adds a CustomLogWriter class to the kotlin library
test, configuring the writer via the exposed node builder and tests
the ability to log to the custom writer destination.

[WIP]
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.

2 participants