Skip to main content

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}