diff --git a/operator/src/metrics.rs b/operator/src/metrics.rs index 5bca8ee..1c8f205 100644 --- a/operator/src/metrics.rs +++ b/operator/src/metrics.rs @@ -1,5 +1,5 @@ use chrono::Utc; -use kube::{api::ListParams, Api, Client, Resource, ResourceExt}; +use kube::{api::ListParams, core::object::HasSpec, Api, Client, Resource, ResourceExt}; use prometheus::{opts, IntCounterVec, Registry}; use serde::{Deserialize, Deserializer}; use std::sync::Arc; @@ -14,6 +14,7 @@ pub struct Metrics { pub reconcile_failures: IntCounterVec, pub metrics_failures: IntCounterVec, pub dcu: IntCounterVec, + pub usage: IntCounterVec, } impl Default for Metrics { @@ -60,12 +61,19 @@ impl Default for Metrics { ) .unwrap(); + let usage = IntCounterVec::new( + opts!("usage", "Feature usage",), + &["feature", "project", "resource_name", "tier"], + ) + .unwrap(); + Metrics { users_created, users_dropped, reconcile_failures, metrics_failures, dcu, + usage, } } } @@ -76,6 +84,7 @@ impl Metrics { registry.register(Box::new(self.users_created.clone()))?; registry.register(Box::new(self.users_dropped.clone()))?; registry.register(Box::new(self.dcu.clone()))?; + registry.register(Box::new(self.usage.clone()))?; Ok(self) } @@ -105,8 +114,7 @@ impl Metrics { .inc(); } - pub fn count_dcu_consumed(&self, namespace: &str, network: &str, dcu: f64) { - let project = get_project_id(namespace); + pub fn count_dcu_consumed(&self, project: &str, network: &str, dcu: f64) { let service = format!("{}-{}", DbSyncPort::kind(&()), network); let service_type = format!("{}.{}", DbSyncPort::plural(&()), DbSyncPort::group(&())); let tenancy = "proxy"; @@ -114,9 +122,18 @@ impl Metrics { let dcu: u64 = dcu.ceil() as u64; self.dcu - .with_label_values(&[&project, &service, &service_type, tenancy]) + .with_label_values(&[project, &service, &service_type, tenancy]) .inc_by(dcu); } + + pub fn count_usage(&self, project: &str, resource_name: &str, tier: &str, value: f64) { + let feature = &DbSyncPort::kind(&()); + let value: u64 = value.ceil() as u64; + + self.usage + .with_label_values(&[feature, project, resource_name, tier]) + .inc_by(value); + } } fn get_project_id(namespace: &str) -> String { @@ -196,9 +213,21 @@ pub async fn run_metrics_collector(state: Arc) { let total_exec_time = result.value * (interval as f64); let dcu = total_exec_time * dcu_per_second; + + let project = get_project_id(&crd.namespace().unwrap()); + state .metrics - .count_dcu_consumed(&crd.namespace().unwrap(), &crd.spec.network, dcu); + .count_dcu_consumed(&project, &crd.spec.network, dcu); + state.metrics.count_usage( + &project, + &crd.name_any(), + &crd.spec() + .throughput_tier + .clone() + .unwrap_or("0".to_string()), + result.value, + ); } } });