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}