use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct AnvilEvent {
pub timestamp: DateTime<Utc>,
pub pid: Option<u32>,
pub event_type: AnvilEventType,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum AnvilEventType {
ConfigWarning {
file_path: String,
line_number: u32,
parameter_name: String,
message: String,
},
Statistics {
metric_type: StatisticType,
value: u32,
rate_window: Option<String>, service_client: String,
timestamp: DateTime<Utc>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum StatisticType {
MaxConnectionRate,
MaxConnectionCount,
MaxMessageRate,
MaxCacheSize,
}
impl AnvilEvent {
pub fn new(timestamp: DateTime<Utc>, pid: Option<u32>, event_type: AnvilEventType) -> Self {
Self {
timestamp,
pid,
event_type,
}
}
pub fn config_warning(
timestamp: DateTime<Utc>,
pid: Option<u32>,
file_path: String,
line_number: u32,
parameter_name: String,
message: String,
) -> Self {
Self::new(
timestamp,
pid,
AnvilEventType::ConfigWarning {
file_path,
line_number,
parameter_name,
message,
},
)
}
pub fn statistics(
timestamp: DateTime<Utc>,
pid: Option<u32>,
metric_type: StatisticType,
value: u32,
rate_window: Option<String>,
service_client: String,
metric_timestamp: DateTime<Utc>,
) -> Self {
Self::new(
timestamp,
pid,
AnvilEventType::Statistics {
metric_type,
value,
rate_window,
service_client,
timestamp: metric_timestamp,
},
)
}
pub fn description(&self) -> String {
match &self.event_type {
AnvilEventType::ConfigWarning {
file_path,
line_number,
parameter_name,
message,
} => {
format!(
"Config warning in {}:{} for {}: {}",
file_path, line_number, parameter_name, message
)
}
AnvilEventType::Statistics {
metric_type,
value,
rate_window,
service_client,
..
} => {
let metric_name = match metric_type {
StatisticType::MaxConnectionRate => "connection rate",
StatisticType::MaxConnectionCount => "connection count",
StatisticType::MaxMessageRate => "message rate",
StatisticType::MaxCacheSize => "cache size",
};
if let Some(window) = rate_window {
format!(
"Max {} {}{} for {}",
metric_name, value, window, service_client
)
} else {
format!("Max {} {} for {}", metric_name, value, service_client)
}
}
}
}
pub fn severity(&self) -> &'static str {
match &self.event_type {
AnvilEventType::ConfigWarning { .. } => "warning",
AnvilEventType::Statistics { .. } => "info",
}
}
}