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
9 changes: 9 additions & 0 deletions core/include/prometheus/counter.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ class PROMETHEUS_CPP_CORE_EXPORT Counter {
/// Collect is called by the Registry when collecting metrics.
ClientMetric Collect() const;

/// \brief Get the current value of the counter.
///
/// \param time The time of when this function was called.
///
/// \return The current value.
///
/// Collect is called by the Registry when collecting metrics.
ClientMetric Collect(const std::chrono::system_clock::time_point& time) const;

/// \brief Check if the counter has expired.
///
/// Expires is called by the Registry when collecting metrics.
Expand Down
7 changes: 4 additions & 3 deletions core/include/prometheus/detail/time_window_quantiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ class PROMETHEUS_CPP_CORE_EXPORT TimeWindowQuantiles {

public:
TimeWindowQuantiles(const std::vector<CKMSQuantiles::Quantile>& quantiles,
const Clock::time_point& creation_time,
Clock::duration max_age_seconds, int age_buckets);

double get(double q) const;
void insert(double value);
double get(double q, const Clock::time_point& time) const;
void insert(double value, const Clock::time_point& time);

private:
CKMSQuantiles& rotate() const;
CKMSQuantiles& rotate(const Clock::time_point& time) const;

const std::vector<CKMSQuantiles::Quantile>& quantiles_;
mutable std::vector<CKMSQuantiles> ckms_quantiles_;
Expand Down
4 changes: 3 additions & 1 deletion core/include/prometheus/family.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,9 @@ class PROMETHEUS_CPP_CORE_EXPORT Family : public Collectable {
std::chrono::seconds ttl_{std::chrono::seconds::max()};
mutable std::mutex mutex_;

ClientMetric CollectMetric(const Labels& labels, T* metric) const;
ClientMetric CollectMetric(
const Labels& labels, T* metric,
const std::chrono::system_clock::time_point& time) const;
T& Add(const Labels& labels, std::unique_ptr<T> object);
};

Expand Down
9 changes: 9 additions & 0 deletions core/include/prometheus/gauge.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ class PROMETHEUS_CPP_CORE_EXPORT Gauge {
/// Collect is called by the Registry when collecting metrics.
ClientMetric Collect() const;

/// \brief Get the current value of the gauge.
///
/// \param time The time of when this function was called.
///
/// \return The current value.
///
/// Collect is called by the Registry when collecting metrics.
ClientMetric Collect(const std::chrono::system_clock::time_point& time) const;

/// \brief Check if the gauge has expired.
///
/// Expires is called by the Registry when collecting metrics.
Expand Down
11 changes: 10 additions & 1 deletion core/include/prometheus/histogram.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,20 @@ class PROMETHEUS_CPP_CORE_EXPORT Histogram {
void ObserveMultiple(const std::vector<double>& bucket_increments,
const double sum_of_values);

/// \brief Get the current value of the counter.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just made upstream PR to fix this, so will remove from this commit.

/// \brief Get the current value of the histogram.
///
/// Collect is called by the Registry when collecting metrics.
ClientMetric Collect() const;

/// \brief Get the current value of the histogram.
///
/// \param time The time of when this function was called.
///
/// \return The current value.
///
/// Collect is called by the Registry when collecting metrics.
ClientMetric Collect(const std::chrono::system_clock::time_point& time) const;

/// \brief Check if the histogram has expired.
///
/// Expires is called by the Registry when collecting metrics.
Expand Down
50 changes: 50 additions & 0 deletions core/include/prometheus/summary.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,64 @@ class PROMETHEUS_CPP_CORE_EXPORT Summary {
std::chrono::milliseconds max_age = std::chrono::seconds{60},
int age_buckets = 5);

/// \brief Create a summary metric.
///
/// \param quantiles A list of 'targeted' Phi-quantiles. A targeted
/// Phi-quantile is specified in the form of a Phi-quantile and tolerated
/// error. For example a Quantile{0.5, 0.1} means that the median (= 50th
/// percentile) should be returned with 10 percent error or a Quantile{0.2,
/// 0.05} means the 20th percentile with 5 percent tolerated error. Note that
/// percentiles and quantiles are the same concept, except percentiles are
/// expressed as percentages. The Phi-quantile must be in the interval [0, 1].
/// Note that a lower tolerated error for a Phi-quantile results in higher
/// usage of resources (memory and cpu) to calculate the summary.
///
/// The Phi-quantiles are calculated over a sliding window of time. The
/// sliding window of time is configured by max_age and age_buckets.
///
/// \param creation_time The time of when this constructor was called.
///
/// \param max_age Set the duration of the time window, i.e., how long
/// observations are kept before they are discarded. The default value is 60
/// seconds.
///
/// \param age_buckets Set the number of buckets of the time window. It
/// determines the number of buckets used to exclude observations that are
/// older than max_age from the summary, e.g., if max_age is 60 seconds and
/// age_buckets is 5, buckets will be switched every 12 seconds. The value is
/// a trade-off between resources (memory and cpu for maintaining the bucket)
/// and how smooth the time window is moved. With only one age bucket it
/// effectively results in a complete reset of the summary each time max_age
/// has passed. The default value is 5.
Summary(const Quantiles& quantiles,
const std::chrono::system_clock::time_point& creation_time,
std::chrono::milliseconds max_age = std::chrono::seconds{60},
int age_buckets = 5);

/// \brief Observe the given amount.
void Observe(double value);

/// \brief Observe the given amount.
///
/// \param quantiles The given amount.
///
/// \param time The time of when this function was called.
void Observe(double value, const std::chrono::system_clock::time_point& time);

/// \brief Get the current value of the summary.
///
/// Collect is called by the Registry when collecting metrics.
ClientMetric Collect() const;

/// \brief Get the current value of the summary.
///
/// \param time The time of when this function was called.
///
/// \return The current value.
///
/// Collect is called by the Registry when collecting metrics.
ClientMetric Collect(const std::chrono::system_clock::time_point& time) const;

/// \brief Check if the summary has expired.
///
/// Expires is called by the Registry when collecting metrics.
Expand Down
6 changes: 6 additions & 0 deletions core/src/counter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ ClientMetric Counter::Collect() const {
return metric;
}

ClientMetric Counter::Collect(
const std::chrono::system_clock::time_point& time) const {
(void)time;
return Collect();
}

bool Counter::Expired(const std::chrono::system_clock::time_point& time,
const std::chrono::seconds& ttl) {
(void)time;
Expand Down
18 changes: 10 additions & 8 deletions core/src/detail/time_window_quantiles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,29 @@ namespace detail {

TimeWindowQuantiles::TimeWindowQuantiles(
const std::vector<CKMSQuantiles::Quantile>& quantiles,
const Clock::duration max_age, const int age_buckets)
const Clock::time_point& creation_time, const Clock::duration max_age,
const int age_buckets)
: quantiles_(quantiles),
ckms_quantiles_(age_buckets, CKMSQuantiles(quantiles_)),
current_bucket_(0),
last_rotation_(Clock::now()),
last_rotation_(creation_time),
rotation_interval_(max_age / age_buckets) {}

double TimeWindowQuantiles::get(double q) const {
CKMSQuantiles& current_bucket = rotate();
double TimeWindowQuantiles::get(double q, const Clock::time_point& time) const {
CKMSQuantiles& current_bucket = rotate(time);
return current_bucket.get(q);
}

void TimeWindowQuantiles::insert(double value) {
rotate();
void TimeWindowQuantiles::insert(double value, const Clock::time_point& time) {
rotate(time);
for (auto& bucket : ckms_quantiles_) {
bucket.insert(value);
}
}

CKMSQuantiles& TimeWindowQuantiles::rotate() const {
auto delta = Clock::now() - last_rotation_;
CKMSQuantiles& TimeWindowQuantiles::rotate(
const Clock::time_point& time) const {
auto delta = time - last_rotation_;
while (delta > rotation_interval_) {
ckms_quantiles_[current_bucket_].reset();

Expand Down
9 changes: 5 additions & 4 deletions core/src/family.cc
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,17 @@ std::vector<MetricFamily> Family<T>::Collect(
for (const auto& m : metrics_) {
if (!m.second->Expired(time, ttl_)) {
family.metric.push_back(
std::move(CollectMetric(m.first, m.second.get())));
std::move(CollectMetric(m.first, m.second.get(), time)));
}
}
return {family};
}

template <typename T>
ClientMetric Family<T>::CollectMetric(const Labels& metric_labels,
T* metric) const {
auto collected = metric->Collect();
ClientMetric Family<T>::CollectMetric(
const Labels& metric_labels, T* metric,
const std::chrono::system_clock::time_point& time) const {
auto collected = metric->Collect(time);
collected.label.reserve(constant_labels_.size() + metric_labels.size());
const auto add_label =
[&collected](const std::pair<std::string, std::string>& label_pair) {
Expand Down
6 changes: 6 additions & 0 deletions core/src/gauge.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ ClientMetric Gauge::Collect() const {
return metric;
}

ClientMetric Gauge::Collect(
const std::chrono::system_clock::time_point& time) const {
(void)time;
return Collect();
}

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 -
Expand Down
6 changes: 6 additions & 0 deletions core/src/histogram.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ ClientMetric Histogram::Collect() const {
return metric;
}

ClientMetric Histogram::Collect(
const std::chrono::system_clock::time_point& time) const {
(void)time;
return Collect();
}

bool Histogram::Expired(const std::chrono::system_clock::time_point& time,
const std::chrono::seconds& ttl) {
(void)time;
Expand Down
22 changes: 19 additions & 3 deletions core/src/summary.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,36 @@ namespace prometheus {

Summary::Summary(const Quantiles& quantiles,
const std::chrono::milliseconds max_age, const int age_buckets)
: Summary(quantiles, std::chrono::system_clock::now(), max_age,
age_buckets) {}

Summary::Summary(const Quantiles& quantiles,
const std::chrono::system_clock::time_point& creation_time,
const std::chrono::milliseconds max_age, const int age_buckets)
: quantiles_{quantiles},
count_{0},
sum_{0},
quantile_values_{quantiles_, max_age, age_buckets} {}
quantile_values_{quantiles_, creation_time, max_age, age_buckets} {}

void Summary::Observe(const double value) {
Observe(value, std::chrono::system_clock::now());
}

void Summary::Observe(const double value,
const std::chrono::system_clock::time_point& time) {
std::lock_guard<std::mutex> lock(mutex_);

count_ += 1;
sum_ += value;
quantile_values_.insert(value);
quantile_values_.insert(value, time);
}

ClientMetric Summary::Collect() const {
return Collect(std::chrono::system_clock::now());
}

ClientMetric Summary::Collect(
const std::chrono::system_clock::time_point& time) const {
auto metric = ClientMetric{};

std::lock_guard<std::mutex> lock(mutex_);
Expand All @@ -28,7 +44,7 @@ ClientMetric Summary::Collect() const {
for (const auto& quantile : quantiles_) {
auto metricQuantile = ClientMetric::Quantile{};
metricQuantile.quantile = quantile.quantile;
metricQuantile.value = quantile_values_.get(quantile.quantile);
metricQuantile.value = quantile_values_.get(quantile.quantile, time);
metric.summary.quantile.push_back(std::move(metricQuantile));
}
metric.summary.sample_count = count_;
Expand Down