Commit 5e0fb483 authored by Dominik Charousset's avatar Dominik Charousset

Add double gauges

parent f20b13b0
......@@ -309,6 +309,7 @@ caf_add_test_suites(caf-core-test
string_view
sum_type
telemetry.collector.prometheus
telemetry.dbl_gauge
telemetry.int_gauge
telemetry.label
telemetry.metric_registry
......
......@@ -234,6 +234,7 @@ struct subscriber_base;
namespace telemetry {
class component;
class dbl_gauge;
class int_gauge;
class label;
class label_view;
......
......@@ -69,6 +69,9 @@ public:
// -- call operators for the metric registry ---------------------------------
void operator()(const metric_family* family, const metric* instance,
const dbl_gauge* gauge);
void operator()(const metric_family* family, const metric* instance,
const int_gauge* gauge);
......
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2020 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include "caf/detail/core_export.hpp"
#include <atomic>
#include <cstdint>
#include "caf/telemetry/metric_type.hpp"
namespace caf::telemetry {
/// A metric that represents a single integer value that can arbitrarily go up
/// and down.
class CAF_CORE_EXPORT dbl_gauge {
public:
static constexpr metric_type runtime_type = metric_type::dbl_gauge;
dbl_gauge() noexcept : value_(0) {
// nop
}
explicit dbl_gauge(double value) noexcept : value_(value) {
// nop
}
/// Increments the gauge by 1.
void inc() noexcept {
inc(1.0);
}
/// Increments the gauge by `amount`.
void inc(double amount) noexcept {
auto val = value_.load();
auto new_val = val + amount;
while (!value_.compare_exchange_weak(val, new_val)) {
new_val = val + amount;
}
}
/// Decrements the gauge by 1.
void dec() noexcept {
dec(1.0);
}
/// Decrements the gauge by `amount`.
void dec(double amount) noexcept {
inc(-amount);
}
/// Sets the gauge to `x`.
void value(double x) noexcept {
value_.store(x);
}
/// Returns the current value of the gauge.
double value() const noexcept {
return value_.load();
}
private:
std::atomic<double> value_;
};
} // namespace caf::telemetry
......@@ -115,6 +115,8 @@ public:
template <class Collector>
void collect(Collector& collector) const {
std::unique_lock<std::mutex> guard{families_mx_};
for (auto& ptr : dbl_gauges_)
ptr->collect(collector);
for (auto& ptr : int_gauges_)
ptr->collect(collector);
}
......@@ -138,14 +140,23 @@ private:
span<const string_view> label_names, string_view unit,
bool is_sum);
void assert_equal(metric_family* old_ptr, metric_family* new_ptr);
template <class Type>
metric_family_container<Type>& container_by_type();
mutable std::mutex families_mx_;
metric_family_container<telemetry::dbl_gauge> dbl_gauges_;
metric_family_container<telemetry::int_gauge> int_gauges_;
};
template <>
inline metric_registry::metric_family_container<dbl_gauge>&
metric_registry::container_by_type<dbl_gauge>() {
return dbl_gauges_;
}
template <>
inline metric_registry::metric_family_container<int_gauge>&
metric_registry::container_by_type<int_gauge>() {
......
......@@ -22,6 +22,7 @@ namespace caf::telemetry {
enum class metric_type : uint8_t {
int_gauge,
dbl_gauge,
};
} // namespace caf::telemetry
......@@ -22,6 +22,7 @@
#include <ctime>
#include <type_traits>
#include "caf/telemetry/dbl_gauge.hpp"
#include "caf/telemetry/int_gauge.hpp"
#include "caf/telemetry/metric.hpp"
#include "caf/telemetry/metric_family.hpp"
......@@ -132,6 +133,12 @@ string_view prometheus::collect_from(const metric_registry& registry) {
return collect_from(registry, time(NULL));
}
void prometheus::operator()(const metric_family* family, const metric* instance,
const dbl_gauge* gauge) {
set_current_family(family, "gauge");
append(buf_, family, instance, ' ', gauge->value(), ' ', now_, '\n');
}
void prometheus::operator()(const metric_family* family, const metric* instance,
const int_gauge* gauge) {
set_current_family(family, "gauge");
......
......@@ -20,6 +20,7 @@
#include "caf/config.hpp"
#include "caf/raise_error.hpp"
#include "caf/telemetry/dbl_gauge.hpp"
#include "caf/telemetry/int_gauge.hpp"
#include "caf/telemetry/metric_family_impl.hpp"
#include "caf/telemetry/metric_impl.hpp"
......@@ -40,6 +41,9 @@ metric_family* metric_registry::fetch(const string_view& prefix,
auto matches = [&](const auto& ptr) {
return ptr->prefix() == prefix && ptr->name() == name;
};
if (auto i = std::find_if(dbl_gauges_.begin(), dbl_gauges_.end(), matches);
i != dbl_gauges_.end())
return i->get();
if (auto i = std::find_if(int_gauges_.begin(), int_gauges_.end(), matches);
i != int_gauges_.end())
return i->get();
......
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2020 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#define CAF_SUITE telemetry.dbl_gauge
#include "caf/telemetry/dbl_gauge.hpp"
#include "caf/test/dsl.hpp"
using namespace caf;
CAF_TEST(double gauges can increment and decrement) {
telemetry::dbl_gauge g;
CAF_MESSAGE("gauges start at 0");
CAF_CHECK_EQUAL(g.value(), 0.0);
CAF_MESSAGE("gauges are incrementable");
g.inc();
g.inc(2.0);
CAF_CHECK_EQUAL(g.value(), 3.0);
CAF_MESSAGE("gauges are decrementable");
g.dec();
g.dec(5.0);
CAF_CHECK_EQUAL(g.value(), -3.0);
CAF_MESSAGE("gauges allow setting values");
g.value(42.0);
CAF_CHECK_EQUAL(g.value(), 42.0);
CAF_MESSAGE("users can create gauges with custom start values");
CAF_CHECK_EQUAL(telemetry::dbl_gauge{42.0}.value(), 42.0);
}
......@@ -23,6 +23,7 @@
#include "caf/test/dsl.hpp"
#include "caf/string_view.hpp"
#include "caf/telemetry/dbl_gauge.hpp"
#include "caf/telemetry/int_gauge.hpp"
#include "caf/telemetry/label_view.hpp"
#include "caf/telemetry/metric_type.hpp"
......@@ -35,8 +36,19 @@ namespace {
struct test_collector {
std::string result;
void operator()(const metric_family* family, const metric* instance,
const dbl_gauge* wrapped) {
concat(family, instance);
result += std::to_string(wrapped->value());
}
void operator()(const metric_family* family, const metric* instance,
const int_gauge* wrapped) {
concat(family, instance);
result += std::to_string(wrapped->value());
}
void concat(const metric_family* family, const metric* instance) {
result += '\n';
result += family->prefix();
result += '_';
......@@ -58,7 +70,6 @@ struct test_collector {
result += '}';
}
result += ' ';
result += std::to_string(wrapped->value());
}
void concat(const label& lbl) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment