use {
anyhow::{format_err, Context, Error},
fidl_fuchsia_metrics::{MetricEventLoggerFactoryMarker, MetricEventLoggerProxy, ProjectSpec},
fuchsia_async as fasync,
fuchsia_component::client::connect_to_protocol,
fuchsia_zircon as zx,
session_framework_metrics_registry::cobalt_registry as metrics,
tracing::warn,
};
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::Time,
end_time: zx::Time,
) -> 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)]
mod tests {
use {
super::*,
fidl::endpoints::create_proxy_and_stream,
fidl_fuchsia_metrics::{MetricEventLoggerMarker, MetricEventLoggerRequest},
futures::TryStreamExt,
};
#[fasync::run_singlethreaded(test)]
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::Time::from_nanos(0);
let end_time = zx::Time::from_nanos(5000);
fasync::Task::spawn(async move {
let _ = log_session_launch_time(logger_proxy, start_time, end_time).await;
})
.detach();
if let Some(log_request) = logger_server.try_next().await.unwrap() {
if let MetricEventLoggerRequest::LogInteger {
metric_id,
value,
event_codes,
responder: _,
} = log_request
{
assert_eq!(metric_id, metrics::SESSION_LAUNCH_TIME_MIGRATED_METRIC_ID);
assert_eq!(
event_codes,
vec![metrics::SessionLaunchTimeMigratedMetricDimensionStatus::Success as u32]
);
assert_eq!(value, 5);
} else {
assert!(false);
}
} else {
assert!(false);
}
}
#[fasync::run_singlethreaded(test)]
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::Time::from_nanos(0);
let end_time = zx::Time::from_nanos(5000);
assert!(log_session_launch_time(logger_proxy, end_time, start_time).await.is_err());
}
}