Skip to content

Commit

Permalink
Move Dart & UniFFI loggers back to their respective places
Browse files Browse the repository at this point in the history
  • Loading branch information
erdemyerebasmaz committed Nov 5, 2024
1 parent 48c1ea8 commit 8f661bb
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 152 deletions.
1 change: 1 addition & 0 deletions libs/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions libs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ version = "0.6.2"
aes = "0.8"
anyhow = { version = "1.0.79", features = ["backtrace"] }
base64 = "0.13.0"
env_logger = "0.10"
bitcoin = "=0.29.2" # Same version as used in gl-client
# Pin the reqwest dependency until macOS linker issue is fixed: https://github.com/seanmonstar/reqwest/issues/2006
hex = "0.4"
Expand Down
1 change: 1 addition & 0 deletions libs/sdk-bindings/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ crate-type = ["staticlib", "cdylib", "lib"]
anyhow = { workspace = true }
breez-sdk-core = { path = "../sdk-core" }
sdk-common = { path = "../sdk-common" }
env_logger = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true }
uniffi = { version = "0.23.0", features = ["bindgen-tests", "cli"] }
Expand Down
68 changes: 67 additions & 1 deletion libs/sdk-bindings/src/uniffi_binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::sync::Arc;

use anyhow::Result;
use breez_sdk_core::lnurl::pay::{LnUrlPayResult, LnUrlPaySuccessData};
use breez_sdk_core::logger::init_uniffi_logger;
use breez_sdk_core::logger::{get_filter_level, init_env_logger};
use breez_sdk_core::{
error::*, mnemonic_to_seed as sdk_mnemonic_to_seed, parse as sdk_parse_input,
parse_invoice as sdk_parse_invoice, AesSuccessActionDataDecrypted, AesSuccessActionDataResult,
Expand Down Expand Up @@ -32,10 +32,76 @@ use breez_sdk_core::{
SwapAmountType, SwapInfo, SwapStatus, Symbol, TlvEntry, UnspentTransactionOutput,
UrlSuccessActionData,
};
use env_logger::{Logger, Target};
use log::{
error, max_level, set_boxed_logger, set_max_level, Log, Metadata, Record, STATIC_MAX_LEVEL,
};
use once_cell::sync::Lazy;
use std::sync::Once;

static RT: Lazy<tokio::runtime::Runtime> = Lazy::new(|| tokio::runtime::Runtime::new().unwrap());

/* UniFFI Logger */

static INIT_UNIFFI_LOGGER: Once = Once::new();

fn init_uniffi_logger(log_stream: Box<dyn LogStream>, filter_level: Option<LevelFilter>) {
INIT_UNIFFI_LOGGER.call_once(|| {
UniFFILogger::set_log_stream(log_stream, filter_level);
});
}

struct UniFFILogger {
env_logger: Logger,
log_stream: Box<dyn LogStream>,
}

impl UniFFILogger {
fn set_log_stream(log_stream: Box<dyn LogStream>, filter_level: Option<LevelFilter>) {
let filter_level = get_filter_level(filter_level);
assert!(
filter_level <= STATIC_MAX_LEVEL,
"Should respect STATIC_MAX_LEVEL={:?}, which is done in compile time. level{:?}",
STATIC_MAX_LEVEL,
filter_level
);

let env_logger = init_env_logger(Some(Target::Stdout), Some(filter_level));

let uniffi_logger = UniFFILogger {
env_logger,
log_stream,
};
set_boxed_logger(Box::new(uniffi_logger))
.unwrap_or_else(|_| error!("Log stream already created."));
set_max_level(filter_level);
}

fn record_to_entry(record: &Record) -> LogEntry {
LogEntry {
line: format!("{}", record.args()),
level: format!("{}", record.level()),
}
}
}

impl Log for UniFFILogger {
fn enabled(&self, metadata: &Metadata) -> bool {
// ignore the internal uniffi log to prevent infinite loop.
return metadata.level() <= max_level()
&& *metadata.target() != *"breez_sdk_bindings::uniffi_binding";
}

fn log(&self, record: &Record) {
let metadata = record.metadata();
if self.enabled(metadata) && self.env_logger.enabled(metadata) {
let entry = Self::record_to_entry(record);
self.log_stream.log(entry);
}
}
fn flush(&self) {}
}

/// Create a new SDK config with default values
pub fn default_config(
env_type: EnvironmentType,
Expand Down
2 changes: 1 addition & 1 deletion libs/sdk-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ zbase32 = "0.1.2"
base64 = { workspace = true }
chrono = "0.4"
ecies = { version = "0.2.6", default-features = false, features = ["pure"] }
env_logger = "0.10"
env_logger = { workspace = true }
futures = "0.3.30"
ripemd = "0.1"
rand = "0.8"
Expand Down
95 changes: 87 additions & 8 deletions libs/sdk-core/src/binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,103 @@ use crate::error::{
ConnectError, ReceiveOnchainError, ReceivePaymentError, RedeemOnchainError, SdkError,
SendOnchainError, SendPaymentError,
};
use crate::logger::{init_dart_logger, DartLogger};
use crate::logger::{get_filter_level, init_env_logger};
use crate::lsp::LspInformation;
use crate::models::{Config, LogEntry, NodeState, Payment, SwapInfo};
use crate::models::{Config, LevelFilter, LogEntry, NodeState, Payment, SwapInfo};
use crate::{
BackupStatus, BuyBitcoinRequest, BuyBitcoinResponse, CheckMessageRequest, CheckMessageResponse,
ConfigureNodeRequest, ConnectRequest, EnvironmentType, LevelFilter, ListPaymentsRequest,
LnUrlAuthError, MaxReverseSwapAmountResponse, NodeConfig, NodeCredentials,
OnchainPaymentLimitsResponse, OpenChannelFeeRequest, OpenChannelFeeResponse, PayOnchainRequest,
PayOnchainResponse, PrepareOnchainPaymentRequest, PrepareOnchainPaymentResponse,
PrepareRedeemOnchainFundsRequest, PrepareRedeemOnchainFundsResponse, PrepareRefundRequest,
PrepareRefundResponse, ReceiveOnchainRequest, ReceivePaymentRequest, ReceivePaymentResponse,
ConfigureNodeRequest, ConnectRequest, EnvironmentType, ListPaymentsRequest, LnUrlAuthError,
MaxReverseSwapAmountResponse, NodeConfig, NodeCredentials, OnchainPaymentLimitsResponse,
OpenChannelFeeRequest, OpenChannelFeeResponse, PayOnchainRequest, PayOnchainResponse,
PrepareOnchainPaymentRequest, PrepareOnchainPaymentResponse, PrepareRedeemOnchainFundsRequest,
PrepareRedeemOnchainFundsResponse, PrepareRefundRequest, PrepareRefundResponse,
ReceiveOnchainRequest, ReceivePaymentRequest, ReceivePaymentResponse,
RedeemOnchainFundsRequest, RedeemOnchainFundsResponse, RefundRequest, RefundResponse,
ReportIssueRequest, ReverseSwapFeesRequest, ReverseSwapInfo, ReverseSwapPairInfo,
SendOnchainRequest, SendOnchainResponse, SendPaymentRequest, SendPaymentResponse,
SendSpontaneousPaymentRequest, ServiceHealthCheckResponse, SignMessageRequest,
SignMessageResponse, StaticBackupRequest, StaticBackupResponse,
};

use lazy_static::lazy_static;
use log::{
max_level, set_boxed_logger, set_max_level, warn, Log, Metadata, Record, STATIC_MAX_LEVEL,
};
use parking_lot::RwLock;
use std::sync::Once;

use env_logger::{Logger, Target};

/* Dart Logger */

static INIT_DART_LOGGER: Once = Once::new();

fn init_dart_logger(filter_level: Option<LevelFilter>) {
INIT_DART_LOGGER.call_once(|| {
let filter_level = get_filter_level(filter_level);

assert!(
filter_level <= STATIC_MAX_LEVEL,
"Should respect STATIC_MAX_LEVEL={:?}, which is done in compile time. level{:?}",
STATIC_MAX_LEVEL,
filter_level
);

let env_logger = init_env_logger(Some(Target::Stdout), Some(filter_level));

let dart_logger = DartLogger { env_logger };
set_boxed_logger(Box::new(dart_logger))
.unwrap_or_else(|_| error!("Log stream already created."));
set_max_level(filter_level);
});
}

lazy_static! {
static ref DART_LOGGER_STREAM_SINK: RwLock<Option<StreamSink<LogEntry>>> = RwLock::new(None);
}

struct DartLogger {
env_logger: Logger,
}

impl DartLogger {
fn set_stream_sink(stream_sink: StreamSink<LogEntry>) {
let mut guard = DART_LOGGER_STREAM_SINK.write();
if guard.is_some() {
warn!(
"BindingLogger::set_stream_sink but already exist a sink, thus overriding. \
(This may or may not be a problem. It will happen normally if hot-reload Flutter app.)"
);
}
*guard = Some(stream_sink);
drop(guard)
}

fn record_to_entry(record: &Record) -> LogEntry {
LogEntry {
line: format!("{}", record.args()),
level: format!("{}", record.level()),
}
}
}

impl Log for DartLogger {
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= max_level()
}

fn log(&self, record: &Record) {
if self.env_logger.enabled(record.metadata()) {
let entry = Self::record_to_entry(record);
if let Some(sink) = &*DART_LOGGER_STREAM_SINK.read() {
sink.add(entry);
}
}
}

fn flush(&self) {}
}

// === FRB mirroring
//
// This section contains frb "mirroring" structs and enums.
Expand Down
Loading

0 comments on commit 8f661bb

Please sign in to comment.