Skip to main content

pipedash_core/domain/
metrics.rs

1use chrono::{
2    DateTime,
3    Utc,
4};
5use serde::{
6    Deserialize,
7    Serialize,
8};
9
10#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
11#[serde(rename_all = "snake_case")]
12pub enum MetricType {
13    RunDuration,
14    SuccessRate,
15    RunFrequency,
16}
17
18impl MetricType {
19    pub fn as_str(&self) -> &'static str {
20        match self {
21            MetricType::RunDuration => "run_duration",
22            MetricType::SuccessRate => "success_rate",
23            MetricType::RunFrequency => "run_frequency",
24        }
25    }
26}
27
28impl std::str::FromStr for MetricType {
29    type Err = String;
30
31    fn from_str(s: &str) -> Result<Self, Self::Err> {
32        match s {
33            "run_duration" => Ok(MetricType::RunDuration),
34            "success_rate" => Ok(MetricType::SuccessRate),
35            "run_frequency" => Ok(MetricType::RunFrequency),
36            _ => Err(format!("Unknown metric type: {}", s)),
37        }
38    }
39}
40
41#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
42#[serde(rename_all = "lowercase")]
43pub enum AggregationPeriod {
44    Hourly,
45    Daily,
46    Weekly,
47    Monthly,
48}
49
50#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
51#[serde(rename_all = "lowercase")]
52pub enum AggregationType {
53    Avg,
54    Sum,
55    Min,
56    Max,
57    P95,
58    P99,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct GlobalMetricsConfig {
63    pub enabled: bool,
64    pub default_retention_days: i64,
65    pub updated_at: DateTime<Utc>,
66}
67
68impl Default for GlobalMetricsConfig {
69    fn default() -> Self {
70        Self {
71            enabled: false,
72            default_retention_days: 7,
73            updated_at: Utc::now(),
74        }
75    }
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
79pub struct MetricsConfig {
80    pub pipeline_id: String,
81    pub enabled: bool,
82    pub retention_days: i64,
83    pub created_at: DateTime<Utc>,
84    pub updated_at: DateTime<Utc>,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize, Default)]
88pub struct MetricsConfigExport {
89    pub global_config: GlobalMetricsConfig,
90    pub pipeline_configs: Vec<MetricsConfig>,
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct MetricEntry {
95    pub id: i64,
96    pub pipeline_id: String,
97    pub run_number: i64,
98    pub timestamp: DateTime<Utc>,
99    pub metric_type: MetricType,
100    pub value: f64,
101    pub metadata: Option<serde_json::Value>,
102    pub created_at: DateTime<Utc>,
103    pub run_hash: Option<String>,
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize)]
107pub struct MetricsQuery {
108    pub pipeline_id: Option<String>,
109    pub metric_type: Option<MetricType>,
110    pub start_date: Option<DateTime<Utc>>,
111    pub end_date: Option<DateTime<Utc>>,
112    pub aggregation_period: Option<AggregationPeriod>,
113    pub aggregation_type: Option<AggregationType>,
114    pub limit: Option<usize>,
115}
116
117impl Default for MetricsQuery {
118    fn default() -> Self {
119        Self {
120            pipeline_id: None,
121            metric_type: None,
122            start_date: None,
123            end_date: None,
124            aggregation_period: None,
125            aggregation_type: None,
126            limit: Some(1000),
127        }
128    }
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize)]
132pub struct AggregatedMetric {
133    pub timestamp: DateTime<Utc>,
134    pub value: f64,
135    pub count: i64,
136    pub min: Option<f64>,
137    pub max: Option<f64>,
138    pub avg: f64,
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct AggregatedMetrics {
143    pub metrics: Vec<AggregatedMetric>,
144    pub total_count: usize,
145    pub metric_type: MetricType,
146    pub aggregation_period: AggregationPeriod,
147}
148
149#[derive(Debug, Clone, Serialize, Deserialize)]
150pub struct MetricsStats {
151    pub total_metrics_count: i64,
152    pub estimated_size_bytes: i64,
153    pub estimated_size_mb: f64,
154    pub last_cleanup_at: Option<DateTime<Utc>>,
155    pub updated_at: DateTime<Utc>,
156    pub by_pipeline: Vec<PipelineMetricsStats>,
157}
158
159#[derive(Debug, Clone, Serialize, Deserialize)]
160pub struct PipelineMetricsStats {
161    pub pipeline_id: String,
162    pub pipeline_name: String,
163    pub metrics_count: i64,
164    pub oldest_metric: Option<DateTime<Utc>>,
165    pub newest_metric: Option<DateTime<Utc>>,
166}
167
168#[derive(Debug, Clone, Serialize, Deserialize)]
169pub struct MetricMetadata {
170    pub status: Option<String>,
171    pub branch: Option<String>,
172    pub repository: Option<String>,
173    pub actor: Option<String>,
174}
175
176impl MetricMetadata {
177    pub fn to_json(&self) -> serde_json::Value {
178        serde_json::to_value(self).unwrap_or(serde_json::Value::Null)
179    }
180}