use alloc::string::String;
use core::sync::atomic::{AtomicU32, AtomicUsize, Ordering};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum HealthStatus {
Healthy,
Warning,
Unhealthy,
}
#[derive(Debug)]
pub struct DbMetrics {
pub total_memory: usize,
pub used_memory: AtomicUsize,
pub read_ops: AtomicU32,
pub write_ops: AtomicU32,
pub delete_ops: AtomicU32,
pub update_ops: AtomicU32,
pub cache_hits: AtomicU32,
pub cache_misses: AtomicU32,
pub index_lookups: AtomicU32,
pub index_inserts: AtomicU32,
pub index_deletes: AtomicU32,
pub transactions: AtomicU32,
pub committed_transactions: AtomicU32,
pub rolled_back_transactions: AtomicU32,
pub gc_ops: AtomicU32,
}
#[derive(Debug, Clone, Copy)]
pub struct DbMetricsSnapshot {
pub total_memory: usize,
pub used_memory: usize,
pub read_ops: u32,
pub write_ops: u32,
pub delete_ops: u32,
pub update_ops: u32,
pub cache_hits: u32,
pub cache_misses: u32,
pub index_lookups: u32,
pub index_inserts: u32,
pub index_deletes: u32,
pub transactions: u32,
pub committed_transactions: u32,
pub rolled_back_transactions: u32,
pub gc_ops: u32,
pub cache_hit_rate: f64,
}
#[derive(Debug)]
pub struct HealthCheckResult {
pub status: HealthStatus,
pub timestamp: u64,
pub metrics: DbMetricsSnapshot,
pub details: String,
}
impl DbMetrics {
pub fn new(total_memory: usize) -> Self {
DbMetrics {
total_memory,
used_memory: AtomicUsize::new(0),
read_ops: AtomicU32::new(0),
write_ops: AtomicU32::new(0),
delete_ops: AtomicU32::new(0),
update_ops: AtomicU32::new(0),
cache_hits: AtomicU32::new(0),
cache_misses: AtomicU32::new(0),
index_lookups: AtomicU32::new(0),
index_inserts: AtomicU32::new(0),
index_deletes: AtomicU32::new(0),
transactions: AtomicU32::new(0),
committed_transactions: AtomicU32::new(0),
rolled_back_transactions: AtomicU32::new(0),
gc_ops: AtomicU32::new(0),
}
}
pub fn snapshot(&self) -> DbMetricsSnapshot {
let cache_hits = self.cache_hits.load(Ordering::Relaxed);
let cache_misses = self.cache_misses.load(Ordering::Relaxed);
let cache_total = cache_hits + cache_misses;
let cache_hit_rate = if cache_total > 0 {
(cache_hits as f64 / cache_total as f64) * 100.0
} else {
0.0
};
DbMetricsSnapshot {
total_memory: self.total_memory,
used_memory: self.used_memory.load(Ordering::Relaxed),
read_ops: self.read_ops.load(Ordering::Relaxed),
write_ops: self.write_ops.load(Ordering::Relaxed),
delete_ops: self.delete_ops.load(Ordering::Relaxed),
update_ops: self.update_ops.load(Ordering::Relaxed),
cache_hits,
cache_misses,
index_lookups: self.index_lookups.load(Ordering::Relaxed),
index_inserts: self.index_inserts.load(Ordering::Relaxed),
index_deletes: self.index_deletes.load(Ordering::Relaxed),
transactions: self.transactions.load(Ordering::Relaxed),
committed_transactions: self.committed_transactions.load(Ordering::Relaxed),
rolled_back_transactions: self.rolled_back_transactions.load(Ordering::Relaxed),
gc_ops: self.gc_ops.load(Ordering::Relaxed),
cache_hit_rate,
}
}
pub fn reset(&self) {
self.used_memory.store(0, Ordering::Relaxed);
self.read_ops.store(0, Ordering::Relaxed);
self.write_ops.store(0, Ordering::Relaxed);
self.delete_ops.store(0, Ordering::Relaxed);
self.update_ops.store(0, Ordering::Relaxed);
self.cache_hits.store(0, Ordering::Relaxed);
self.cache_misses.store(0, Ordering::Relaxed);
self.index_lookups.store(0, Ordering::Relaxed);
self.index_inserts.store(0, Ordering::Relaxed);
self.index_deletes.store(0, Ordering::Relaxed);
self.transactions.store(0, Ordering::Relaxed);
self.committed_transactions.store(0, Ordering::Relaxed);
self.rolled_back_transactions.store(0, Ordering::Relaxed);
self.gc_ops.store(0, Ordering::Relaxed);
}
pub fn inc_read_ops(&self) {
self.read_ops.fetch_add(1, Ordering::Relaxed);
}
pub fn inc_write_ops(&self) {
self.write_ops.fetch_add(1, Ordering::Relaxed);
}
pub fn inc_delete_ops(&self) {
self.delete_ops.fetch_add(1, Ordering::Relaxed);
}
pub fn inc_update_ops(&self) {
self.update_ops.fetch_add(1, Ordering::Relaxed);
}
pub fn inc_cache_hits(&self) {
self.cache_hits.fetch_add(1, Ordering::Relaxed);
}
pub fn inc_cache_misses(&self) {
self.cache_misses.fetch_add(1, Ordering::Relaxed);
}
pub fn inc_index_lookups(&self) {
self.index_lookups.fetch_add(1, Ordering::Relaxed);
}
pub fn inc_index_inserts(&self) {
self.index_inserts.fetch_add(1, Ordering::Relaxed);
}
pub fn inc_index_deletes(&self) {
self.index_deletes.fetch_add(1, Ordering::Relaxed);
}
pub fn inc_transactions(&self) {
self.transactions.fetch_add(1, Ordering::Relaxed);
}
pub fn inc_committed_transactions(&self) {
self.committed_transactions.fetch_add(1, Ordering::Relaxed);
}
pub fn inc_rolled_back_transactions(&self) {
self.rolled_back_transactions
.fetch_add(1, Ordering::Relaxed);
}
pub fn inc_gc_ops(&self) {
self.gc_ops.fetch_add(1, Ordering::Relaxed);
}
pub fn set_used_memory(&self, memory: usize) {
self.used_memory.store(memory, Ordering::Relaxed);
}
pub fn add_used_memory(&self, memory: usize) {
self.used_memory.fetch_add(memory, Ordering::Relaxed);
}
pub fn sub_used_memory(&self, memory: usize) {
self.used_memory.fetch_sub(memory, Ordering::Relaxed);
}
}
impl DbMetricsSnapshot {
pub fn to_text(&self) -> String {
let mut text = alloc::string::String::new();
text.push_str("===== 数据库监控指标 =====\n");
text.push_str(&alloc::format!(
"内存使用: {}/{} 字节\n",
self.used_memory,
self.total_memory
));
text.push_str(&alloc::format!(
"操作计数: 读={}, 写={}, 删除={}, 更新={}\n",
self.read_ops,
self.write_ops,
self.delete_ops,
self.update_ops
));
text.push_str(&alloc::format!(
"缓存统计: 命中={}, 未命中={}, 命中率={:.2}%\n",
self.cache_hits,
self.cache_misses,
self.cache_hit_rate
));
text.push_str(&alloc::format!(
"索引操作: 查找={}, 插入={}, 删除={}\n",
self.index_lookups,
self.index_inserts,
self.index_deletes
));
text.push_str(&alloc::format!(
"事务统计: 总数={}, 已提交={}, 已回滚={}\n",
self.transactions,
self.committed_transactions,
self.rolled_back_transactions
));
text.push_str("========================\n");
text
}
pub fn to_json(&self) -> String {
alloc::format!(
r#"{{"total_memory":{},"used_memory":{},"read_ops":{},"write_ops":{},"delete_ops":{},"update_ops":{},"cache_hits":{},"cache_misses":{},"cache_hit_rate":{:.2},"index_lookups":{},"index_inserts":{},"index_deletes":{},"transactions":{},"committed_transactions":{},"rolled_back_transactions":{}}}"#,
self.total_memory,
self.used_memory,
self.read_ops,
self.write_ops,
self.delete_ops,
self.update_ops,
self.cache_hits,
self.cache_misses,
self.cache_hit_rate,
self.index_lookups,
self.index_inserts,
self.index_deletes,
self.transactions,
self.committed_transactions,
self.rolled_back_transactions
)
}
pub fn to_bytes(&self) -> alloc::vec::Vec<u8> {
self.to_json().into_bytes()
}
}
impl HealthCheckResult {
pub fn new(status: HealthStatus, metrics: DbMetricsSnapshot, details: String) -> Self {
HealthCheckResult {
status,
timestamp: crate::platform::get_timestamp(),
metrics,
details,
}
}
pub fn to_text(&self) -> String {
let mut text = alloc::string::String::new();
text.push_str(&alloc::format!("===== 健康检查结果 =====\n"));
text.push_str(&alloc::format!("时间戳: {}\n", self.timestamp));
text.push_str(&alloc::format!("状态: {:?}\n", self.status));
text.push_str(&alloc::format!("详细信息: {}\n", self.details));
text.push_str(&self.metrics.to_text());
text.push_str("========================\n");
text
}
pub fn to_json(&self) -> String {
alloc::format!(
r#"{{"status":"{:?}","timestamp":{},"metrics":{},"details":"{}"}}"#,
self.status,
self.timestamp,
self.metrics.to_json(),
self.details
)
}
pub fn to_bytes(&self) -> alloc::vec::Vec<u8> {
self.to_json().into_bytes()
}
}