use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::fmt;
use tabled::Tabled;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
pub struct QueueMetrics {
pub name: String,
pub total_messages: i64,
pub pending_messages: i64,
pub locked_messages: i64,
pub archived_messages: i64,
pub oldest_pending_message: Option<DateTime<Utc>>,
pub newest_message: Option<DateTime<Utc>>,
}
impl Tabled for QueueMetrics {
const LENGTH: usize = 7;
fn fields(&self) -> Vec<std::borrow::Cow<'static, str>> {
vec![
self.name.clone().into(),
self.total_messages.to_string().into(),
self.pending_messages.to_string().into(),
self.locked_messages.to_string().into(),
self.archived_messages.to_string().into(),
display_option_datetime(&self.oldest_pending_message).into(),
display_option_datetime(&self.newest_message).into(),
]
}
fn headers() -> Vec<std::borrow::Cow<'static, str>> {
vec![
"name",
"total_messages",
"pending_messages",
"locked_messages",
"archived_messages",
"oldest_pending_message",
"newest_message",
]
.into_iter()
.map(|s| s.into())
.collect()
}
}
pub fn display_option_datetime(o: &Option<DateTime<Utc>>) -> String {
match o {
Some(dt) => dt.to_rfc3339(),
None => "N/A".to_string(),
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
pub struct SystemStats {
pub total_queues: i64,
pub total_workers: i64,
pub active_workers: i64,
pub total_messages: i64,
pub pending_messages: i64,
pub locked_messages: i64,
pub archived_messages: i64,
pub schema_version: String,
}
impl Tabled for SystemStats {
const LENGTH: usize = 8;
fn fields(&self) -> Vec<std::borrow::Cow<'static, str>> {
vec![
self.total_queues.to_string().into(),
self.total_workers.to_string().into(),
self.active_workers.to_string().into(),
self.total_messages.to_string().into(),
self.pending_messages.to_string().into(),
self.locked_messages.to_string().into(),
self.archived_messages.to_string().into(),
self.schema_version.clone().into(),
]
}
fn headers() -> Vec<std::borrow::Cow<'static, str>> {
vec![
"total_queues",
"total_workers",
"active_workers",
"total_messages",
"pending_messages",
"locked_messages",
"archived_messages",
"schema_version",
]
.into_iter()
.map(|s| s.into())
.collect()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
pub struct WorkerHealthStats {
pub queue_name: String,
pub total_workers: i64,
pub ready_workers: i64,
pub polling_workers: i64,
pub interrupted_workers: i64,
pub suspended_workers: i64,
pub stopped_workers: i64,
pub stale_workers: i64,
}
impl Tabled for WorkerHealthStats {
const LENGTH: usize = 8;
fn fields(&self) -> Vec<std::borrow::Cow<'static, str>> {
vec![
self.queue_name.clone().into(),
self.total_workers.to_string().into(),
self.ready_workers.to_string().into(),
self.polling_workers.to_string().into(),
self.interrupted_workers.to_string().into(),
self.suspended_workers.to_string().into(),
self.stopped_workers.to_string().into(),
self.stale_workers.to_string().into(),
]
}
fn headers() -> Vec<std::borrow::Cow<'static, str>> {
vec![
"queue_name",
"total_workers",
"ready_workers",
"polling_workers",
"interrupted_workers",
"suspended_workers",
"stopped_workers",
"stale_workers",
]
.into_iter()
.map(|s| s.into())
.collect()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkerStats {
pub total_workers: u32,
pub ready_workers: u32,
pub polling_workers: u32,
pub interrupted_workers: u32,
pub suspended_workers: u32,
pub stopped_workers: u32,
pub average_messages_per_worker: f64,
pub oldest_worker_age: chrono::Duration,
pub newest_heartbeat_age: chrono::Duration,
}
impl fmt::Display for WorkerStats {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"WorkerStats {{ total: {}, ready: {}, polling: {}, interrupted: {}, suspended: {}, stopped: {}, avg_messages: {:.2}, oldest: {:?}, newest: {:?} }}",
self.total_workers,
self.ready_workers,
self.polling_workers,
self.interrupted_workers,
self.suspended_workers,
self.stopped_workers,
self.average_messages_per_worker,
self.oldest_worker_age,
self.newest_heartbeat_age
)
}
}