logger.rs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. use file_rotate::{compression::Compression, suffix::AppendCount, ContentLimit, FileRotate};
  2. use log::{Level, LevelFilter, Log, Metadata, Record};
  3. use simplelog::{
  4. ColorChoice, CombinedLogger, Config, ConfigBuilder, SharedLogger, TermLogger, TerminalMode,
  5. WriteLogger,
  6. };
  7. use std::{path::PathBuf, thread::sleep, time::Duration};
  8. #[cfg(target_os = "android")]
  9. const LOGS_ENABLED: bool = true;
  10. #[cfg(not(target_os = "android"))]
  11. const LOGS_ENABLED: bool = true;
  12. // Measured in bytes
  13. const LOGFILE_MAXSIZE: usize = 5_000_000;
  14. static MUTED_TARGETS: &[&'static str] = &[
  15. "sled",
  16. "rustls",
  17. "net::channel",
  18. "net::message_publisher",
  19. "net::hosts",
  20. "net::protocol",
  21. "net::session",
  22. "net::outbound_session",
  23. "net::tcp",
  24. "net::p2p::seed",
  25. "net::refinery::handshake_node()",
  26. "system::publisher",
  27. "event_graph::dag_sync()",
  28. "event_graph::dag_insert()",
  29. "event_graph::protocol",
  30. ];
  31. #[cfg(target_os = "android")]
  32. fn logfile_path() -> PathBuf {
  33. use crate::android::get_external_storage_path;
  34. get_external_storage_path().join("Download/darkfi.log")
  35. }
  36. #[cfg(not(target_os = "android"))]
  37. fn logfile_path() -> PathBuf {
  38. dirs::cache_dir().unwrap().join("darkfi/darkfi.log")
  39. }
  40. #[cfg(target_os = "android")]
  41. mod android {
  42. use super::*;
  43. use android_logger::{AndroidLogger, Config as AndroidConfig};
  44. /// Implements a wrapper around the android logger so it's compatible with simplelog.
  45. pub struct AndroidLoggerWrapper {
  46. logger: AndroidLogger,
  47. level: LevelFilter,
  48. config: Config,
  49. }
  50. impl AndroidLoggerWrapper {
  51. pub fn new(level: LevelFilter, config: Config) -> Box<Self> {
  52. let cfg = AndroidConfig::default().with_max_level(level).with_tag("darkfi");
  53. Box::new(Self { logger: AndroidLogger::new(cfg), level, config })
  54. }
  55. }
  56. impl Log for AndroidLoggerWrapper {
  57. fn enabled(&self, metadata: &Metadata<'_>) -> bool {
  58. let target = metadata.target();
  59. for muted in MUTED_TARGETS {
  60. if target.starts_with(muted) {
  61. return false
  62. }
  63. }
  64. if metadata.level() > self.level {
  65. return false
  66. }
  67. self.logger.enabled(metadata)
  68. }
  69. fn log(&self, record: &Record<'_>) {
  70. if self.enabled(record.metadata()) {
  71. self.logger.log(record)
  72. }
  73. }
  74. fn flush(&self) {}
  75. }
  76. impl SharedLogger for AndroidLoggerWrapper {
  77. fn level(&self) -> LevelFilter {
  78. self.level
  79. }
  80. fn config(&self) -> Option<&Config> {
  81. Some(&self.config)
  82. }
  83. fn as_log(self: Box<Self>) -> Box<dyn Log> {
  84. Box::new(*self)
  85. }
  86. }
  87. }
  88. pub fn setup_logging() {
  89. // https://gist.github.com/jb-alvarado/6e223936446bb88cd9a93e7028fc2c4f
  90. let mut loggers: Vec<Box<dyn SharedLogger>> = vec![];
  91. let mut cfg = ConfigBuilder::new();
  92. for target in MUTED_TARGETS {
  93. cfg.add_filter_ignore_str(target);
  94. }
  95. let cfg = cfg.build();
  96. if LOGS_ENABLED {
  97. let log_file = FileRotate::new(
  98. logfile_path(),
  99. AppendCount::new(0),
  100. ContentLimit::BytesSurpassed(LOGFILE_MAXSIZE),
  101. Compression::None,
  102. #[cfg(unix)]
  103. None,
  104. );
  105. let file_logger = WriteLogger::new(LevelFilter::Debug, cfg.clone(), log_file);
  106. loggers.push(file_logger);
  107. }
  108. #[cfg(target_os = "android")]
  109. {
  110. use android::AndroidLoggerWrapper;
  111. let android_logger = AndroidLoggerWrapper::new(LevelFilter::Debug, cfg);
  112. loggers.push(android_logger);
  113. }
  114. #[cfg(not(target_os = "android"))]
  115. {
  116. // For ANSI colors in the terminal
  117. colored::control::set_override(true);
  118. let term_logger =
  119. TermLogger::new(LevelFilter::Debug, cfg, TerminalMode::Mixed, ColorChoice::Auto);
  120. loggers.push(term_logger);
  121. }
  122. CombinedLogger::init(loggers).expect("logger");
  123. }