Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ endif()

# prometheus-cpp

if(WIN32)
add_compile_definitions(NOMINMAX)
endif()

add_subdirectory(core)

if(ENABLE_PULL)
Expand Down
5 changes: 3 additions & 2 deletions core/include/prometheus/collectable.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include <ctime>
#include <chrono>
#include <vector>

#include "prometheus/detail/core_export.h"
Expand All @@ -21,7 +21,8 @@ class PROMETHEUS_CPP_CORE_EXPORT Collectable {

/// \brief Returns a list of metrics and their samples.
virtual std::vector<MetricFamily> Collect() const = 0;
virtual std::vector<MetricFamily> Collect(std::time_t) const = 0;
virtual std::vector<MetricFamily> Collect(
const std::chrono::system_clock::time_point& time) const = 0;
};

} // namespace prometheus
11 changes: 9 additions & 2 deletions core/include/prometheus/counter.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include <ctime>
#include <chrono>

#include "prometheus/client_metric.h"
#include "prometheus/detail/builder.h" // IWYU pragma: export
Expand Down Expand Up @@ -47,7 +47,14 @@ class PROMETHEUS_CPP_CORE_EXPORT Counter {
///
/// Collect is called by the Registry when collecting metrics.
ClientMetric Collect() const;
bool Expired(std::time_t, double) const;

/// \brief Check if the counter has expired.
///
/// Expires is called by the Registry when collecting metrics.
///
/// A counter never expires.
static bool Expired(const std::chrono::system_clock::time_point& time,
const std::chrono::seconds& ttl);

private:
Gauge gauge_{0.0};
Expand Down
5 changes: 3 additions & 2 deletions core/include/prometheus/detail/builder.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <chrono>
#include <string>

#include "prometheus/labels.h"
Expand All @@ -21,14 +22,14 @@ class Builder {
Builder& Labels(const ::prometheus::Labels& labels);
Builder& Name(const std::string&);
Builder& Help(const std::string&);
Builder& Seconds(double);
Builder& TTL(const std::chrono::seconds& ttl);
Family<T>& Register(Registry&);

private:
::prometheus::Labels labels_;
std::string name_;
std::string help_;
double seconds_;
std::chrono::seconds ttl_{std::chrono::seconds::max()};
};

} // namespace detail
Expand Down
2 changes: 1 addition & 1 deletion core/include/prometheus/detail/time_window_quantiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace prometheus {
namespace detail {

class PROMETHEUS_CPP_CORE_EXPORT TimeWindowQuantiles {
using Clock = std::chrono::steady_clock;
using Clock = std::chrono::system_clock;

public:
TimeWindowQuantiles(const std::vector<CKMSQuantiles::Quantile>& quantiles,
Expand Down
21 changes: 17 additions & 4 deletions core/include/prometheus/family.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

#include <algorithm>
#include <cassert>
#include <chrono>
#include <cstddef>
#include <ctime>
#include <map>
#include <memory>
#include <mutex>
Expand Down Expand Up @@ -92,9 +92,12 @@ class PROMETHEUS_CPP_CORE_EXPORT Family : public Collectable {
/// \param constant_labels Assign a set of key-value pairs (= labels) to the
/// metric. All these labels are propagated to each time series within the
/// metric.
/// \param ttl Set the time to live in seconds. Any gauges that are not
/// updated within `ttl` seconds will not be collected.
/// \throw std::runtime_exception on invalid metric or label names.
Family(const std::string& name, const std::string& help,
const Labels& constant_labels, double seconds);
const Labels& constant_labels,
const std::chrono::seconds& ttl = std::chrono::seconds::max());

/// \brief Add a new dimensional data.
///
Expand Down Expand Up @@ -145,15 +148,25 @@ class PROMETHEUS_CPP_CORE_EXPORT Family : public Collectable {
///
/// \return Zero or more samples for each dimensional data.
std::vector<MetricFamily> Collect() const override;
std::vector<MetricFamily> Collect(std::time_t) const override;

/// \brief Returns the current value of each dimensional data.
///
/// Collect is called by the Registry when collecting metrics.
///
/// \param time The current time. This is used to check for
/// expired gauges.
///
/// \return Zero or more samples for each dimensional data.
std::vector<MetricFamily> Collect(
const std::chrono::system_clock::time_point& time) const override;

private:
std::unordered_map<Labels, std::unique_ptr<T>, detail::LabelHasher> metrics_;

const std::string name_;
const std::string help_;
const Labels constant_labels_;
double seconds_;
std::chrono::seconds ttl_{std::chrono::seconds::max()};
mutable std::mutex mutex_;

ClientMetric CollectMetric(const Labels& labels, T* metric) const;
Expand Down
23 changes: 20 additions & 3 deletions core/include/prometheus/gauge.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#include <atomic>
#include <ctime>
#include <chrono>

#include "prometheus/client_metric.h"
#include "prometheus/detail/builder.h" // IWYU pragma: export
Expand Down Expand Up @@ -57,12 +57,26 @@ class PROMETHEUS_CPP_CORE_EXPORT Gauge {
///
/// Collect is called by the Registry when collecting metrics.
ClientMetric Collect() const;
bool Expired(std::time_t, double) const;

/// \brief Check if the gauge has expired.
///
/// Expires is called by the Registry when collecting metrics.
///
/// A gauge has expired if it has been more than `ttl` seconds
/// since `time`.
///
/// \param time The current time.
/// \param time Time to live in seconds.
///
/// \return Has the gauge expired.
bool Expired(const std::chrono::system_clock::time_point& time,
const std::chrono::seconds& ttl) const;

private:
void Change(double);
std::atomic<double> value_{0.0};
std::atomic<std::time_t> time_{std::time(nullptr)};
std::atomic<std::chrono::system_clock::time_point> time_{
std::chrono::system_clock::now()};
};

/// \brief Return a builder to configure and register a Gauge metric.
Expand All @@ -77,6 +91,7 @@ class PROMETHEUS_CPP_CORE_EXPORT Gauge {
/// .Name("some_name")
/// .Help("Additional description.")
/// .Labels({{"key", "value"}})
/// .TTL(360)
/// .Register(*registry);
///
/// ...
Expand All @@ -89,6 +104,8 @@ class PROMETHEUS_CPP_CORE_EXPORT Gauge {
/// - Help(const std::string&) to set an additional description.
/// - Labels(const Labels&) to assign a set of
/// key-value pairs (= labels) to the metric.
/// - TTL(const std::chrono::seconds&)` to set the time to live. Gauges that
/// are not updated within `ttl` seconds will not be collected.
///
/// To finish the configuration of the Gauge metric register it with
/// Register(Registry&).
Expand Down
11 changes: 9 additions & 2 deletions core/include/prometheus/histogram.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include <ctime>
#include <chrono>
#include <mutex>
#include <vector>

Expand Down Expand Up @@ -67,7 +67,14 @@ class PROMETHEUS_CPP_CORE_EXPORT Histogram {
///
/// Collect is called by the Registry when collecting metrics.
ClientMetric Collect() const;
bool Expired(std::time_t, double) const;

/// \brief Check if the histogram has expired.
///
/// Expires is called by the Registry when collecting metrics.
///
/// A histogram never expires.
static bool Expired(const std::chrono::system_clock::time_point& time,
const std::chrono::seconds& ttl);

private:
const BucketBoundaries bucket_boundaries_;
Expand Down
17 changes: 14 additions & 3 deletions core/include/prometheus/registry.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include <ctime>
#include <chrono>
#include <memory>
#include <mutex>
#include <string>
Expand Down Expand Up @@ -80,7 +80,18 @@ class PROMETHEUS_CPP_CORE_EXPORT Registry : public Collectable {
///
/// \return Zero or more metrics and their samples.
std::vector<MetricFamily> Collect() const override;
std::vector<MetricFamily> Collect(std::time_t) const override;

/// \brief Returns a list of metrics and their samples.
///
/// Every time the Registry is scraped it calls each of the metrics Collect
/// function.
///
/// \param time The current time. This is used to check for
/// expired gauges.
///
/// \return Zero or more metrics and their samples.
std::vector<MetricFamily> Collect(
const std::chrono::system_clock::time_point& time) const override;

/// \brief Removes a metrics family from the registry.
///
Expand All @@ -107,7 +118,7 @@ class PROMETHEUS_CPP_CORE_EXPORT Registry : public Collectable {

template <typename T>
Family<T>& Add(const std::string& name, const std::string& help,
const Labels& labels, double seconds);
const Labels& labels, const std::chrono::seconds& ttl);

const InsertBehavior insert_behavior_;
std::vector<std::unique_ptr<Family<Counter>>> counters_;
Expand Down
10 changes: 8 additions & 2 deletions core/include/prometheus/summary.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#include <chrono>
#include <cstdint>
#include <ctime>
#include <mutex>
#include <vector>

Expand Down Expand Up @@ -83,7 +82,14 @@ class PROMETHEUS_CPP_CORE_EXPORT Summary {
///
/// Collect is called by the Registry when collecting metrics.
ClientMetric Collect() const;
bool Expired(std::time_t, double) const;

/// \brief Check if the summary has expired.
///
/// Expires is called by the Registry when collecting metrics.
///
/// A summary never expires.
static bool Expired(const std::chrono::system_clock::time_point& time,
const std::chrono::seconds& ttl);

private:
const Quantiles quantiles_;
Expand Down
5 changes: 3 additions & 2 deletions core/src/counter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ ClientMetric Counter::Collect() const {
return metric;
}

bool Counter::Expired(const std::time_t time, const double seconds) const {
bool Counter::Expired(const std::chrono::system_clock::time_point& time,
const std::chrono::seconds& ttl) {
(void)time;
(void)seconds;
(void)ttl;
return false;
}

Expand Down
6 changes: 3 additions & 3 deletions core/src/detail/builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ Builder<T>& Builder<T>::Help(const std::string& help) {
}

template <typename T>
Builder<T>& Builder<T>::Seconds(const double seconds) {
seconds_ = seconds;
Builder<T>& Builder<T>::TTL(const std::chrono::seconds& ttl) {
ttl_ = ttl;
return *this;
}

template <typename T>
Family<T>& Builder<T>::Register(Registry& registry) {
return registry.Add<T>(name_, help_, labels_, seconds_);
return registry.Add<T>(name_, help_, labels_, ttl_);
}

template class PROMETHEUS_CPP_CORE_EXPORT Builder<Counter>;
Expand Down
17 changes: 8 additions & 9 deletions core/src/family.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <algorithm>
#include <cassert>
#include <chrono>
#include <map>
#include <stdexcept>
#include <type_traits>
Expand All @@ -17,11 +18,9 @@ namespace prometheus {

template <typename T>
Family<T>::Family(const std::string& name, const std::string& help,
const Labels& constant_labels, const double seconds)
: name_(name),
help_(help),
constant_labels_(constant_labels),
seconds_(seconds) {
const Labels& constant_labels,
const std::chrono::seconds& ttl)
: name_(name), help_(help), constant_labels_(constant_labels), ttl_(ttl) {
if (!CheckMetricName(name_)) {
throw std::invalid_argument("Invalid metric name");
}
Expand Down Expand Up @@ -90,12 +89,12 @@ const Labels Family<T>::GetConstantLabels() const {

template <typename T>
std::vector<MetricFamily> Family<T>::Collect() const {
const auto time = std::time(nullptr);
return Collect(time);
return Collect(std::chrono::system_clock::now());
}

template <typename T>
std::vector<MetricFamily> Family<T>::Collect(const std::time_t time) const {
std::vector<MetricFamily> Family<T>::Collect(
const std::chrono::system_clock::time_point& time) const {
std::lock_guard<std::mutex> lock{mutex_};

if (metrics_.empty()) {
Expand All @@ -108,7 +107,7 @@ std::vector<MetricFamily> Family<T>::Collect(const std::time_t time) const {
family.type = T::metric_type;
family.metric.reserve(metrics_.size());
for (const auto& m : metrics_) {
if (!m.second.get()->Expired(time, seconds_)) {
if (!m.second->Expired(time, ttl_)) {
family.metric.push_back(
std::move(CollectMetric(m.first, m.second.get())));
}
Expand Down
12 changes: 8 additions & 4 deletions core/src/gauge.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "prometheus/gauge.h"

#include <ctime>

namespace prometheus {

Gauge::Gauge(const double value) : value_{value} {}
Expand All @@ -14,7 +16,7 @@ void Gauge::Decrement(const double value) { Change(-1.0 * value); }

void Gauge::Set(const double value) {
value_.store(value);
time_.store(std::time(nullptr));
time_.store(std::chrono::system_clock::now());
}

void Gauge::Change(const double value) {
Expand All @@ -23,7 +25,7 @@ void Gauge::Change(const double value) {
while (!value_.compare_exchange_weak(current, current + value)) {
// intentionally empty block
}
time_.store(std::time(nullptr));
time_.store(std::chrono::system_clock::now());
}

void Gauge::SetToCurrentTime() {
Expand All @@ -39,8 +41,10 @@ ClientMetric Gauge::Collect() const {
return metric;
}

bool Gauge::Expired(const std::time_t time, const double seconds) const {
return std::difftime(time, time_) > seconds;
bool Gauge::Expired(const std::chrono::system_clock::time_point& time,
const std::chrono::seconds& ttl) const {
return std::chrono::duration_cast<std::chrono::seconds>(time -
time_.load()) >= ttl;
}

} // namespace prometheus
Loading