/* This file is part of DarkFi (https://dark.fi) * * Copyright (C) 2020-2026 Dyne.org foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ use tracing_appender::non_blocking::WorkerGuard; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, Layer, Registry}; #[cfg(feature = "enable-filelog")] use { file_rotate::{compression::Compression, suffix::AppendCount, ContentLimit, FileRotate}, std::path::PathBuf, }; #[cfg(target_os = "android")] use tracing_subscriber::filter::{LevelFilter, Targets}; #[cfg(any(not(target_os = "android"), feature = "enable-filelog"))] use { darkfi::util::logger::{EventFormatter, Level, TargetFilter}, //tracing_subscriber::fmt::format::FmtSpan, }; // Measured in bytes #[cfg(feature = "enable-filelog")] const LOGFILE_MAXSIZE: usize = 5_000_000; static MUTED_TARGETS: &[&'static str] = &[ "sled", "rustls", "async_io", "polling", "net::channel", "net::message_publisher", "net::hosts", "net::protocol", "net::session", "net::outbound_session", "net::tcp", "net::p2p::seed", "net::refinery::handshake_node()", "system::publisher", "event_graph::dag_sync()", "event_graph::dag_insert()", "event_graph::protocol", ]; #[cfg(not(target_os = "android"))] static ALLOW_TRACE: &[&'static str] = &["ui", "app", "gfx"]; #[cfg(all(target_os = "android", feature = "enable-filelog"))] fn logfile_path() -> PathBuf { use crate::android::get_external_storage_path; get_external_storage_path().join("darkfi-app.log") } #[cfg(all(not(target_os = "android"), feature = "enable-filelog"))] fn logfile_path() -> PathBuf { dirs::cache_dir().unwrap().join("darkfi/darkfi-app.log") } pub fn setup_logging() -> Option { let mut layers: Vec<(Box + Send + Sync>, Option)> = vec![]; #[cfg(feature = "enable-filelog")] { let (non_blocking_file_rotate, guard) = tracing_appender::non_blocking(FileRotate::new( logfile_path(), AppendCount::new(0), ContentLimit::BytesSurpassed(LOGFILE_MAXSIZE), Compression::None, #[cfg(unix)] None, )); let file_layer = tracing_subscriber::fmt::Layer::new() .event_format(EventFormatter::new(false, true)) .fmt_fields(tracing_subscriber::fmt::format::debug_fn( darkfi::util::logger::file_field_formatter, )) .with_writer(non_blocking_file_rotate) .with_filter( TargetFilter::default() .ignore_targets(["sled", "rustls", "async_io", "polling"]) .default_level(Level::Trace), ); layers.push((file_layer.boxed(), Some(guard))); } #[cfg(target_os = "android")] { let logcat_layer = tracing_android::layer("darkfi").expect("tracing_android layer").with_filter( Targets::new() .with_targets( crate::logger::MUTED_TARGETS.iter().map(|&t| (t, LevelFilter::OFF)), ) .with_default(LevelFilter::TRACE), ); layers.push((logcat_layer.boxed(), None)); } #[cfg(not(target_os = "android"))] { let terminal_layer = tracing_subscriber::fmt::Layer::new() //.with_span_events(FmtSpan::ENTER | FmtSpan::CLOSE) .event_format(EventFormatter::new(true, true)) .fmt_fields(tracing_subscriber::fmt::format::debug_fn( darkfi::util::logger::terminal_field_formatter, )) .with_writer(std::io::stdout) .with_filter( TargetFilter::default() .targets_level(ALLOW_TRACE, Level::Trace) .targets_level(MUTED_TARGETS, Level::Info) .default_level(Level::Debug), ); layers.push((terminal_layer.boxed(), None)); } let file_logging_guard = layers.iter_mut().find_map(|l| l.1.take()); Registry::default() .with(layers.into_iter().map(|l| l.0).collect::>()) .try_init() .expect("logger"); file_logging_guard }