use anyhow::{format_err, Context, Error};
use fidl_fuchsia_metrics::{MetricEventLoggerFactoryMarker, MetricEventLoggerProxy, ProjectSpec};
use fuchsia_component::client::connect_to_protocol;
use session_framework_metrics_registry::cobalt_registry as metrics;
use tracing::warn;
use {fuchsia_async as fasync, fuchsia_zircon as zx};
pub fn get_logger() -> Result<MetricEventLoggerProxy, Error> {
let (logger_proxy, server_end) =
fidl::endpoints::create_proxy().context("Failed to create endpoints")?;
let logger_factory = connect_to_protocol::<MetricEventLoggerFactoryMarker>()
.context("Failed to connect to the Cobalt MetricEventLoggerFactory")?;
fasync::Task::spawn(async move {
if let Err(err) = logger_factory
.create_metric_event_logger(
&ProjectSpec { project_id: Some(metrics::PROJECT_ID), ..Default::default() },
server_end,
)
.await
{
warn!(%err, "Failed to create Cobalt logger");
}
})
.detach();
Ok(logger_proxy)
}
pub async fn log_session_launch_time(
logger_proxy: MetricEventLoggerProxy,
start_time: zx::MonotonicTime,
end_time: zx::MonotonicTime,
) -> Result<(), Error> {
let elapsed_time = (end_time - start_time).into_micros();
if elapsed_time < 0 {
return Err(format_err!("End time must be after start time."));
}
logger_proxy
.log_integer(
metrics::SESSION_LAUNCH_TIME_MIGRATED_METRIC_ID,
elapsed_time,
&[metrics::SessionLaunchTimeMigratedMetricDimensionStatus::Success as u32],
)
.await
.context("Could not log session launch time.")?
.map_err(|e| format_err!("Logging session launch time returned an error: {:?}", e))?;
Ok(())
}
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use super::*;
use assert_matches::assert_matches;
use fidl::endpoints::create_proxy_and_stream;
use fidl_fuchsia_metrics::{MetricEventLoggerMarker, MetricEventLoggerRequest};
use futures::TryStreamExt;
#[fuchsia::test(allow_stalls = false)]
async fn test_log_session_launch_time() {
let (logger_proxy, mut logger_server) =
create_proxy_and_stream::<MetricEventLoggerMarker>()
.expect("Failed to create Logger FIDL.");
let start_time = zx::MonotonicTime::from_nanos(0);
let end_time = zx::MonotonicTime::from_nanos(5000);
fasync::Task::spawn(async move {
let _ = log_session_launch_time(logger_proxy, start_time, end_time).await;
})
.detach();
assert_matches!(
logger_server.try_next().await.unwrap(),
Some(MetricEventLoggerRequest::LogInteger {
metric_id: metrics::SESSION_LAUNCH_TIME_MIGRATED_METRIC_ID,
value: 5,
event_codes,
responder: _,
}) => {
assert_eq!(
event_codes,
vec![metrics::SessionLaunchTimeMigratedMetricDimensionStatus::Success as u32]
);
}
)
}
#[fuchsia::test(allow_stalls = false)]
async fn test_log_session_launch_time_swap_start_end_time() {
let (logger_proxy, _logger_server) = create_proxy_and_stream::<MetricEventLoggerMarker>()
.expect("Failed to create Logger FIDL.");
let start_time = zx::MonotonicTime::from_nanos(0);
let end_time = zx::MonotonicTime::from_nanos(5000);
assert!(log_session_launch_time(logger_proxy, end_time, start_time).await.is_err());
}
}