Skip to content

Commit

Permalink
Adds json log output format
Browse files Browse the repository at this point in the history
  • Loading branch information
scottopell committed Nov 30, 2024
1 parent a728b66 commit 3583c6e
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 20 deletions.
60 changes: 40 additions & 20 deletions crates/librqbit/src/tracing_subscriber_config_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ pub struct InitLoggingOptions<'a> {
pub default_rust_log_value: Option<&'a str>,
pub log_file: Option<&'a str>,
pub log_file_rust_log: Option<&'a str>,
pub log_file_json: bool,
pub log_json: bool,
}

pub struct InitLoggingResult {
Expand All @@ -62,7 +64,7 @@ pub struct InitLoggingResult {

#[inline(never)]
pub fn init_logging(opts: InitLoggingOptions) -> anyhow::Result<InitLoggingResult> {
let stderr_filter = EnvFilter::builder()
let stdout_filter = EnvFilter::builder()
.with_default_directive(
opts.default_rust_log_value
.unwrap_or("info")
Expand All @@ -72,16 +74,23 @@ pub fn init_logging(opts: InitLoggingOptions) -> anyhow::Result<InitLoggingResul
.from_env()
.context("invalid RUST_LOG value")?;

let (stderr_filter, reload_stderr_filter) =
tracing_subscriber::reload::Layer::new(stderr_filter);
let (stdout_filter, reload_stdout_filter) =
tracing_subscriber::reload::Layer::new(stdout_filter);

use tracing_subscriber::{fmt, prelude::*, EnvFilter};

let (line_sub, line_broadcast) = Subscriber::new();

// Stdout logging layer.
let (json, human) = if opts.log_json {
(
Some(fmt::Layer::default().json().with_filter(stdout_filter)),
None,
)
} else {
(None, Some(fmt::Layer::default().with_filter(stdout_filter)))
};
let layered = tracing_subscriber::registry()
// Stderr logging layer.
.with(fmt::layer().with_filter(stderr_filter))
// HTTP API log broadcast layer.
.with(
fmt::layer()
Expand All @@ -107,35 +116,46 @@ pub fn init_logging(opts: InitLoggingOptions) -> anyhow::Result<InitLoggingResul
.open(&log_file)
.with_context(|| format!("error opening log file {:?}", log_file))?,
));
layered
.with(
fmt::layer()
.with_ansi(false)
.with_writer(log_file)
.with_filter(
EnvFilter::builder()
.parse(opts.log_file_rust_log.unwrap_or("info,librqbit=debug"))
.context("can't parse log-file-rust-log")?,
),
)
.try_init()
.context("can't init logging")?;
let log_env_filter = EnvFilter::builder()
.parse(opts.log_file_rust_log.unwrap_or("info,librqbit=debug"))
.context("can't parse log-file-rust-log")?;
if opts.log_file_json {
layered
.with(
fmt::layer()
.json()
.with_writer(log_file)
.with_filter(log_env_filter),
)
.try_init()
.context("can't init json file logging")?;
} else {
layered
.with(
fmt::layer()
.with_ansi(false)
.with_writer(log_file)
.with_filter(log_env_filter),
)
.try_init()
.context("can't init logging to file")?;
}
} else {
layered.try_init().context("can't init logging")?;
}

let (reload_tx, mut reload_rx) = tokio::sync::mpsc::unbounded_channel::<String>();
spawn(error_span!("fmt_filter_reloader"), async move {
while let Some(rust_log) = reload_rx.recv().await {
let stderr_env_filter = match EnvFilter::builder().parse(&rust_log) {
let stdout_env_filter = match EnvFilter::builder().parse(&rust_log) {
Ok(f) => f,
Err(e) => {
eprintln!("can't parse env filter {:?}: {:#?}", rust_log, e);
continue;
}
};
eprintln!("setting RUST_LOG to {:?}", rust_log);
let _ = reload_stderr_filter.reload(stderr_env_filter);
let _ = reload_stdout_filter.reload(stdout_env_filter);
}
Ok(())
});
Expand Down
10 changes: 10 additions & 0 deletions crates/rqbit/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ struct Opts {
)]
log_file_rust_log: String,

/// Logging to console (ie, stdout) will emit each log record as a json object
#[arg(long = "log-json", env = "RQBIT_LOG_JSON")]
log_json: bool,

/// Log file will contain json-formatted log records
#[arg(long = "log-file-json", env = "RQBIT_LOG_FILE_JSON")]
log_file_json: bool,

/// The interval to poll trackers, e.g. 30s.
/// Trackers send the refresh interval when we connect to them. Often this is
/// pretty big, e.g. 30 minutes. This can force a certain value.
Expand Down Expand Up @@ -438,6 +446,8 @@ async fn async_main(opts: Opts, cancel: CancellationToken) -> anyhow::Result<()>
}),
log_file: opts.log_file.as_deref(),
log_file_rust_log: Some(&opts.log_file_rust_log),
log_file_json: opts.log_file_json,
log_json: opts.log_json,
})?;

match librqbit::try_increase_nofile_limit() {
Expand Down
2 changes: 2 additions & 0 deletions desktop/src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,8 @@ async fn start() {
default_rust_log_value: Some("info"),
log_file: None,
log_file_rust_log: None,
log_file_json: false,
log_json: false,
})
.unwrap();

Expand Down

0 comments on commit 3583c6e

Please sign in to comment.