input_pipeline/metrics/
mod.rs1use anyhow::{Context as _, Error};
6use cobalt_client::traits::AsEventCode;
7use log::warn;
8use metrics_registry::*;
9use {fidl_fuchsia_metrics as metrics, fuchsia_async as fasync};
10
11fn create_metrics_logger() -> Result<metrics::MetricEventLoggerProxy, Error> {
14 let factory_proxy =
15 fuchsia_component::client::connect_to_protocol::<metrics::MetricEventLoggerFactoryMarker>()
16 .context("connecting to metrics")?;
17
18 let (cobalt_proxy, cobalt_server) =
19 fidl::endpoints::create_proxy::<metrics::MetricEventLoggerMarker>();
20
21 let project_spec = metrics::ProjectSpec {
22 customer_id: None, project_id: Some(PROJECT_ID),
24 ..Default::default()
25 };
26
27 fasync::Task::spawn(async move {
28 match factory_proxy.create_metric_event_logger(&project_spec, cobalt_server).await {
29 Err(e) => warn!("FIDL failure setting up event logger: {e:?}"),
30 Ok(Err(e)) => warn!("CreateMetricEventLogger failure: {e:?}"),
31 Ok(Ok(())) => {}
32 }
33 })
34 .detach();
35
36 Ok(cobalt_proxy)
37}
38
39fn log_on_failure(result: Result<Result<(), metrics::Error>, fidl::Error>) {
40 match result {
41 Ok(Ok(())) => (),
42 e => warn!("failed to log metrics: {:?}", e),
43 };
44}
45
46#[derive(Clone, Default)]
48pub struct MetricsLogger(Option<metrics::MetricEventLoggerProxy>);
49
50impl MetricsLogger {
51 pub fn new() -> Self {
52 let logger =
53 create_metrics_logger().map_err(|e| warn!("Failed to create metrics logger: {e}")).ok();
54 Self(logger)
55 }
56
57 pub fn log_warn<E: AsEventCode, S: Into<String>>(&self, event_code: E, message: S) {
59 log::warn!("{}", message.into());
60 self.send_metric(event_code);
61 }
62
63 pub fn log_error<E: AsEventCode, S: Into<String>>(&self, event_code: E, message: S) {
65 log::error!("{}", message.into());
66 self.send_metric(event_code);
67 }
68
69 fn send_metric<E: AsEventCode>(&self, event_code: E) {
71 let Some(c) = self.0.clone() else { return };
72 let code = event_code.as_event_code();
73 fuchsia_async::Task::spawn(async move {
74 log_on_failure(c.log_occurrence(INPUT_PIPELINE_ERROR_METRIC_ID, 1, &[code]).await);
75 })
76 .detach();
77 }
78}