Skip to content

Commit 5e05236

Browse files
feat(core): add tracing for vital functionality closes #5204 (#8289)
* feat(core): add tracing for vital functionality * Update core/tauri-runtime-wry/src/lib.rs [skip ci] * Update Cargo.toml [skip ci] * tracing feature * wry 0.24.6 * add change tag * add tracing to CI test * enhance spans for update check * remove app from debug impl
1 parent b3e53e7 commit 5e05236

File tree

16 files changed

+582
-114
lines changed

16 files changed

+582
-114
lines changed

.changes/tracing.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"tauri": patch:enhance
3+
"tauri-runtime-wry": patch:enhance
4+
"tauri-macros": patch:enhance
5+
---
6+
7+
Added tracing for window startup, plugins, `Window::eval`, events, IPC, updater and custom protocol request handlers behind the `tracing` feature flag.

.github/workflows/test-core.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ jobs:
5656
key: api-all
5757
}
5858
- {
59-
args: --features compression,wry,linux-protocol-headers,isolation,custom-protocol,api-all,cli,updater,system-tray,windows7-compat,http-multipart,test,
59+
args: --features tracing,compression,wry,linux-protocol-headers,isolation,custom-protocol,api-all,cli,updater,system-tray,windows7-compat,http-multipart,test,
6060
key: all
6161
}
6262

core/tauri-macros/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ readme = "README.md"
1616
proc-macro = true
1717

1818
[dependencies]
19-
proc-macro2 = "1"
19+
proc-macro2 = { version = "1", features = ["span-locations"] }
2020
quote = "1"
2121
syn = { version = "1", features = [ "full" ] }
2222
heck = "0.4"
@@ -30,3 +30,4 @@ isolation = [ "tauri-codegen/isolation" ]
3030
shell-scope = [ "tauri-codegen/shell-scope" ]
3131
config-json5 = [ "tauri-codegen/config-json5", "tauri-utils/config-json5" ]
3232
config-toml = [ "tauri-codegen/config-toml", "tauri-utils/config-toml" ]
33+
tracing = []

core/tauri-macros/src/command/wrapper.rs

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,21 +161,51 @@ pub fn wrapper(attributes: TokenStream, item: TokenStream) -> TokenStream {
161161
}
162162

