use metrique::test_util::test_metric;
use metrique::unit_of_work::metrics;
#[metrics(value(string))]
#[derive(Copy, Clone)]
enum Priority {
Low,
Medium,
High,
}
#[metrics(subfield)]
pub struct ReadMetrics {
bytes_read: usize,
cache_hit: bool,
}
#[metrics(subfield)]
pub struct WriteMetrics {
bytes_written: usize,
fsync_required: bool,
}
#[metrics(tag(name = "Operation"), subfield)]
enum OperationMetrics {
Read(#[metrics(flatten)] ReadMetrics),
#[metrics(name = "Put")]
Write(#[metrics(flatten)] WriteMetrics),
Delete {
key_count: usize,
},
}
#[metrics(rename_all = "PascalCase")]
struct RequestMetrics {
#[metrics(sample_group)]
priority: Priority,
#[metrics(flatten)]
details: OperationMetrics,
success: bool,
request_id: String,
}
struct StorageLayer;
impl StorageLayer {
fn read(&self, key: &str) -> (Vec<u8>, ReadMetrics) {
let cache_hit = key.len() % 2 == 0;
let data = vec![0u8; 1024];
let metrics = ReadMetrics {
bytes_read: data.len(),
cache_hit,
};
(data, metrics)
}
fn write(&self, data: &[u8]) -> WriteMetrics {
WriteMetrics {
bytes_written: data.len(),
fsync_required: data.len() > 4096,
}
}
fn delete(&self, keys: &[String]) -> usize {
keys.len()
}
}
fn handle_read_request(storage: &StorageLayer, key: &str, priority: Priority) -> RequestMetrics {
let (data, read_metrics) = storage.read(key);
RequestMetrics {
priority,
details: OperationMetrics::Read(read_metrics),
success: !data.is_empty(),
request_id: format!("read-{}", key),
}
}
fn handle_write_request(
storage: &StorageLayer,
data: Vec<u8>,
priority: Priority,
) -> RequestMetrics {
let write_metrics = storage.write(&data);
RequestMetrics {
priority,
details: OperationMetrics::Write(write_metrics),
success: true,
request_id: format!("write-{}", data.len()),
}
}
fn handle_delete_request(
storage: &StorageLayer,
keys: Vec<String>,
priority: Priority,
) -> RequestMetrics {
let key_count = storage.delete(&keys);
RequestMetrics {
priority,
details: OperationMetrics::Delete { key_count },
success: key_count > 0,
request_id: format!("delete-{}", key_count),
}
}
fn main() {
let storage = StorageLayer;
let read_metrics = handle_read_request(&storage, "user:123", Priority::High);
let read_entry = test_metric(read_metrics);
let write_metrics = handle_write_request(&storage, vec![0u8; 2048], Priority::Medium);
let write_entry = test_metric(write_metrics);
let delete_metrics = handle_delete_request(
&storage,
vec!["key1".to_string(), "key2".to_string()],
Priority::Low,
);
let delete_entry = test_metric(delete_metrics);
assert_eq!(read_entry.values["Priority"], "High");
assert_eq!(read_entry.values["Operation"], "Read");
assert_eq!(read_entry.metrics["Success"], 1);
assert_eq!(read_entry.metrics["BytesRead"], 1024);
assert_eq!(write_entry.values["Priority"], "Medium");
assert_eq!(write_entry.values["Operation"], "Put"); assert_eq!(write_entry.metrics["Success"], 1);
assert_eq!(write_entry.metrics["BytesWritten"], 2048);
assert_eq!(delete_entry.values["Priority"], "Low");
assert_eq!(delete_entry.values["Operation"], "Delete");
assert_eq!(delete_entry.metrics["Success"], 1);
assert_eq!(delete_entry.metrics["KeyCount"], 2);
}