@@ -374,6 +374,154 @@ public function updateCounter(array $data): void
374
374
);
375
375
}
376
376
377
+ /**
378
+ * @param mixed[] $data
379
+ * @throws StorageException
380
+ */
381
+ public function initHistogram (array $ data ): void
382
+ {
383
+ $ this ->ensureOpenConnection ();
384
+
385
+ $ metricKey = $ this ->toMetricKey ($ data );
386
+
387
+ // If hash exists, we skip init TODO: new labels adding [checking __meta]
388
+ if ((bool ) $ this ->redis ->hLen ($ metricKey )) {
389
+ return ;
390
+ }
391
+
392
+ $ bucketsToSet = $ data ['buckets ' ];
393
+ array_unshift ($ bucketsToSet , 'sum ' );
394
+ $ bucketsToSet [] = '+Inf ' ;
395
+
396
+ $ labelsCartesian = $ this ->cartesian ($ data ['labelValuesSet ' ]);
397
+
398
+ $ values = [];
399
+ foreach ($ bucketsToSet as $ bucket ) {
400
+ foreach ($ labelsCartesian as $ labelValues ) {
401
+ $ values [] = json_encode (['b ' => $ bucket , 'labelValues ' => array_values ($ labelValues )]);
402
+ }
403
+ }
404
+
405
+ $ valuesString = $ this ->makeLuaValuesString ($ values );
406
+
407
+ // metadata
408
+ unset($ data ['labelValuesSet ' ]);
409
+
410
+ $ this ->redis ->eval (
411
+ <<<LUA
412
+ redis.call('hSet', KEYS[1], '__meta', ARGV[1])
413
+
414
+ for _, subKey in pairs({ {$ valuesString }}) do
415
+ redis.call('hIncrBy', KEYS[1], subKey, 0)
416
+ end
417
+
418
+ redis.call('sAdd', KEYS[2], KEYS[1])
419
+ LUA
420
+ ,
421
+ [
422
+ $ metricKey , // key1
423
+ self ::$ prefix . Histogram::TYPE . self ::PROMETHEUS_METRIC_KEYS_SUFFIX , // key2
424
+ json_encode ($ data ), // arg1
425
+ ],
426
+ 2
427
+ );
428
+ }
429
+
430
+ /**
431
+ * @param mixed[] $data
432
+ *
433
+ * @throws StorageException
434
+ */
435
+ public function initGauge (array $ data ): void
436
+ {
437
+ $ this ->ensureOpenConnection ();
438
+
439
+ $ metricKey = $ this ->toMetricKey ($ data );
440
+
441
+ // If hash exists, we skip init TODO: new labels adding [checking __meta]
442
+ if ((bool ) $ this ->redis ->hLen ($ metricKey )) {
443
+ return ;
444
+ }
445
+
446
+ $ labelsCartesian = $ this ->cartesian ($ data ['labelValuesSet ' ]);
447
+
448
+ $ values = [];
449
+ foreach ($ labelsCartesian as $ labelValues ) {
450
+ $ values [] = json_encode (array_values ($ labelValues ));
451
+ }
452
+
453
+ $ valuesString = $ this ->makeLuaValuesString ($ values );
454
+
455
+ // metadata
456
+ unset($ data ['labelValuesSet ' ]);
457
+
458
+ $ this ->redis ->eval (
459
+ <<<LUA
460
+ redis.call('hMSet', KEYS[1], '__meta', ARGV[1])
461
+
462
+ for _, subKey in pairs({ {$ valuesString }}) do
463
+ redis.call('hIncrBy', KEYS[1], subKey, 0)
464
+ end
465
+
466
+ redis.call('sAdd', KEYS[2], KEYS[1])
467
+ LUA
468
+ ,
469
+ [
470
+ $ metricKey , // key1
471
+ self ::$ prefix . Gauge::TYPE . self ::PROMETHEUS_METRIC_KEYS_SUFFIX , // key2
472
+ json_encode ($ data ), // arg1
473
+ ],
474
+ 2
475
+ );
476
+ }
477
+
478
+ /**
479
+ * @param mixed[] $data
480
+ *
481
+ * @throws StorageException
482
+ */
483
+ public function initCounter (array $ data ): void
484
+ {
485
+ $ this ->ensureOpenConnection ();
486
+
487
+ $ metricKey = $ this ->toMetricKey ($ data );
488
+
489
+ // If hash exists, we skip init TODO: new labels adding [checking __meta]
490
+ if ((bool ) $ this ->redis ->hLen ($ metricKey )) {
491
+ return ;
492
+ }
493
+
494
+ $ labelsCartesian = $ this ->cartesian ($ data ['labelValuesSet ' ]);
495
+
496
+ $ values = [];
497
+ foreach ($ labelsCartesian as $ labelValues ) {
498
+ $ values [] = json_encode (array_values ($ labelValues ));
499
+ }
500
+
501
+ $ valuesString = $ this ->makeLuaValuesString ($ values );
502
+
503
+ // metadata
504
+ unset($ data ['labelValuesSet ' ]);
505
+
506
+ $ this ->redis ->eval (
507
+ <<<LUA
508
+ redis.call('hMSet', KEYS[1], '__meta', ARGV[1])
509
+
510
+ for _, subKey in pairs({ {$ valuesString }}) do
511
+ redis.call('hIncrBy', KEYS[1], subKey, 0)
512
+ end
513
+
514
+ redis.call('sAdd', KEYS[2], KEYS[1])
515
+ LUA
516
+ ,
517
+ [
518
+ $ metricKey , // key1
519
+ self ::$ prefix . Counter::TYPE . self ::PROMETHEUS_METRIC_KEYS_SUFFIX , // key2
520
+ json_encode ($ data ), // arg1
521
+ ],
522
+ 2
523
+ );
524
+ }
377
525
378
526
/**
379
527
* @param mixed[] $data
@@ -682,4 +830,44 @@ private function decodeLabelValues(string $values): array
682
830
}
683
831
return $ decodedValues ;
684
832
}
833
+
834
+ /**
835
+ * @param mixed[] $input
836
+ * @return mixed[]
837
+ */
838
+ private function cartesian (array $ input ): array
839
+ {
840
+ $ result = [[]];
841
+
842
+ foreach ($ input as $ key => $ values ) {
843
+ $ append = [];
844
+
845
+ foreach ($ result as $ product ) {
846
+ foreach ($ values as $ item ) {
847
+ $ product [$ key ] = $ item ;
848
+ $ append [] = $ product ;
849
+ }
850
+ }
851
+
852
+ $ result = $ append ;
853
+ }
854
+
855
+ return $ result ;
856
+ }
857
+
858
+ /**
859
+ * @param mixed[] $values
860
+ * @return string
861
+ */
862
+ private function makeLuaValuesString (array $ values ): string
863
+ {
864
+ $ values = array_map (
865
+ static function (string $ value ): string {
866
+ return '" ' . addslashes ($ value ) . '" ' ;
867
+ },
868
+ $ values
869
+ );
870
+
871
+ return implode (', ' , $ values );
872
+ }
685
873
}
0 commit comments