Accept initializer_list, span, and string_view in api

This commit is contained in:
2025-08-31 12:31:29 -04:00
parent 93ccd2eb71
commit 4b2c5b8ce8
2 changed files with 89 additions and 83 deletions

View File

@@ -36,8 +36,8 @@
// histogram.observe(0.25); // ONLY call from creating thread
#include <functional>
#include <initializer_list>
#include <span>
#include <string>
#include <type_traits>
#include <vector>
@@ -127,20 +127,36 @@ template <class T> struct Family {
// Labels are sorted by key for Prometheus compatibility
// ERROR: Will abort if labels already registered via register_callback()
// OK: Multiple calls with same labels return same instance (idempotent)
T create(std::vector<std::pair<std::string, std::string>> labels);
T create(std::initializer_list<std::pair<std::string_view, std::string_view>>
labels) {
return create(
std::span<const std::pair<std::string_view, std::string_view>>(
labels.begin(), labels.end()));
}
T create(
std::span<const std::pair<std::string_view, std::string_view>> labels);
// Register callback-based metric (Counter and Gauge only)
// Validates that label set isn't already taken
void
register_callback(std::vector<std::pair<std::string, std::string>> labels,
MetricCallback<T> callback);
void register_callback(
std::initializer_list<std::pair<std::string_view, std::string_view>>
labels,
MetricCallback<T> callback) {
register_callback(
std::span<const std::pair<std::string_view, std::string_view>>(
labels.begin(), labels.end()),
callback);
}
void register_callback(
std::span<const std::pair<std::string_view, std::string_view>> labels,
MetricCallback<T> callback);
private:
Family();
friend struct Metric;
friend Family<Counter> create_counter(std::string, std::string);
friend Family<Gauge> create_gauge(std::string, std::string);
friend Family<Histogram> create_histogram(std::string, std::string,
friend Family<Counter> create_counter(std::string_view, std::string_view);
friend Family<Gauge> create_gauge(std::string_view, std::string_view);
friend Family<Histogram> create_histogram(std::string_view, std::string_view,
std::span<const double>);
struct State;
@@ -153,19 +169,25 @@ private:
// Create counter family (monotonically increasing values)
// ERROR: Aborts if family with same name is registered with different help
// text.
Family<Counter> create_counter(std::string name, std::string help);
Family<Counter> create_counter(std::string_view name, std::string_view help);
// Create gauge family (can increase/decrease)
// ERROR: Aborts if family with same name is registered with different help
// text.
Family<Gauge> create_gauge(std::string name, std::string help);
Family<Gauge> create_gauge(std::string_view name, std::string_view help);
// Create histogram family with custom buckets
// Buckets will be sorted, deduplicated, and +Inf will be added automatically
// ERROR: Aborts if family with same name is registered with different help text
// or buckets.
Family<Histogram> create_histogram(std::string name, std::string help,
Family<Histogram> create_histogram(std::string_view name, std::string_view help,
std::span<const double> buckets);
inline Family<Histogram>
create_histogram(std::string_view name, std::string_view help,
std::initializer_list<double> buckets) {
return create_histogram(
name, help, std::span<const double>(buckets.begin(), buckets.end()));
}
// Helper functions for generating standard histogram buckets
// Following Prometheus client library conventions
@@ -189,9 +211,9 @@ std::vector<double> exponential_buckets(double start, double factor, int count);
std::span<std::string_view> render(ArenaAllocator &arena);
// Validation functions for Prometheus compatibility
bool is_valid_metric_name(const std::string &name);
bool is_valid_label_key(const std::string &key);
bool is_valid_label_value(const std::string &value);
bool is_valid_metric_name(std::string_view name);
bool is_valid_label_key(std::string_view key);
bool is_valid_label_value(std::string_view value);
// Note: Histograms do not support callbacks due to their multi-value nature
// (buckets + sum + count). Use static histogram metrics only.