Skip to content

Commit e294939

Browse files
committed
Allow summary metrics to use custom time source
1 parent 726422f commit e294939

File tree

12 files changed

+137
-20
lines changed

12 files changed

+137
-20
lines changed

core/include/prometheus/counter.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ class PROMETHEUS_CPP_CORE_EXPORT Counter {
4848
/// Collect is called by the Registry when collecting metrics.
4949
ClientMetric Collect() const;
5050

51+
/// \brief Get the current value of the counter.
52+
///
53+
/// \param time The time of when this function was called.
54+
///
55+
/// \return The current value.
56+
///
57+
/// Collect is called by the Registry when collecting metrics.
58+
ClientMetric Collect(const std::chrono::system_clock::time_point& time) const;
59+
5160
/// \brief Check if the counter has expired.
5261
///
5362
/// Expires is called by the Registry when collecting metrics.

core/include/prometheus/detail/time_window_quantiles.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ class PROMETHEUS_CPP_CORE_EXPORT TimeWindowQuantiles {
1717

1818
public:
1919
TimeWindowQuantiles(const std::vector<CKMSQuantiles::Quantile>& quantiles,
20+
const Clock::time_point& creation_time,
2021
Clock::duration max_age_seconds, int age_buckets);
2122

22-
double get(double q) const;
23-
void insert(double value);
23+
double get(double q, const Clock::time_point& time) const;
24+
void insert(double value, const Clock::time_point& time);
2425

2526
private:
26-
CKMSQuantiles& rotate() const;
27+
CKMSQuantiles& rotate(const Clock::time_point& time) const;
2728

2829
const std::vector<CKMSQuantiles::Quantile>& quantiles_;
2930
mutable std::vector<CKMSQuantiles> ckms_quantiles_;

core/include/prometheus/family.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,9 @@ class PROMETHEUS_CPP_CORE_EXPORT Family : public Collectable {
169169
std::chrono::seconds ttl_{std::chrono::seconds::max()};
170170
mutable std::mutex mutex_;
171171

172-
ClientMetric CollectMetric(const Labels& labels, T* metric) const;
172+
ClientMetric CollectMetric(
173+
const Labels& labels, T* metric,
174+
const std::chrono::system_clock::time_point& time) const;
173175
T& Add(const Labels& labels, std::unique_ptr<T> object);
174176
};
175177

core/include/prometheus/gauge.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ class PROMETHEUS_CPP_CORE_EXPORT Gauge {
5858
/// Collect is called by the Registry when collecting metrics.
5959
ClientMetric Collect() const;
6060

61+
/// \brief Get the current value of the gauge.
62+
///
63+
/// \param time The time of when this function was called.
64+
///
65+
/// \return The current value.
66+
///
67+
/// Collect is called by the Registry when collecting metrics.
68+
ClientMetric Collect(const std::chrono::system_clock::time_point& time) const;
69+
6170
/// \brief Check if the gauge has expired.
6271
///
6372
/// Expires is called by the Registry when collecting metrics.

core/include/prometheus/histogram.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,20 @@ class PROMETHEUS_CPP_CORE_EXPORT Histogram {
6363
void ObserveMultiple(const std::vector<double>& bucket_increments,
6464
const double sum_of_values);
6565

66-
/// \brief Get the current value of the counter.
66+
/// \brief Get the current value of the histogram.
6767
///
6868
/// Collect is called by the Registry when collecting metrics.
6969
ClientMetric Collect() const;
7070

71+
/// \brief Get the current value of the histogram.
72+
///
73+
/// \param time The time of when this function was called.
74+
///
75+
/// \return The current value.
76+
///
77+
/// Collect is called by the Registry when collecting metrics.
78+
ClientMetric Collect(const std::chrono::system_clock::time_point& time) const;
79+
7180
/// \brief Check if the histogram has expired.
7281
///
7382
/// Expires is called by the Registry when collecting metrics.

core/include/prometheus/summary.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,64 @@ class PROMETHEUS_CPP_CORE_EXPORT Summary {
7575
std::chrono::milliseconds max_age = std::chrono::seconds{60},
7676
int age_buckets = 5);
7777

78+
/// \brief Create a summary metric.
79+
///
80+
/// \param quantiles A list of 'targeted' Phi-quantiles. A targeted
81+
/// Phi-quantile is specified in the form of a Phi-quantile and tolerated
82+
/// error. For example a Quantile{0.5, 0.1} means that the median (= 50th
83+
/// percentile) should be returned with 10 percent error or a Quantile{0.2,
84+
/// 0.05} means the 20th percentile with 5 percent tolerated error. Note that
85+
/// percentiles and quantiles are the same concept, except percentiles are
86+
/// expressed as percentages. The Phi-quantile must be in the interval [0, 1].
87+
/// Note that a lower tolerated error for a Phi-quantile results in higher
88+
/// usage of resources (memory and cpu) to calculate the summary.
89+
///
90+
/// The Phi-quantiles are calculated over a sliding window of time. The
91+
/// sliding window of time is configured by max_age and age_buckets.
92+
///
93+
/// \param creation_time The time of when this constructor was called.
94+
///
95+
/// \param max_age Set the duration of the time window, i.e., how long
96+
/// observations are kept before they are discarded. The default value is 60
97+
/// seconds.
98+
///
99+
/// \param age_buckets Set the number of buckets of the time window. It
100+
/// determines the number of buckets used to exclude observations that are
101+
/// older than max_age from the summary, e.g., if max_age is 60 seconds and
102+
/// age_buckets is 5, buckets will be switched every 12 seconds. The value is
103+
/// a trade-off between resources (memory and cpu for maintaining the bucket)
104+
/// and how smooth the time window is moved. With only one age bucket it
105+
/// effectively results in a complete reset of the summary each time max_age
106+
/// has passed. The default value is 5.
107+
Summary(const Quantiles& quantiles,
108+
const std::chrono::system_clock::time_point& creation_time,
109+
std::chrono::milliseconds max_age = std::chrono::seconds{60},
110+
int age_buckets = 5);
111+
78112
/// \brief Observe the given amount.
79113
void Observe(double value);
80114

115+
/// \brief Observe the given amount.
116+
///
117+
/// \param quantiles The given amount.
118+
///
119+
/// \param time The time of when this function was called.
120+
void Observe(double value, const std::chrono::system_clock::time_point& time);
121+
81122
/// \brief Get the current value of the summary.
82123
///
83124
/// Collect is called by the Registry when collecting metrics.
84125
ClientMetric Collect() const;
85126

127+
/// \brief Get the current value of the summary.
128+
///
129+
/// \param time The time of when this function was called.
130+
///
131+
/// \return The current value.
132+
///
133+
/// Collect is called by the Registry when collecting metrics.
134+
ClientMetric Collect(const std::chrono::system_clock::time_point& time) const;
135+
86136
/// \brief Check if the summary has expired.
87137
///
88138
/// Expires is called by the Registry when collecting metrics.

core/src/counter.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ ClientMetric Counter::Collect() const {
1919
return metric;
2020
}
2121

22+
ClientMetric Counter::Collect(
23+
const std::chrono::system_clock::time_point& time) const {
24+
(void)time;
25+
return Collect();
26+
}
27+
2228
bool Counter::Expired(const std::chrono::system_clock::time_point& time,
2329
const std::chrono::seconds& ttl) {
2430
(void)time;

core/src/detail/time_window_quantiles.cc

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,29 @@ namespace detail {
88

99
TimeWindowQuantiles::TimeWindowQuantiles(
1010
const std::vector<CKMSQuantiles::Quantile>& quantiles,
11-
const Clock::duration max_age, const int age_buckets)
11+
const Clock::time_point& creation_time, const Clock::duration max_age,
12+
const int age_buckets)
1213
: quantiles_(quantiles),
1314
ckms_quantiles_(age_buckets, CKMSQuantiles(quantiles_)),
1415
current_bucket_(0),
15-
last_rotation_(Clock::now()),
16+
last_rotation_(creation_time),
1617
rotation_interval_(max_age / age_buckets) {}
1718

18-
double TimeWindowQuantiles::get(double q) const {
19-
CKMSQuantiles& current_bucket = rotate();
19+
double TimeWindowQuantiles::get(double q, const Clock::time_point& time) const {
20+
CKMSQuantiles& current_bucket = rotate(time);
2021
return current_bucket.get(q);
2122
}
2223

23-
void TimeWindowQuantiles::insert(double value) {
24-
rotate();
24+
void TimeWindowQuantiles::insert(double value, const Clock::time_point& time) {
25+
rotate(time);
2526
for (auto& bucket : ckms_quantiles_) {
2627
bucket.insert(value);
2728
}
2829
}
2930

30-
CKMSQuantiles& TimeWindowQuantiles::rotate() const {
31-
auto delta = Clock::now() - last_rotation_;
31+
CKMSQuantiles& TimeWindowQuantiles::rotate(
32+
const Clock::time_point& time) const {
33+
auto delta = time - last_rotation_;
3234
while (delta > rotation_interval_) {
3335
ckms_quantiles_[current_bucket_].reset();
3436

core/src/family.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,17 @@ std::vector<MetricFamily> Family<T>::Collect(
109109
for (const auto& m : metrics_) {
110110
if (!m.second->Expired(time, ttl_)) {
111111
family.metric.push_back(
112-
std::move(CollectMetric(m.first, m.second.get())));
112+
std::move(CollectMetric(m.first, m.second.get(), time)));
113113
}
114114
}
115115
return {family};
116116
}
117117

118118
template <typename T>
119-
ClientMetric Family<T>::CollectMetric(const Labels& metric_labels,
120-
T* metric) const {
121-
auto collected = metric->Collect();
119+
ClientMetric Family<T>::CollectMetric(
120+
const Labels& metric_labels, T* metric,
121+
const std::chrono::system_clock::time_point& time) const {
122+
auto collected = metric->Collect(time);
122123
collected.label.reserve(constant_labels_.size() + metric_labels.size());
123124
const auto add_label =
124125
[&collected](const std::pair<std::string, std::string>& label_pair) {

core/src/gauge.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ ClientMetric Gauge::Collect() const {
4141
return metric;
4242
}
4343

44+
ClientMetric Gauge::Collect(
45+
const std::chrono::system_clock::time_point& time) const {
46+
(void)time;
47+
return Collect();
48+
}
49+
4450
bool Gauge::Expired(const std::chrono::system_clock::time_point& time,
4551
const std::chrono::seconds& ttl) const {
4652
return std::chrono::duration_cast<std::chrono::seconds>(

0 commit comments

Comments
 (0)