redis_enterprise/usage_report.rs
1//! Usage reporting
2//!
3//! The Redis Enterprise REST API documents `GET /v1/usage_report` only.
4//! Earlier revisions of this module exposed `/latest`, `/generate`, `/config`,
5//! per-report `/{uid}` and `/{uid}/csv` endpoints at paths the docs never
6//! define; those have been removed.
7//!
8//! Note: the live cluster response is a streaming NDJSON document and the
9//! `Vec<UsageReport>` shape modeled by `list()` is a best-effort buffered
10//! decode. A streaming reshape is tracked as a follow-up to the #65 audit.
11
12use crate::client::RestClient;
13use crate::error::Result;
14use serde::{Deserialize, Serialize};
15
16/// Usage report
17#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct UsageReport {
19 /// Unique identifier for this usage report
20 pub report_id: String,
21 /// Timestamp when the report was generated
22 pub timestamp: String,
23 /// Start time of the reporting period
24 pub period_start: String,
25 /// End time of the reporting period
26 pub period_end: String,
27 /// Name of the cluster
28 pub cluster_name: String,
29 /// Usage information for individual databases
30 #[serde(skip_serializing_if = "Option::is_none")]
31 pub databases: Option<Vec<DatabaseUsage>>,
32 /// Usage information for cluster nodes
33 #[serde(skip_serializing_if = "Option::is_none")]
34 pub nodes: Option<Vec<NodeUsage>>,
35 /// Summary of overall usage across the cluster
36 #[serde(skip_serializing_if = "Option::is_none")]
37 pub summary: Option<UsageSummary>,
38}
39
40/// Database usage information
41#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct DatabaseUsage {
43 /// Database unique identifier
44 pub bdb_uid: u32,
45 /// Name of the database
46 pub name: String,
47 /// Average memory usage during the reporting period (bytes)
48 pub memory_used_avg: u64,
49 /// Peak memory usage during the reporting period (bytes)
50 pub memory_used_peak: u64,
51 /// Average operations per second
52 pub ops_per_sec_avg: f64,
53 /// Average bandwidth usage (bytes per second)
54 pub bandwidth_avg: u64,
55 /// Number of shards in the database
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub shard_count: Option<u32>,
58}
59
60/// Node usage information
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct NodeUsage {
63 /// Node unique identifier
64 pub node_uid: u32,
65 /// Average CPU usage as a percentage (0.0-1.0)
66 pub cpu_usage_avg: f32,
67 /// Average memory usage during the reporting period (bytes)
68 pub memory_usage_avg: u64,
69 /// Persistent storage usage (bytes)
70 pub persistent_storage_usage: u64,
71 /// Ephemeral storage usage (bytes)
72 pub ephemeral_storage_usage: u64,
73}
74
75/// Usage summary
76#[derive(Debug, Clone, Serialize, Deserialize)]
77pub struct UsageSummary {
78 /// Total memory usage across the cluster (GB)
79 pub total_memory_gb: f64,
80 /// Total number of operations across the cluster
81 pub total_ops: u64,
82 /// Total bandwidth usage across the cluster (GB)
83 pub total_bandwidth_gb: f64,
84 /// Total number of databases in the cluster
85 pub database_count: u32,
86 /// Total number of nodes in the cluster
87 pub node_count: u32,
88 /// Total number of shards in the cluster
89 pub shard_count: u32,
90}
91
92/// Usage report handler
93pub struct UsageReportHandler {
94 client: RestClient,
95}
96
97impl UsageReportHandler {
98 /// Create a new handler bound to the given REST client.
99 pub fn new(client: RestClient) -> Self {
100 UsageReportHandler { client }
101 }
102
103 /// List usage reports - GET /v1/usage_report.
104 ///
105 /// The live cluster returns a streaming NDJSON document; this method
106 /// buffers and decodes the whole payload, which is fine for short
107 /// reporting periods but should not be relied on for cluster-wide
108 /// scans. A streaming reshape is a #65 follow-up.
109 pub async fn list(&self) -> Result<Vec<UsageReport>> {
110 self.client.get("/v1/usage_report").await
111 }
112}