Skip to content
This repository was archived by the owner on Oct 22, 2019. It is now read-only.

Commit ce813f7

Browse files
martinssipenkoNoelDavies
authored andcommitted
Inject Redis via named constructor (#8)
* Inject Redis via named constructor * change method name * Added withExistingConnection test * Fix for redis prefix support and respective tests * removed unneeded code * phpcbf
1 parent f4c614c commit ce813f7

6 files changed

Lines changed: 147 additions & 37 deletions

File tree

src/Prometheus/Storage/Redis.php

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ class Redis implements Adapter
4242
*/
4343
private $redis;
4444

45+
/**
46+
* @var boolean
47+
*/
48+
private $connectionInitialized = false;
49+
4550
/**
4651
* Redis constructor.
4752
* @param array $options
@@ -52,6 +57,19 @@ public function __construct(array $options = [])
5257
$this->redis = new \Redis();
5358
}
5459

60+
public static function fromExistingConnection(\Redis $redis): self
61+
{
62+
if ($redis->isConnected() === false) {
63+
throw new StorageException('Connection to Redis server not established');
64+
}
65+
66+
$self = new self();
67+
$self->connectionInitialized = true;
68+
$self->redis = $redis;
69+
70+
return $self;
71+
}
72+
5573
/**
5674
* @param array $options
5775
*/
@@ -100,6 +118,10 @@ function (array $metric) {
100118
*/
101119
private function openConnection(): void
102120
{
121+
if ($this->connectionInitialized === true) {
122+
return;
123+
}
124+
103125
$connectionStatus = $this->connectToServer();
104126
if ($connectionStatus === false) {
105127
throw new StorageException("Can't connect to Redis server", 0);
@@ -153,25 +175,26 @@ public function updateHistogram(array $data): void
153175
$metaData = $data;
154176
unset($metaData['value']);
155177
unset($metaData['labelValues']);
178+
156179
$this->redis->eval(
157180
<<<LUA
158-
local increment = redis.call('hIncrByFloat', KEYS[1], KEYS[2], ARGV[1])
159-
redis.call('hIncrBy', KEYS[1], KEYS[3], 1)
160-
if increment == ARGV[1] then
161-
redis.call('hSet', KEYS[1], '__meta', ARGV[2])
162-
redis.call('sAdd', KEYS[4], KEYS[1])
181+
local increment = redis.call('hIncrByFloat', KEYS[1], ARGV[1], ARGV[3])
182+
redis.call('hIncrBy', KEYS[1], ARGV[2], 1)
183+
if increment == ARGV[3] then
184+
redis.call('hSet', KEYS[1], '__meta', ARGV[4])
185+
redis.call('sAdd', KEYS[2], KEYS[1])
163186
end
164187
LUA
165188
,
166189
[
167190
$this->toMetricKey($data),
191+
self::$prefix . Histogram::TYPE . self::PROMETHEUS_METRIC_KEYS_SUFFIX,
168192
json_encode(['b' => 'sum', 'labelValues' => $data['labelValues']]),
169193
json_encode(['b' => $bucketToIncrease, 'labelValues' => $data['labelValues']]),
170-
self::$prefix . Histogram::TYPE . self::PROMETHEUS_METRIC_KEYS_SUFFIX,
171194
$data['value'],
172195
json_encode($metaData),
173196
],
174-
4
197+
2
175198
);
176199
}
177200

@@ -188,30 +211,30 @@ public function updateGauge(array $data): void
188211
unset($metaData['command']);
189212
$this->redis->eval(
190213
<<<LUA
191-
local result = redis.call(KEYS[2], KEYS[1], KEYS[4], ARGV[1])
214+
local result = redis.call(ARGV[1], KEYS[1], ARGV[2], ARGV[3])
192215
193-
if KEYS[2] == 'hSet' then
216+
if ARGV[1] == 'hSet' then
194217
if result == 1 then
195-
redis.call('hSet', KEYS[1], '__meta', ARGV[2])
196-
redis.call('sAdd', KEYS[3], KEYS[1])
218+
redis.call('hSet', KEYS[1], '__meta', ARGV[4])
219+
redis.call('sAdd', KEYS[2], KEYS[1])
197220
end
198221
else
199-
if result == ARGV[1] then
200-
redis.call('hSet', KEYS[1], '__meta', ARGV[2])
201-
redis.call('sAdd', KEYS[3], KEYS[1])
222+
if result == ARGV[3] then
223+
redis.call('hSet', KEYS[1], '__meta', ARGV[4])
224+
redis.call('sAdd', KEYS[2], KEYS[1])
202225
end
203226
end
204227
LUA
205228
,
206229
[
207230
$this->toMetricKey($data),
208-
$this->getRedisCommand($data['command']),
209231
self::$prefix . Gauge::TYPE . self::PROMETHEUS_METRIC_KEYS_SUFFIX,
232+
$this->getRedisCommand($data['command']),
210233
json_encode($data['labelValues']),
211234
$data['value'],
212235
json_encode($metaData),
213236
],
214-
4
237+
2
215238
);
216239
}
217240

@@ -228,23 +251,23 @@ public function updateCounter(array $data): void
228251
unset($metaData['command']);
229252
$this->redis->eval(
230253
<<<LUA
231-
local result = redis.call(KEYS[2], KEYS[1], KEYS[4], ARGV[1])
232-
if result == tonumber(ARGV[1]) then
233-
redis.call('hMSet', KEYS[1], '__meta', ARGV[2])
234-
redis.call('sAdd', KEYS[3], KEYS[1])
254+
local result = redis.call(ARGV[1], KEYS[1], ARGV[3], ARGV[2])
255+
if result == tonumber(ARGV[2]) then
256+
redis.call('hMSet', KEYS[1], '__meta', ARGV[4])
257+
redis.call('sAdd', KEYS[2], KEYS[1])
235258
end
236259
return result
237260
LUA
238261
,
239262
[
240263
$this->toMetricKey($data),
241-
$this->getRedisCommand($data['command']),
242264
self::$prefix . Counter::TYPE . self::PROMETHEUS_METRIC_KEYS_SUFFIX,
243-
json_encode($data['labelValues']),
265+
$this->getRedisCommand($data['command']),
244266
$data['value'],
267+
json_encode($data['labelValues']),
245268
json_encode($metaData),
246269
],
247-
4
270+
2
248271
);
249272
}
250273

@@ -257,7 +280,7 @@ private function collectHistograms(): array
257280
sort($keys);
258281
$histograms = [];
259282
foreach ($keys as $key) {
260-
$raw = $this->redis->hGetAll($key);
283+
$raw = $this->redis->hGetAll(str_replace($this->redis->_prefix(''), '', $key));
261284
$histogram = json_decode($raw['__meta'], true);
262285
unset($raw['__meta']);
263286
$histogram['samples'] = [];
@@ -334,7 +357,7 @@ private function collectGauges(): array
334357
sort($keys);
335358
$gauges = [];
336359
foreach ($keys as $key) {
337-
$raw = $this->redis->hGetAll($key);
360+
$raw = $this->redis->hGetAll(str_replace($this->redis->_prefix(''), '', $key));
338361
$gauge = json_decode($raw['__meta'], true);
339362
unset($raw['__meta']);
340363
$gauge['samples'] = [];
@@ -363,7 +386,7 @@ private function collectCounters(): array
363386
sort($keys);
364387
$counters = [];
365388
foreach ($keys as $key) {
366-
$raw = $this->redis->hGetAll($key);
389+
$raw = $this->redis->hGetAll(str_replace($this->redis->_prefix(''), '', $key));
367390
$counter = json_decode($raw['__meta'], true);
368391
unset($raw['__meta']);
369392
$counter['samples'] = [];

tests/Test/Prometheus/AbstractCounterTest.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ abstract public function configureAdapter();
3131
*/
3232
public function itShouldIncreaseWithLabels()
3333
{
34-
$gauge = new Counter($this->adapter, 'test', 'some_metric', 'this is for testing', ['foo', 'bar']);
35-
$gauge->inc(['lalal', 'lululu']);
36-
$gauge->inc(['lalal', 'lululu']);
37-
$gauge->inc(['lalal', 'lululu']);
34+
$counter = new Counter($this->adapter, 'test', 'some_metric', 'this is for testing', ['foo', 'bar']);
35+
$counter->inc(['lalal', 'lululu']);
36+
$counter->inc(['lalal', 'lululu']);
37+
$counter->inc(['lalal', 'lululu']);
3838
$this->assertThat(
3939
$this->adapter->collect(),
4040
$this->equalTo(
@@ -65,8 +65,8 @@ public function itShouldIncreaseWithLabels()
6565
*/
6666
public function itShouldIncreaseWithoutLabelWhenNoLabelsAreDefined()
6767
{
68-
$gauge = new Counter($this->adapter, 'test', 'some_metric', 'this is for testing');
69-
$gauge->inc();
68+
$counter = new Counter($this->adapter, 'test', 'some_metric', 'this is for testing');
69+
$counter->inc();
7070
$this->assertThat(
7171
$this->adapter->collect(),
7272
$this->equalTo(
@@ -97,9 +97,9 @@ public function itShouldIncreaseWithoutLabelWhenNoLabelsAreDefined()
9797
*/
9898
public function itShouldIncreaseTheCounterByAnArbitraryInteger()
9999
{
100-
$gauge = new Counter($this->adapter, 'test', 'some_metric', 'this is for testing', ['foo', 'bar']);
101-
$gauge->inc(['lalal', 'lululu']);
102-
$gauge->incBy(123, ['lalal', 'lululu']);
100+
$counter = new Counter($this->adapter, 'test', 'some_metric', 'this is for testing', ['foo', 'bar']);
101+
$counter->inc(['lalal', 'lululu']);
102+
$counter->incBy(123, ['lalal', 'lululu']);
103103
$this->assertThat(
104104
$this->adapter->collect(),
105105
$this->equalTo(
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Test\Prometheus\Redis;
4+
5+
use Prometheus\Storage\Redis;
6+
use Test\Prometheus\AbstractCounterTest;
7+
8+
/**
9+
* See https://prometheus.io/docs/instrumenting/exposition_formats/
10+
* @requires extension redis
11+
*/
12+
class CounterWithPrefixTest extends AbstractCounterTest
13+
{
14+
public function configureAdapter()
15+
{
16+
$connection = new \Redis();
17+
$connection->connect(REDIS_HOST);
18+
19+
$connection->setOption(\Redis::OPT_PREFIX, 'prefix:');
20+
21+
$this->adapter = Redis::fromExistingConnection($connection);
22+
$this->adapter->flushRedis();
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Test\Prometheus\Redis;
4+
5+
use Prometheus\Storage\Redis;
6+
use Test\Prometheus\AbstractGaugeTest;
7+
8+
/**
9+
* See https://prometheus.io/docs/instrumenting/exposition_formats/
10+
* @requires extension redis
11+
*/
12+
class GaugeWithPrefixTest extends AbstractGaugeTest
13+
{
14+
public function configureAdapter()
15+
{
16+
$connection = new \Redis();
17+
$connection->connect(REDIS_HOST);
18+
19+
$connection->setOption(\Redis::OPT_PREFIX, 'prefix:');
20+
21+
$this->adapter = Redis::fromExistingConnection($connection);
22+
$this->adapter->flushRedis();
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Test\Prometheus\Redis;
4+
5+
use Prometheus\Storage\Redis;
6+
use Test\Prometheus\AbstractHistogramTest;
7+
8+
/**
9+
* See https://prometheus.io/docs/instrumenting/exposition_formats/
10+
* @requires extension redis
11+
*/
12+
class HistogramWithPrefixTest extends AbstractHistogramTest
13+
{
14+
public function configureAdapter()
15+
{
16+
$connection = new \Redis();
17+
$connection->connect(REDIS_HOST);
18+
19+
$connection->setOption(\Redis::OPT_PREFIX, 'prefix:');
20+
21+
$this->adapter = Redis::fromExistingConnection($connection);
22+
$this->adapter->flushRedis();
23+
}
24+
}

tests/Test/Prometheus/Storage/RedisTest.php

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,28 @@ class RedisTest extends TestCase
1212
{
1313
/**
1414
* @test
15-
* @expectedException Prometheus\Exception\StorageException
16-
* @expectedExceptionMessage Can't connect to Redis server
1715
*/
1816
public function itShouldThrowAnExceptionOnConnectionFailure()
1917
{
2018
$redis = new Redis(['host' => '/dev/null']);
19+
20+
$this->expectException(StorageException::class);
21+
$this->expectExceptionMessage("Can't connect to Redis server");
22+
2123
$redis->collect();
2224
$redis->flushRedis();
2325
}
26+
27+
/**
28+
* @test
29+
*/
30+
public function itShouldThrowExceptionWhenInjectedRedisIsNotConnected()
31+
{
32+
$connection = new \Redis();
33+
34+
$this->expectException(StorageException::class);
35+
$this->expectExceptionMessage('Connection to Redis server not established');
36+
37+
Redis::fromExistingConnection($connection);
38+
}
2439
}

0 commit comments

Comments
 (0)