Skip to content

Commit 7516ba3

Browse files
committed
gui: display logs when starting daemon
1 parent 1a59d03 commit 7516ba3

File tree

5 files changed

+81
-12
lines changed

5 files changed

+81
-12
lines changed

gui/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gui/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ path = "src/main.rs"
1515

1616
[dependencies]
1717
async-hwi = "0.0.12"
18+
crossbeam-channel = "0.5"
1819
liana = { git = "https://github.com/wizardsardine/liana", branch = "master", default-features = false, features = ["nonblocking_shutdown"] }
1920
liana_ui = { path = "ui" }
2021
backtrace = "0.3"

gui/src/loader.rs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,16 @@ pub struct Loader {
4444
pub daemon_started: bool,
4545
pub internal_bitcoind: Option<Bitcoind>,
4646
pub waiting_daemon_bitcoind: bool,
47+
pub receiver: crossbeam_channel::Receiver<String>,
4748

4849
step: Step,
4950
}
5051

5152
pub enum Step {
5253
Connecting,
53-
StartingDaemon,
54+
StartingDaemon {
55+
liana_logs: String,
56+
},
5457
Syncing {
5558
daemon: Arc<dyn Daemon + Sync + Send>,
5659
progress: f64,
@@ -77,7 +80,7 @@ pub enum Message {
7780
),
7881
Started(Result<(Arc<dyn Daemon + Sync + Send>, Option<Bitcoind>), Error>),
7982
Loaded(Result<Arc<dyn Daemon + Sync + Send>, Error>),
80-
BitcoindLog(Option<String>),
83+
LogMessage(Option<String>),
8184
Failure(DaemonError),
8285
}
8386

@@ -87,6 +90,7 @@ impl Loader {
8790
gui_config: GUIConfig,
8891
network: bitcoin::Network,
8992
internal_bitcoind: Option<Bitcoind>,
93+
receiver: crossbeam_channel::Receiver<String>,
9094
) -> (Self, Command<Message>) {
9195
let path = gui_config
9296
.daemon_rpc_path
@@ -102,6 +106,7 @@ impl Loader {
102106
daemon_started: false,
103107
internal_bitcoind,
104108
waiting_daemon_bitcoind: false,
109+
receiver,
105110
},
106111
Command::perform(connect(path), Message::Loaded),
107112
)
@@ -128,7 +133,9 @@ impl Loader {
128133
| Error::Daemon(DaemonError::Transport(Some(ErrorKind::ConnectionRefused), _))
129134
| Error::Daemon(DaemonError::Transport(Some(ErrorKind::NotFound), _)) => {
130135
if let Some(daemon_config_path) = self.gui_config.daemon_config_path.clone() {
131-
self.step = Step::StartingDaemon;
136+
self.step = Step::StartingDaemon {
137+
liana_logs: String::new(),
138+
};
132139
self.daemon_started = true;
133140
self.waiting_daemon_bitcoind = true;
134141
return Command::perform(
@@ -153,7 +160,11 @@ impl Loader {
153160
}
154161

155162
fn on_log(&mut self, log: Option<String>) -> Command<Message> {
156-
if let Step::Syncing { bitcoind_logs, .. } = &mut self.step {
163+
if let Step::StartingDaemon { liana_logs } = &mut self.step {
164+
if let Some(l) = log {
165+
*liana_logs = l;
166+
}
167+
} else if let Step::Syncing { bitcoind_logs, .. } = &mut self.step {
157168
if let Some(l) = log {
158169
*bitcoind_logs = l;
159170
}
@@ -254,14 +265,15 @@ impl Loader {
254265
self.gui_config.clone(),
255266
self.network,
256267
self.internal_bitcoind.clone(),
268+
self.receiver.clone(),
257269
);
258270
*self = loader;
259271
cmd
260272
}
261273
Message::Started(res) => self.on_start(res),
262274
Message::Loaded(res) => self.on_load(res),
263275
Message::Syncing(res) => self.on_sync(res),
264-
Message::BitcoindLog(log) => self.on_log(log),
276+
Message::LogMessage(log) => self.on_log(log),
265277
Message::Synced(Err(e)) => {
266278
self.step = Step::Error(Box::new(e));
267279
Command::none()
@@ -275,6 +287,16 @@ impl Loader {
275287
}
276288

277289
pub fn subscription(&self) -> Subscription<Message> {
290+
if let Step::StartingDaemon { .. } = self.step {
291+
return iced::subscription::unfold(1, self.receiver.clone(), move |recv| async {
292+
let log_msg = match recv.recv() {
293+
Ok(msg) => msg,
294+
Err(e) => e.to_string(),
295+
};
296+
297+
(Message::LogMessage(Some(log_msg)), recv)
298+
});
299+
}
278300
if let Some(Some(bitcoind_stdout)) =
279301
self.internal_bitcoind.as_ref().map(|b| b.stdout.clone())
280302
{
@@ -284,8 +306,8 @@ impl Loader {
284306
let mut s = std::io::BufReader::new(s.deref_mut());
285307
let mut buffer = String::new();
286308
match s.read_line(&mut buffer) {
287-
Err(e) => Message::BitcoindLog(Some(e.to_string())),
288-
Ok(_) => Message::BitcoindLog(Some(buffer)),
309+
Err(e) => Message::LogMessage(Some(e.to_string())),
310+
Ok(_) => Message::LogMessage(Some(buffer)),
289311
}
290312
};
291313
(msg, stdout)
@@ -342,12 +364,13 @@ pub enum ViewMessage {
342364

343365
pub fn view(step: &Step) -> Element<ViewMessage> {
344366
match &step {
345-
Step::StartingDaemon => cover(
367+
Step::StartingDaemon { liana_logs } => cover(
346368
None,
347369
Column::new()
348370
.width(Length::Fill)
349371
.push(ProgressBar::new(0.0..=1.0, 0.0).width(Length::Fill))
350-
.push(text("Starting daemon...")),
372+
.push(text("Starting daemon..."))
373+
.push(p2_regular(liana_logs).style(color::GREY_3)),
351374
),
352375
Step::Connecting => cover(
353376
None,

gui/src/logger.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
use liana::miniscript::bitcoin::Network;
22
use std::path::PathBuf;
33
use std::{fs::File, sync::Arc};
4-
use tracing::error;
4+
use tracing::{error, Event, Subscriber};
55
use tracing_subscriber::{
66
filter,
77
fmt::{format, writer::BoxMakeWriter, Layer},
8+
layer,
89
prelude::*,
910
reload, Registry,
1011
};
1112

13+
use crossbeam_channel::unbounded;
14+
1215
const INSTALLER_LOG_FILE_NAME: &str = "installer.log";
1316
const GUI_LOG_FILE_NAME: &str = "liana-gui.log";
1417

@@ -36,6 +39,7 @@ pub struct Logger {
3639
Registry,
3740
>,
3841
level_handle: reload::Handle<filter::LevelFilter, Registry>,
42+
receiver: crossbeam_channel::Receiver<String>,
3943
}
4044

4145
impl Logger {
@@ -47,6 +51,8 @@ impl Logger {
4751
.with_file(false);
4852
let (file_log, file_handle) = reload::Layer::new(file_log);
4953
let stdout_log = tracing_subscriber::fmt::layer().pretty().with_file(false);
54+
let channel = unbounded::<String>();
55+
let streamer_log = LogStream { sender: channel.0 }.with_filter(filter::LevelFilter::INFO);
5056
tracing_subscriber::registry()
5157
.with(
5258
stdout_log
@@ -68,10 +74,12 @@ impl Logger {
6874
&& !metadata.target().starts_with("ledger_transport_hid")
6975
})),
7076
)
77+
.with(streamer_log)
7178
.init();
7279
Self {
7380
file_handle,
7481
level_handle,
82+
receiver: channel.1,
7583
}
7684
}
7785

@@ -117,4 +125,37 @@ impl Logger {
117125
self.level_handle.modify(|filter| *filter = log_level)?;
118126
Ok(())
119127
}
128+
129+
pub fn receiver(&self) -> crossbeam_channel::Receiver<String> {
130+
self.receiver.clone()
131+
}
132+
}
133+
134+
pub struct LogStream {
135+
pub sender: crossbeam_channel::Sender<String>,
136+
}
137+
138+
impl<S> layer::Layer<S> for LogStream
139+
where
140+
S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>,
141+
{
142+
fn on_event(&self, event: &Event<'_>, _ctx: layer::Context<'_, S>) {
143+
let mut visitor = LogStreamVisitor {
144+
sender: self.sender.clone(),
145+
};
146+
event.record(&mut visitor);
147+
}
148+
}
149+
150+
struct LogStreamVisitor {
151+
sender: crossbeam_channel::Sender<String>,
152+
}
153+
154+
impl tracing::field::Visit for LogStreamVisitor {
155+
fn record_debug(&mut self, field: &tracing::field::Field, value: &dyn std::fmt::Debug) {
156+
if field.name() == "message" {
157+
let msg = format!("{:?}", value);
158+
let _ = self.sender.send(msg);
159+
}
160+
}
120161
}

gui/src/main.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ impl Application for GUI {
142142
network,
143143
cfg.log_level().unwrap_or(LevelFilter::INFO),
144144
);
145-
let (loader, command) = Loader::new(datadir_path, cfg, network, None);
145+
let (loader, command) =
146+
Loader::new(datadir_path, cfg, network, None, logger.receiver());
146147
(
147148
Self {
148149
state: State::Loader(Box::new(loader)),
@@ -189,7 +190,8 @@ impl Application for GUI {
189190
network,
190191
cfg.log_level().unwrap_or(LevelFilter::INFO),
191192
);
192-
let (loader, command) = Loader::new(datadir_path, cfg, network, None);
193+
let (loader, command) =
194+
Loader::new(datadir_path, cfg, network, None, self.logger.receiver());
193195
self.state = State::Loader(Box::new(loader));
194196
command.map(|msg| Message::Load(Box::new(msg)))
195197
}
@@ -217,6 +219,7 @@ impl Application for GUI {
217219
cfg,
218220
daemon_cfg.bitcoin_config.network,
219221
internal_bitcoind,
222+
self.logger.receiver(),
220223
);
221224
self.state = State::Loader(Box::new(loader));
222225
command.map(|msg| Message::Load(Box::new(msg)))

0 commit comments

Comments
 (0)