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