163163
// body to the command wrapper or a `compile_error!` of an error occurred while parsing it.
164-
let body = syn::parse::<WrapperAttributes>(attributes)
164+
let (body, attributes) = syn::parse::<WrapperAttributes>(attributes)
165165
.map(|mut attrs| {
166166
if function.sig.asyncness.is_some() {
167167
attrs.execution_context = ExecutionContext::Async;
168168
}
169169
attrs
170170
})
171-
.and_then(|attrs| match attrs.execution_context {
172-
ExecutionContext::Async => body_async(&function, &invoke, attrs.argument_case),
173-
ExecutionContext::Blocking => body_blocking(&function, &invoke, attrs.argument_case),
171+
.and_then(|attrs| {
172+
let body = match attrs.execution_context {
173+
ExecutionContext::Async => body_async(&function, &invoke, attrs.argument_case),
174+
ExecutionContext::Blocking => body_blocking(&function, &invoke, attrs.argument_case),
175+
};
176+
body.map(|b| (b, Some(attrs)))
174177
})
175-
.unwrap_or_else(syn::Error::into_compile_error);
178+
.unwrap_or_else(|e| (syn::Error::into_compile_error(e), None));
176179

177180
let Invoke { message, resolver } = invoke;
178181

182+
let kind = match attributes.as_ref().map(|a| &a.execution_context) {
183+
Some(ExecutionContext::Async) if function.sig.asyncness.is_none() => "sync_threadpool",
184+
Some(ExecutionContext::Async) => "async",
185+
Some(ExecutionContext::Blocking) => "sync",
186+
_ => "sync",
187+
};
188+
189+
let loc = function.span().start();
190+
let line = loc.line;
191+
let col = loc.column;
192+
193+
let maybe_span = if cfg!(feature = "tracing") {
194+
quote!({
195+
let _span = tracing::debug_span!(
196+
"ipc::request::handler",
197+
cmd = #message.command(),
198+
kind = #kind,
199+
loc.line = #line,
200+
loc.col = #col,
201+
is_internal = false,
202+
)
203+
.entered();
204+
})
205+
} else {
206+
quote!()
207+
};
208+
179209
// Rely on rust 2018 edition to allow importing a macro from a path.
180210
quote!(
181211
#async_command_check
@@ -193,6 +223,8 @@ pub fn wrapper(attributes: TokenStream, item: TokenStream) -> TokenStream {
193223
#[allow(unused_variables)]
194224
let ::tauri::Invoke { message: #message, resolver: #resolver } = $invoke;
195225

226+
#maybe_span
227+
196228
#body
197229
}};
198230
}
@@ -212,6 +244,20 @@ pub fn wrapper(attributes: TokenStream, item: TokenStream) -> TokenStream {
212244
fn body_async(function: &ItemFn, invoke: &Invoke, case: ArgumentCase) -> syn::Result<TokenStream2> {
213245
let Invoke { message, resolver } = invoke;
214246
parse_args(function, message, case).map(|args| {
247+
#[cfg(feature = "tracing")]
248+
quote! {
249+
use tracing::Instrument;
250+
251+
let span = tracing::debug_span!("ipc::request::run");
252+
#resolver.respond_async_serialized(async move {
253+
let result = $path(#(#args?),*);
254+
let kind = (&result).async_kind();
255+
kind.future(result).await
256+
}
257+
.instrument(span));
258+
}
259+
260+
#[cfg(not(feature = "tracing"))]
215261
quote! {
216262
#resolver.respond_async_serialized(async move {
217263
let result = $path(#(#args?),*);
@@ -241,7 +287,14 @@ fn body_blocking(
241287
Err(err) => return #resolver.invoke_error(err),
242288
});
243289

290+
let maybe_span = if cfg!(feature = "tracing") {
291+
quote!(let _span = tracing::debug_span!("ipc::request::run").entered();)
292+
} else {
293+
quote!()
294+
};
295+
244296
Ok(quote! {
297+
#maybe_span
245298
let result = $path(#(match #args #match_body),*);
246299
let kind = (&result).blocking_kind();
247300
kind.block(result, #resolver);

core/tauri-runtime-wry/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@ exclude = [ "CHANGELOG.md", "/target" ]
1313
readme = "README.md"
1414

1515
[dependencies]
16-
wry = { version = "0.24.4", default-features = false, features = [ "file-drop", "protocol" ] }
16+
wry = { version = "0.24.6", default-features = false, features = [ "file-drop", "protocol" ] }
1717
tauri-runtime = { version = "0.14.1", path = "../tauri-runtime" }
1818
tauri-utils = { version = "1.5.0", path = "../tauri-utils" }
1919
uuid = { version = "1", features = [ "v4" ] }
2020
rand = "0.8"
2121
raw-window-handle = "0.5"
22+
tracing = { version = "0.1", optional = true }
2223

2324
[target."cfg(windows)".dependencies]
2425
webview2-com = "0.19.1"
@@ -48,3 +49,4 @@ objc-exception = [ "wry/objc-exception" ]
4849
global-shortcut = [ "tauri-runtime/global-shortcut" ]
4950
clipboard = [ "tauri-runtime/clipboard" ]
5051
linux-headers = [ "wry/linux-headers", "webkit2gtk/v2_36" ]
52+
tracing = [ "dep:tracing", "wry/tracing" ]

core/tauri-runtime-wry/src/lib.rs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,32 @@ impl<T: UserEvent> Context<T> {
244244
}
245245
}
246246

247+
#[cfg(feature = "tracing")]
248+
#[derive(Debug, Clone, Default)]
249+
pub struct ActiveTraceSpanStore(Rc<RefCell<Vec<ActiveTracingSpan>>>);
250+
251+
#[cfg(feature = "tracing")]
252+
impl ActiveTraceSpanStore {
253+
pub fn remove_window_draw(&self, window_id: WindowId) {
254+
let mut store = self.0.borrow_mut();
255+
if let Some(index) = store
256+
.iter()
257+
.position(|t| matches!(t, ActiveTracingSpan::WindowDraw { id, span: _ } if id == &window_id))
258+
{
259+
store.remove(index);
260+
}
261+
}
262+
}
263+
264+
#[cfg(feature = "tracing")]
265+
#[derive(Debug)]
266+
pub enum ActiveTracingSpan {
267+
WindowDraw {
268+
id: WindowId,
269+
span: tracing::span::EnteredSpan,
270+
},
271+
}
272+
247273
#[derive(Debug, Clone)]
248274
pub struct DispatcherMainThreadContext<T: UserEvent> {
249275
pub window_target: EventLoopWindowTarget<Message<T>>,
@@ -255,6 +281,8 @@ pub struct DispatcherMainThreadContext<T: UserEvent> {
255281
pub windows: Rc<RefCell<HashMap<WebviewId, WindowWrapper>>>,
256282
#[cfg(all(desktop, feature = "system-tray"))]
257283
system_tray_manager: SystemTrayManager,
284+
#[cfg(feature = "tracing")]
285+
pub active_tracing_spans: ActiveTraceSpanStore,
258286
}
259287

260288
// SAFETY: we ensure this type is only used on the main thread.
@@ -1135,7 +1163,10 @@ pub enum WindowMessage {
11351163

11361164
#[derive(Debug, Clone)]
11371165
pub enum WebviewMessage {
1166+
#[cfg(not(feature = "tracing"))]
11381167
EvaluateScript(String),
1168+
#[cfg(feature = "tracing")]
1169+
EvaluateScript(String, Sender<()>, tracing::Span),
11391170
#[allow(dead_code)]
11401171
WebviewEvent(WebviewEvent),
11411172
Print,
@@ -1651,6 +1682,21 @@ impl<T: UserEvent> Dispatch<T> for WryDispatcher<T> {
16511682
)
16521683
}
16531684

1685+
#[cfg(feature = "tracing")]
1686+
fn eval_script<S: Into<String>>(&self, script: S) -> Result<()> {
1687+
// use a channel so the EvaluateScript task uses the current span as parent
1688+
let (tx, rx) = channel();
1689+
getter!(
1690+
self,
1691+
rx,
1692+
Message::Webview(
1693+
self.window_id,
1694+
WebviewMessage::EvaluateScript(script.into(), tx, tracing::Span::current()),
1695+
)
1696+
)
1697+
}
1698+
1699+
#[cfg(not(feature = "tracing"))]
16541700
fn eval_script<S: Into<String>>(&self, script: S) -> Result<()> {
16551701
send_user_message(
16561702
&self.context,
@@ -1962,6 +2008,8 @@ impl<T: UserEvent> Wry<T> {
19622008
windows,
19632009
#[cfg(all(desktop, feature = "system-tray"))]
19642010
system_tray_manager,
2011+
#[cfg(feature = "tracing")]
2012+
active_tracing_spans: Default::default(),
19652013
},
19662014
};
19672015

@@ -2165,6 +2213,9 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
21652213
#[cfg(all(desktop, feature = "system-tray"))]
21662214
let system_tray_manager = self.context.main_thread.system_tray_manager.clone();
21672215

2216+
#[cfg(feature = "tracing")]
2217+
let active_tracing_spans = self.context.main_thread.active_tracing_spans.clone();
2218+
21682219
#[cfg(all(desktop, feature = "global-shortcut"))]
21692220
let global_shortcut_manager = self.context.main_thread.global_shortcut_manager.clone();
21702221
#[cfg(all(desktop, feature = "global-shortcut"))]
@@ -2202,6 +2253,8 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
22022253
clipboard_manager: clipboard_manager.clone(),
22032254
#[cfg(all(desktop, feature = "system-tray"))]
22042255
system_tray_manager: system_tray_manager.clone(),
2256+
#[cfg(feature = "tracing")]
2257+
active_tracing_spans: active_tracing_spans.clone(),
22052258
},
22062259
web_context,
22072260
);
@@ -2226,6 +2279,8 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
22262279
clipboard_manager: clipboard_manager.clone(),
22272280
#[cfg(all(desktop, feature = "system-tray"))]
22282281
system_tray_manager: system_tray_manager.clone(),
2282+
#[cfg(feature = "tracing")]
2283+
active_tracing_spans: active_tracing_spans.clone(),
22292284
},
22302285
web_context,
22312286
);
@@ -2240,6 +2295,9 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
22402295
let web_context = self.context.main_thread.web_context;
22412296
let mut plugins = self.plugins;
22422297

2298+
#[cfg(feature = "tracing")]
2299+
let active_tracing_spans = self.context.main_thread.active_tracing_spans.clone();
2300+
22432301
#[cfg(all(desktop, feature = "system-tray"))]
22442302
let system_tray_manager = self.context.main_thread.system_tray_manager;
22452303

@@ -2272,6 +2330,8 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
22722330
clipboard_manager: clipboard_manager.clone(),
22732331
#[cfg(all(desktop, feature = "system-tray"))]
22742332
system_tray_manager: system_tray_manager.clone(),
2333+
#[cfg(feature = "tracing")]
2334+
active_tracing_spans: active_tracing_spans.clone(),
22752335
},
22762336
&web_context,
22772337
);
@@ -2295,6 +2355,8 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
22952355
clipboard_manager: clipboard_manager.clone(),
22962356
#[cfg(all(desktop, feature = "system-tray"))]
22972357
system_tray_manager: system_tray_manager.clone(),
2358+
#[cfg(feature = "tracing")]
2359+
active_tracing_spans: active_tracing_spans.clone(),
22982360
},
22992361
&web_context,
23002362
);
@@ -2314,6 +2376,8 @@ pub struct EventLoopIterationContext<'a, T: UserEvent> {
23142376
pub clipboard_manager: Arc<Mutex<Clipboard>>,
23152377
#[cfg(all(desktop, feature = "system-tray"))]
23162378
pub system_tray_manager: SystemTrayManager,
2379+
#[cfg(feature = "tracing")]
2380+
pub active_tracing_spans: ActiveTraceSpanStore,
23172381
}
23182382

23192383
struct UserMessageContext {
@@ -2590,6 +2654,19 @@ fn handle_user_message<T: UserEvent>(
25902654
}
25912655
}
25922656
Message::Webview(id, webview_message) => match webview_message {
2657+
#[cfg(feature = "tracing")]
2658+
WebviewMessage::EvaluateScript(script, tx, span) => {
2659+
let _span = span.entered();
2660+
if let Some(WindowHandle::Webview { inner: webview, .. }) =
2661+
windows.borrow().get(&id).and_then(|w| w.inner.as_ref())
2662+
{
2663+
if let Err(e) = webview.evaluate_script(&script) {
2664+
debug_eprintln!("{}", e);
2665+
}
2666+
}
2667+
tx.send(()).unwrap();
2668+
}
2669+
#[cfg(not(feature = "tracing"))]
25932670
WebviewMessage::EvaluateScript(script) => {
25942671
if let Some(WindowHandle::Webview { inner: webview, .. }) =
25952672
windows.borrow().get(&id).and_then(|w| w.inner.as_ref())
@@ -2758,6 +2835,8 @@ fn handle_event_loop<T: UserEvent>(
27582835
clipboard_manager,
27592836
#[cfg(all(desktop, feature = "system-tray"))]
27602837
system_tray_manager,
2838+
#[cfg(feature = "tracing")]
2839+
active_tracing_spans,
27612840
} = context;
27622841
if *control_flow != ControlFlow::Exit {
27632842
*control_flow = ControlFlow::Wait;
@@ -2780,6 +2859,11 @@ fn handle_event_loop<T: UserEvent>(
27802859
callback(RunEvent::Exit);
27812860
}
27822861

2862+
#[cfg(feature = "tracing")]
2863+
Event::RedrawRequested(id) => {
2864+
active_tracing_spans.remove_window_draw(id);
2865+
}
2866+
27832867
#[cfg(all(desktop, feature = "global-shortcut"))]
27842868
Event::GlobalShortcutEvent(accelerator_id) => {
27852869
for (id, handler) in &*global_shortcut_manager_handle.listeners.lock().unwrap() {
@@ -3123,6 +3207,14 @@ fn create_webview<T: UserEvent>(
31233207
#[cfg(windows)]
31243208
let proxy = context.proxy.clone();
31253209

3210+
#[cfg(feature = "tracing")]
3211+
let _webview_create_span = tracing::debug_span!("wry::webview::create").entered();
3212+
#[cfg(feature = "tracing")]
3213+
let window_draw_span = tracing::debug_span!("wry::window::draw").entered();
3214+
#[cfg(feature = "tracing")]
3215+
let window_create_span =
3216+
tracing::debug_span!(parent: &window_draw_span, "wry::window::create").entered();
3217+
31263218
let window_event_listeners = WindowEventListeners::default();
31273219

31283220
#[cfg(windows)]
@@ -3157,6 +3249,21 @@ fn create_webview<T: UserEvent>(
31573249
let focused = window_builder.inner.window.focused;
31583250
let window = window_builder.inner.build(event_loop).unwrap();
31593251

3252+
#[cfg(feature = "tracing")]
3253+
{
3254+
drop(window_create_span);
3255+
3256+
context
3257+
.main_thread
3258+
.active_tracing_spans
3259+
.0
3260+
.borrow_mut()
3261+
.push(ActiveTracingSpan::WindowDraw {
3262+
id: window.id(),
3263+
span: window_draw_span,
3264+
});
3265+
}
3266+
31603267
webview_id_map.insert(window.id(), window_id);
31613268

31623269
if window_builder.center {

core/tauri/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ png = { version = "0.17", optional = true }
9494
ico = { version = "0.2.0", optional = true }
9595
encoding_rs = "0.8.31"
9696
sys-locale = { version = "0.2.3", optional = true }
97+
tracing = { version = "0.1", optional = true }
9798

9899
[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
99100
rfd = { version = "0.10", optional = true, features = [ "gtk3", "common-controls-v6" ] }
@@ -135,6 +136,7 @@ cargo_toml = "0.11"
135136

136137
[features]
137138
default = [ "wry", "compression", "objc-exception" ]
139+
tracing = [ "dep:tracing", "tauri-macros/tracing", "tauri-runtime-wry/tracing" ]
138140
test = [ ]
139141
compression = [ "tauri-macros/compression", "tauri-utils/compression" ]
140142
wry = [ "tauri-runtime-wry" ]

0 commit comments

Comments
 (0)