1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
//! API request/response models for health probes.
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use utoipa::{IntoParams, ToSchema};
use uuid::Uuid;
/// Request payload for creating a new probe.
///
/// Created probes are automatically activated and start executing on their
/// configured interval.
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CreateProbe {
/// Human-readable name for the probe
pub name: String,
/// Reference to the deployment (model) to monitor
#[schema(value_type = String, format = "uuid")]
pub deployment_id: Uuid,
/// How often to execute the probe, in seconds
pub interval_seconds: i32,
/// HTTP method to use for the probe request (defaults to POST if not provided)
#[serde(default = "default_http_method")]
pub http_method: String,
/// Path to append to the endpoint URL (e.g., /v1/chat/completions)
pub request_path: Option<String>,
/// JSON body to send with the probe request
pub request_body: Option<serde_json::Value>,
}
fn default_http_method() -> String {
"POST".to_string()
}
/// Request payload for testing a probe configuration
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct TestProbeRequest {
/// HTTP method to use for the test request
pub http_method: Option<String>,
/// Path to append to the endpoint URL
pub request_path: Option<String>,
/// JSON body to send with the test request
pub request_body: Option<serde_json::Value>,
}
/// Query parameters for filtering probes
#[derive(Debug, Deserialize, IntoParams, ToSchema)]
pub struct ProbesQuery {
/// Filter by probe status: "active" to show only active probes, omit to show all
pub status: Option<String>,
}
/// Query parameters for filtering probe results
#[derive(Debug, Deserialize, IntoParams, ToSchema)]
pub struct ResultsQuery {
/// Start time for filtering results
#[param(value_type = Option<String>, format = "date-time")]
#[schema(value_type = Option<String>, format = "date-time")]
pub start_time: Option<DateTime<Utc>>,
/// End time for filtering results
#[param(value_type = Option<String>, format = "date-time")]
#[schema(value_type = Option<String>, format = "date-time")]
pub end_time: Option<DateTime<Utc>>,
/// Maximum number of results to return
pub limit: Option<i64>,
}
/// Query parameters for probe statistics
#[derive(Debug, Deserialize, IntoParams, ToSchema)]
pub struct StatsQuery {
/// Start time for statistics calculation
#[param(value_type = Option<String>, format = "date-time")]
#[schema(value_type = Option<String>, format = "date-time")]
pub start_time: Option<DateTime<Utc>>,
/// End time for statistics calculation
#[param(value_type = Option<String>, format = "date-time")]
#[schema(value_type = Option<String>, format = "date-time")]
pub end_time: Option<DateTime<Utc>>,
}
/// Request payload for updating a probe
#[derive(Debug, Clone, Deserialize, ToSchema)]
pub struct UpdateProbeRequest {
/// Update probe execution interval in seconds
pub interval_seconds: Option<i32>,
/// Update HTTP method for the probe request
pub http_method: Option<String>,
/// Update the request path
pub request_path: Option<String>,
/// Update the request body
pub request_body: Option<serde_json::Value>,
}
/// Aggregated statistics for a probe over a time period.
///
/// Statistics are calculated from stored probe results and include
/// percentile metrics for response times.
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct ProbeStatistics {
/// Total number of probe executions
pub total_executions: i64,
/// Number of successful executions
pub successful_executions: i64,
/// Number of failed executions
pub failed_executions: i64,
/// Success rate as a percentage (0-100)
pub success_rate: f64,
/// Average response time in milliseconds (successful probes only)
pub avg_response_time_ms: Option<f64>,
/// Minimum response time in milliseconds
pub min_response_time_ms: Option<i32>,
/// Maximum response time in milliseconds
pub max_response_time_ms: Option<i32>,
/// 50th percentile (median) response time
pub p50_response_time_ms: Option<f64>,
/// 95th percentile response time
pub p95_response_time_ms: Option<f64>,
/// 99th percentile response time
pub p99_response_time_ms: Option<f64>,
/// Timestamp of the most recent execution
#[schema(value_type = Option<String>, format = "date-time")]
pub last_execution: Option<DateTime<Utc>>,
/// Timestamp of the most recent successful execution
#[schema(value_type = Option<String>, format = "date-time")]
pub last_success: Option<DateTime<Utc>>,
/// Timestamp of the most recent failed execution
#[schema(value_type = Option<String>, format = "date-time")]
pub last_failure: Option<DateTime<Utc>>,
}
impl Default for ProbeStatistics {
fn default() -> Self {
Self {
total_executions: 0,
successful_executions: 0,
failed_executions: 0,
success_rate: 0.0,
avg_response_time_ms: None,
min_response_time_ms: None,
max_response_time_ms: None,
p50_response_time_ms: None,
p95_response_time_ms: None,
p99_response_time_ms: None,
last_execution: None,
last_success: None,
last_failure: None,
}
}
}