Desktop: button to show a modal with logs (#48)

* Add an endpoint to stream logs /stream_logs
* Display logs in desktop app
* UI component to stream logs
This commit is contained in:
Igor Katson 2023-12-08 19:47:48 +00:00 • committed by GitHub
parent f7345ae6df
commit 9385524a1a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 521 additions and 125 deletions

View file

@ -38,6 +38,7 @@ reqwest = "0.11"
serde = {version = "1", features=["derive"]}
serde_json = "1"
size_format = "1"
bytes = "1.5.0"
[dev-dependencies]
futures = {version = "0.3"}
futures = {version = "0.3"}

View file

@ -3,9 +3,9 @@ use std::{io::LineWriter, net::SocketAddr, path::PathBuf, sync::Arc, time::Durat
use anyhow::Context;
use clap::{Parser, ValueEnum};
use librqbit::{
api::ApiAddTorrentResponse, http_api::HttpApi, http_api_client, librqbit_spawn, AddTorrent,
api::ApiAddTorrentResponse, http_api::{HttpApi, HttpApiOptions}, http_api_client, librqbit_spawn, AddTorrent,
AddTorrentOptions, AddTorrentResponse, ListOnlyResponse, ManagedTorrentState,
PeerConnectionOptions, Session, SessionOptions,
PeerConnectionOptions, Session, SessionOptions, log_subscriber::LineBroadcast, Api,
};
use size_format::SizeFormatterBinary as SF;
use tracing::{error, error_span, info, trace_span, warn};
@ -178,8 +178,13 @@ enum SubCommand {
Download(DownloadOpts),
}
struct InitLoggingResult {
rust_log_reload_tx: tokio::sync::mpsc::UnboundedSender<String>,
line_broadcast: LineBroadcast,
}
// Init logging and make a channel to send new RUST_LOG values to.
fn init_logging(opts: &Opts) -> tokio::sync::mpsc::UnboundedSender<String> {
fn init_logging(opts: &Opts) -> InitLoggingResult {
let default_rust_log = match opts.log_level.as_ref() {
Some(level) => match level {
LogLevel::Trace => "trace",
@ -204,6 +209,8 @@ fn init_logging(opts: &Opts) -> tokio::sync::mpsc::UnboundedSender<String> {
use tracing_subscriber::{fmt, prelude::*, EnvFilter};
let (line_sub, line_broadcast) = librqbit::log_subscriber::Subscriber::new();
#[cfg(feature = "tokio-console")]
{
let (console_layer, server) = console_subscriber::Builder::default()
@ -230,7 +237,15 @@ fn init_logging(opts: &Opts) -> tokio::sync::mpsc::UnboundedSender<String> {
#[cfg(not(feature = "tokio-console"))]
{
let layered = tracing_subscriber::registry().with(fmt::layer().with_filter(stderr_filter));
let layered = tracing_subscriber::registry()
.with(fmt::layer().with_filter(stderr_filter))
.with(
fmt::layer()
.event_format(fmt::format().with_ansi(false).compact())
.with_ansi(false)
.with_writer(line_sub)
.with_filter(EnvFilter::builder().parse("info").unwrap()),
);
if let Some(log_file) = &opts.log_file {
let log_file = log_file.clone();
let log_file = move || {
@ -276,7 +291,10 @@ fn init_logging(opts: &Opts) -> tokio::sync::mpsc::UnboundedSender<String> {
Ok(())
},
);
reload_tx
InitLoggingResult {
rust_log_reload_tx: reload_tx,
line_broadcast,
}
}
fn _start_deadlock_detector_thread() {
@ -332,7 +350,7 @@ fn main() -> anyhow::Result<()> {
}
async fn async_main(opts: Opts) -> anyhow::Result<()> {
let logging_reload_tx = init_logging(&opts);
let log_config = init_logging(&opts);
let mut sopts = SessionOptions {
disable_dht: opts.disable_dht,
@ -427,10 +445,17 @@ async fn async_main(opts: Opts) -> anyhow::Result<()> {
trace_span!("stats_printer"),
stats_printer(session.clone()),
);
let http_api = HttpApi::new(session, Some(logging_reload_tx));
let api = Api::new(session, Some(log_config.rust_log_reload_tx), Some(log_config.line_broadcast));
let http_api = HttpApi::new(
api,
Some(HttpApiOptions{
read_only: false,
cors_enable_all: false,
}),
);
let http_api_listen_addr = opts.http_api_listen_addr;
http_api
.make_http_api_and_run(http_api_listen_addr, false)
.make_http_api_and_run(http_api_listen_addr)
.await
.context("error running HTTP API")
}
@ -507,14 +532,15 @@ async fn async_main(opts: Opts) -> anyhow::Result<()> {
trace_span!("stats_printer"),
stats_printer(session.clone()),
);
let http_api = HttpApi::new(session.clone(), Some(logging_reload_tx));
let api = Api::new(session.clone(), Some(log_config.rust_log_reload_tx), Some(log_config.line_broadcast));
let http_api = HttpApi::new(
api, Some(HttpApiOptions { cors_enable_all: false, read_only: true })
);
let http_api_listen_addr = opts.http_api_listen_addr;
librqbit_spawn(
"http_api",
error_span!("http_api"),
http_api
.clone()
.make_http_api_and_run(http_api_listen_addr, true),
http_api.make_http_api_and_run(http_api_listen_addr),
);
let mut added = false;