Skip to content

Commit d576d10

Browse files
authored
Merge pull request #22 from PromPHP/allow-incrementing-counters-with-floats
Allow incrementing counters with floats
2 parents 0ced5ab + 7e3186e commit d576d10

File tree

3 files changed

+60
-16
lines changed

3 files changed

+60
-16
lines changed

src/Prometheus/Counter.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ public function inc(array $labels = []): void
2727
}
2828

2929
/**
30-
* @param int $count e.g. 2
30+
* @param int|float $count e.g. 2
3131
* @param mixed[] $labels e.g. ['status', 'opcode']
3232
*/
33-
public function incBy(int $count, array $labels = []): void
33+
public function incBy($count, array $labels = []): void
3434
{
3535
$this->assertLabelsAreDefinedCorrectly($labels);
3636

@@ -42,7 +42,7 @@ public function incBy(int $count, array $labels = []): void
4242
'labelNames' => $this->getLabelNames(),
4343
'labelValues' => $labels,
4444
'value' => $count,
45-
'command' => Adapter::COMMAND_INCREMENT_INTEGER,
45+
'command' => is_float($count) ? Adapter::COMMAND_INCREMENT_FLOAT : Adapter::COMMAND_INCREMENT_INTEGER,
4646
]
4747
);
4848
}

