session_manager_lib/
cobalt.rs1use anyhow::{format_err, Context, Error};
6use fidl_fuchsia_metrics::{MetricEventLoggerFactoryMarker, MetricEventLoggerProxy, ProjectSpec};
7use fuchsia_async as fasync;
8use fuchsia_component::client::connect_to_protocol;
9use log::warn;
10use session_framework_metrics_registry::cobalt_registry as metrics;
11
12pub fn get_logger() -> Result<MetricEventLoggerProxy, Error> {
20 let (logger_proxy, server_end) = fidl::endpoints::create_proxy();
21 let logger_factory = connect_to_protocol::<MetricEventLoggerFactoryMarker>()
22 .context("Failed to connect to the Cobalt MetricEventLoggerFactory")?;
23
24 fasync::Task::spawn(async move {
25 if let Err(err) = logger_factory
26 .create_metric_event_logger(
27 &ProjectSpec { project_id: Some(metrics::PROJECT_ID), ..Default::default() },
28 server_end,
29 )
30 .await
31 {
32 warn!(err:%; "Failed to create Cobalt logger");
33 }
34 })
35 .detach();
36
37 Ok(logger_proxy)
38}
39
40pub async fn log_session_launch_time(
51 logger_proxy: MetricEventLoggerProxy,
52 start_time: zx::MonotonicInstant,
53 end_time: zx::MonotonicInstant,
54) -> Result<(), Error> {
55 let elapsed_time = (end_time - start_time).into_micros();
56 if elapsed_time < 0 {
57 return Err(format_err!("End time must be after start time."));
58 }
59
60 logger_proxy
61 .log_integer(
62 metrics::SESSION_LAUNCH_TIME_MIGRATED_METRIC_ID,
63 elapsed_time,
64 &[metrics::SessionLaunchTimeMigratedMetricDimensionStatus::Success as u32],
65 )
66 .await
67 .context("Could not log session launch time.")?
68 .map_err(|e| format_err!("Logging session launch time returned an error: {:?}", e))?;
69
70 Ok(())
71}
72
73#[cfg(test)]
74#[allow(clippy::unwrap_used)]
75mod tests {
76 use super::*;
77 use assert_matches::assert_matches;
78 use fidl::endpoints::create_proxy_and_stream;
79 use fidl_fuchsia_metrics::{MetricEventLoggerMarker, MetricEventLoggerRequest};
80 use futures::TryStreamExt;
81
82 #[fuchsia::test(allow_stalls = false)]
84 async fn test_log_session_launch_time() {
85 let (logger_proxy, mut logger_server) =
86 create_proxy_and_stream::<MetricEventLoggerMarker>();
87 let start_time = zx::MonotonicInstant::from_nanos(0);
88 let end_time = zx::MonotonicInstant::from_nanos(5000);
89
90 fasync::Task::spawn(async move {
91 let _ = log_session_launch_time(logger_proxy, start_time, end_time).await;
92 })
93 .detach();
94
95 assert_matches!(
96 logger_server.try_next().await.unwrap(),
97 Some(MetricEventLoggerRequest::LogInteger {
98 metric_id: metrics::SESSION_LAUNCH_TIME_MIGRATED_METRIC_ID,
99 value: 5,
100 event_codes,
101 responder: _,
102 }) => {
103 assert_eq!(
104 event_codes,
105 vec![metrics::SessionLaunchTimeMigratedMetricDimensionStatus::Success as u32]
106 );
107 }
108 )
109 }
110
111 #[fuchsia::test(allow_stalls = false)]
113 async fn test_log_session_launch_time_swap_start_end_time() {
114 let (logger_proxy, _logger_server) = create_proxy_and_stream::<MetricEventLoggerMarker>();
115 let start_time = zx::MonotonicInstant::from_nanos(0);
116 let end_time = zx::MonotonicInstant::from_nanos(5000);
117
118 assert!(log_session_launch_time(logger_proxy, end_time, start_time).await.is_err());
119 }
120}