PluginProbe
DecaLog / 4.4.0
DecaLog v4.4.0
3.0.2 3.1.0 3.10.0 3.2.0 3.3.0 3.4.0 3.4.1 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.6.3 3.7.0 3.7.1 3.8.0 3.9.0 3.9.1 4.0.0 4.1.0 4.2.0 4.3.0 4.3.1 4.4.0 4.5.0 All 75 releases
decalog / includes / libraries / prometheus / Histogram.php

Histogram.php in DecaLog 4.4.0, at includes/libraries/prometheus/Histogram.php

144 lines 3.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Prometheus;
6
7 use InvalidArgumentException;
8 use Prometheus\Storage\Adapter;
9
10 class Histogram extends Collector
11 {
12 const TYPE = 'histogram';
13
14 /**
15 * @var float[]|null
16 */
17 private $buckets;
18
19 /**
20 * @param Adapter $adapter
21 * @param string $namespace
22 * @param string $name
23 * @param string $help
24 * @param string[] $labels
25 * @param float[]|null $buckets
26 */
27 public function __construct(
28 Adapter $adapter,
29 string $namespace,
30 string $name,
31 string $help,
32 array $labels = [],
33 array $buckets = null
34 ) {
35 parent::__construct($adapter, $namespace, $name, $help, $labels);
36
37 if (null === $buckets) {
38 $buckets = self::getDefaultBuckets();
39 }
40
41 if (0 === count($buckets)) {
42 throw new InvalidArgumentException("Histogram must have at least one bucket.");
43 }
44
45 for ($i = 0; $i < count($buckets) - 1; $i++) {
46 if ($buckets[$i] >= $buckets[$i + 1]) {
47 throw new InvalidArgumentException(
48 "Histogram buckets must be in increasing order: " .
49 $buckets[$i] . " >= " . $buckets[$i + 1]
50 );
51 }
52 }
53 if (in_array('le', $labels, true)) {
54 throw new \InvalidArgumentException("Histogram cannot have a label named 'le'.");
55 }
56 $this->buckets = $buckets;
57 }
58
59 /**
60 * List of default buckets suitable for typical web application latency metrics
61 *
62 * @return float[]
63 */
64 public static function getDefaultBuckets(): array
65 {
66 return [
67 0.005,
68 0.01,
69 0.025,
70 0.05,
71 0.075,
72 0.1,
73 0.25,
74 0.5,
75 0.75,
76 1.0,
77 2.5,
78 5.0,
79 7.5,
80 10.0,
81 ];
82 }
83
84 /**
85 * @param float $start
86 * @param float $growthFactor
87 * @param int $numberOfBuckets
88 *
89 * @return float[]
90 */
91 public static function exponentialBuckets(float $start, float $growthFactor, int $numberOfBuckets): array
92 {
93 if ($numberOfBuckets < 1) {
94 throw new InvalidArgumentException('Number of buckets must be a positive integer');
95 }
96
97 if ($start <= 0) {
98 throw new InvalidArgumentException('The starting position of a set of buckets must be a positive integer');
99 }
100
101 if ($growthFactor <= 1) {
102 throw new InvalidArgumentException('The growth factor must greater than 1');
103 }
104
105 $buckets = [];
106
107 for ($i = 0; $i < $numberOfBuckets; $i++) {
108 $buckets[$i] = $start;
109 $start *= $growthFactor;
110 }
111
112 return $buckets;
113 }
114
115 /**
116 * @param double $value e.g. 123
117 * @param string[] $labels e.g. ['status', 'opcode']
118 */
119 public function observe(float $value, array $labels = []): void
120 {
121 $this->assertLabelsAreDefinedCorrectly($labels);
122
123 $this->storageAdapter->updateHistogram(
124 [
125 'value' => $value,
126 'name' => $this->getName(),
127 'help' => $this->getHelp(),
128 'type' => $this->getType(),
129 'labelNames' => $this->getLabelNames(),
130 'labelValues' => $labels,
131 'buckets' => $this->buckets,
132 ]
133 );
134 }
135
136 /**
137 * @return string
138 */
139 public function getType(): string
140 {
141 return self::TYPE;
142 }
143 }
144