use crate::proto::tero::policy::v1::{AttributePath, LogField, MetricField, TraceField};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum LogFieldSelector {
Simple(LogField),
LogAttribute(Vec<String>),
ResourceAttribute(Vec<String>),
ScopeAttribute(Vec<String>),
}
impl LogFieldSelector {
pub fn from_json(field_type: &str, key: Option<&str>) -> Option<Self> {
match field_type {
"log_body" => Some(LogFieldSelector::Simple(LogField::Body)),
"log_severity_text" => Some(LogFieldSelector::Simple(LogField::SeverityText)),
"log_trace_id" => Some(LogFieldSelector::Simple(LogField::TraceId)),
"log_span_id" => Some(LogFieldSelector::Simple(LogField::SpanId)),
"log_event_name" => Some(LogFieldSelector::Simple(LogField::EventName)),
"resource_schema_url" => Some(LogFieldSelector::Simple(LogField::ResourceSchemaUrl)),
"scope_schema_url" => Some(LogFieldSelector::Simple(LogField::ScopeSchemaUrl)),
"log_attribute" => key.map(|k| LogFieldSelector::LogAttribute(vec![k.to_string()])),
"resource_attribute" => {
key.map(|k| LogFieldSelector::ResourceAttribute(vec![k.to_string()]))
}
"scope_attribute" => key.map(|k| LogFieldSelector::ScopeAttribute(vec![k.to_string()])),
_ => None,
}
}
pub fn from_log_attribute(path: &AttributePath) -> Self {
LogFieldSelector::LogAttribute(path.path.clone())
}
pub fn from_resource_attribute(path: &AttributePath) -> Self {
LogFieldSelector::ResourceAttribute(path.path.clone())
}
pub fn from_scope_attribute(path: &AttributePath) -> Self {
LogFieldSelector::ScopeAttribute(path.path.clone())
}
pub fn attribute_path(&self) -> Option<&[String]> {
match self {
LogFieldSelector::LogAttribute(p)
| LogFieldSelector::ResourceAttribute(p)
| LogFieldSelector::ScopeAttribute(p) => Some(p),
LogFieldSelector::Simple(_) => None,
}
}
pub fn attribute_key(&self) -> Option<&str> {
self.attribute_path()
.and_then(|p| p.first())
.map(|s| s.as_str())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum MetricFieldSelector {
Simple(MetricField),
DatapointAttribute(Vec<String>),
ResourceAttribute(Vec<String>),
ScopeAttribute(Vec<String>),
Type,
Temporality,
}
impl MetricFieldSelector {
pub fn from_datapoint_attribute(path: &AttributePath) -> Self {
MetricFieldSelector::DatapointAttribute(path.path.clone())
}
pub fn from_resource_attribute(path: &AttributePath) -> Self {
MetricFieldSelector::ResourceAttribute(path.path.clone())
}
pub fn from_scope_attribute(path: &AttributePath) -> Self {
MetricFieldSelector::ScopeAttribute(path.path.clone())
}
pub fn attribute_path(&self) -> Option<&[String]> {
match self {
MetricFieldSelector::DatapointAttribute(p)
| MetricFieldSelector::ResourceAttribute(p)
| MetricFieldSelector::ScopeAttribute(p) => Some(p),
MetricFieldSelector::Simple(_)
| MetricFieldSelector::Type
| MetricFieldSelector::Temporality => None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum TraceFieldSelector {
Simple(TraceField),
SpanAttribute(Vec<String>),
ResourceAttribute(Vec<String>),
ScopeAttribute(Vec<String>),
SpanKind,
SpanStatus,
EventName,
EventAttribute(Vec<String>),
LinkTraceId,
SamplingThreshold,
}
impl TraceFieldSelector {
pub fn from_span_attribute(path: &AttributePath) -> Self {
TraceFieldSelector::SpanAttribute(path.path.clone())
}
pub fn from_resource_attribute(path: &AttributePath) -> Self {
TraceFieldSelector::ResourceAttribute(path.path.clone())
}
pub fn from_scope_attribute(path: &AttributePath) -> Self {
TraceFieldSelector::ScopeAttribute(path.path.clone())
}
pub fn from_event_attribute(path: &AttributePath) -> Self {
TraceFieldSelector::EventAttribute(path.path.clone())
}
pub fn attribute_path(&self) -> Option<&[String]> {
match self {
TraceFieldSelector::SpanAttribute(p)
| TraceFieldSelector::ResourceAttribute(p)
| TraceFieldSelector::ScopeAttribute(p)
| TraceFieldSelector::EventAttribute(p) => Some(p),
TraceFieldSelector::Simple(_)
| TraceFieldSelector::SpanKind
| TraceFieldSelector::SpanStatus
| TraceFieldSelector::EventName
| TraceFieldSelector::LinkTraceId
| TraceFieldSelector::SamplingThreshold => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_simple_fields() {
assert_eq!(
LogFieldSelector::from_json("log_body", None),
Some(LogFieldSelector::Simple(LogField::Body))
);
assert_eq!(
LogFieldSelector::from_json("log_severity_text", None),
Some(LogFieldSelector::Simple(LogField::SeverityText))
);
}
#[test]
fn parse_attribute_fields() {
assert_eq!(
LogFieldSelector::from_json("log_attribute", Some("ddsource")),
Some(LogFieldSelector::LogAttribute(vec!["ddsource".to_string()]))
);
assert_eq!(
LogFieldSelector::from_json("resource_attribute", Some("service.name")),
Some(LogFieldSelector::ResourceAttribute(vec![
"service.name".to_string()
]))
);
}
#[test]
fn parse_attribute_without_key_returns_none() {
assert_eq!(LogFieldSelector::from_json("log_attribute", None), None);
}
#[test]
fn parse_unknown_field_returns_none() {
assert_eq!(LogFieldSelector::from_json("unknown", None), None);
}
#[test]
fn from_attribute_path() {
let path = AttributePath {
path: vec!["http".to_string(), "method".to_string()],
};
let selector = LogFieldSelector::from_log_attribute(&path);
assert_eq!(
selector,
LogFieldSelector::LogAttribute(vec!["http".to_string(), "method".to_string()])
);
assert_eq!(
selector.attribute_path(),
Some(&["http".to_string(), "method".to_string()][..])
);
assert_eq!(selector.attribute_key(), Some("http"));
}
#[test]
fn attribute_key_backward_compat() {
let selector = LogFieldSelector::LogAttribute(vec!["user_id".to_string()]);
assert_eq!(selector.attribute_key(), Some("user_id"));
}
#[test]
fn trace_field_selector_from_span_attribute() {
let path = AttributePath {
path: vec!["http.method".to_string()],
};
let selector = TraceFieldSelector::from_span_attribute(&path);
assert_eq!(
selector,
TraceFieldSelector::SpanAttribute(vec!["http.method".to_string()])
);
assert_eq!(
selector.attribute_path(),
Some(&["http.method".to_string()][..])
);
}
#[test]
fn trace_field_selector_simple_has_no_path() {
let selector = TraceFieldSelector::Simple(TraceField::Name);
assert_eq!(selector.attribute_path(), None);
}
#[test]
fn trace_field_selector_unit_variants_have_no_path() {
assert_eq!(TraceFieldSelector::SpanKind.attribute_path(), None);
assert_eq!(TraceFieldSelector::SpanStatus.attribute_path(), None);
assert_eq!(TraceFieldSelector::EventName.attribute_path(), None);
assert_eq!(TraceFieldSelector::LinkTraceId.attribute_path(), None);
assert_eq!(TraceFieldSelector::SamplingThreshold.attribute_path(), None);
}
}