chore: add some metrics for grpc client (#1398)

* chore: add some metrics for grpc client

* chore: add grpc preix and change metrics-exporter-ptometheus to add global prefix

---------

Co-authored-by: paomian <qtang@greptime.com>
This commit is contained in:
localhost
2023-04-18 13:55:01 +08:00
committed by GitHub
parent f4190cfca6
commit 0c88bb09e3
11 changed files with 118 additions and 13 deletions

View File

@@ -8,7 +8,7 @@ license.workspace = true
async-trait.workspace = true
common-error = { path = "../error" }
common-telemetry = { path = "../telemetry" }
metrics = "0.20"
metrics.workspace = true
once_cell = "1.12"
paste.workspace = true
snafu.workspace = true

View File

@@ -12,8 +12,8 @@ deadlock_detection = ["parking_lot"]
backtrace = "0.3"
common-error = { path = "../error" }
console-subscriber = { version = "0.1", optional = true }
metrics = "0.20.1"
metrics-exporter-prometheus = { version = "0.11", default-features = false }
metrics-exporter-prometheus = { git = "https://github.com/GreptimeTeam/metrics.git", rev = "174de287e9f7f9f57c0272be56c95df156489476", default-features = false }
metrics.workspace = true
once_cell = "1.10"
opentelemetry = { version = "0.17", default-features = false, features = [
"trace",

View File

@@ -32,7 +32,9 @@ pub fn init_default_metrics_recorder() {
/// Init prometheus recorder.
fn init_prometheus_recorder() {
let recorder = PrometheusBuilder::new().build_recorder();
let recorder = PrometheusBuilder::new()
.add_global_prefix("greptime".to_string())
.build_recorder();
let mut h = PROMETHEUS_HANDLE.as_ref().write().unwrap();
*h = Some(recorder.handle());
// TODO(LFC): separate metrics for testing and metrics for production
@@ -60,6 +62,7 @@ pub fn try_handle() -> Option<PrometheusHandle> {
pub struct Timer {
start: Instant,
name: &'static str,
labels: Vec<(String, String)>,
}
impl Timer {
@@ -67,9 +70,25 @@ impl Timer {
Self {
start: Instant::now(),
name,
labels: Vec::new(),
}
}
pub fn new_with_labels<S: Into<String> + Clone>(name: &'static str, labels: &[(S, S)]) -> Self {
Self {
start: Instant::now(),
name,
labels: labels
.iter()
.map(|(k, v)| (k.clone().into(), v.clone().into()))
.collect::<Vec<_>>(),
}
}
pub fn labels_mut(&mut self) -> &mut Vec<(String, String)> {
self.labels.as_mut()
}
pub fn elapsed(&self) -> Duration {
self.start.elapsed()
}
@@ -77,7 +96,11 @@ impl Timer {
impl Drop for Timer {
fn drop(&mut self) {
histogram!(self.name, self.start.elapsed());
if !self.labels.is_empty() {
histogram!(self.name, self.start.elapsed(), &self.labels);
} else {
histogram!(self.name, self.start.elapsed());
}
}
}
@@ -86,6 +109,9 @@ macro_rules! timer {
($name: expr) => {
$crate::metric::Timer::new($name)
};
($name:expr,$labels:expr) => {
$crate::metric::Timer::new_with_labels($name, $labels)
};
}
#[cfg(test)]
@@ -109,4 +135,48 @@ mod tests {
assert!(text.contains("test_elapsed_timer_a"));
assert!(text.contains("test_elapsed_timer_b"));
}
#[test]
fn test_elapsed_timer_with_label() {
init_default_metrics_recorder();
{
let t = Timer::new("test_elapsed_timer_a");
drop(t);
}
let handle = try_handle().unwrap();
let text = handle.render();
assert!(text.contains("test_elapsed_timer_a"));
assert!(!text.contains("test_elapsed_timer_b"));
let label_a = "label_a";
let label_b = "label_b";
let label_c = "label_c";
let label_d = "label_d";
let label_e = "label_e";
assert!(!text.contains(label_a));
assert!(!text.contains(label_b));
{
let mut timer_b = timer!("test_elapsed_timer_b", &[(label_a, "a"), (label_b, "b")]);
let labels = timer_b.labels_mut();
labels.push((label_c.to_owned(), "d".to_owned()));
}
let text = handle.render();
assert!(text.contains("test_elapsed_timer_a"));
assert!(text.contains("test_elapsed_timer_b"));
assert!(text.contains(label_a));
assert!(text.contains(label_b));
assert!(text.contains(label_c));
{
let mut timer_c = timer!("test_elapsed_timer_c");
let labels = timer_c.labels_mut();
labels.push((label_d.to_owned(), "d".to_owned()));
labels.push((label_e.to_owned(), "e".to_owned()));
}
let text = handle.render();
assert!(text.contains("test_elapsed_timer_c"));
assert!(text.contains(label_d));
assert!(text.contains(label_e));
}
}