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

Commit 283c9b6

Browse files
author
Marko Kruljac
committed
implemented missing methods
1 parent 1c45edf commit 283c9b6

1 file changed

Lines changed: 231 additions & 26 deletions

File tree

src/Prometheus/Storage/InMemory.php

Lines changed: 231 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,132 @@
33
namespace Prometheus\Storage;
44

55

6-
use Prometheus\Collector;
76
use Prometheus\MetricFamilySamples;
87
use Prometheus\Sample;
98

109
class InMemory implements Adapter
1110
{
12-
/**
13-
* @var Collector[]
14-
*/
15-
private $metrics = array();
16-
/**
17-
* @var array
18-
*/
19-
private $samples = array();
11+
12+
private $counters = [];
13+
private $gauges = [];
14+
private $histograms = [];
2015

2116
/**
2217
* @return MetricFamilySamples[]
2318
*/
2419
public function collect()
2520
{
26-
$responses = array();
27-
foreach ($this->metrics as $metric) {
28-
$samples = $this->samples[$metric->getKey()];
29-
array_multisort($samples);
30-
$responses[] = new MetricFamilySamples(
31-
array(
32-
'name' => $metric->getName(),
33-
'type' => $metric->getType(),
34-
'help' => $metric->getHelp(),
35-
'samples' => $samples,
36-
'labelNames' => $metric->getLabelNames()
37-
)
21+
$metrics = $this->internalCollect($this->counters);
22+
$metrics = array_merge($metrics, $this->internalCollect($this->gauges));
23+
$metrics = array_merge($metrics, $this->collectHistograms());
24+
return $metrics;
25+
}
26+
27+
public function flushMemory()
28+
{
29+
$this->counters = [];
30+
$this->gauges = [];
31+
$this->histograms = [];
32+
}
33+
34+
private function collectHistograms()
35+
{
36+
$histograms = array();
37+
foreach ($this->histograms as $histogram) {
38+
$metaData = $histogram['meta'];
39+
$data = array(
40+
'name' => $metaData['name'],
41+
'help' => $metaData['help'],
42+
'type' => $metaData['type'],
43+
'labelNames' => $metaData['labelNames'],
44+
'buckets' => $metaData['buckets']
3845
);
46+
47+
// Add the Inf bucket so we can compute it later on
48+
$data['buckets'][] = '+Inf';
49+
50+
$histogramBuckets = array();
51+
foreach ($histogram['samples'] as $key => $value) {
52+
$parts = explode(':', $key);
53+
$labelValues = $parts[2];
54+
$bucket = $parts[3];
55+
// Key by labelValues
56+
$histogramBuckets[$labelValues][$bucket] = $value;
57+
}
58+
59+
// Compute all buckets
60+
$labels = array_keys($histogramBuckets);
61+
sort($labels);
62+
foreach ($labels as $labelValues) {
63+
$acc = 0;
64+
$decodedLabelValues = json_decode($labelValues);
65+
foreach ($data['buckets'] as $bucket) {
66+
$bucket = (string) $bucket;
67+
if (!isset($histogramBuckets[$labelValues][$bucket])) {
68+
$data['samples'][] = array(
69+
'name' => $metaData['name'] . '_bucket',
70+
'labelNames' => array('le'),
71+
'labelValues' => array_merge($decodedLabelValues, array($bucket)),
72+
'value' => $acc
73+
);
74+
} else {
75+
$acc += $histogramBuckets[$labelValues][$bucket];
76+
$data['samples'][] = array(
77+
'name' => $metaData['name'] . '_' . 'bucket',
78+
'labelNames' => array('le'),
79+
'labelValues' => array_merge($decodedLabelValues, array($bucket)),
80+
'value' => $acc
81+
);
82+
}
83+
}
84+
85+
// Add the count
86+
$data['samples'][] = array(
87+
'name' => $metaData['name'] . '_count',
88+
'labelNames' => array(),
89+
'labelValues' => $decodedLabelValues,
90+
'value' => $acc
91+
);
92+
93+
// Add the sum
94+
$data['samples'][] = array(
95+
'name' => $metaData['name'] . '_sum',
96+
'labelNames' => array(),
97+
'labelValues' => $decodedLabelValues,
98+
'value' => $histogramBuckets[$labelValues]['sum']
99+
);
100+
101+
}
102+
$histograms[] = new MetricFamilySamples($data);
103+
}
104+
return $histograms;
105+
}
106+
107+
private function internalCollect(array $metrics)
108+
{
109+
$result = [];
110+
foreach ($metrics as $metric) {
111+
$metaData = $metric['meta'];
112+
$data = array(
113+
'name' => $metaData['name'],
114+
'help' => $metaData['help'],
115+
'type' => $metaData['type'],
116+
'labelNames' => $metaData['labelNames'],
117+
);
118+
foreach ($metric['samples'] as $key => $value) {
119+
$parts = explode(':', $key);
120+
$labelValues = $parts[2];
121+
$data['samples'][] = array(
122+
'name' => $metaData['name'],
123+
'labelNames' => array(),
124+
'labelValues' => json_decode($labelValues),
125+
'value' => $value
126+
);
127+
}
128+
$this->sortSamples($data['samples']);
129+
$result[] = new MetricFamilySamples($data);
39130
}
40-
array_multisort($responses);
41-
return $responses;
131+
return $result;
42132
}
43133

44134
/**
@@ -54,18 +144,133 @@ function ($data) { return new Sample($data); },
54144

55145
public function updateHistogram(array $data)
56146
{
57-
// TODO: Implement incrementByFloat() method.
147+
// Initialize the sum
148+
$metaKey = $this->metaKey($data);
149+
if (array_key_exists($metaKey, $this->histograms) === false) {
150+
$this->histograms[$metaKey] = [
151+
'meta' => $this->metaData($data),
152+
'samples' => []
153+
];
154+
}
155+
$sumKey = $this->histogramBucketValueKey($data, 'sum');
156+
if (array_key_exists($sumKey, $this->histograms[$metaKey]['samples']) === false) {
157+
$this->histograms[$metaKey]['samples'][$sumKey] = 0;
158+
}
159+
160+
$this->histograms[$metaKey]['samples'][$sumKey] += $data['value'];
161+
162+
163+
$bucketToIncrease = '+Inf';
164+
foreach ($data['buckets'] as $bucket) {
165+
if ($data['value'] <= $bucket) {
166+
$bucketToIncrease = $bucket;
167+
break;
168+
}
169+
}
170+
171+
$bucketKey = $this->histogramBucketValueKey($data, $bucketToIncrease);
172+
if (array_key_exists($bucketKey, $this->histograms[$metaKey]['samples']) === false) {
173+
$this->histograms[$metaKey]['samples'][$bucketKey] = 0;
174+
}
175+
$this->histograms[$metaKey]['samples'][$bucketKey] += 1;
58176
}
59177

60178
public function updateGauge(array $data)
61179
{
62-
// TODO: Implement updateGauge() method.
180+
$metaKey = $this->metaKey($data);
181+
$valueKey = $this->valueKey($data);
182+
if (array_key_exists($metaKey, $this->gauges) === false) {
183+
$this->gauges[$metaKey] = [
184+
'meta' => $this->metaData($data),
185+
'samples' => []
186+
];
187+
}
188+
if (array_key_exists($valueKey, $this->gauges[$metaKey]['samples']) === false) {
189+
$this->gauges[$metaKey]['samples'][$valueKey] = 0;
190+
}
191+
if ($data['command'] === Adapter::COMMAND_SET) {
192+
$this->gauges[$metaKey]['samples'][$valueKey] = $data['value'];
193+
} else {
194+
$this->gauges[$metaKey]['samples'][$valueKey] += $data['value'];
195+
}
63196
}
64197

65198
public function updateCounter(array $data)
66199
{
67-
// TODO: Implement updateCounter() method.
200+
$metaKey = $this->metaKey($data);
201+
$valueKey = $this->valueKey($data);
202+
if (array_key_exists($metaKey, $this->counters) === false) {
203+
$this->counters[$metaKey] = [
204+
'meta' => $this->metaData($data),
205+
'samples' => []
206+
];
207+
}
208+
if (array_key_exists($valueKey, $this->counters[$metaKey]['samples']) === false) {
209+
$this->counters[$metaKey]['samples'][$valueKey] = 0;
210+
}
211+
if ($data['command'] === Adapter::COMMAND_SET) {
212+
$this->counters[$metaKey]['samples'][$valueKey] = 0;
213+
} else {
214+
$this->counters[$metaKey]['samples'][$valueKey] += $data['value'];
215+
}
216+
}
217+
218+
/**
219+
* @param array $data
220+
*
221+
* @param $bucket
222+
*
223+
* @return string
224+
*/
225+
private function histogramBucketValueKey(array $data, $bucket)
226+
{
227+
return implode(':', array(
228+
$data['type'],
229+
$data['name'],
230+
json_encode($data['labelValues']),
231+
$bucket
232+
));
233+
}
234+
235+
/**
236+
* @param array $data
237+
*
238+
* @return string
239+
*/
240+
private function metaKey(array $data)
241+
{
242+
return implode(':', array($data['type'], $data['name'], 'meta'));
243+
}
244+
245+
/**
246+
* @param array $data
247+
*
248+
* @return string
249+
*/
250+
private function valueKey(array $data)
251+
{
252+
return implode(':',
253+
array($data['type'], $data['name'], json_encode($data['labelValues']), 'value'));
68254
}
69255

256+
/**
257+
* @param array $data
258+
*
259+
* @return array
260+
*/
261+
private function metaData(array $data)
262+
{
263+
$metricsMetaData = $data;
264+
unset($metricsMetaData['value']);
265+
unset($metricsMetaData['command']);
266+
unset($metricsMetaData['labelValues']);
267+
return $metricsMetaData;
268+
}
70269

270+
private function sortSamples(array &$samples)
271+
{
272+
usort($samples, function ($a, $b) {
273+
return strcmp(implode("", $a['labelValues']), implode("", $b['labelValues']));
274+
});
275+
}
71276
}

0 commit comments

Comments
 (0)