Skip to content

Commit ee34417

Browse files
committed
#646 document implications of negative observations for summaries and histograms
1 parent 29dfd0a commit ee34417

File tree

4 files changed

+66
-3
lines changed

4 files changed

+66
-3
lines changed

simpleclient/src/main/java/io/prometheus/client/Histogram.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ private Child(double[] buckets) {
255255

256256
/**
257257
* Observe the given amount.
258+
* @param amt in most cases amt should be >= 0. Negative values are supported, but you should read
259+
* <a href="https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations">
260+
* https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations</a> for
261+
* implications and alternatives.
258262
*/
259263
public void observe(double amt) {
260264
for (int i = 0; i < upperBounds.length; ++i) {
@@ -293,6 +297,10 @@ public Value get() {
293297
// Convenience methods.
294298
/**
295299
* Observe the given amount on the histogram with no labels.
300+
* @param amt in most cases amt should be >= 0. Negative values are supported, but you should read
301+
* <a href="https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations">
302+
* https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations</a> for
303+
* implications and alternatives.
296304
*/
297305
public void observe(double amt) {
298306
noLabelsChild.observe(amt);

simpleclient/src/main/java/io/prometheus/client/Summary.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,10 @@ private Child(List<Quantile> quantiles, long maxAgeSeconds, int ageBuckets) {
278278

279279
/**
280280
* Observe the given amount.
281+
* @param amt in most cases amt should be >= 0. Negative values are supported, but you should read
282+
* <a href="https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations">
283+
* https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations</a> for
284+
* implications and alternatives.
281285
*/
282286
public void observe(double amt) {
283287
count.add(1);
@@ -307,6 +311,10 @@ public Value get() {
307311
// Convenience methods.
308312
/**
309313
* Observe the given amount on the summary with no labels.
314+
* @param amt in most cases amt should be >= 0. Negative values are supported, but you should read
315+
* <a href="https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations">
316+
* https://prometheus.io/docs/practices/histograms/#count-and-sum-of-observations</a> for
317+
* implications and alternatives.
310318
*/
311319
public void observe(double amt) {
312320
noLabelsChild.observe(amt);

simpleclient/src/test/java/io/prometheus/client/HistogramTest.java

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,27 @@ public void tearDown() {
3939
}
4040

4141
private double getCount() {
42-
return registry.getSampleValue("nolabels_count").doubleValue();
42+
return getCount("nolabels");
4343
}
44+
45+
private double getCount(String name) {
46+
return registry.getSampleValue(name + "_count").doubleValue();
47+
}
48+
4449
private double getSum() {
45-
return registry.getSampleValue("nolabels_sum").doubleValue();
50+
return getSum("nolabels");
4651
}
52+
53+
private double getSum(String name) {
54+
return registry.getSampleValue(name + "_sum").doubleValue();
55+
}
56+
4757
private double getBucket(double b) {
48-
return registry.getSampleValue("nolabels_bucket",
58+
return getBucket(b, "nolabels");
59+
}
60+
61+
private double getBucket(double b, String name) {
62+
return registry.getSampleValue(name + "_bucket",
4963
new String[]{"le"},
5064
new String[]{Collector.doubleToGoString(b)}).doubleValue();
5165
}
@@ -68,6 +82,30 @@ public void testObserve() {
6882
assertEquals(2.0, getBucket(Double.POSITIVE_INFINITY), .001);
6983
}
7084

85+
@Test
86+
// See https://github.com/prometheus/client_java/issues/646
87+
public void testNegativeAmount() {
88+
Histogram histogram = Histogram.build()
89+
.name("histogram")
90+
.help("test histogram for negative values")
91+
.buckets(-10, -5, 0, 5, 10)
92+
.register(registry);
93+
double expectedCount = 0;
94+
double expectedSum = 0;
95+
for (int i=10; i>=-11; i--) {
96+
histogram.observe(i);
97+
expectedCount++;
98+
expectedSum += i;
99+
assertEquals(expectedSum, getSum("histogram"), .001);
100+
assertEquals(expectedCount, getCount("histogram"), .001);
101+
}
102+
double[] expectedBucketValues = new double[]{2.0, 7.0, 12.0, 17.0, 22.0, 22.0}; // buckets -10, -5, 0, 5, 10, +Inf
103+
for (int i=0; i<expectedBucketValues.length; i++) {
104+
double bucket = histogram.getBuckets()[i];
105+
assertEquals(expectedBucketValues[i], getBucket(bucket, "histogram"), .001);
106+
}
107+
}
108+
71109
@Test
72110
public void testBoundaryConditions() {
73111
// Equal to a bucket.

simpleclient/src/test/java/io/prometheus/client/SummaryTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,15 @@ public void testObserve() {
7070
assertEquals(6.0, noLabels.get().sum, .001);
7171
}
7272

73+
@Test
74+
// See https://github.com/prometheus/client_java/issues/646
75+
public void testNegativeAmount() {
76+
noLabels.observe(-1);
77+
noLabels.observe(-3);
78+
assertEquals(2.0, getCount(), .001);
79+
assertEquals(-4.0, getSum(), .001);
80+
}
81+
7382
@Test
7483
public void testQuantiles() {
7584
int nSamples = 1000000; // simulate one million samples

0 commit comments

Comments
 (0)