Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

368 improve exported metrics for usage in grafana dashboards #468

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
77 changes: 68 additions & 9 deletions clients/vault/src/metrics.rs
Expand Up @@ -6,7 +6,7 @@ use crate::{
};
use async_trait::async_trait;
use lazy_static::lazy_static;
use primitives::stellar;
use primitives::{stellar, Asset};
use runtime::{
prometheus::{
gather, proto::MetricFamily, Encoder, Gauge, GaugeVec, IntCounter, IntGaugeVec, Opts,
Expand All @@ -33,6 +33,7 @@ const XLM_BALANCE_TYPE_LABEL: &str = "type";
const REQUEST_STATUS_LABEL: &str = "status";
const TASK_NAME: &str = "task";
const TOKIO_POLLING_INTERVAL_MS: u64 = 10000;
const DISPLAY_NAME_LABEL: &str = "display_name";

// Metrics are stored under the [`CURRENCY_LABEL`] key so that multiple vaults can be easily
// monitored at the same time.
Expand Down Expand Up @@ -63,17 +64,17 @@ lazy_static! {
.expect("Failed to create prometheus metric");
pub static ref XLM_BALANCE: GaugeVec = GaugeVec::new(
Opts::new("stellar_balance", "Stellar Balance"),
&[CURRENCY_LABEL, XLM_BALANCE_TYPE_LABEL]
&[CURRENCY_LABEL, XLM_BALANCE_TYPE_LABEL, DISPLAY_NAME_LABEL]
)
.expect("Failed to create prometheus metric");
pub static ref ISSUES: GaugeVec = GaugeVec::new(
Opts::new("issue_count", "Number of issues"),
&[CURRENCY_LABEL, REQUEST_STATUS_LABEL]
&[CURRENCY_LABEL, REQUEST_STATUS_LABEL, DISPLAY_NAME_LABEL]
)
.expect("Failed to create prometheus metric");
pub static ref REDEEMS: GaugeVec = GaugeVec::new(
Opts::new("redeem_count", "Number of redeems"),
&[CURRENCY_LABEL, REQUEST_STATUS_LABEL]
&[CURRENCY_LABEL, REQUEST_STATUS_LABEL, DISPLAY_NAME_LABEL]
)
.expect("Failed to create prometheus metric");
pub static ref NATIVE_CURRENCY_BALANCE: Gauge =
Expand Down Expand Up @@ -121,35 +122,93 @@ impl VaultDataReader for VaultIdManager {
}
}

struct DisplayLabels {
upperbound_label: String,
lowerbound_label: String,
actual_label: String,
open_label: String,
completed_label: String,
expired_label: String,
}

impl PerCurrencyMetrics {
pub fn new(vault_id: &VaultId) -> Self {
let label = format!(
"{}_{}",
vault_id.collateral_currency().inner().unwrap_or_default(),
vault_id.wrapped_currency().inner().unwrap_or_default()
);
Self::new_with_label(label.as_ref())

let display_label = format!(
"{}_{}",
Self::format_currency_for_display(vault_id.collateral_currency()),
Self::format_currency_for_display(vault_id.wrapped_currency())
);
Self::new_with_label(label.as_ref(), display_label.as_ref())
}

// construct a dummy metrics struct for testing purposes
pub fn dummy() -> Self {
Self::new_with_label("dummy")
Self::new_with_label("dummy", "dummy")
}

fn format_currency_for_display(currency: CurrencyId) -> String {
match currency {
CurrencyId::Stellar(asset) => match asset {
Asset::AlphaNum4 { code, .. } =>
String::from_utf8(code.to_vec()).unwrap_or_default().replace('\"', ""),
Asset::AlphaNum12 { code, .. } =>
String::from_utf8(code.to_vec()).unwrap_or_default().replace('\"', ""),
Asset::StellarNative => "XLM".to_owned(),
},
CurrencyId::Native => "Native".to_owned(),
CurrencyId::ZenlinkLPToken(token1_id, token1_type, token2_id, token2_type) => {
format!("LP_{}_{}_{}_{}", token1_id, token1_type, token2_id, token2_type)
},
CurrencyId::XCM(_) => currency.inner().unwrap_or_default(),
_ => "Unknown".to_owned(),
}
}

fn new_with_label(label: &str) -> Self {
fn new_with_label(label: &str, display_label: &str) -> Self {
let labels = HashMap::from([(CURRENCY_LABEL, label)]);

let labels_struct = DisplayLabels {
upperbound_label: format!("{} - required_upperbound", display_label),
lowerbound_label: format!("{} - required_lowerbound", display_label),
actual_label: format!("{} - actual", display_label),
open_label: format!("{} - open", display_label),
completed_label: format!("{} - completed", display_label),
expired_label: format!("{} - expired", display_label),
};

let stellar_balance_gauge = |balance_type: &'static str| {
let display_name = match balance_type {
"required_upperbound" => &labels_struct.upperbound_label,
"required_lowerbound" => &labels_struct.lowerbound_label,
"actual" => &labels_struct.actual_label,
_ => "",
};

let labels = HashMap::<&str, &str>::from([
(CURRENCY_LABEL, label),
(XLM_BALANCE_TYPE_LABEL, balance_type),
(DISPLAY_NAME_LABEL, display_name),
]);
XLM_BALANCE.with(&labels)
};
let request_type_label = |balance_type: &'static str| {
let request_type_label = |request_type: &'static str| {
let display_name = match request_type {
"open" => &labels_struct.open_label,
"completed" => &labels_struct.completed_label,
"expired" => &labels_struct.expired_label,
_ => "",
};

HashMap::<&str, &str>::from([
(CURRENCY_LABEL, label),
(REQUEST_STATUS_LABEL, balance_type),
(REQUEST_STATUS_LABEL, request_type),
(DISPLAY_NAME_LABEL, display_name),
])
};

Expand Down