Add support for callbacks for gauges/counters, restore process stat metrics

This commit is contained in:
Tim Wojtulewicz 2024-03-14 15:08:08 -07:00
parent e93e4cc26d
commit 1cad305e58
8 changed files with 103 additions and 81 deletions

View file

@ -41,7 +41,12 @@ public:
return Value();
}
BaseType Value() const noexcept { return static_cast<BaseType>(handle.Value()); }
BaseType Value() const noexcept {
// Use Collect() here instead of Value() to correctly handle metrics with
// callbacks.
auto metric = handle.Collect();
return static_cast<BaseType>(metric.counter.value);
}
bool operator==(const BaseCounter<BaseType>& rhs) const noexcept { return &handle == &rhs.handle; }
bool operator!=(const BaseCounter<BaseType>& rhs) const noexcept { return &handle != &rhs.handle; }
@ -49,8 +54,12 @@ public:
bool CompareLabels(const prometheus::Labels& lbls) const { return labels == lbls; }
protected:
explicit BaseCounter(FamilyType& family, const prometheus::Labels& labels) noexcept
: handle(family.Add(labels)), labels(labels) {}
explicit BaseCounter(FamilyType& family, const prometheus::Labels& labels,
prometheus::CollectCallbackPtr callback = nullptr) noexcept
: handle(family.Add(labels)), labels(labels) {
if ( callback )
handle.AddCollectCallback(callback);
}
Handle& handle;
prometheus::Labels labels;
@ -63,7 +72,9 @@ protected:
class IntCounter : public BaseCounter<uint64_t> {
public:
static inline const char* OpaqueName = "IntCounterMetricVal";
explicit IntCounter(FamilyType& family, const prometheus::Labels& labels) noexcept : BaseCounter(family, labels) {}
explicit IntCounter(FamilyType& family, const prometheus::Labels& labels,
prometheus::CollectCallbackPtr callback = nullptr) noexcept
: BaseCounter(family, labels, callback) {}
};
/**
@ -72,7 +83,9 @@ public:
class DblCounter : public BaseCounter<double> {
public:
static inline const char* OpaqueName = "DblCounterMetricVal";
explicit DblCounter(FamilyType& family, const prometheus::Labels& labels) noexcept : BaseCounter(family, labels) {}
explicit DblCounter(FamilyType& family, const prometheus::Labels& labels,
prometheus::CollectCallbackPtr callback = nullptr) noexcept
: BaseCounter(family, labels, callback) {}
};
template<class CounterType, typename BaseType>
@ -89,7 +102,8 @@ public:
* Returns the metrics handle for given labels, creating a new instance
* lazily if necessary.
*/
std::shared_ptr<CounterType> GetOrAdd(Span<const LabelView> labels) {
std::shared_ptr<CounterType> GetOrAdd(Span<const LabelView> labels,
prometheus::CollectCallbackPtr callback = nullptr) {
prometheus::Labels p_labels = BuildPrometheusLabels(labels);
auto check = [&](const std::shared_ptr<CounterType>& counter) { return counter->CompareLabels(p_labels); };
@ -97,7 +111,7 @@ public:
if ( auto it = std::find_if(counters.begin(), counters.end(), check); it != counters.end() )
return *it;
auto counter = std::make_shared<CounterType>(family, p_labels);
auto counter = std::make_shared<CounterType>(family, p_labels, callback);
counters.push_back(counter);
return counter;
}
@ -105,8 +119,9 @@ public:
/**
* @copydoc GetOrAdd
*/
std::shared_ptr<CounterType> GetOrAdd(std::initializer_list<LabelView> labels) {
return GetOrAdd(Span{labels.begin(), labels.size()});
std::shared_ptr<CounterType> GetOrAdd(std::initializer_list<LabelView> labels,
prometheus::CollectCallbackPtr callback = nullptr) {
return GetOrAdd(Span{labels.begin(), labels.size()}, callback);
}
std::vector<std::shared_ptr<CounterType>>& GetAllCounters() { return counters; }