use std::time::Duration;
use once_cell::sync::Lazy;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::config::{
primitives::value_or_expression::ValueOrExpression, usage_reporting::UsageReportingConfig,
};
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
#[serde(deny_unknown_fields)]
#[derive(Default)]
pub struct HiveTelemetryConfig {
#[serde(default)]
pub token: Option<ValueOrExpression<String>>,
#[serde(default)]
pub target: Option<ValueOrExpression<String>>,
#[serde(default)]
pub tracing: TracingConfig,
#[serde(default)]
pub usage_reporting: UsageReportingConfig,
}
static TARGET_ID_SLUG_REGEX: Lazy<regex_automata::meta::Regex> = Lazy::new(|| {
regex_automata::meta::Regex::new(r"^[a-zA-Z0-9-_]+\/[a-zA-Z0-9-_]+\/[a-zA-Z0-9-_]+$")
.expect("Failed to compile slug regex")
});
static TARGET_ID_UUID_REGEX: Lazy<regex_automata::meta::Regex> = Lazy::new(|| {
regex_automata::meta::Regex::new(
r"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",
)
.expect("Failed to compile UUID regex")
});
pub fn is_uuid_target_ref(target_id: &str) -> bool {
TARGET_ID_UUID_REGEX.is_match(target_id.trim())
}
pub fn is_slug_target_ref(target_id: &str) -> bool {
TARGET_ID_SLUG_REGEX.is_match(target_id.trim())
}
fn default_hive_tracing_endpoint() -> ValueOrExpression<String> {
ValueOrExpression::Value("https://api.graphql-hive.com/otel/v1/traces".to_string())
}
impl Default for TracingConfig {
fn default() -> Self {
Self {
enabled: default_tracing_enabled(),
endpoint: default_hive_tracing_endpoint(),
batch_processor: TraceBatchProcessorConfig::default(),
}
}
}
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
#[serde(deny_unknown_fields)]
pub struct TracingConfig {
#[serde(default = "default_tracing_enabled")]
pub enabled: bool,
#[serde(default = "default_hive_tracing_endpoint")]
pub endpoint: ValueOrExpression<String>,
#[serde(default)]
pub batch_processor: TraceBatchProcessorConfig,
}
fn default_tracing_enabled() -> bool {
false
}
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
#[serde(deny_unknown_fields)]
pub struct TraceBatchProcessorConfig {
#[serde(default = "default_max_traces_in_memory")]
pub max_traces_in_memory: u32,
#[serde(default = "default_max_spans_per_trace")]
pub max_spans_per_trace: u32,
#[serde(
default = "default_max_export_timeout",
deserialize_with = "humantime_serde::deserialize",
serialize_with = "humantime_serde::serialize"
)]
#[schemars(with = "String")]
pub max_export_timeout: Duration,
#[serde(default = "default_max_queue_size")]
pub max_queue_size: u32,
#[serde(default = "default_max_export_batch_size")]
pub max_export_batch_size: u32,
#[serde(
default = "default_scheduled_delay",
deserialize_with = "humantime_serde::deserialize",
serialize_with = "humantime_serde::serialize"
)]
#[schemars(with = "String")]
pub scheduled_delay: Duration,
#[serde(default = "default_max_concurrent_exports")]
pub max_concurrent_exports: u32,
}
impl Default for TraceBatchProcessorConfig {
fn default() -> Self {
Self {
max_concurrent_exports: default_max_concurrent_exports(),
max_traces_in_memory: default_max_traces_in_memory(),
max_export_timeout: default_max_export_timeout(),
max_spans_per_trace: default_max_spans_per_trace(),
max_queue_size: default_max_queue_size(),
max_export_batch_size: default_max_export_batch_size(),
scheduled_delay: default_scheduled_delay(),
}
}
}
fn default_max_traces_in_memory() -> u32 {
30_000
}
fn default_max_spans_per_trace() -> u32 {
1000
}
fn default_max_export_timeout() -> Duration {
Duration::from_secs(5)
}
fn default_max_queue_size() -> u32 {
20_000
}
fn default_max_export_batch_size() -> u32 {
500
}
fn default_scheduled_delay() -> Duration {
Duration::from_secs(5)
}
fn default_max_concurrent_exports() -> u32 {
1
}