|
9 | 9 | use Prometheus\MetricFamilySamples; |
10 | 10 | use Prometheus\Storage\RedisTxn\Collecter\CounterCollecter; |
11 | 11 | use Prometheus\Storage\RedisTxn\Collecter\GaugeCollecter; |
| 12 | +use Prometheus\Storage\RedisTxn\Collecter\HistogramCollecter; |
12 | 13 | use Prometheus\Storage\RedisTxn\Collecter\SummaryCollecter; |
13 | 14 | use Prometheus\Storage\RedisTxn\Updater\CounterUpdater; |
14 | 15 | use Prometheus\Storage\RedisTxn\Updater\GaugeUpdater; |
| 16 | +use Prometheus\Storage\RedisTxn\Updater\HistogramUpdater; |
15 | 17 | use Prometheus\Storage\RedisTxn\Updater\SummaryUpdater; |
16 | 18 | use function \sort; |
17 | 19 |
|
|
35 | 37 | */ |
36 | 38 | class RedisTxn implements Adapter |
37 | 39 | { |
38 | | - const PROMETHEUS_METRIC_KEYS_SUFFIX = '_METRIC_KEYS'; |
39 | | - |
40 | | - const PROMETHEUS_METRIC_META_SUFFIX = '_METRIC_META'; |
41 | | - |
42 | 40 | /** |
43 | 41 | * @var mixed[] |
44 | 42 | */ |
@@ -152,21 +150,14 @@ public function collect(): array |
152 | 150 | // Ensure Redis connection |
153 | 151 | $this->ensureOpenConnection(); |
154 | 152 |
|
155 | | - $metrics = $this->collectHistograms(); |
156 | | - $metricFamilySamples = array_map( |
157 | | - function (array $metric): MetricFamilySamples { |
158 | | - return new MetricFamilySamples($metric); |
159 | | - }, |
160 | | - $metrics |
161 | | - ); |
162 | | - |
163 | 153 | // Collect all metrics |
164 | 154 | $counters = $this->collectCounters(); |
| 155 | + $histograms = $this->collectHistograms(); |
165 | 156 | $gauges = $this->collectGauges(); |
166 | 157 | $summaries = $this->collectSummaries(); |
167 | 158 | return array_merge( |
168 | | - $metricFamilySamples, |
169 | 159 | $counters, |
| 160 | + $histograms, |
170 | 161 | $gauges, |
171 | 162 | $summaries |
172 | 163 | ); |
@@ -221,43 +212,16 @@ private function connectToServer(): void |
221 | 212 | } |
222 | 213 |
|
223 | 214 | /** |
224 | | - * @param mixed[] $data |
225 | | - * @throws StorageException |
| 215 | + * @inheritDoc |
226 | 216 | */ |
227 | 217 | public function updateHistogram(array $data): void |
228 | 218 | { |
| 219 | + // Ensure Redis connection |
229 | 220 | $this->ensureOpenConnection(); |
230 | | - $bucketToIncrease = '+Inf'; |
231 | | - foreach ($data['buckets'] as $bucket) { |
232 | | - if ($data['value'] <= $bucket) { |
233 | | - $bucketToIncrease = $bucket; |
234 | | - break; |
235 | | - } |
236 | | - } |
237 | | - $metaData = $data; |
238 | | - unset($metaData['value'], $metaData['labelValues']); |
239 | 221 |
|
240 | | - $this->redis->eval( |
241 | | - <<<LUA |
242 | | -local result = redis.call('hIncrByFloat', KEYS[1], ARGV[1], ARGV[3]) |
243 | | -redis.call('hIncrBy', KEYS[1], ARGV[2], 1) |
244 | | -if tonumber(result) >= tonumber(ARGV[3]) then |
245 | | - redis.call('hSet', KEYS[1], '__meta', ARGV[4]) |
246 | | - redis.call('sAdd', KEYS[2], KEYS[1]) |
247 | | -end |
248 | | -return result |
249 | | -LUA |
250 | | - , |
251 | | - [ |
252 | | - $this->toMetricKey($data), |
253 | | - self::$prefix . Histogram::TYPE . self::PROMETHEUS_METRIC_KEYS_SUFFIX, |
254 | | - json_encode(['b' => 'sum', 'labelValues' => $data['labelValues']]), |
255 | | - json_encode(['b' => $bucketToIncrease, 'labelValues' => $data['labelValues']]), |
256 | | - $data['value'], |
257 | | - json_encode($metaData), |
258 | | - ], |
259 | | - 2 |
260 | | - ); |
| 222 | + // Update metric |
| 223 | + $updater = new HistogramUpdater($this->redis); |
| 224 | + $updater->update($data); |
261 | 225 | } |
262 | 226 |
|
263 | 227 | /** |
@@ -300,80 +264,12 @@ public function updateCounter(array $data): void |
300 | 264 | } |
301 | 265 |
|
302 | 266 | /** |
303 | | - * @return mixed[] |
| 267 | + * @return MetricFamilySamples[] |
304 | 268 | */ |
305 | 269 | private function collectHistograms(): array |
306 | 270 | { |
307 | | - $keys = $this->redis->sMembers(self::$prefix . Histogram::TYPE . self::PROMETHEUS_METRIC_KEYS_SUFFIX); |
308 | | - sort($keys); |
309 | | - $histograms = []; |
310 | | - foreach ($keys as $key) { |
311 | | - $raw = $this->redis->hGetAll(str_replace($this->redis->_prefix(''), '', $key)); |
312 | | - $histogram = json_decode($raw['__meta'], true); |
313 | | - unset($raw['__meta']); |
314 | | - $histogram['samples'] = []; |
315 | | - |
316 | | - // Add the Inf bucket so we can compute it later on |
317 | | - $histogram['buckets'][] = '+Inf'; |
318 | | - |
319 | | - $allLabelValues = []; |
320 | | - foreach (array_keys($raw) as $k) { |
321 | | - $d = json_decode($k, true); |
322 | | - if ($d['b'] == 'sum') { |
323 | | - continue; |
324 | | - } |
325 | | - $allLabelValues[] = $d['labelValues']; |
326 | | - } |
327 | | - |
328 | | - // We need set semantics. |
329 | | - // This is the equivalent of array_unique but for arrays of arrays. |
330 | | - $allLabelValues = array_map("unserialize", array_unique(array_map("serialize", $allLabelValues))); |
331 | | - sort($allLabelValues); |
332 | | - |
333 | | - foreach ($allLabelValues as $labelValues) { |
334 | | - // Fill up all buckets. |
335 | | - // If the bucket doesn't exist fill in values from |
336 | | - // the previous one. |
337 | | - $acc = 0; |
338 | | - foreach ($histogram['buckets'] as $bucket) { |
339 | | - $bucketKey = json_encode(['b' => $bucket, 'labelValues' => $labelValues]); |
340 | | - if (!isset($raw[$bucketKey])) { |
341 | | - $histogram['samples'][] = [ |
342 | | - 'name' => $histogram['name'] . '_bucket', |
343 | | - 'labelNames' => ['le'], |
344 | | - 'labelValues' => array_merge($labelValues, [$bucket]), |
345 | | - 'value' => $acc, |
346 | | - ]; |
347 | | - } else { |
348 | | - $acc += $raw[$bucketKey]; |
349 | | - $histogram['samples'][] = [ |
350 | | - 'name' => $histogram['name'] . '_bucket', |
351 | | - 'labelNames' => ['le'], |
352 | | - 'labelValues' => array_merge($labelValues, [$bucket]), |
353 | | - 'value' => $acc, |
354 | | - ]; |
355 | | - } |
356 | | - } |
357 | | - |
358 | | - // Add the count |
359 | | - $histogram['samples'][] = [ |
360 | | - 'name' => $histogram['name'] . '_count', |
361 | | - 'labelNames' => [], |
362 | | - 'labelValues' => $labelValues, |
363 | | - 'value' => $acc, |
364 | | - ]; |
365 | | - |
366 | | - // Add the sum |
367 | | - $histogram['samples'][] = [ |
368 | | - 'name' => $histogram['name'] . '_sum', |
369 | | - 'labelNames' => [], |
370 | | - 'labelValues' => $labelValues, |
371 | | - 'value' => $raw[json_encode(['b' => 'sum', 'labelValues' => $labelValues])], |
372 | | - ]; |
373 | | - } |
374 | | - $histograms[] = $histogram; |
375 | | - } |
376 | | - return $histograms; |
| 271 | + $collector = new HistogramCollecter($this->redis); |
| 272 | + return $collector->getMetricFamilySamples(); |
377 | 273 | } |
378 | 274 |
|
379 | 275 | /** |
@@ -402,13 +298,4 @@ private function collectCounters(): array |
402 | 298 | $collector = new CounterCollecter($this->redis); |
403 | 299 | return $collector->getMetricFamilySamples(); |
404 | 300 | } |
405 | | - |
406 | | - /** |
407 | | - * @param mixed[] $data |
408 | | - * @return string |
409 | | - */ |
410 | | - private function toMetricKey(array $data): string |
411 | | - { |
412 | | - return implode(':', [self::$prefix, $data['type'], $data['name']]); |
413 | | - } |
414 | 301 | } |
0 commit comments