@@ -307,6 +307,155 @@ public function updateCounter(array $data): void
307
307
);
308
308
}
309
309
310
+ /**
311
+ * @param mixed[] $data
312
+ * @throws StorageException
313
+ */
314
+ public function initHistogram (array $ data ): void
315
+ {
316
+ $ this ->ensureOpenConnection ();
317
+
318
+ $ metricKey = $ this ->toMetricKey ($ data );
319
+
320
+ // If hash exists, we skip init
321
+ if ((bool ) $ this ->redis ->hLen ($ metricKey )) {
322
+ return ;
323
+ }
324
+
325
+ $ bucketsToSet = $ data ['buckets ' ];
326
+ array_unshift ($ bucketsToSet , 'sum ' );
327
+ $ bucketsToSet [] = '+Inf ' ;
328
+
329
+ $ labelsCartesian = $ this ->cartesian ($ data ['labelValuesSet ' ]);
330
+
331
+ $ values = [];
332
+ foreach ($ bucketsToSet as $ bucket ) {
333
+ foreach ($ labelsCartesian as $ labelValues ) {
334
+ $ values [] = json_encode (['b ' => $ bucket , 'labelValues ' => array_values ($ labelValues )]);
335
+ }
336
+ }
337
+
338
+ $ valuesString = $ this ->makeLuaValuesString ($ values );
339
+
340
+ // metadata
341
+ unset($ data ['labelValuesSet ' ]);
342
+
343
+ $ this ->redis ->eval (
344
+ <<<LUA
345
+ redis.call('hSet', KEYS[1], '__meta', ARGV[1])
346
+
347
+ for _, subKey in pairs({ {$ valuesString }}) do
348
+ redis.call('hIncrBy', KEYS[1], subKey, 0)
349
+ end
350
+
351
+ redis.call('sAdd', KEYS[2], KEYS[1])
352
+ LUA
353
+ ,
354
+ [
355
+ $ metricKey , // key1
356
+ self ::$ prefix . Histogram::TYPE . self ::PROMETHEUS_METRIC_KEYS_SUFFIX , // key2
357
+ json_encode ($ data ), // arg1
358
+ ],
359
+ 2
360
+ );
361
+ }
362
+
363
+ /**
364
+ * @param mixed[] $data
365
+ *
366
+ * @throws StorageException
367
+ */
368
+ public function initGauge (array $ data ): void
369
+ {
370
+ $ this ->ensureOpenConnection ();
371
+
372
+ $ metricKey = $ this ->toMetricKey ($ data );
373
+
374
+ // If hash exists, we skip init
375
+ if ((bool ) $ this ->redis ->hLen ($ metricKey )) {
376
+ return ;
377
+ }
378
+
379
+ $ labelsCartesian = $ this ->cartesian ($ data ['labelValuesSet ' ]);
380
+
381
+ $ values = [];
382
+ foreach ($ labelsCartesian as $ labelValues ) {
383
+ $ values [] = json_encode (array_values ($ labelValues ));
384
+ }
385
+
386
+ $ valuesString = $ this ->makeLuaValuesString ($ values );
387
+
388
+ // metadata
389
+ unset($ data ['labelValuesSet ' ]);
390
+
391
+ $ this ->redis ->eval (
392
+ <<<LUA
393
+ redis.call('hMSet', KEYS[1], '__meta', ARGV[1])
394
+
395
+ for _, subKey in pairs({ {$ valuesString }}) do
396
+ redis.call('hIncrBy', KEYS[1], subKey, 0)
397
+ end
398
+
399
+ redis.call('sAdd', KEYS[2], KEYS[1])
400
+ LUA
401
+ ,
402
+ [
403
+ $ metricKey , // key1
404
+ self ::$ prefix . Gauge::TYPE . self ::PROMETHEUS_METRIC_KEYS_SUFFIX , // key2
405
+ json_encode ($ data ), // arg1
406
+ ],
407
+ 2
408
+ );
409
+ }
410
+
411
+ /**
412
+ * @param mixed[] $data
413
+ *
414
+ * @throws StorageException
415
+ */
416
+ public function initCounter (array $ data ): void
417
+ {
418
+ $ this ->ensureOpenConnection ();
419
+
420
+ $ metricKey = $ this ->toMetricKey ($ data );
421
+
422
+ // If hash exists, we skip init
423
+ if ((bool ) $ this ->redis ->hLen ($ metricKey )) {
424
+ return ;
425
+ }
426
+
427
+ $ labelsCartesian = $ this ->cartesian ($ data ['labelValuesSet ' ]);
428
+
429
+ $ values = [];
430
+ foreach ($ labelsCartesian as $ labelValues ) {
431
+ $ values [] = json_encode (array_values ($ labelValues ));
432
+ }
433
+
434
+ $ valuesString = $ this ->makeLuaValuesString ($ values );
435
+
436
+ // metadata
437
+ unset($ data ['labelValuesSet ' ]);
438
+
439
+ $ this ->redis ->eval (
440
+ <<<LUA
441
+ redis.call('hMSet', KEYS[1], '__meta', ARGV[1])
442
+
443
+ for _, subKey in pairs({ {$ valuesString }}) do
444
+ redis.call('hIncrBy', KEYS[1], subKey, 0)
445
+ end
446
+
447
+ redis.call('sAdd', KEYS[2], KEYS[1])
448
+ LUA
449
+ ,
450
+ [
451
+ $ metricKey , // key1
452
+ self ::$ prefix . Counter::TYPE . self ::PROMETHEUS_METRIC_KEYS_SUFFIX , // key2
453
+ json_encode ($ data ), // arg1
454
+ ],
455
+ 2
456
+ );
457
+ }
458
+
310
459
/**
311
460
* @return mixed[]
312
461
*/
@@ -468,4 +617,44 @@ private function toMetricKey(array $data): string
468
617
{
469
618
return implode (': ' , [self ::$ prefix , $ data ['type ' ], $ data ['name ' ]]);
470
619
}
620
+
621
+ /**
622
+ * @param mixed[] $input
623
+ * @return mixed[]
624
+ */
625
+ private function cartesian (array $ input ): array
626
+ {
627
+ $ result = [[]];
628
+
629
+ foreach ($ input as $ key => $ values ) {
630
+ $ append = [];
631
+
632
+ foreach ($ result as $ product ) {
633
+ foreach ($ values as $ item ) {
634
+ $ product [$ key ] = $ item ;
635
+ $ append [] = $ product ;
636
+ }
637
+ }
638
+
639
+ $ result = $ append ;
640
+ }
641
+
642
+ return $ result ;
643
+ }
644
+
645
+ /**
646
+ * @param mixed[] $values
647
+ * @return string
648
+ */
649
+ private function makeLuaValuesString (array $ values ): string
650
+ {
651
+ $ values = array_map (
652
+ static function (string $ value ): string {
653
+ return '" ' . addslashes ($ value ) . '" ' ;
654
+ },
655
+ $ values
656
+ );
657
+
658
+ return implode (', ' , $ values );
659
+ }
471
660
}
0 commit comments