1use fidl_fuchsia_tracing_controller::{self as trace, RecordingError, StartError};
6
7mod trace_task;
8mod triggers;
9
10pub use trace_task::TraceTask;
11pub use triggers::{Trigger, TriggerAction, TriggersWatcher};
12
13#[derive(Debug, thiserror::Error)]
14pub enum TracingError {
15 #[error("cannot open proxy")]
17 TargetProxyOpen,
18 #[error("cannot start recording: {0}")]
20 RecordingStart(String),
21 #[error("recording already started")]
24 RecordingAlreadyStarted,
25 #[error("unable to stop recording: {0:?}")]
29 RecordingStop(String),
30 #[error("trace file {0} already exists.")]
33 DuplicateTraceFile(String),
34 #[error("trace file {0} does not exist.")]
37 NoSuchTraceFile(String),
38
39 #[error("fidl error: {0:?}")]
40 FidlError(#[from] fidl::Error),
41
42 #[error("general error: {0}")]
43 GeneralError(String),
44}
45
46impl From<StartError> for TracingError {
47 fn from(value: StartError) -> Self {
48 match value {
49 StartError::NotInitialized => Self::RecordingStart("not initialized".into()),
50 StartError::AlreadyStarted => Self::RecordingAlreadyStarted,
51 StartError::Stopping => Self::RecordingStart("tracing is stopping".into()),
52 StartError::Terminating => Self::RecordingStart("tracing is terminating".into()),
53 e => Self::GeneralError(format!("Unknown StartError: {e:?}")),
54 }
55 }
56}
57
58impl Into<RecordingError> for TracingError {
59 fn into(self) -> RecordingError {
60 match self {
61 TracingError::TargetProxyOpen => RecordingError::TargetProxyOpen,
62 TracingError::RecordingStart(_) => RecordingError::RecordingStart,
63 TracingError::RecordingAlreadyStarted => RecordingError::RecordingAlreadyStarted,
64 TracingError::RecordingStop(_) => RecordingError::RecordingStop,
65 TracingError::DuplicateTraceFile(_) => RecordingError::DuplicateTraceFile,
66 TracingError::NoSuchTraceFile(_) => RecordingError::NoSuchTraceFile,
67 TracingError::FidlError(_) | TracingError::GeneralError(_) => {
68 RecordingError::RecordingStart
69 }
70 }
71 }
72}
73
74impl PartialEq for TracingError {
75 fn eq(&self, other: &Self) -> bool {
76 match (self, other) {
77 (Self::RecordingStart(l0), Self::RecordingStart(r0)) => l0 == r0,
78 (Self::RecordingStop(l0), Self::RecordingStop(r0)) => l0 == r0,
79 (Self::DuplicateTraceFile(l0), Self::DuplicateTraceFile(r0)) => l0 == r0,
80 (Self::NoSuchTraceFile(l0), Self::NoSuchTraceFile(r0)) => l0 == r0,
81 (Self::FidlError(l0), Self::FidlError(r0)) => l0.to_string() == r0.to_string(),
82 (Self::GeneralError(l0), Self::GeneralError(r0)) => l0 == r0,
83 _ => core::mem::discriminant(self) == core::mem::discriminant(other),
84 }
85 }
86}
87
88pub(crate) async fn trace_shutdown(
89 proxy: &trace::SessionProxy,
90) -> Result<trace::StopResult, TracingError> {
91 let res = proxy
92 .stop_tracing(&trace::StopOptions { write_results: Some(true), ..Default::default() })
93 .await
94 .map_err(|e| {
95 log::warn!("stopping tracing: {:?}", e);
96 TracingError::RecordingStop(e.to_string())
97 })?
98 .map_err(|e| {
99 let msg = format!("Received stop error: {:?}", e);
100 log::warn!("{msg}");
101 TracingError::RecordingStop(msg)
102 });
103 res
104}