diff --git a/src/Prometheus/Counter.php b/src/Prometheus/Counter.php index 3624c9c..e99acd2 100644 --- a/src/Prometheus/Counter.php +++ b/src/Prometheus/Counter.php @@ -45,4 +45,23 @@ public function incBy($count, array $labels = array()) ) ); } + + /** + * @param array $labels e.g. ['status', 'opcode'] + */ + public function reset(array $labels = array()) + { + $this->assertLabelsAreDefinedCorrectly($labels); + $this->storageAdapter->updateCounter( + array( + 'name' => $this->getName(), + 'help' => $this->getHelp(), + 'type' => $this->getType(), + 'labelNames' => $this->getLabelNames(), + 'labelValues' => $labels, + 'value' => 0, + 'command' => Adapter::COMMAND_SET + ) + ); + } } diff --git a/src/Prometheus/Storage/APC.php b/src/Prometheus/Storage/APC.php index b5a9c4b..a81b739 100644 --- a/src/Prometheus/Storage/APC.php +++ b/src/Prometheus/Storage/APC.php @@ -76,11 +76,16 @@ public function updateGauge(array $data) public function updateCounter(array $data) { - $new = apc_add($this->valueKey($data), 0); + $valueKey = $this->valueKey($data); + $new = apc_add($valueKey, 0); if ($new) { apc_store($this->metaKey($data), json_encode($this->metaData($data))); } - apc_inc($this->valueKey($data), $data['value']); + if ($data['command'] == Adapter::COMMAND_SET) { + apc_store($valueKey, 0); + } else { + apc_inc($valueKey, $data['value']); + } } public function flushAPC() diff --git a/tests/Test/Prometheus/AbstractCounterTest.php b/tests/Test/Prometheus/AbstractCounterTest.php index 92501f5..b884ea7 100644 --- a/tests/Test/Prometheus/AbstractCounterTest.php +++ b/tests/Test/Prometheus/AbstractCounterTest.php @@ -121,6 +121,78 @@ public function itShouldIncreaseTheCounterByAnArbitraryInteger() ); } + /** + * @test + */ + public function itShouldResetWithoutLabels() { + $counter = new Counter($this->adapter, 'test', 'some_metric', 'this is for testing'); + $counter->inc(); + $counter->incBy(125); + $counter->reset(); + $this->assertThat( + $this->adapter->collect(), + $this->equalTo( + array( + new MetricFamilySamples( + array( + 'type' => Counter::TYPE, + 'help' => 'this is for testing', + 'name' => 'test_some_metric', + 'labelNames' => array(), + 'samples' => array( + array( + 'labelValues' => array(), + 'value' => 0, + 'name' => 'test_some_metric', + 'labelNames' => array() + ), + ) + ) + ) + ) + ) + ); + } + + /** + * @test + */ + public function itShouldResetWithLabels() { + $counter = new Counter($this->adapter, 'test', 'some_metric', 'this is for testing', array('foo', 'bar')); + $counter->incBy(10, array('foo1', 'bar1')); + $counter->incBy(20, array('foo2', 'bar2')); + $counter->reset(array('foo1', 'bar1')); + $this->assertThat( + $this->adapter->collect(), + $this->equalTo( + array( + new MetricFamilySamples( + array( + 'type' => Counter::TYPE, + 'help' => 'this is for testing', + 'name' => 'test_some_metric', + 'labelNames' => array('foo', 'bar'), + 'samples' => array( + array( + 'labelValues' => array('foo1', 'bar1'), + 'value' => 0, + 'name' => 'test_some_metric', + 'labelNames' => array() + ), + array( + 'labelValues' => array('foo2', 'bar2'), + 'value' => 20, + 'name' => 'test_some_metric', + 'labelNames' => array() + ), + ) + ) + ) + ) + ) + ); + } + /** * @test * @expectedException \InvalidArgumentException