Skip to content

Commit d621d34

Browse files
lucasfernog-crabnebulalucasfernogCrabNejonas
authored
feat: add tracing (port from #8289) (#8607)
* feat(tracing): add IPC tracing * span for deserialization * trace spans for IPC command handlers * fix spans usage * app tracing [skip ci] * window tracing * fix run never resolving all spans * fix draw not entered * change level * feat(core): Manager::emit_filter and optimize serialization (#7512) Co-authored-by: Lucas Nogueira <lucas@tauri.studio> * event spans * lint & fix tests * change eval to run sync * fix instrument * update wry * change separator * Update core/tauri/src/plugin.rs Co-authored-by: Jonas Kruckenberg <118265418+CrabNejonas@users.noreply.github.com> * Update core/tauri/src/window.rs Co-authored-by: Jonas Kruckenberg <118265418+CrabNejonas@users.noreply.github.com> * Update core/tauri/src/window.rs Co-authored-by: Jonas Kruckenberg <118265418+CrabNejonas@users.noreply.github.com> * Update core/tauri/src/window.rs Co-authored-by: Jonas Kruckenberg <118265418+CrabNejonas@users.noreply.github.com> * Update core/tauri/src/window.rs Co-authored-by: Jonas Kruckenberg <118265418+CrabNejonas@users.noreply.github.com> * instrument separators * remove on_event trace * skip all arguments on App::build tracing * ipc spans adjustments * delete change file * improve how request and response are added as values (serialize) * do not run evalScript sync on android :( freezes the app * wry 0.35.2 * add change file --------- Co-authored-by: Lucas Nogueira <lucas@tauri.studio> Co-authored-by: Jonas Kruckenberg <118265418+CrabNejonas@users.noreply.github.com>
1 parent 5cb1969 commit d621d34

File tree

10 files changed

+145
-26
lines changed

10 files changed

+145
-26
lines changed

.changes/tracing.md

+7
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.

core/tauri-runtime-wry/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ edition = { workspace = true }
1313
rust-version = { workspace = true }
1414

1515
[dependencies]
16-
wry = { version = "0.35", default-features = false, features = [ "file-drop", "protocol", "os-webview" ] }
16+
wry = { version = "0.35.2", default-features = false, features = [ "file-drop", "protocol", "os-webview" ] }
1717
tao = { version = "0.24", default-features = false, features = [ "rwh_05" ] }
1818
tauri-runtime = { version = "1.0.0-alpha.7", path = "../tauri-runtime" }
1919
tauri-utils = { version = "2.0.0-alpha.12", path = "../tauri-utils" }
@@ -48,4 +48,4 @@ macos-private-api = [
4848
]
4949
objc-exception = [ "wry/objc-exception" ]
5050
linux-protocol-body = [ "wry/linux-body", "webkit2gtk/v2_40" ]
51-
tracing = [ "dep:tracing" ]
51+
tracing = [ "dep:tracing", "wry/tracing" ]

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

+6-6
Original file line numberDiff line numberDiff line change
@@ -1070,9 +1070,9 @@ pub enum WindowMessage {
10701070

10711071
#[derive(Debug, Clone)]
10721072
pub enum WebviewMessage {
1073-
#[cfg(not(feature = "tracing"))]
1073+
#[cfg(not(all(feature = "tracing", not(target_os = "android"))))]
10741074
EvaluateScript(String),
1075-
#[cfg(feature = "tracing")]
1075+
#[cfg(all(feature = "tracing", not(target_os = "android")))]
10761076
EvaluateScript(String, Sender<()>, tracing::Span),
10771077
#[allow(dead_code)]
10781078
WebviewEvent(WebviewEvent),
@@ -1583,7 +1583,7 @@ impl<T: UserEvent> Dispatch<T> for WryDispatcher<T> {
15831583
)
15841584
}
15851585

1586-
#[cfg(feature = "tracing")]
1586+
#[cfg(all(feature = "tracing", not(target_os = "android")))]
15871587
fn eval_script<S: Into<String>>(&self, script: S) -> Result<()> {
15881588
// use a channel so the EvaluateScript task uses the current span as parent
15891589
let (tx, rx) = channel();
@@ -1597,7 +1597,7 @@ impl<T: UserEvent> Dispatch<T> for WryDispatcher<T> {
15971597
)
15981598
}
15991599

1600-
#[cfg(not(feature = "tracing"))]
1600+
#[cfg(not(all(feature = "tracing", not(target_os = "android"))))]
16011601
fn eval_script<S: Into<String>>(&self, script: S) -> Result<()> {
16021602
send_user_message(
16031603
&self.context,
@@ -2429,7 +2429,7 @@ fn handle_user_message<T: UserEvent>(
24292429
}
24302430
}
24312431
Message::Webview(id, webview_message) => match webview_message {
2432-
#[cfg(feature = "tracing")]
2432+
#[cfg(all(feature = "tracing", not(target_os = "android")))]
24332433
WebviewMessage::EvaluateScript(script, tx, span) => {
24342434
let _span = span.entered();
24352435
if let Some(WindowHandle::Webview { inner: webview, .. }) =
@@ -2441,7 +2441,7 @@ fn handle_user_message<T: UserEvent>(
24412441
}
24422442
tx.send(()).unwrap();
24432443
}
2444-
#[cfg(not(feature = "tracing"))]
2444+
#[cfg(not(all(feature = "tracing", not(target_os = "android"))))]
24452445
WebviewMessage::EvaluateScript(script) => {
24462446
if let Some(WindowHandle::Webview { inner: webview, .. }) =
24472447
windows.borrow().get(&id).and_then(|w| w.inner.as_ref())

core/tauri/src/app.rs

+5
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,10 @@ shared_app_impl!(App<R>);
762762
shared_app_impl!(AppHandle<R>);
763763

764764
impl<R: Runtime> App<R> {
765+
#[cfg_attr(
766+
feature = "tracing",
767+
tracing::instrument(name = "app::core_plugins::register")
768+
)]
765769
fn register_core_plugins(&self) -> crate::Result<()> {
766770
self.handle.plugin(crate::path::plugin::init())?;
767771
self.handle.plugin(crate::event::plugin::init())?;
@@ -1663,6 +1667,7 @@ unsafe impl<R: Runtime> HasRawDisplayHandle for App<R> {
16631667
}
16641668
}
16651669

1670+
#[cfg_attr(feature = "tracing", tracing::instrument(name = "app::setup"))]
16661671
fn setup<R: Runtime>(app: &mut App<R>) -> crate::Result<()> {
16671672
let pending_windows = app.pending_windows.take();
16681673
if let Some(pending_windows) = pending_windows {

core/tauri/src/ipc/mod.rs

+13
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,19 @@ pub enum InvokeResponse {
204204
Err(InvokeError),
205205
}
206206

207+
impl Serialize for InvokeResponse {
208+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
209+
where
210+
S: serde::Serializer,
211+
{
212+
match self {
213+
Self::Ok(InvokeBody::Json(j)) => j.serialize(serializer),
214+
Self::Ok(InvokeBody::Raw(b)) => b.serialize(serializer),
215+
Self::Err(e) => e.0.serialize(serializer),
216+
}
217+
}
218+
}
219+
207220
impl<T: IpcResponse, E: Into<InvokeError>> From<Result<T, E>> for InvokeResponse {
208221
#[inline]
209222
fn from(result: Result<T, E>) -> Self {

core/tauri/src/ipc/protocol.rs

+98-15
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,15 @@
44

55
use std::{borrow::Cow, sync::Arc};
66

7-
use http::{
8-
header::{ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_ORIGIN, CONTENT_TYPE},
9-
HeaderValue, Method, StatusCode,
10-
};
11-
127
use crate::{
138
manager::AppManager,
149
window::{InvokeRequest, UriSchemeProtocolHandler},
1510
Runtime,
1611
};
12+
use http::{
13+
header::{ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_ORIGIN, CONTENT_TYPE},
14+
HeaderValue, Method, StatusCode,
15+
};
1716

1817
use super::{CallbackFn, InvokeBody, InvokeResponse};
1918

@@ -29,6 +28,14 @@ pub fn message_handler<R: Runtime>(
2928

3029
pub fn get<R: Runtime>(manager: Arc<AppManager<R>>, label: String) -> UriSchemeProtocolHandler {
3130
Box::new(move |request, responder| {
31+
#[cfg(feature = "tracing")]
32+
let span = tracing::trace_span!(
33+
"ipc::request",
34+
kind = "custom-protocol",
35+
request = tracing::field::Empty
36+
)
37+
.entered();
38+
3239
let manager = manager.clone();
3340
let label = label.clone();
3441

@@ -44,9 +51,35 @@ pub fn get<R: Runtime>(manager: Arc<AppManager<R>>, label: String) -> UriSchemeP
4451
if let Some(window) = manager.get_window(&label) {
4552
match parse_invoke_request(&manager, request) {
4653
Ok(request) => {
54+
#[cfg(feature = "tracing")]
55+
span.record(
56+
"request",
57+
match &request.body {
58+
InvokeBody::Json(j) => serde_json::to_string(j).unwrap(),
59+
InvokeBody::Raw(b) => serde_json::to_string(b).unwrap(),
60+
},
61+
);
62+
#[cfg(feature = "tracing")]
63+
let request_span = tracing::trace_span!("ipc::request::handle", cmd = request.cmd);
64+
4765
window.on_message(
4866
request,
4967
Box::new(move |_window, _cmd, response, _callback, _error| {
68+
#[cfg(feature = "tracing")]
69+
let _respond_span = tracing::trace_span!(
70+
parent: &request_span,
71+
"ipc::request::respond"
72+
)
73+
.entered();
74+
75+
#[cfg(feature = "tracing")]
76+
let response_span = tracing::trace_span!(
77+
"ipc::request::response",
78+
response = serde_json::to_string(&response).unwrap(),
79+
mime_type = tracing::field::Empty
80+
)
81+
.entered();
82+
5083
let (mut response, mime_type) = match response {
5184
InvokeResponse::Ok(InvokeBody::Json(v)) => (
5285
http::Response::new(serde_json::to_vec(&v).unwrap().into()),
@@ -64,6 +97,9 @@ pub fn get<R: Runtime>(manager: Arc<AppManager<R>>, label: String) -> UriSchemeP
6497
}
6598
};
6699

100+
#[cfg(feature = "tracing")]
101+
response_span.record("mime_type", mime_type.essence_str());
102+
67103
response.headers_mut().insert(
68104
CONTENT_TYPE,
69105
HeaderValue::from_str(mime_type.essence_str()).unwrap(),
@@ -129,6 +165,10 @@ pub fn get<R: Runtime>(manager: Arc<AppManager<R>>, label: String) -> UriSchemeP
129165
#[cfg(any(target_os = "macos", target_os = "ios", not(ipc_custom_protocol)))]
130166
fn handle_ipc_message<R: Runtime>(message: String, manager: &AppManager<R>, label: &str) {
131167
if let Some(window) = manager.get_window(label) {
168+
#[cfg(feature = "tracing")]
169+
let _span =
170+
tracing::trace_span!("ipc::request", kind = "post-message", request = message).entered();
171+
132172
use serde::{Deserialize, Deserializer};
133173

134174
pub(crate) struct HeaderMap(http::HeaderMap);
@@ -185,6 +225,9 @@ fn handle_ipc_message<R: Runtime>(message: String, manager: &AppManager<R>, labe
185225
}
186226

187227
if let crate::Pattern::Isolation { crypto_keys, .. } = &*manager.pattern {
228+
#[cfg(feature = "tracing")]
229+
let _span = tracing::trace_span!("ipc::request::decrypt_isolation_payload").entered();
230+
188231
invoke_message.replace(
189232
serde_json::from_str::<IsolationMessage<'_>>(&message)
190233
.map_err(Into::into)
@@ -201,18 +244,25 @@ fn handle_ipc_message<R: Runtime>(message: String, manager: &AppManager<R>, labe
201244
}
202245
}
203246

204-
match invoke_message
205-
.unwrap_or_else(|| serde_json::from_str::<Message>(&message).map_err(Into::into))
206-
{
247+
match invoke_message.unwrap_or_else(|| {
248+
#[cfg(feature = "tracing")]
249+
let _span = tracing::trace_span!("ipc::request::deserialize").entered();
250+
serde_json::from_str::<Message>(&message).map_err(Into::into)
251+
}) {
207252
Ok(message) => {
253+
let request = InvokeRequest {
254+
cmd: message.cmd,
255+
callback: message.callback,
256+
error: message.error,
257+
body: message.payload.into(),
258+
headers: message.options.map(|o| o.headers.0).unwrap_or_default(),
259+
};
260+
261+
#[cfg(feature = "tracing")]
262+
let request_span = tracing::trace_span!("ipc::request::handle", cmd = request.cmd);
263+
208264
window.on_message(
209-
InvokeRequest {
210-
cmd: message.cmd,
211-
callback: message.callback,
212-
error: message.error,
213-
body: message.payload.into(),
214-
headers: message.options.map(|o| o.headers.0).unwrap_or_default(),
215-
},
265+
request,
216266
Box::new(move |window, cmd, response, callback, error| {
217267
use crate::ipc::{
218268
format_callback::{
@@ -222,6 +272,13 @@ fn handle_ipc_message<R: Runtime>(message: String, manager: &AppManager<R>, labe
222272
};
223273
use serde_json::Value as JsonValue;
224274

275+
#[cfg(feature = "tracing")]
276+
let _respond_span = tracing::trace_span!(
277+
parent: &request_span,
278+
"ipc::request::respond"
279+
)
280+
.entered();
281+
225282
// the channel data command is the only command that uses a custom protocol on Linux
226283
if window.manager.window.invoke_responder.is_none()
227284
&& cmd != crate::ipc::channel::FETCH_CHANNEL_DATA_COMMAND
@@ -240,6 +297,19 @@ fn handle_ipc_message<R: Runtime>(message: String, manager: &AppManager<R>, labe
240297
let _ = window.eval(&eval_js);
241298
}
242299

300+
#[cfg(feature = "tracing")]
301+
let _response_span = tracing::trace_span!(
302+
"ipc::request::response",
303+
response = serde_json::to_string(&response).unwrap(),
304+
mime_type = match &response {
305+
InvokeResponse::Ok(InvokeBody::Json(_)) => mime::APPLICATION_JSON,
306+
InvokeResponse::Ok(InvokeBody::Raw(_)) => mime::APPLICATION_OCTET_STREAM,
307+
InvokeResponse::Err(_) => mime::TEXT_PLAIN,
308+
}
309+
.essence_str()
310+
)
311+
.entered();
312+
243313
match &response {
244314
InvokeResponse::Ok(InvokeBody::Json(v)) => {
245315
if !(cfg!(target_os = "macos") || cfg!(target_os = "ios"))
@@ -277,6 +347,9 @@ fn handle_ipc_message<R: Runtime>(message: String, manager: &AppManager<R>, labe
277347
);
278348
}
279349
Err(e) => {
350+
#[cfg(feature = "tracing")]
351+
tracing::trace!("ipc.request.error {}", e);
352+
280353
let _ = window.eval(&format!(
281354
r#"console.error({})"#,
282355
serde_json::Value::String(e.to_string())
@@ -301,6 +374,9 @@ fn parse_invoke_request<R: Runtime>(
301374
// the body is not set if ipc_custom_protocol is not enabled so we'll just ignore it
302375
#[cfg(all(feature = "isolation", ipc_custom_protocol))]
303376
if let crate::Pattern::Isolation { crypto_keys, .. } = &*manager.pattern {
377+
#[cfg(feature = "tracing")]
378+
let _span = tracing::trace_span!("ipc::request::decrypt_isolation_payload").entered();
379+
304380
body = crate::utils::pattern::isolation::RawIsolationPayload::try_from(&body)
305381
.and_then(|raw| crypto_keys.decrypt(raw))
306382
.map_err(|e| e.to_string())?;
@@ -334,6 +410,10 @@ fn parse_invoke_request<R: Runtime>(
334410
.map(|mime| mime.parse())
335411
.unwrap_or(Ok(mime::APPLICATION_OCTET_STREAM))
336412
.map_err(|_| "unknown content type")?;
413+
414+
#[cfg(feature = "tracing")]
415+
let span = tracing::trace_span!("ipc::request::deserialize").entered();
416+
337417
let body = if content_type == mime::APPLICATION_OCTET_STREAM {
338418
body.into()
339419
} else if content_type == mime::APPLICATION_JSON {
@@ -349,6 +429,9 @@ fn parse_invoke_request<R: Runtime>(
349429
return Err(format!("content type {content_type} is not implemented"));
350430
};
351431

432+
#[cfg(feature = "tracing")]
433+
drop(span);
434+
352435
let payload = InvokeRequest {
353436
cmd,
354437
callback,

core/tauri/src/manager/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,9 @@ impl<R: Runtime> AppManager<R> {
480480
{
481481
assert_event_name_is_valid(event);
482482

483+
#[cfg(feature = "tracing")]
484+
let _span = tracing::debug_span!("emit::run").entered();
485+
483486
let emit_args = EmitArgs::from(event, source_window_label, payload)?;
484487

485488
self
@@ -506,6 +509,9 @@ impl<R: Runtime> AppManager<R> {
506509
) -> crate::Result<()> {
507510
assert_event_name_is_valid(event);
508511

512+
#[cfg(feature = "tracing")]
513+
let _span = tracing::debug_span!("emit::run").entered();
514+
509515
let emit_args = EmitArgs::from(event, source_window_label, payload)?;
510516

511517
self

core/tauri/src/plugin.rs

+3
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,9 @@ impl<R: Runtime> PluginStore<R> {
750750

751751
pub(crate) fn on_navigation(&mut self, window: &Window<R>, url: &Url) -> bool {
752752
for plugin in self.store.iter_mut() {
753+
#[cfg(feature = "tracing")]
754+
let _span =
755+
tracing::trace_span!("plugin::hooks::on_navigation", name = plugin.name()).entered();
753756
if !plugin.on_navigation(window, url) {
754757
return false;
755758
}

core/tauri/src/window/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2410,6 +2410,8 @@ impl<R: Runtime> Window<R> {
24102410
load_channels(&payload, &message.window);
24112411

24122412
let resolver_ = resolver.clone();
2413+
#[cfg(feature = "span")]
2414+
let _span = tracing::debug_span!("ipc::request::mobile_plugin").entered();
24132415
if let Err(e) = crate::plugin::mobile::run_command(
24142416
plugin,
24152417
&app_handle,

0 commit comments

Comments
 (0)