ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
Metric.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21namespace ILIAS\Setup\Metrics;
22
25
33final class Metric
34{
38 // Config metrics only change when some administrator explicitely changes
39 // a configuration.
40 public const STABILITY_CONFIG = "config";
41 // Stable metric only change occassionally when some change in the installation
42 // happened, e.g. a config change or an update.
43 public const STABILITY_STABLE = "stable";
44 // Volatile metrics may change at every time even unexpectedly.
45 public const STABILITY_VOLATILE = "volatile";
46 // This should only be used for collections with mixed content.
47 public const STABILITY_MIXED = "mixed";
48
52 // Simply a yes or a no.
53 public const TYPE_BOOL = "bool";
54 // A number that always increases.
55 public const TYPE_COUNTER = "counter";
56 // A numeric value to measure some quantity of the installation.
57 public const TYPE_GAUGE = "gauge";
58 // A timestamp to inform about a certain event in the installation.
59 public const TYPE_TIMESTAMP = "timestamp";
60 // Some textual information about the installation. Prefer using one of the
61 // other types.
62 public const TYPE_TEXT = "text";
63 // A collection of metrics that contains multiple named metrics.
64 public const TYPE_COLLECTION = "collection";
65
69 protected string $stability;
70
74 protected string $type;
75
79 protected $value;
80
81
82 protected ?string $description;
83
84 public function __construct(
85 string $stability,
86 string $type,
87 $value,
88 ?string $description = null
89 ) {
90 $this->checkStability($stability, $type);
91 $this->checkType($type);
92 $this->checkValue($type, $value);
93
94 $this->stability = $stability;
95 $this->type = $type;
96 $this->value = $value;
97 $this->description = $description;
98 }
99
100 protected function checkStability(string $stability, string $type): void
101 {
102 if (
103 $stability !== self::STABILITY_CONFIG
104 && $stability !== self::STABILITY_STABLE
105 && $stability !== self::STABILITY_VOLATILE
106 && !($stability === self::STABILITY_MIXED && $type === self::TYPE_COLLECTION)
107 ) {
108 throw new \InvalidArgumentException(
109 "Invalid stability for metric: $stability"
110 );
111 }
112 }
113
114 protected function checkType($type): void
115 {
116 if (
117 $type !== self::TYPE_BOOL
118 && $type !== self::TYPE_COUNTER
119 && $type !== self::TYPE_GAUGE
120 && $type !== self::TYPE_TIMESTAMP
121 && $type !== self::TYPE_TEXT
122 && $type !== self::TYPE_COLLECTION
123 ) {
124 throw new \InvalidArgumentException(
125 "Invalid type for metric: $type"
126 );
127 }
128 }
129
130 protected function checkValue($type, $value): void
131 {
132 if (
133 ($type === self::TYPE_BOOL && !is_bool($value))
134 || ($type === self::TYPE_COUNTER && !is_int($value))
135 || ($type === self::TYPE_GAUGE && !(is_int($value) || is_float($value)))
136 || ($type === self::TYPE_TIMESTAMP && !($value instanceof \DateTimeImmutable))
137 || ($type === self::TYPE_TEXT && !is_string($value))
138 || ($type === self::TYPE_COLLECTION && !is_array($value))
139 ) {
140 throw new \InvalidArgumentException(
141 "Invalid type " . gettype($value) . " for metric of type $type"
142 );
143 }
144
145 if ($type === self::TYPE_COLLECTION) {
146 foreach ($value as $v) {
147 if (!($v instanceof Metric)) {
148 throw new \InvalidArgumentException(
149 "Every element of a collection needs to be a metric, found " . gettype($v)
150 );
151 }
152 }
153 }
154 }
155
156 public function getStability(): string
157 {
158 return $this->stability;
159 }
160
161 public function getType(): string
162 {
163 return $this->type;
164 }
165
169 public function getValue()
170 {
171 return $this->value;
172 }
173
174 public function getDescription(): ?string
175 {
176 return $this->description;
177 }
178
179 public function toYAML(int $indentation = 0): string
180 {
181 $value = $this->getValue();
182 switch ($this->getType()) {
183 case self::TYPE_BOOL:
184 if ($value) {
185 return "true";
186 } else {
187 return "false";
188 }
189 // no break
191 return "$value";
192 case self::TYPE_GAUGE:
193 if (is_int($value)) {
194 return "$value";
195 }
196 return sprintf("%.03f", $value);
198 return $value->format(\DateTimeInterface::ISO8601);
199 case self::TYPE_TEXT:
200 if (substr_count($value, "\n") > 0) {
201 return ">" . str_replace("\n", "\n" . $this->getIndentation($indentation), "\n$value");
202 }
203 return $value;
205 return implode(
206 "\n",
207 array_map(
208 function (string $k, Metric $v) use ($indentation): string {
209 if ($v->getType() === self::TYPE_COLLECTION) {
210 $split = "\n";
211 } else {
212 $split = " ";
213 }
214 return $this->getIndentation($indentation) . "$k:$split" . $v->toYAML($indentation + 1);
215 },
216 array_keys($value),
217 array_values($value)
218 )
219 );
220 default:
221 throw new \LogicException("Unknown type: " . $this->getType());
222 }
223 }
224
225 public function toArray(int $indentation = 0)
226 {
227 $value = $this->getValue();
228
229 switch ($this->getType()) {
230 case self::TYPE_BOOL:
231 if ($value) {
232 return "true";
233 } else {
234 return "false";
235 }
236 // no break
238 return (string) $value;
239 case self::TYPE_GAUGE:
240 if (is_int($value)) {
241 return (string) $value;
242 }
243 return sprintf("%.03f", $value);
245 return $value->format(\DateTimeInterface::ISO8601);
246 case self::TYPE_TEXT:
247 if (substr_count($value, "\n") > 0) {
248 return ">" . str_replace("\n", "\n" . $this->getIndentation($indentation), "\n$value");
249 }
250 return $value;
252 $result = [];
253 foreach ($value as $key => $val) {
254 $result[$key] = $val->toArray($indentation + 1);
255 }
256 return $result;
257 default:
258 throw new \LogicException("Unknown type: " . $this->getType());
259 }
260 }
261
262 protected function getIndentation(int $indentation = 0): string
263 {
264 $res = "";
265 while ($indentation--) {
266 $res .= " ";
267 }
268 return $res;
269 }
270
277 public function extractByStability(string $stability): array
278 {
279 if ($stability === self::STABILITY_MIXED) {
280 throw new \LogicException("Can not extract by mixed.");
281 }
282
283 if ($this->getStability() === $stability) {
284 return [$this, null];
285 }
286 if ($this->getType() !== self::TYPE_COLLECTION) {
287 return [null, $this];
288 }
289
290 // Now, this is a mixed collection. We need to go down.
291 $values = $this->getValue();
292 $extracted = [];
293 $rest = [];
294 foreach ($values as $k => $v) {
295 list($e, $r) = $v->extractByStability($stability);
296 if ($e !== null) {
297 $extracted[$k] = $e;
298 }
299 if ($r !== null) {
300 $rest[$k] = $r;
301 }
302 }
303
304 if ($extracted !== []) {
305 $extracted = new Metric(
307 self::TYPE_COLLECTION,
308 $extracted,
309 $this->getDescription()
310 );
311 } else {
312 $extracted = null;
313 }
314
315 if ($rest !== []) {
316 $rest = new Metric(
317 $this->getStability(),
318 self::TYPE_COLLECTION,
319 $rest,
320 $this->getDescription()
321 );
322 } else {
323 $rest = null;
324 }
325
326 return [$extracted, $rest];
327 }
328
329 public function toUIReport(Factory $f, string $name): Report
330 {
331 $yaml = $this->toYAML();
332 $sub = $f->panel()->sub("", $f->legacy()->content("<pre>" . $yaml . "</pre>"));
333 return $f->panel()->report($name, [$sub]);
334 }
335}
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
A metric is something we can measure about the system.
Definition: Metric.php:34
getIndentation(int $indentation=0)
Definition: Metric.php:262
__construct(string $stability, string $type, $value, ?string $description=null)
Definition: Metric.php:84
toYAML(int $indentation=0)
Definition: Metric.php:179
checkValue($type, $value)
Definition: Metric.php:130
checkStability(string $stability, string $type)
Definition: Metric.php:100
extractByStability(string $stability)
The extracted part will be the first entry of the array, the second will be the rest of the metrics.
Definition: Metric.php:277
toArray(int $indentation=0)
Definition: Metric.php:225
const TYPE_BOOL
The type of the metric tells what to expect of the values.
Definition: Metric.php:53
toUIReport(Factory $f, string $name)
Definition: Metric.php:329
const STABILITY_CONFIG
The stability of a metric tells how often we expect changes in the metric.
Definition: Metric.php:40
This describes how a Report could be modified during construction of UI.
Definition: Report.php:29
$res
Definition: ltiservices.php:69