use async_graphql::{Enum, Object};
use chrono::{DateTime, Utc};
use serde_json::Value;
use vector_lib::encode_logfmt;
use vector_lib::event;
use vector_lib::tap::topology::TapOutput;
use super::EventEncodingType;
#[derive(Debug, Clone)]
pub struct Metric {
output: TapOutput,
event: event::Metric,
}
impl Metric {
pub const fn new(output: TapOutput, event: event::Metric) -> Self {
Self { output, event }
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Enum)]
enum MetricKind {
Incremental,
Absolute,
}
impl From<event::MetricKind> for MetricKind {
fn from(kind: event::MetricKind) -> Self {
match kind {
event::MetricKind::Incremental => Self::Incremental,
event::MetricKind::Absolute => Self::Absolute,
}
}
}
struct MetricTag {
key: String,
value: String,
}
#[Object]
impl MetricTag {
async fn key(&self) -> &str {
self.key.as_ref()
}
async fn value(&self) -> &str {
self.value.as_ref()
}
}
#[Object]
impl Metric {
async fn component_id(&self) -> &str {
self.output.output_id.component.id()
}
async fn component_type(&self) -> &str {
self.output.component_type.as_ref()
}
async fn component_kind(&self) -> &str {
self.output.component_kind
}
async fn timestamp(&self) -> Option<&DateTime<Utc>> {
self.event.data().timestamp()
}
async fn name(&self) -> &str {
self.event.name()
}
async fn namespace(&self) -> Option<&str> {
self.event.namespace()
}
async fn kind(&self) -> MetricKind {
self.event.kind().into()
}
async fn value_type(&self) -> &str {
self.event.value().as_name()
}
async fn value(&self) -> String {
self.event.value().to_string()
}
async fn tags(&self) -> Option<Vec<MetricTag>> {
self.event.tags().map(|tags| {
tags.iter_single()
.map(|(key, value)| MetricTag {
key: key.to_owned(),
value: value.to_owned(),
})
.collect()
})
}
async fn string(&self, encoding: EventEncodingType) -> String {
match encoding {
EventEncodingType::Json => serde_json::to_string(&self.event)
.expect("JSON serialization of metric event failed. Please report."),
EventEncodingType::Yaml => serde_yaml::to_string(&self.event)
.expect("YAML serialization of metric event failed. Please report."),
EventEncodingType::Logfmt => {
let json = serde_json::to_value(&self.event)
.expect("logfmt serialization of metric event failed: conversion to serde Value failed. Please report.");
match json {
Value::Object(map) => encode_logfmt::encode_map(
&map.into_iter().map(|(k,v)| (event::KeyString::from(k), v)).collect(),
)
.expect("logfmt serialization of metric event failed. Please report."),
_ => panic!("logfmt serialization of metric event failed: metric converted to unexpected serde Value. Please report."),
}
}
}
}
}