Skip to content

Commit 1ff820f

Browse files
CopilotGZTimeWalker
andcommitted
Wire up UI logger to display real-time tracing logs in NetworkLogsView
Co-authored-by: GZTimeWalker <[email protected]>
1 parent 3b5bb58 commit 1ff820f

File tree

3 files changed

+42
-65
lines changed

3 files changed

+42
-65
lines changed

crates/wsrx-desktop-gpui/src/main.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,10 @@ impl AssetSource for EmbeddedAssets {
5050
}
5151

5252
fn main() -> Result<()> {
53-
// Initialize logging
54-
let (_console_guard, _file_guard) = logging::setup()?;
53+
// Initialize logging with UI logger
54+
let (_console_guard, _file_guard, mut log_receiver) = ui_logger::setup_with_ui()?;
55+
56+
tracing::info!("Starting wsrx-desktop-gpui");
5557

5658
// Initialize i18n with system locale
5759
i18n::init_locale();
@@ -71,7 +73,7 @@ fn main() -> Result<()> {
7173
..Default::default()
7274
});
7375

74-
cx.open_window(
76+
let window_entity = cx.open_window(
7577
WindowOptions {
7678
window_bounds: Some(WindowBounds::Windowed(bounds)),
7779
titlebar: titlebar_config,
@@ -90,6 +92,19 @@ fn main() -> Result<()> {
9092
)
9193
.expect("Failed to open window");
9294

95+
// Spawn task to receive logs and update the UI
96+
let root_view = window_entity.root_view(cx).expect("Failed to get root view");
97+
cx.spawn(|mut cx| async move {
98+
while let Some(log_entry) = log_receiver.recv().await {
99+
let _ = root_view.update(&mut cx, |root, cx| {
100+
root.add_log(log_entry, cx);
101+
});
102+
}
103+
})
104+
.detach();
105+
106+
tracing::info!("Application window created");
107+
93108
cx.activate(true);
94109
});
95110

crates/wsrx-desktop-gpui/src/views/network_logs.rs

Lines changed: 13 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -11,45 +11,19 @@ pub struct NetworkLogsView {
1111

1212
impl NetworkLogsView {
1313
pub fn new(_window: &mut Window, _cx: &mut Context<Self>) -> Self {
14-
// Add some sample logs for demonstration
15-
let mut logs = VecDeque::new();
16-
17-
logs.push_back(LogEntry {
18-
timestamp: "2025-11-10 15:00:01".to_string(),
19-
level: "INFO".to_string(),
20-
target: "wsrx::daemon".to_string(),
21-
message: "Daemon started successfully".to_string(),
22-
});
23-
24-
logs.push_back(LogEntry {
25-
timestamp: "2025-11-10 15:00:05".to_string(),
26-
level: "DEBUG".to_string(),
27-
target: "wsrx::tunnel".to_string(),
28-
message: "Initializing WebSocket connection to ws://example.com".to_string(),
29-
});
30-
31-
logs.push_back(LogEntry {
32-
timestamp: "2025-11-10 15:00:10".to_string(),
33-
level: "INFO".to_string(),
34-
target: "wsrx::tunnel".to_string(),
35-
message: "Connection established: 127.0.0.1:8080 → ws://example.com".to_string(),
36-
});
37-
38-
logs.push_back(LogEntry {
39-
timestamp: "2025-11-10 15:00:15".to_string(),
40-
level: "WARN".to_string(),
41-
target: "wsrx::proxy".to_string(),
42-
message: "High latency detected: 250ms".to_string(),
43-
});
44-
45-
logs.push_back(LogEntry {
46-
timestamp: "2025-11-10 15:00:20".to_string(),
47-
level: "ERROR".to_string(),
48-
target: "wsrx::tunnel".to_string(),
49-
message: "Connection failed: Connection refused".to_string(),
50-
});
14+
// Start with empty logs - will be populated from tracing
15+
Self {
16+
logs: VecDeque::new(),
17+
}
18+
}
5119

52-
Self { logs }
20+
/// Add a log entry (called from RootView when logs are received)
21+
pub fn add_log(&mut self, entry: LogEntry) {
22+
// Keep max 1000 logs to prevent memory issues
23+
if self.logs.len() >= 1000 {
24+
self.logs.pop_front();
25+
}
26+
self.logs.push_back(entry);
5327
}
5428

5529
fn render_log_entry(&self, entry: &LogEntry, index: usize) -> impl IntoElement {
@@ -146,28 +120,6 @@ impl Render for NetworkLogsView {
146120
)
147121
.child(
148122
div().flex().gap_2()
149-
.child(
150-
div()
151-
.id("add-sample-log-button")
152-
.px_3()
153-
.py_1()
154-
.text_sm()
155-
.bg(colors::accent())
156-
.rounded_md()
157-
.cursor_pointer()
158-
.hover(|div| div.bg(gpui::rgba(0x0088DDFF)))
159-
.on_click(cx.listener(|this, _event, _window, cx| {
160-
use chrono::Local;
161-
this.logs.push_back(LogEntry {
162-
timestamp: Local::now().format("%Y-%m-%d %H:%M:%S").to_string(),
163-
level: "INFO".to_string(),
164-
target: "wsrx::test".to_string(),
165-
message: format!("Sample log entry #{}", this.logs.len() + 1),
166-
});
167-
cx.notify();
168-
}))
169-
.child("Add Sample"),
170-
)
171123
.child(
172124
div()
173125
.id("clear-logs-button")
@@ -182,7 +134,7 @@ impl Render for NetworkLogsView {
182134
this.logs.clear();
183135
cx.notify();
184136
}))
185-
.child("Clear"),
137+
.child("Clear Logs"),
186138
),
187139
),
188140
)

crates/wsrx-desktop-gpui/src/views/root.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
use gpui::{Context, Entity, Render, Window, div, prelude::*};
33

44
use super::{ConnectionsView, GetStartedView, NetworkLogsView, SettingsView, SidebarView};
5-
use crate::{components::title_bar::TitleBar, models::app_state::PageId, styles::colors};
5+
use crate::{
6+
components::title_bar::TitleBar, models::{LogEntry, app_state::PageId}, styles::colors,
7+
};
68

79
pub struct RootView {
810
/// Current active page (string-based: "home", "logs", "settings", "default-scope", or scope.host)
@@ -77,6 +79,14 @@ impl RootView {
7779
cx.notify();
7880
}
7981

82+
/// Add a log entry to the network logs view
83+
pub fn add_log(&mut self, log_entry: LogEntry, cx: &mut Context<Self>) {
84+
self.network_logs.update(cx, |logs_view, cx| {
85+
logs_view.add_log(log_entry);
86+
cx.notify();
87+
});
88+
}
89+
8090
fn render_sidebar(&self) -> impl IntoElement {
8191
div()
8292
.flex()

0 commit comments

Comments
 (0)