src/Prometheus/Storage/APC.php

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public function updateHistogram(array $data): void
3030
{
3131
// Initialize the sum
3232
$sumKey = $this->histogramBucketValueKey($data, 'sum');
33-
$new = apcu_add($sumKey, $this->toInteger(0));
33+
$new = apcu_add($sumKey, $this->toBinaryRepresentationAsInteger(0));
3434

3535
// If sum does not exist, assume a new histogram and store the metadata
3636
if ($new) {
@@ -43,7 +43,7 @@ public function updateHistogram(array $data): void
4343
while (!$done) {
4444
$old = apcu_fetch($sumKey);
4545
if ($old !== false) {
46-
$done = apcu_cas($sumKey, $old, $this->toInteger($this->fromInteger($old) + $data['value']));
46+
$done = apcu_cas($sumKey, $old, $this->toBinaryRepresentationAsInteger($this->fromBinaryRepresentationAsInteger($old) + $data['value']));
4747
}
4848
}
4949

@@ -68,10 +68,10 @@ public function updateGauge(array $data): void
6868
{
6969
$valueKey = $this->valueKey($data);
7070
if ($data['command'] === Adapter::COMMAND_SET) {
71-
apcu_store($valueKey, $this->toInteger($data['value']));
71+
apcu_store($valueKey, $this->toBinaryRepresentationAsInteger($data['value']));
7272
apcu_store($this->metaKey($data), json_encode($this->metaData($data)));
7373
} else {
74-
$new = apcu_add($valueKey, $this->toInteger(0));
74+
$new = apcu_add($valueKey, $this->toBinaryRepresentationAsInteger(0));
7575
if ($new) {
7676
apcu_store($this->metaKey($data), json_encode($this->metaData($data)));
7777
}
@@ -80,7 +80,7 @@ public function updateGauge(array $data): void
8080
while (!$done) {
8181
$old = apcu_fetch($valueKey);
8282
if ($old !== false) {
83-
$done = apcu_cas($valueKey, $old, $this->toInteger($this->fromInteger($old) + $data['value']));
83+
$done = apcu_cas($valueKey, $old, $this->toBinaryRepresentationAsInteger($this->fromBinaryRepresentationAsInteger($old) + $data['value']));
8484
}
8585
}
8686
}
@@ -91,11 +91,21 @@ public function updateGauge(array $data): void
9191
*/
9292
public function updateCounter(array $data): void
9393
{
94-
$new = apcu_add($this->valueKey($data), 0);
95-
if ($new) {
94+
$valueKey = $this->valueKey($data);
95+
// Check if value key already exists
96+
if (apcu_exists($this->valueKey($data)) === false) {
97+
apcu_add($this->valueKey($data), 0);
9698
apcu_store($this->metaKey($data), json_encode($this->metaData($data)));
9799
}
98-
apcu_inc($this->valueKey($data), $data['value']);
100+
101+
// Taken from https://github.com/prometheus/client_golang/blob/66058aac3a83021948e5fb12f1f408ff556b9037/prometheus/value.go#L91
102+
$done = false;
103+
while (!$done) {
104+
$old = apcu_fetch($valueKey);
105+
if ($old !== false) {
106+
$done = apcu_cas($valueKey, $old, $this->toBinaryRepresentationAsInteger($this->fromBinaryRepresentationAsInteger($old) + $data['value']));
107+
}
108+
}
99109
}
100110

101111
/**
@@ -180,7 +190,7 @@ private function collectCounters(): array
180190
'name' => $metaData['name'],
181191
'labelNames' => [],
182192
'labelValues' => $this->decodeLabelValues($labelValues),
183-
'value' => $value['value'],
193+
'value' => $this->fromBinaryRepresentationAsInteger($value['value']),
184194
];
185195
}
186196
$this->sortSamples($data['samples']);
@@ -211,7 +221,7 @@ private function collectGauges(): array
211221
'name' => $metaData['name'],
212222
'labelNames' => [],
213223
'labelValues' => $this->decodeLabelValues($labelValues),
214-
'value' => $this->fromInteger($value['value']),
224+
'value' => $this->fromBinaryRepresentationAsInteger($value['value']),
215225
];
216226
}
217227

@@ -288,7 +298,7 @@ private function collectHistograms(): array
288298
'name' => $metaData['name'] . '_sum',
289299
'labelNames' => [],
290300
'labelValues' => $decodedLabelValues,
291-
'value' => $this->fromInteger($histogramBuckets[$labelValues]['sum']),
301+
'value' => $this->fromBinaryRepresentationAsInteger($histogramBuckets[$labelValues]['sum']),
292302
];
293303
}
294304
$histograms[] = new MetricFamilySamples($data);
@@ -300,7 +310,7 @@ private function collectHistograms(): array
300310
* @param mixed $val
301311
* @return int
302312
*/
303-
private function toInteger($val): int
313+
private function toBinaryRepresentationAsInteger($val): int
304314
{
305315
return unpack('Q', pack('d', $val))[1];
306316
}
@@ -309,7 +319,7 @@ private function toInteger($val): int
309319
* @param mixed $val
310320
* @return float
311321
*/
312-
private function fromInteger($val): float
322+
private function fromBinaryRepresentationAsInteger($val): float
313323
{
314324
return unpack('d', pack('Q', $val))[1];
315325
}

tests/Test/Prometheus/AbstractCounterTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,40 @@ public function itShouldIncreaseTheCounterByAnArbitraryInteger(): void
127127
);
128128
}
129129

130+
/**
131+
* @test
132+
*/
133+
public function itShouldIncreaseTheCounterWithAFloat(): void
134+
{
135+
$counter = new Counter($this->adapter, 'test', 'some_metric', 'this is for testing', ['foo', 'bar']);
136+
$counter->inc(['lalal', 'lululu']);
137+
$counter->incBy(1.5, ['lalal', 'lululu']);
138+
self::assertThat(
139+
$this->adapter->collect(),
140+
self::equalTo(
141+
[
142+
new MetricFamilySamples(
143+
[
144+
'type' => Counter::TYPE,
145+
'help' => 'this is for testing',
146+
'name' => 'test_some_metric',
147+
'labelNames' => ['foo', 'bar'],
148+
'samples' => [
149+
[
150+
'labelValues' => ['lalal', 'lululu'],
151+
'value' => 2.5,
152+
'name' => 'test_some_metric',
153+
'labelNames' => [],
154+
],
155+
],
156+
]
157+
),
158+
]
159+
)
160+
);
161+
}
162+
163+
130164
/**
131165
* @test
132166
*/

0 commit comments

Comments
 (0)