From 59d114005ec130df5efaaf3681ecf50f1af3c0ae Mon Sep 17 00:00:00 2001 From: Dominik Charousset Date: Sat, 27 Feb 2021 14:40:13 +0100 Subject: [PATCH] Add gauge metric types --- src/telemetry/CMakeLists.txt | 1 + src/telemetry/Gauge.cc | 189 ++++++++++++++++++++++++ src/telemetry/Gauge.h | 262 ++++++++++++++++++++++++++++++++++ src/telemetry/Manager.cc | 250 +++++++++++++++++++++++++++++++- src/telemetry/Manager.h | 112 +++++++++++++++ src/telemetry/MetricFamily.cc | 52 +++++++ src/telemetry/MetricFamily.h | 2 +- 7 files changed, 866 insertions(+), 2 deletions(-) create mode 100644 src/telemetry/Gauge.cc create mode 100644 src/telemetry/Gauge.h diff --git a/src/telemetry/CMakeLists.txt b/src/telemetry/CMakeLists.txt index 867805aa38..004ab29b42 100644 --- a/src/telemetry/CMakeLists.txt +++ b/src/telemetry/CMakeLists.txt @@ -7,6 +7,7 @@ include_directories(BEFORE set(telemetry_SRCS Counter.cc + Gauge.cc Manager.cc MetricFamily.cc ) diff --git a/src/telemetry/Gauge.cc b/src/telemetry/Gauge.cc new file mode 100644 index 0000000000..2d9616b10c --- /dev/null +++ b/src/telemetry/Gauge.cc @@ -0,0 +1,189 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "zeek/telemetry/Gauge.h" + +#include "caf/telemetry/gauge.hpp" +#include "caf/telemetry/metric_family.hpp" +#include "caf/telemetry/metric_family_impl.hpp" + +namespace zeek::telemetry { + +// -- private utilities -------------------------------------------------------- + +namespace { + +namespace ct = caf::telemetry; + +using NativeMetricFamily = ct::metric_family; + +using NativeIntGauge = ct::int_gauge; + +using NativeIntGaugeFamily = ct::metric_family_impl; + +using NativeDblGauge = ct::dbl_gauge; + +using NativeDblGaugeFamily = ct::metric_family_impl; + +auto& deref(IntGauge::Impl* ptr) + { + return *reinterpret_cast(ptr); + } + +auto& deref(IntGaugeFamily*, MetricFamily::Impl* ptr) + { + auto basePtr = reinterpret_cast(ptr); + return *static_cast(basePtr); + } + +auto upcast(IntGaugeFamily::Impl* ptr) + { + auto native = reinterpret_cast(ptr); + auto basePtr = static_cast(native); + return reinterpret_cast(basePtr); + } + +auto opaque(NativeIntGauge* ptr) + { + return reinterpret_cast(ptr); + } + +auto& deref(DblGauge::Impl* ptr) + { + return *reinterpret_cast(ptr); + } + +auto& deref(DblGaugeFamily*, MetricFamily::Impl* ptr) + { + auto basePtr = reinterpret_cast(ptr); + return *static_cast(basePtr); + } + +auto upcast(DblGaugeFamily::Impl* ptr) + { + auto native = reinterpret_cast(ptr); + auto basePtr = static_cast(native); + return reinterpret_cast(basePtr); + } + +auto opaque(NativeDblGauge* ptr) + { + return reinterpret_cast(ptr); + } + +template +auto withNativeLabels(Span xs, F continuation) + { + if (xs.size() <= 10) + { + ct::label_view buf[10]={ + {{},{}}, {{},{}}, {{},{}}, {{},{}}, {{},{}}, + {{},{}}, {{},{}}, {{},{}}, {{},{}}, {{},{}}, + }; + for (size_t index = 0; index < xs.size(); ++index) + buf[index] = ct::label_view{xs[index].first, xs[index].second}; + return continuation(Span{buf, xs.size()}); + } + else + { + std::vector buf; + for (auto x : xs) + buf.emplace_back(x.first, x.second); + return continuation(Span{buf}); + } + } + +} // namespace + +// -- IntGauge --------------------------------------------------------------- + +void IntGauge::inc() noexcept + { + deref(pimpl).inc(); + } + +void IntGauge::inc(int64_t amount) noexcept + { + deref(pimpl).inc(amount); + } + +void IntGauge::dec() noexcept + { + deref(pimpl).dec(); + } + +void IntGauge::dec(int64_t amount) noexcept + { + deref(pimpl).dec(amount); + } + +int64_t IntGauge::operator++() noexcept + { + return ++deref(pimpl); + } + +int64_t IntGauge::operator--() noexcept + { + return --deref(pimpl); + } + +int64_t IntGauge::value() const noexcept + { + return deref(pimpl).value(); + } + +IntGaugeFamily::IntGaugeFamily(Impl* ptr) : MetricFamily(upcast(ptr)) + { + // nop + } + +IntGauge IntGaugeFamily::getOrAdd(Span labels) + { + return withNativeLabels(labels, [this](auto nativeLabels) + { + auto hdl = opaque(deref(this, pimpl).get_or_add(nativeLabels)); + return IntGauge{hdl}; + }); + } + +// -- DblGauge --------------------------------------------------------------- + +void DblGauge::inc() noexcept + { + deref(pimpl).inc(); + } + +void DblGauge::inc(double amount) noexcept + { + deref(pimpl).inc(amount); + } + +void DblGauge::dec() noexcept + { + deref(pimpl).dec(); + } + +void DblGauge::dec(double amount) noexcept + { + deref(pimpl).dec(amount); + } + +double DblGauge::value() const noexcept + { + return deref(pimpl).value(); + } + +DblGaugeFamily::DblGaugeFamily(Impl* ptr) : MetricFamily(upcast(ptr)) + { + // nop + } + +DblGauge DblGaugeFamily::getOrAdd(Span labels) + { + return withNativeLabels(labels, [this](auto nativeLabels) + { + auto hdl = opaque(deref(this, pimpl).get_or_add(nativeLabels)); + return DblGauge{hdl}; + }); + } + +} // namespace zeek::telemetry diff --git a/src/telemetry/Gauge.h b/src/telemetry/Gauge.h new file mode 100644 index 0000000000..2f83b75462 --- /dev/null +++ b/src/telemetry/Gauge.h @@ -0,0 +1,262 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#pragma once + +#include +#include +#include + +#include "zeek/Span.h" +#include "zeek/telemetry/MetricFamily.h" + +namespace zeek::telemetry { + +class DblGaugeFamily; +class IntGaugeFamily; +class Manager; + +/** + * A handle to a metric that represents an integer value. Gauges are less + * permissive than counters and also allow decrementing the value. + */ +class IntGauge { +public: + friend class IntGaugeFamily; + + struct Impl; + + IntGauge() = delete; + IntGauge(const IntGauge&) noexcept = default; + IntGauge& operator=(const IntGauge&) noexcept = default; + + /** + * Increments the value by 1. + */ + void inc() noexcept; + + /** + * Increments the value by @p amount. + */ + void inc(int64_t amount) noexcept; + + /** + * Increments the value by 1. + * @returns the new value. + */ + int64_t operator++() noexcept; + + /** + * Decrements the value by 1. + */ + void dec() noexcept; + + /** + * Decrements the value by @p amount. + */ + void dec(int64_t amount) noexcept; + + /** + * Decrements the value by 1. + * @returns the new value. + */ + int64_t operator--() noexcept; + + /** + * @returns the current value. + */ + int64_t value() const noexcept; + + /** + * @returns whether @c this and @p other refer to the same counter. + */ + constexpr bool isSameAs(IntGauge other) const noexcept + { + return pimpl == other.pimpl; + } + +private: + explicit IntGauge(Impl* ptr) noexcept : pimpl(ptr) + { + // nop + } + + Impl* pimpl; +}; + +/** + * Checks whether two @ref IntGauge handles are identical. + * @returns whether @p lhs and @p rhs refer to the same object. + * @note compare their @c value instead to check for equality. + */ +constexpr bool operator==(IntGauge lhs, IntGauge rhs) noexcept + { + return lhs.isSameAs(rhs); + } + +/// @relates IntGauge +constexpr bool operator!=(IntGauge lhs, IntGauge rhs) noexcept + { + return !(lhs == rhs); + } + +/** + * Manages a collection of IntGauge metrics. + */ +class IntGaugeFamily : public MetricFamily { +public: + friend class Manager; + + class Impl; + + IntGaugeFamily(const IntGaugeFamily&) noexcept = default; + IntGaugeFamily& operator=(const IntGaugeFamily&) noexcept = default; + + /** + * Returns the metrics handle for given labels, creating a new instance + * lazily if necessary. + */ + IntGauge getOrAdd(Span labels); + + /** + * @copydoc getOrAdd + */ + IntGauge getOrAdd(std::initializer_list labels) + { + return getOrAdd(Span{labels.begin(), labels.size()}); + } + +private: + explicit IntGaugeFamily(Impl* ptr); +}; + +/** + * A handle to a metric that represents a floating point value. Gauges are less + * permissive than counters and also allow decrementing the value. + * up. + */ +class DblGauge { +public: + friend class DblGaugeFamily; + + struct Impl; + + DblGauge() = delete; + DblGauge(const DblGauge&) noexcept = default; + DblGauge& operator=(const DblGauge&) noexcept = default; + + /** + * Increments the value by 1. + */ + void inc() noexcept; + + /** + * Increments the value by @p amount. + */ + void inc(double amount) noexcept; + + /** + * Increments the value by 1. + */ + void dec() noexcept; + + /** + * Increments the value by @p amount. + */ + void dec(double amount) noexcept; + + /** + * @returns the current value. + */ + double value() const noexcept; + + /** + * @returns whether @c this and @p other refer to the same counter. + */ + constexpr bool isSameAs(DblGauge other) const noexcept + { + return pimpl == other.pimpl; + } + +private: + explicit DblGauge(Impl* ptr) noexcept : pimpl(ptr) + { + // nop + } + + Impl* pimpl; +}; + +/** + * Checks whether two @ref DblGauge handles are identical. + * @returns whether @p lhs and @p rhs refer to the same object. + * @note compare their @c value instead to check for equality. + */ +constexpr bool operator==(DblGauge lhs, DblGauge rhs) noexcept + { + return lhs.isSameAs(rhs); + } + +/// @relates DblGauge +constexpr bool operator!=(DblGauge lhs, DblGauge rhs) noexcept + { + return !(lhs == rhs); + } + +/** + * Manages a collection of DblGauge metrics. + */ +class DblGaugeFamily : public MetricFamily { +public: + friend class Manager; + + class Impl; + + DblGaugeFamily(const DblGaugeFamily&) noexcept = default; + DblGaugeFamily& operator=(const DblGaugeFamily&) noexcept = default; + + /** + * Returns the metrics handle for given labels, creating a new instance + * lazily if necessary. + */ + DblGauge getOrAdd(Span labels); + + /** + * @copydoc getOrAdd + */ + DblGauge getOrAdd(std::initializer_list labels) + { + return getOrAdd(Span{labels.begin(), labels.size()}); + } + +private: + explicit DblGaugeFamily(Impl* ptr); +}; + +namespace detail { + +template +struct GaugeOracle { + static_assert(std::is_same::value, + "Gauge only supports int64_t and double"); + + using type = IntGauge; + + using family_type = IntGaugeFamily; +}; + +template <> +struct GaugeOracle { + using type = DblGauge; + + using family_type = DblGaugeFamily; +}; + +} // namespace detail + +template +using Gauge = typename detail::GaugeOracle::type; + +template +using GaugeFamily = typename detail::GaugeOracle::family_type; + +} // namespace zeek::telemetry diff --git a/src/telemetry/Manager.cc b/src/telemetry/Manager.cc index f9765bef85..4ba9535ca1 100644 --- a/src/telemetry/Manager.cc +++ b/src/telemetry/Manager.cc @@ -22,6 +22,14 @@ using NativeDblCounter = ct::dbl_counter; using NativeDblCounterFamily = ct::metric_family_impl; +using NativeIntGauge = ct::int_gauge; + +using NativeIntGaugeFamily = ct::metric_family_impl; + +using NativeDblGauge = ct::dbl_gauge; + +using NativeDblGaugeFamily = ct::metric_family_impl; + auto& deref(Manager::Impl* ptr) { return *reinterpret_cast(ptr); @@ -42,6 +50,16 @@ auto opaque(NativeDblCounterFamily* ptr) return reinterpret_cast(ptr); } +auto opaque(NativeIntGaugeFamily* ptr) + { + return reinterpret_cast(ptr); + } + +auto opaque(NativeDblGaugeFamily* ptr) + { + return reinterpret_cast(ptr); + } + template auto withNative(Span xs, F continuation) { @@ -91,13 +109,56 @@ DblCounterFamily Manager::dblCounterFam(std::string_view prefix, }); } +IntGaugeFamily Manager::intGaugeFam(std::string_view prefix, + std::string_view name, + Span labels, + std::string_view helptext, + std::string_view unit, bool isSum) + { + return withNative(labels, [&, this](auto xs) + { + auto ptr = deref(pimpl).gauge_family(prefix, name, xs, + helptext, unit, isSum); + return IntGaugeFamily{opaque(ptr)}; + }); + } + +DblGaugeFamily Manager::dblGaugeFam(std::string_view prefix, + std::string_view name, + Span labels, + std::string_view helptext, + std::string_view unit, bool isSum) + { + return withNative(labels, [&, this](auto xs) + { + auto ptr = deref(pimpl).gauge_family(prefix, name, xs, + helptext, unit, isSum); + return DblGaugeFamily{opaque(ptr)}; + }); + } + } // namespace zeek::telemetry // -- unit tests --------------------------------------------------------------- +using namespace std::literals; using namespace zeek::telemetry; -SCENARIO("telemetry managers provide access to counters") +namespace { + +template +auto toVector(zeek::Span xs) + { + std::vector> result; + for (auto&& x : xs) + result.emplace_back(x); + return result; + } + + +} // namespace + +SCENARIO("telemetry managers provide access to counter singletons") { GIVEN("a telemetry manager") { @@ -157,3 +218,190 @@ SCENARIO("telemetry managers provide access to counters") } } } + +SCENARIO("telemetry managers provide access to counter families") + { + GIVEN("a telemetry manager") + { + NativeManager nativeMgr; + Manager mgr{opaque(&nativeMgr)}; + WHEN("retrieving an IntCounter family") + { + auto family = mgr.counterFamily("zeek", "requests", {"method"}, "test", "1", true); + THEN("the family object stores the parameters") + { + CHECK_EQ(family.prefix(), "zeek"sv); + CHECK_EQ(family.name(), "requests"sv); + CHECK_EQ(toVector(family.labelNames()), std::vector{"method"s}); + CHECK_EQ(family.helptext(), "test"sv); + CHECK_EQ(family.unit(), "1"sv); + CHECK_EQ(family.isSum(), true); + } + AND_THEN("getOrAdd returns the same metric for the same labels") + { + auto first = family.getOrAdd({{"method", "get"}}); + auto second = family.getOrAdd({{"method", "get"}}); + CHECK_EQ(first, second); + } + AND_THEN("getOrAdd returns different metric for the disjoint labels") + { + auto first = family.getOrAdd({{"method", "get"}}); + auto second = family.getOrAdd({{"method", "put"}}); + CHECK_NE(first, second); + } + } + WHEN("retrieving a DblCounter family") + { + auto family = mgr.counterFamily("zeek", "runtime", {"query"}, "test", "seconds", true); + THEN("the family object stores the parameters") + { + CHECK_EQ(family.prefix(), "zeek"sv); + CHECK_EQ(family.name(), "runtime"sv); + CHECK_EQ(toVector(family.labelNames()), std::vector{"query"s}); + CHECK_EQ(family.helptext(), "test"sv); + CHECK_EQ(family.unit(), "seconds"sv); + CHECK_EQ(family.isSum(), true); + } + AND_THEN("getOrAdd returns the same metric for the same labels") + { + auto first = family.getOrAdd({{"query", "foo"}}); + auto second = family.getOrAdd({{"query", "foo"}}); + CHECK_EQ(first, second); + } + AND_THEN("getOrAdd returns different metric for the disjoint labels") + { + auto first = family.getOrAdd({{"query", "foo"}}); + auto second = family.getOrAdd({{"query", "bar"}}); + CHECK_NE(first, second); + } + } + } + } + +SCENARIO("telemetry managers provide access to gauge singletons") + { + GIVEN("a telemetry manager") + { + NativeManager nativeMgr; + Manager mgr{opaque(&nativeMgr)}; + WHEN("retrieving an IntGauge singleton") + { + auto first = mgr.gaugeSingleton("zeek", "int-gauge", "test"); + THEN("its initial value is zero") + { + CHECK_EQ(first.value(), 0); + } + AND_THEN("calling inc(), dec(), operator++ or operator-- changes the value") + { + first.inc(); + CHECK_EQ(first.value(), 1); + first.inc(2); + CHECK_EQ(first.value(), 3); + first.dec(); + CHECK_EQ(first.value(), 2); + CHECK_EQ(++first, 3); + CHECK_EQ(first.value(), 3); + CHECK_EQ(--first, 2); + CHECK_EQ(first.value(), 2); + } + AND_THEN("calling gaugeSingleton again for the same name returns the same handle") + { + auto second = mgr.gaugeSingleton("zeek", "int-gauge", "test"); + CHECK_EQ(first, second); + } + AND_THEN("calling gaugeSingleton for a different name returns another handle") + { + auto third = mgr.gaugeSingleton("zeek", "int-gauge-2", "test"); + CHECK_NE(first, third); + } + } + WHEN("retrieving a DblGauge singleton") + { + auto first = mgr.gaugeSingleton("zeek", "dbl-gauge", "test"); + THEN("its initial value is zero") + { + CHECK_EQ(first.value(), 0.0); + } + AND_THEN("calling inc() or dec() changes the value") + { + first.inc(); + CHECK_EQ(first.value(), 1.0); + first.inc(3.0); + CHECK_EQ(first.value(), 4.0); + first.dec(2.0); + CHECK_EQ(first.value(), 2.0); + first.dec(); + CHECK_EQ(first.value(), 1.0); + } + AND_THEN("calling gaugeSingleton again for the same name returns the same handle") + { + auto second = mgr.gaugeSingleton("zeek", "dbl-gauge", "test"); + CHECK_EQ(first, second); + } + AND_THEN("calling gaugeSingleton for a different name returns another handle") + { + auto third = mgr.gaugeSingleton("zeek", "dbl-gauge-2", "test"); + CHECK_NE(first, third); + } + } + } + } + +SCENARIO("telemetry managers provide access to gauge families") + { + GIVEN("a telemetry manager") + { + NativeManager nativeMgr; + Manager mgr{opaque(&nativeMgr)}; + WHEN("retrieving an IntGauge family") + { + auto family = mgr.gaugeFamily("zeek", "open-connections", {"protocol"}, "test"); + THEN("the family object stores the parameters") + { + CHECK_EQ(family.prefix(), "zeek"sv); + CHECK_EQ(family.name(), "open-connections"sv); + CHECK_EQ(toVector(family.labelNames()), std::vector{"protocol"s}); + CHECK_EQ(family.helptext(), "test"sv); + CHECK_EQ(family.unit(), "1"sv); + CHECK_EQ(family.isSum(), false); + } + AND_THEN("getOrAdd returns the same metric for the same labels") + { + auto first = family.getOrAdd({{"protocol", "tcp"}}); + auto second = family.getOrAdd({{"protocol", "tcp"}}); + CHECK_EQ(first, second); + } + AND_THEN("getOrAdd returns different metric for the disjoint labels") + { + auto first = family.getOrAdd({{"protocol", "tcp"}}); + auto second = family.getOrAdd({{"protocol", "quic"}}); + CHECK_NE(first, second); + } + } + WHEN("retrieving a DblGauge family") + { + auto family = mgr.gaugeFamily("zeek", "water-level", {"river"}, "test", "meters"); + THEN("the family object stores the parameters") + { + CHECK_EQ(family.prefix(), "zeek"sv); + CHECK_EQ(family.name(), "water-level"sv); + CHECK_EQ(toVector(family.labelNames()), std::vector{"river"s}); + CHECK_EQ(family.helptext(), "test"sv); + CHECK_EQ(family.unit(), "meters"sv); + CHECK_EQ(family.isSum(), false); + } + AND_THEN("getOrAdd returns the same metric for the same labels") + { + auto first = family.getOrAdd({{"river", "Sacramento"}}); + auto second = family.getOrAdd({{"river", "Sacramento"}}); + CHECK_EQ(first, second); + } + AND_THEN("getOrAdd returns different metric for the disjoint labels") + { + auto first = family.getOrAdd({{"query", "Sacramento"}}); + auto second = family.getOrAdd({{"query", "San Joaquin"}}); + CHECK_NE(first, second); + } + } + } + } diff --git a/src/telemetry/Manager.h b/src/telemetry/Manager.h index 3206b3ed25..32f08f89b2 100644 --- a/src/telemetry/Manager.h +++ b/src/telemetry/Manager.h @@ -9,6 +9,7 @@ #include "zeek/Span.h" #include "zeek/telemetry/Counter.h" +#include "zeek/telemetry/Gauge.h" namespace zeek::telemetry { @@ -129,6 +130,107 @@ public: return fam.getOrAdd({}); } + /** + * @returns a gauge metric family. Creates the family lazily if necessary. + * @param prefix The prefix (namespace) this family belongs to. + * @param name The human-readable name of the metric, e.g., `requests`. + * @param labels Names for all label dimensions of the metric. + * @param helptext Short explanation of the metric. + * @param unit Unit of measurement. + * @param isSum Indicates whether this metric accumulates something, where + * only the total value is of interest. + */ + template + GaugeFamily + gaugeFamily(std::string_view prefix, std::string_view name, + Span labels, + std::string_view helptext, + std::string_view unit = "1", bool isSum = false) { + if constexpr (std::is_same::value) + { + return intGaugeFam(prefix, name, labels, helptext, unit, isSum); + } + else + { + static_assert(std::is_same::value, + "metrics only support int64_t and double values"); + return dblGaugeFam(prefix, name, labels, helptext, unit, isSum); + } + } + + /// @copydoc gaugeFamily + template + GaugeFamily + gaugeFamily(std::string_view prefix, std::string_view name, + std::initializer_list labels, + std::string_view helptext, std::string_view unit = "1", + bool isSum = false) + { + auto lblSpan = Span{labels.begin(), labels.size()}; + return gaugeFamily(prefix, name, lblSpan, helptext, + unit, isSum); + } + + /** + * Accesses a gauge instance. Creates the hosting metric family as well + * as the gauge lazily if necessary. + * @param prefix The prefix (namespace) this family belongs to. + * @param name The human-readable name of the metric, e.g., `requests`. + * @param labels Values for all label dimensions of the metric. + * @param helptext Short explanation of the metric. + * @param unit Unit of measurement. + * @param isSum Indicates whether this metric accumulates something, where + * only the total value is of interest. + */ + template + Gauge + gaugeInstance(std::string_view prefix, std::string_view name, + Span labels, std::string_view helptext, + std::string_view unit = "1", bool isSum = false) + { + return withLabelNames(labels, [&, this](auto labelNames) + { + auto family = gaugeFamily(prefix, name, labelNames, + helptext, unit, isSum); + return family.getOrAdd(labels); + }); + } + + /// @copydoc gaugeInstance + template + Gauge + gaugeInstance(std::string_view prefix, std::string_view name, + std::initializer_list labels, + std::string_view helptext, std::string_view unit = "1", + bool isSum = false) + { + auto lblSpan = Span{labels.begin(), labels.size()}; + return gaugeInstance(prefix, name, lblSpan, helptext, unit, isSum); + } + + /** + * Accesses a gauge singleton, i.e., a gauge that belongs to a family + * without label dimensions (which thus only has a single member). Creates + * the hosting metric family as well as the gauge lazily if necessary. + * @param prefix The prefix (namespace) this family belongs to. + * @param name The human-readable name of the metric, e.g., `requests`. + * @param helptext Short explanation of the metric. + * @param unit Unit of measurement. + * @param isSum Indicates whether this metric accumulates something, where + * only the total value is of interest. + */ + template + Gauge + gaugeSingleton(std::string_view prefix, std::string_view name, + std::string_view helptext, std::string_view unit = "1", + bool isSum = false) + { + auto labels = Span{}; + auto fam = gaugeFamily(prefix, name, labels, helptext, + unit, isSum); + return fam.getOrAdd({}); + } + private: IntCounterFamily intCounterFam(std::string_view prefix, std::string_view name, @@ -140,6 +242,16 @@ private: Span labels, std::string_view helptext, std::string_view unit, bool isSum); + IntGaugeFamily + intGaugeFam(std::string_view prefix, std::string_view name, + Span labels, + std::string_view helptext, std::string_view unit, bool isSum); + + DblGaugeFamily + dblGaugeFam(std::string_view prefix, std::string_view name, + Span labels, + std::string_view helptext, std::string_view unit, bool isSum); + template static void withLabelNames(Span xs, F continuation) { diff --git a/src/telemetry/MetricFamily.cc b/src/telemetry/MetricFamily.cc index e69de29bb2..dbece54de3 100644 --- a/src/telemetry/MetricFamily.cc +++ b/src/telemetry/MetricFamily.cc @@ -0,0 +1,52 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "zeek/telemetry/MetricFamily.h" + +#include "caf/telemetry/metric_family.hpp" + +namespace zeek::telemetry { + +namespace { + +namespace ct = caf::telemetry; + +using NativeMetricFamily = ct::metric_family; + +auto& deref(MetricFamily::Impl* ptr) + { + return *reinterpret_cast(ptr); + } + +} // namespace + +std::string_view MetricFamily::prefix() const noexcept + { + return deref(pimpl).prefix(); + } + +std::string_view MetricFamily::name() const noexcept + { + return deref(pimpl).name(); + } + +Span MetricFamily::labelNames() const noexcept + { + return deref(pimpl).label_names(); + } + +std::string_view MetricFamily::helptext() const noexcept + { + return deref(pimpl).helptext(); + } + +std::string_view MetricFamily::unit() const noexcept + { + return deref(pimpl).unit(); + } + +bool MetricFamily::isSum() const noexcept + { + return deref(pimpl).is_sum(); + } + +} // namespace zeek::telemetry diff --git a/src/telemetry/MetricFamily.h b/src/telemetry/MetricFamily.h index efac9a33ed..1f79d73907 100644 --- a/src/telemetry/MetricFamily.h +++ b/src/telemetry/MetricFamily.h @@ -44,7 +44,7 @@ public: /** * @returns the names for all label dimensions. */ - Span label_names() const noexcept; + Span labelNames() const noexcept; /** * @returns a short explanation of the metric.