From cba4249146f1f54d1d4bcbd5a5ce11503a684b7b Mon Sep 17 00:00:00 2001 From: Muir Manders Date: Fri, 6 Dec 2024 08:19:24 -0800 Subject: [PATCH] metrics: add basic ods support to Counter Summary: Now (when compiled by buck in fbsource) the Counter type also contains an ODS counter that gets updated as the Counter is updated. Rather than using the dynamic counter in stats::define_stats macro, I directly instantiate a BoxSingletonCounter and store it in the Counter. This avoids computing the String metric name every time when incrementing. Reviewed By: quark-zju Differential Revision: D66848953 fbshipit-source-id: 71858669fb3c4e55339ed52bd2a5023aa7927e6b --- eden/scm/lib/metrics/Cargo.toml | 7 +++++++ eden/scm/lib/metrics/src/dummy_ods.rs | 14 ++++++++++++++ eden/scm/lib/metrics/src/lib.rs | 21 ++++++++++++++------- eden/scm/lib/metrics/src/ods.rs | 20 ++++++++++++++++++++ 4 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 eden/scm/lib/metrics/src/dummy_ods.rs create mode 100644 eden/scm/lib/metrics/src/ods.rs diff --git a/eden/scm/lib/metrics/Cargo.toml b/eden/scm/lib/metrics/Cargo.toml index 8c6ffba8f74cb..2340b08eca480 100644 --- a/eden/scm/lib/metrics/Cargo.toml +++ b/eden/scm/lib/metrics/Cargo.toml @@ -13,6 +13,13 @@ license = "MIT" name = "metrics" [dependencies] +fbinit = { version = "0.2.0", git = "https://github.com/facebookexperimental/rust-shed.git", branch = "main", optional = true } futures = { version = "0.3.30", features = ["async-await", "compat"] } once_cell = "1.12" parking_lot = { version = "0.12.1", features = ["send_guard"] } +stats = { version = "0.1.0", git = "https://github.com/facebookexperimental/rust-shed.git", branch = "main", optional = true } +stats_traits = { version = "0.1.0", git = "https://github.com/facebookexperimental/rust-shed.git", branch = "main", optional = true } + +[features] +default = [] +ods = ["fbinit", "stats", "stats_traits"] diff --git a/eden/scm/lib/metrics/src/dummy_ods.rs b/eden/scm/lib/metrics/src/dummy_ods.rs new file mode 100644 index 0000000000000..04de6359b5ee2 --- /dev/null +++ b/eden/scm/lib/metrics/src/dummy_ods.rs @@ -0,0 +1,14 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +pub(crate) type Counter = (); + +pub(crate) fn new_counter(_name: &'static str) -> Counter { + () +} + +pub(crate) fn increment(_counter: &Counter, _value: i64) {} diff --git a/eden/scm/lib/metrics/src/lib.rs b/eden/scm/lib/metrics/src/lib.rs index e0d621d88365b..7882203c4a911 100644 --- a/eden/scm/lib/metrics/src/lib.rs +++ b/eden/scm/lib/metrics/src/lib.rs @@ -14,9 +14,12 @@ use once_cell::sync::Lazy; use once_cell::sync::OnceCell; use parking_lot::RwLock; +#[cfg_attr(not(feature = "ods"), path = "dummy_ods.rs")] +mod ods; + pub struct Counter { name: &'static str, - counter: OnceCell, + counter: OnceCell<(AtomicUsize, ods::Counter)>, gauge: bool, } @@ -43,15 +46,19 @@ impl Counter { } pub fn add(&'static self, val: usize) { - self.counter().fetch_add(val, Ordering::Relaxed); + let (counter, ods) = self.counter(); + counter.fetch_add(val, Ordering::Relaxed); + ods::increment(ods, val as i64); } pub fn sub(&'static self, val: usize) { - self.counter().fetch_sub(val, Ordering::Relaxed); + let (counter, ods) = self.counter(); + counter.fetch_sub(val, Ordering::Relaxed); + ods::increment(ods, -(val as i64)); } pub fn value(&'static self) -> usize { - self.counter().load(Ordering::Relaxed) + self.counter().0.load(Ordering::Relaxed) } /// Increment counter by v and decrement it back by v when returned guard is dropped @@ -64,10 +71,10 @@ impl Counter { self.gauge } - fn counter(&'static self) -> &AtomicUsize { + fn counter(&'static self) -> &(AtomicUsize, ods::Counter) { self.counter.get_or_init(|| { Registry::global().register_counter(self); - AtomicUsize::new(0) + (AtomicUsize::new(0), ods::new_counter(self.name)) }) } } @@ -115,7 +122,7 @@ impl Registry { pub fn reset(&self) { for counter in self.counters.read().values() { - counter.counter().store(0, Ordering::Relaxed); + counter.counter().0.store(0, Ordering::Relaxed); } } } diff --git a/eden/scm/lib/metrics/src/ods.rs b/eden/scm/lib/metrics/src/ods.rs new file mode 100644 index 0000000000000..3fd225044893b --- /dev/null +++ b/eden/scm/lib/metrics/src/ods.rs @@ -0,0 +1,20 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +pub(crate) type Counter = stats_traits::stat_types::BoxSingletonCounter; + +pub(crate) fn new_counter(name: &'static str) -> Counter { + stats::create_singleton_counter(name.to_string()) +} + +pub(crate) fn increment(counter: &Counter, value: i64) { + if !fbinit::was_performed() { + return; + } + + counter.increment_value(fbinit::expect_init(), value); +}