vector/api/schema/events/
metric.rs

1use async_graphql::{Enum, Object};
2use chrono::{DateTime, Utc};
3use serde_json::Value;
4use vector_lib::{encode_logfmt, event, tap::topology::TapOutput};
5
6use super::EventEncodingType;
7
8#[derive(Debug, Clone)]
9pub struct Metric {
10    output: TapOutput,
11    event: event::Metric,
12}
13
14impl Metric {
15    pub const fn new(output: TapOutput, event: event::Metric) -> Self {
16        Self { output, event }
17    }
18}
19
20#[derive(Copy, Clone, Debug, PartialEq, Eq, Enum)]
21enum MetricKind {
22    /// Incremental metrics update previous values
23    Incremental,
24    /// Absolute metrics set the reference value for future updates
25    Absolute,
26}
27
28impl From<event::MetricKind> for MetricKind {
29    fn from(kind: event::MetricKind) -> Self {
30        match kind {
31            event::MetricKind::Incremental => Self::Incremental,
32            event::MetricKind::Absolute => Self::Absolute,
33        }
34    }
35}
36
37struct MetricTag {
38    key: String,
39    value: String,
40}
41
42#[Object]
43impl MetricTag {
44    /// Metric tag key
45    async fn key(&self) -> &str {
46        self.key.as_ref()
47    }
48
49    /// Metric tag value
50    async fn value(&self) -> &str {
51        self.value.as_ref()
52    }
53}
54
55#[Object]
56/// Metric event with fields for querying metric data
57impl Metric {
58    /// Id of the component associated with the metric event
59    async fn component_id(&self) -> &str {
60        self.output.output_id.component.id()
61    }
62
63    /// Type of component associated with the metric event
64    async fn component_type(&self) -> &str {
65        self.output.component_type.as_ref()
66    }
67
68    /// Kind of component associated with the metric event
69    async fn component_kind(&self) -> &str {
70        self.output.component_kind
71    }
72
73    /// Metric timestamp
74    async fn timestamp(&self) -> Option<&DateTime<Utc>> {
75        self.event.data().timestamp()
76    }
77
78    /// Metric name
79    async fn name(&self) -> &str {
80        self.event.name()
81    }
82
83    /// Metric namespace
84    async fn namespace(&self) -> Option<&str> {
85        self.event.namespace()
86    }
87
88    /// Metric kind
89    async fn kind(&self) -> MetricKind {
90        self.event.kind().into()
91    }
92
93    /// Metric type
94    async fn value_type(&self) -> &str {
95        self.event.value().as_name()
96    }
97
98    /// Metric value in human readable form
99    async fn value(&self) -> String {
100        self.event.value().to_string()
101    }
102
103    /// Metric tags
104    async fn tags(&self) -> Option<Vec<MetricTag>> {
105        self.event.tags().map(|tags| {
106            tags.iter_single()
107                .map(|(key, value)| MetricTag {
108                    key: key.to_owned(),
109                    value: value.to_owned(),
110                })
111                .collect()
112        })
113    }
114
115    /// Metric event as an encoded string format
116    async fn string(&self, encoding: EventEncodingType) -> String {
117        match encoding {
118            EventEncodingType::Json => serde_json::to_string(&self.event)
119                .expect("JSON serialization of metric event failed. Please report."),
120            EventEncodingType::Yaml => serde_yaml::to_string(&self.event)
121                .expect("YAML serialization of metric event failed. Please report."),
122            EventEncodingType::Logfmt => {
123                let json = serde_json::to_value(&self.event)
124                    .expect("logfmt serialization of metric event failed: conversion to serde Value failed. Please report.");
125                match json {
126                    Value::Object(map) => encode_logfmt::encode_map(
127                        &map.into_iter()
128                            .map(|(k, v)| (event::KeyString::from(k), v))
129                            .collect(),
130                    )
131                    .expect("logfmt serialization of metric event failed. Please report."),
132                    _ => panic!(
133                        "logfmt serialization of metric event failed: metric converted to unexpected serde Value. Please report."
134                    ),
135                }
136            }
137        }
138    }
139}