pub mod http;
use crate::config::telemetry::tracing::OtlpGrpcTlsConfig;
use hive_console_sdk::expressions::{CompileExpression, ExecutableProgram};
use std::{collections::HashMap, str::FromStr};
use tonic::{
metadata::{MetadataKey, MetadataMap},
transport::ClientTlsConfig,
};
use vrl::core::Value;
use crate::config::primitives::value_or_expression::ValueOrExpression;
use crate::telemetry::error::TelemetryError;
pub(super) fn build_metadata(
headers: HashMap<String, String>,
) -> Result<MetadataMap, TelemetryError> {
let metadata = tonic::metadata::MetadataMap::with_capacity(headers.len());
headers
.into_iter()
.try_fold(metadata, |mut acc, (header_name, header_value)| {
let key = MetadataKey::from_str(header_name.as_str()).map_err(|e| {
TelemetryError::Internal(format!("Invalid metadata key '{}': {}", header_name, e))
})?;
acc.insert(
key,
header_value.as_str().parse().map_err(|e| {
TelemetryError::Internal(format!(
"Invalid metadata value for key '{}': {}",
header_name, e
))
})?,
);
Ok(acc)
})
}
pub(super) fn build_tls_config(
tls: Option<&OtlpGrpcTlsConfig>,
) -> Result<ClientTlsConfig, TelemetryError> {
match tls {
Some(tls_config) => ClientTlsConfig::try_from(tls_config)
.map_err(|e| TelemetryError::TracesExporterSetup(e.to_string())),
None => Ok(ClientTlsConfig::default()),
}
}
pub(super) fn resolve_string_map(
map: &HashMap<String, ValueOrExpression<String>>,
context_prefix: &str,
) -> Result<HashMap<String, String>, TelemetryError> {
map.iter()
.map(|(k, v)| {
let value = resolve_value_or_expression(v, &format!("{} '{}'", context_prefix, k))?;
Ok((k.clone(), value))
})
.collect()
}
pub fn evaluate_expression_as_string(
expression: &str,
context: &str,
) -> Result<String, TelemetryError> {
Ok(expression
.compile_expression(None)
.map_err(|e| {
TelemetryError::TracesExporterSetup(format!(
"Failed to compile {} expression: {}",
context, e
))
})?
.execute(Value::Null) .map_err(|e| {
TelemetryError::TracesExporterSetup(format!(
"Failed to execute {} expression: {}",
context, e
))
})?
.as_str()
.ok_or_else(|| {
TelemetryError::TracesExporterSetup(format!(
"{} expression must return a string",
context
))
})?
.to_string())
}
pub fn resolve_value_or_expression(
value_or_expr: &ValueOrExpression<String>,
context: &str,
) -> Result<String, TelemetryError> {
match value_or_expr {
ValueOrExpression::Value(v) => Ok(v.clone()),
ValueOrExpression::Expression { expression } => {
evaluate_expression_as_string(expression, context)
}
}
}
pub struct RequestRoutePattern(pub &'static str);