From a93cced8e6b947a3d1cbb08f0a177aa8b43ab709 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Wed, 27 Sep 2023 02:05:48 +0300 Subject: [PATCH 01/34] add prometheus reporter --- docker-compose.yml | 16 ++++++ prom.yml | 11 ++++ .../PrometheusPushGatewayReporter.php | 41 ++++++++++++++ src/Application/Report/Reporter/Reporter.php | 11 ++++ .../Report/Reporter/ReporterFactory.php | 30 +++++++++++ src/Application/Report/ReporterHandler.php | 28 ++++++++++ .../Http/Exceptions/HttpRequestException.php | 7 ++- .../Prometheus/PushGateway/Metric.php | 29 ++++++++++ .../Prometheus/PushGateway/PushGateway.php | 22 ++++++++ .../PushGateway/PushGatewayClient.php | 21 ++++++++ .../Prometheus/PushGateway/Renderer.php | 54 +++++++++++++++++++ .../Application/ApplicationFactory.php | 2 + .../Console/Command/LintCommand.php | 2 +- src/Providers/ReportProvider.php | 35 ++++++++++++ src/Shared/Metrics/Value/Record.php | 7 +-- .../Unit/Shared/Metrics/Value/RecordTest.php | 31 ----------- 16 files changed, 308 insertions(+), 39 deletions(-) create mode 100644 docker-compose.yml create mode 100644 prom.yml create mode 100644 src/Application/Report/Reporter/PrometheusPushGatewayReporter.php create mode 100644 src/Application/Report/Reporter/Reporter.php create mode 100644 src/Application/Report/Reporter/ReporterFactory.php create mode 100644 src/Application/Report/ReporterHandler.php create mode 100644 src/Infrastructure/Prometheus/PushGateway/Metric.php create mode 100644 src/Infrastructure/Prometheus/PushGateway/PushGateway.php create mode 100644 src/Infrastructure/Prometheus/PushGateway/PushGatewayClient.php create mode 100644 src/Infrastructure/Prometheus/PushGateway/Renderer.php create mode 100644 src/Providers/ReportProvider.php delete mode 100644 tests/Unit/Shared/Metrics/Value/RecordTest.php diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..1f36c7474 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,16 @@ +services: + prometheus: + restart: always + image: bitnami/prometheus:latest + links: + - pushgateway + volumes: + - ./prom.yml:/opt/bitnami/prometheus/conf/prometheus.yml + ports: + - 9092:9090 + + pushgateway: + restart: always + image: bitnami/pushgateway:latest + ports: + - 9091:9091 diff --git a/prom.yml b/prom.yml new file mode 100644 index 000000000..48164fa04 --- /dev/null +++ b/prom.yml @@ -0,0 +1,11 @@ +global: + scrape_interval: 5s + scrape_timeout: 2s + evaluation_interval: 15s + +scrape_configs: + - job_name: pushgateway + honor_labels: true + static_configs: + - targets: + - 'pushgateway:9091' diff --git a/src/Application/Report/Reporter/PrometheusPushGatewayReporter.php b/src/Application/Report/Reporter/PrometheusPushGatewayReporter.php new file mode 100644 index 000000000..968d8adab --- /dev/null +++ b/src/Application/Report/Reporter/PrometheusPushGatewayReporter.php @@ -0,0 +1,41 @@ +uri, time()); + $jobIdHash = md5($jobId); + + $this->client->push($jobIdHash, $this->collectMetrics($request, $result)); + } + + /** + * @return array + */ + private function collectMetrics(MergeRequest $request, LintResult $result): array + { + $labels = ['repo' => (string) $request->uri, 'request_id' => $request->id]; + $metrics = []; + + $metrics[] = Metric::gauge('mr_linter_lint_state', 'MR Linter: lint state', $labels, $result->state->value); + $metrics[] = Metric::gauge('mr_linter_lint_duration', 'MR Linter: lint duration', $labels, $result->duration->seconds); + $metrics[] = Metric::gauge('mr_linter_lint_notes', 'MR Linter: lint duration', $labels, $result->notes->count()); + + return $metrics; + } +} diff --git a/src/Application/Report/Reporter/Reporter.php b/src/Application/Report/Reporter/Reporter.php new file mode 100644 index 000000000..6e34b0b01 --- /dev/null +++ b/src/Application/Report/Reporter/Reporter.php @@ -0,0 +1,11 @@ +metrics, + new PushGateway(new PushGatewayClient(new ClientGuzzleWrapper(new Client(), $this->logger)), new Renderer()), + ); + } + } +} diff --git a/src/Application/Report/ReporterHandler.php b/src/Application/Report/ReporterHandler.php new file mode 100644 index 000000000..34c070b19 --- /dev/null +++ b/src/Application/Report/ReporterHandler.php @@ -0,0 +1,28 @@ +reporter->report($event->request, $event->result); + } +} diff --git a/src/Infrastructure/Http/Exceptions/HttpRequestException.php b/src/Infrastructure/Http/Exceptions/HttpRequestException.php index 3e032b663..18737840a 100644 --- a/src/Infrastructure/Http/Exceptions/HttpRequestException.php +++ b/src/Infrastructure/Http/Exceptions/HttpRequestException.php @@ -24,7 +24,12 @@ public static function create(RequestInterface $request, ResponseInterface $resp return new static( $request, $response, - sprintf('%s returns response with status %d', $request->getUri()->getHost(), $response->getStatusCode()), + sprintf( + '%s returns response with status %d: %s', + $request->getUri()->getHost(), + $response->getStatusCode(), + $response->getBody()->getContents(), + ), ); } diff --git a/src/Infrastructure/Prometheus/PushGateway/Metric.php b/src/Infrastructure/Prometheus/PushGateway/Metric.php new file mode 100644 index 000000000..b0b4976c5 --- /dev/null +++ b/src/Infrastructure/Prometheus/PushGateway/Metric.php @@ -0,0 +1,29 @@ + $labels + */ + public function __construct( + public string $type, + public string $key, + public string $help, + public array $labels, + public int|string|float $value, + ) { + } + + /** + * @param array $labels + */ + public static function gauge(string $key, string $help, array $labels, int|string|float $value): self + { + return new self('gauge', $key, $help, $labels, $value); + } +} diff --git a/src/Infrastructure/Prometheus/PushGateway/PushGateway.php b/src/Infrastructure/Prometheus/PushGateway/PushGateway.php new file mode 100644 index 000000000..9901969f8 --- /dev/null +++ b/src/Infrastructure/Prometheus/PushGateway/PushGateway.php @@ -0,0 +1,22 @@ + $records + */ + public function push(string $job, iterable $records): void + { + $data = $this->renderer->render($records); + + $this->client->replace($job, $data); + } +} diff --git a/src/Infrastructure/Prometheus/PushGateway/PushGatewayClient.php b/src/Infrastructure/Prometheus/PushGateway/PushGatewayClient.php new file mode 100644 index 000000000..6f104e044 --- /dev/null +++ b/src/Infrastructure/Prometheus/PushGateway/PushGatewayClient.php @@ -0,0 +1,21 @@ +http->sendRequest(new Request('POST', $url, body: $data)); + } +} diff --git a/src/Infrastructure/Prometheus/PushGateway/Renderer.php b/src/Infrastructure/Prometheus/PushGateway/Renderer.php new file mode 100644 index 000000000..1fb8a154e --- /dev/null +++ b/src/Infrastructure/Prometheus/PushGateway/Renderer.php @@ -0,0 +1,54 @@ + $records + */ + public function render(iterable $records): string + { + $content = ''; + + foreach ($records as $metric) { + $value = $metric->value; + + $labelsString = $this->collectLabels($metric); + + $content .= <<key} The number of items in the queue. +# TYPE {$metric->key} {$metric->type} + +{$metric->key}{$labelsString} $value + +HTML; + } + + return $content; + } + + private function collectLabels(Metric $metric): string + { + if (count($metric->labels) === 0) { + return ''; + } + + $labelsString = '{'; + $labels = $metric->labels; + + foreach ($labels as $labelKey => $labelValue) { + $labelsString .= sprintf( + '%s=%s', + $labelKey, + is_string($labelValue) ? ('"'. $labelValue .'"') : $labelValue, + ); + + if (next($labels) !== false) { + $labelsString .= ','; + } + } + + return $labelsString . '}'; + } +} diff --git a/src/Presentation/Console/Application/ApplicationFactory.php b/src/Presentation/Console/Application/ApplicationFactory.php index 273db526b..55b9d4573 100644 --- a/src/Presentation/Console/Application/ApplicationFactory.php +++ b/src/Presentation/Console/Application/ApplicationFactory.php @@ -41,6 +41,7 @@ use ArtARTs36\MergeRequestLinter\Providers\CommentProvider; use ArtARTs36\MergeRequestLinter\Providers\EventDispatcherProvider; use ArtARTs36\MergeRequestLinter\Providers\NotificationsProvider; +use ArtARTs36\MergeRequestLinter\Providers\ReportProvider; use ArtARTs36\MergeRequestLinter\Providers\RuleProvider; use ArtARTs36\MergeRequestLinter\Providers\ServiceProvider; use ArtARTs36\MergeRequestLinter\Shared\Events\EventManager; @@ -61,6 +62,7 @@ class ApplicationFactory NotificationsProvider::class, RuleProvider::class, CommentProvider::class, + ReportProvider::class, ]; public function __construct( diff --git a/src/Presentation/Console/Command/LintCommand.php b/src/Presentation/Console/Command/LintCommand.php index d7c99a127..b415d7e27 100644 --- a/src/Presentation/Console/Command/LintCommand.php +++ b/src/Presentation/Console/Command/LintCommand.php @@ -117,7 +117,7 @@ private function printMetrics(StyleInterface $style, LintResult $result, bool $f if ($fullMetrics) { $metrics = $metrics->merge( $this->metrics->describe()->mapToArray( - static fn (Record $record) => new Metric($record->subject->name, $record->getValue()), + static fn (Record $record) => new Metric($record->subject->name, $record->value->getMetricValue()), ) ); } diff --git a/src/Providers/ReportProvider.php b/src/Providers/ReportProvider.php new file mode 100644 index 000000000..4e5f34589 --- /dev/null +++ b/src/Providers/ReportProvider.php @@ -0,0 +1,35 @@ +container + ->bind(ReporterFactory::class, static function (ContainerInterface $container) { + return new ReporterFactory( + $container->get(MetricManager::class), + $container->get(LoggerInterface::class), + ); + }); + + $this + ->container + ->get(EventManager::class) + ->listen(LintFinishedEvent::class, new CallbackListener('reporter', function (LintFinishedEvent $event) { + $factory = $this->container->get(ReporterFactory::class); + + $factory->create('prometheusPushGateway', [])->report($event->request, $event->result); + })); + } +} diff --git a/src/Shared/Metrics/Value/Record.php b/src/Shared/Metrics/Value/Record.php index cf216291d..4825939d8 100644 --- a/src/Shared/Metrics/Value/Record.php +++ b/src/Shared/Metrics/Value/Record.php @@ -6,13 +6,8 @@ { public function __construct( public MetricSubject $subject, - private Metric $value, + public Metric $value, public \DateTimeInterface $date, ) { } - - public function getValue(): string - { - return $this->value->getMetricValue(); - } } diff --git a/tests/Unit/Shared/Metrics/Value/RecordTest.php b/tests/Unit/Shared/Metrics/Value/RecordTest.php deleted file mode 100644 index 9222e14e1..000000000 --- a/tests/Unit/Shared/Metrics/Value/RecordTest.php +++ /dev/null @@ -1,31 +0,0 @@ -getValue()); - } -} From 8e82e4c47a4d23235ef8fc4f9d36ca33aaf8e7ef Mon Sep 17 00:00:00 2001 From: artarts36 Date: Wed, 27 Sep 2023 14:56:07 +0300 Subject: [PATCH 02/34] add category to metric subjct --- src/Application/Linter/Linter.php | 5 +++-- .../Resolver/MetricableConfigResolver.php | 2 +- .../Http/Client/MetricableClient.php | 10 ++++++---- src/Infrastructure/Logger/MetricableLogger.php | 2 +- .../RequestFetcher/CiRequestFetcher.php | 2 +- .../Rule/Factories/ConditionRuleFactory.php | 6 +++++- .../Console/Application/Application.php | 5 +++-- src/Presentation/Console/Command/LintCommand.php | 9 ++++++--- src/Shared/Metrics/Value/MetricSubject.php | 15 ++++++++++++++- .../Metrics/Manager/MemoryMetricManagerTest.php | 4 ++-- 10 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/Application/Linter/Linter.php b/src/Application/Linter/Linter.php index d5e0de115..846c0db16 100644 --- a/src/Application/Linter/Linter.php +++ b/src/Application/Linter/Linter.php @@ -97,8 +97,9 @@ private function addMetricUsedRules(): void { $this->metrics->add( new MetricSubject( - 'linter_used_rules', - '[Linter] Used rules', + 'linter', + 'used_rules', + 'Used rules', ), IncCounter::create($this->rules), ); diff --git a/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php b/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php index 7beb76995..f101a1ba8 100644 --- a/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php +++ b/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php @@ -23,7 +23,7 @@ public function resolve(User $user, int $configSubjects = Config::SUBJECT_ALL): $config = $this->resolver->resolve($user, $configSubjects); $this->metrics->add( - new MetricSubject('config_resolving_time', '[Config] Duration of config resolving'), + new MetricSubject('config', 'resolving_time', 'Duration of config resolving'), $timer->finish(), ); diff --git a/src/Infrastructure/Http/Client/MetricableClient.php b/src/Infrastructure/Http/Client/MetricableClient.php index 5015cb1f0..7f4fa3ee4 100644 --- a/src/Infrastructure/Http/Client/MetricableClient.php +++ b/src/Infrastructure/Http/Client/MetricableClient.php @@ -25,8 +25,9 @@ public function sendRequest(RequestInterface $request): ResponseInterface $response = $this->client->sendRequest($request); $this->metrics->add(new MetricSubject( - 'http_send_request', - sprintf('[HTTP] Wait of response from %s', $request->getUri()->getHost()), + 'http', + 'send_request', + sprintf('Wait of response from %s', $request->getUri()->getHost()), ), $timer->finish()); return $response; @@ -41,8 +42,9 @@ public function sendAsyncRequests(array $requests): array $hosts = $this->getHosts($requests)->implode(', '); $this->metrics->add(new MetricSubject( - 'http_send_request', - sprintf('[HTTP] Wait of response from %s for %d async requests', $hosts, count($requests)), + 'http', + 'send_request', + sprintf('Wait of response from %s for %d async requests', $hosts, count($requests)), ), $timer->finish()); return $responses; diff --git a/src/Infrastructure/Logger/MetricableLogger.php b/src/Infrastructure/Logger/MetricableLogger.php index bd07e8969..6381d64eb 100644 --- a/src/Infrastructure/Logger/MetricableLogger.php +++ b/src/Infrastructure/Logger/MetricableLogger.php @@ -22,7 +22,7 @@ public static function create(MetricManager $manager): self { $counter = new IncCounter(); - $manager->add(new MetricSubject('logger_logs_count', '[Logger] Logs count'), $counter); + $manager->add(new MetricSubject('logger', 'logger_logs_count', 'Logs count'), $counter); return new self($counter); } diff --git a/src/Infrastructure/RequestFetcher/CiRequestFetcher.php b/src/Infrastructure/RequestFetcher/CiRequestFetcher.php index f993bd13c..1761fff73 100644 --- a/src/Infrastructure/RequestFetcher/CiRequestFetcher.php +++ b/src/Infrastructure/RequestFetcher/CiRequestFetcher.php @@ -25,7 +25,7 @@ public function fetch(): MergeRequest $ci = $this->systems->createCurrently(); $this->metrics->add( - new MetricSubject('used_ci_system', '[CI] Used CI System'), + new MetricSubject('ci', 'used_systems', 'Used CI System'), new StringMetric($ci->getName()), ); diff --git a/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php b/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php index 5dc5872c9..d2d970014 100644 --- a/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php +++ b/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php @@ -25,7 +25,11 @@ public static function new(OperatorResolver $operatorResolver, MetricManager $me { $counter = new IncCounter(); - $metrics->add(new MetricSubject('linter_skipped_rules', '[Linter] Skipped rules'), $counter); + $metrics->add(new MetricSubject( + 'linter', + 'skipped_rules', + 'Skipped rules', + ), $counter); return new self($operatorResolver, $counter); } diff --git a/src/Presentation/Console/Application/Application.php b/src/Presentation/Console/Application/Application.php index a5aeb432f..22fae0093 100644 --- a/src/Presentation/Console/Application/Application.php +++ b/src/Presentation/Console/Application/Application.php @@ -25,8 +25,9 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI $this->metrics->add( new MetricSubject( - sprintf('command_time_execution_%s', $command->getName() ?? 'main'), - sprintf('[Console] Command "%s" execution', $command->getName()), + 'console', + sprintf('time_execution_%s', $command->getName() ?? 'main'), + sprintf('Command "%s" execution', $command->getName()), ), new MetricProxy(function () use ($timer) { return $timer->finish(); diff --git a/src/Presentation/Console/Command/LintCommand.php b/src/Presentation/Console/Command/LintCommand.php index b415d7e27..40e43688a 100644 --- a/src/Presentation/Console/Command/LintCommand.php +++ b/src/Presentation/Console/Command/LintCommand.php @@ -116,9 +116,12 @@ private function printMetrics(StyleInterface $style, LintResult $result, bool $f if ($fullMetrics) { $metrics = $metrics->merge( - $this->metrics->describe()->mapToArray( - static fn (Record $record) => new Metric($record->subject->name, $record->value->getMetricValue()), - ) + $this + ->metrics + ->describe() + ->mapToArray( + static fn (Record $record) => new Metric($record->subject->wrapTitle(), $record->value->getMetricValue()), + ), ); } diff --git a/src/Shared/Metrics/Value/MetricSubject.php b/src/Shared/Metrics/Value/MetricSubject.php index ab6148d09..fddd46c93 100644 --- a/src/Shared/Metrics/Value/MetricSubject.php +++ b/src/Shared/Metrics/Value/MetricSubject.php @@ -2,14 +2,27 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Value; +use ArtARTs36\Str\Facade\Str; + /** * @codeCoverageIgnore */ readonly class MetricSubject { public function __construct( + public string $category, public string $key, - public string $name, + public string $title, ) { } + + public function identity(): string + { + return sprintf('%s_%s', $this->category, $this->key); + } + + public function wrapTitle(): string + { + return sprintf('[%s] %s', Str::upFirstSymbol($this->category), $this->title); + } } diff --git a/tests/Unit/Shared/Metrics/Manager/MemoryMetricManagerTest.php b/tests/Unit/Shared/Metrics/Manager/MemoryMetricManagerTest.php index f5e00b81f..340bcaeb6 100644 --- a/tests/Unit/Shared/Metrics/Manager/MemoryMetricManagerTest.php +++ b/tests/Unit/Shared/Metrics/Manager/MemoryMetricManagerTest.php @@ -22,7 +22,7 @@ public function testAdd(): void self::assertCount(0, $manager->describe()); - $manager->add(new MetricSubject('', ''), new IncCounter()); + $manager->add(new MetricSubject('', '', ''), new IncCounter()); self::assertCount(1, $manager->describe()); } @@ -32,7 +32,7 @@ public function providerForTestDescribe(): array return [ [ [ - [$subject1 = new MetricSubject('k', 'n'), $metric1 = new IncCounter()], + [$subject1 = new MetricSubject('', 'k', 'n'), $metric1 = new IncCounter()], ], [ new Record($subject1, $metric1, new \DateTimeImmutable()), From 198c8e10f276edc03abc9b9ac2275244186ac7cd Mon Sep 17 00:00:00 2001 From: artarts36 Date: Wed, 27 Sep 2023 18:25:45 +0300 Subject: [PATCH 03/34] add samples --- src/Application/Linter/Linter.php | 15 ++++---- .../PrometheusPushGatewayReporter.php | 18 +-------- .../Resolver/MetricableConfigResolver.php | 5 ++- .../Http/Client/MetricableClient.php | 20 +++++----- .../Logger/MetricableLogger.php | 2 +- .../Prometheus/PushGateway/PushGateway.php | 4 +- .../Prometheus/PushGateway/Renderer.php | 34 ++++++++++------- .../RequestFetcher/CiRequestFetcher.php | 6 +-- .../Rule/Factories/ConditionRuleFactory.php | 2 +- .../Console/Application/Application.php | 15 ++++---- .../Application/ApplicationFactory.php | 2 +- .../Console/Command/LintCommand.php | 2 +- src/Shared/DataStructure/ArrayMap.php | 15 ++++++++ .../Metrics/Manager/MemoryMetricManager.php | 38 +++++++++++-------- .../Metrics/Manager/NullMetricManager.php | 4 +- .../Metrics/Value/AbstractMetricSample.php | 17 +++++++++ src/Shared/Metrics/Value/Counter.php | 2 +- src/Shared/Metrics/Value/Gauge.php | 22 +++++++++++ src/Shared/Metrics/Value/IncCounter.php | 19 +++++++++- src/Shared/Metrics/Value/MetricManager.php | 20 +++++++--- .../Value/{Metric.php => MetricSample.php} | 12 +++++- ...{MetricProxy.php => MetricSampleProxy.php} | 14 +++++-- src/Shared/Metrics/Value/MetricType.php | 9 +++++ src/Shared/Metrics/Value/NullCounter.php | 7 +++- src/Shared/Metrics/Value/Record.php | 10 +++-- src/Shared/Metrics/Value/StringMetric.php | 16 -------- src/Shared/Time/Duration.php | 11 +----- ...roxyTest.php => MetricSampleProxyTest.php} | 14 +++---- 28 files changed, 224 insertions(+), 131 deletions(-) create mode 100644 src/Shared/Metrics/Value/AbstractMetricSample.php create mode 100644 src/Shared/Metrics/Value/Gauge.php rename src/Shared/Metrics/Value/{Metric.php => MetricSample.php} (50%) rename src/Shared/Metrics/Value/{MetricProxy.php => MetricSampleProxy.php} (54%) create mode 100644 src/Shared/Metrics/Value/MetricType.php delete mode 100644 src/Shared/Metrics/Value/StringMetric.php rename tests/Unit/Shared/Metrics/Value/{MetricProxyTest.php => MetricSampleProxyTest.php} (65%) diff --git a/src/Application/Linter/Linter.php b/src/Application/Linter/Linter.php index 846c0db16..06c7fe493 100644 --- a/src/Application/Linter/Linter.php +++ b/src/Application/Linter/Linter.php @@ -19,6 +19,7 @@ use ArtARTs36\MergeRequestLinter\Domain\Rule\Rule; use ArtARTs36\MergeRequestLinter\Domain\Rule\Rules; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Gauge; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; @@ -95,14 +96,12 @@ public function run(MergeRequest $request): LintResult private function addMetricUsedRules(): void { - $this->metrics->add( - new MetricSubject( - 'linter', - 'used_rules', - 'Used rules', - ), - IncCounter::create($this->rules), - ); + $this + ->metrics + ->registerWithSample( + new MetricSubject('linter', 'used_rules', 'Used rules'), + new Gauge($this->rules->count()), + ); } /** diff --git a/src/Application/Report/Reporter/PrometheusPushGatewayReporter.php b/src/Application/Report/Reporter/PrometheusPushGatewayReporter.php index 968d8adab..5dcb73940 100644 --- a/src/Application/Report/Reporter/PrometheusPushGatewayReporter.php +++ b/src/Application/Report/Reporter/PrometheusPushGatewayReporter.php @@ -4,7 +4,6 @@ use ArtARTs36\MergeRequestLinter\Domain\Linter\LintResult; use ArtARTs36\MergeRequestLinter\Domain\Request\MergeRequest; -use ArtARTs36\MergeRequestLinter\Infrastructure\Prometheus\PushGateway\Metric; use ArtARTs36\MergeRequestLinter\Infrastructure\Prometheus\PushGateway\PushGateway; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; @@ -21,21 +20,6 @@ public function report(MergeRequest $request, LintResult $result): void $jobId = sprintf('%s-%s', $request->uri, time()); $jobIdHash = md5($jobId); - $this->client->push($jobIdHash, $this->collectMetrics($request, $result)); - } - - /** - * @return array - */ - private function collectMetrics(MergeRequest $request, LintResult $result): array - { - $labels = ['repo' => (string) $request->uri, 'request_id' => $request->id]; - $metrics = []; - - $metrics[] = Metric::gauge('mr_linter_lint_state', 'MR Linter: lint state', $labels, $result->state->value); - $metrics[] = Metric::gauge('mr_linter_lint_duration', 'MR Linter: lint duration', $labels, $result->duration->seconds); - $metrics[] = Metric::gauge('mr_linter_lint_notes', 'MR Linter: lint duration', $labels, $result->notes->count()); - - return $metrics; + $this->client->push($jobIdHash, $this->metrics->describe()); } } diff --git a/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php b/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php index f101a1ba8..1b2e20e9d 100644 --- a/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php +++ b/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php @@ -4,6 +4,7 @@ use ArtARTs36\MergeRequestLinter\Domain\Configuration\Config; use ArtARTs36\MergeRequestLinter\Infrastructure\Configuration\User; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Gauge; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Time\Timer; @@ -22,9 +23,9 @@ public function resolve(User $user, int $configSubjects = Config::SUBJECT_ALL): $config = $this->resolver->resolve($user, $configSubjects); - $this->metrics->add( + $this->metrics->registerWithSample( new MetricSubject('config', 'resolving_time', 'Duration of config resolving'), - $timer->finish(), + new Gauge($timer->finish()), ); return $config; diff --git a/src/Infrastructure/Http/Client/MetricableClient.php b/src/Infrastructure/Http/Client/MetricableClient.php index 7f4fa3ee4..d29931d17 100644 --- a/src/Infrastructure/Http/Client/MetricableClient.php +++ b/src/Infrastructure/Http/Client/MetricableClient.php @@ -4,6 +4,7 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Http\Client; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Gauge; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Time\Timer; @@ -16,6 +17,11 @@ public function __construct( private readonly Client $client, private readonly MetricManager $metrics, ) { + $this->metrics->register(new MetricSubject( + 'http', + 'send_request', + 'Wait of response' + )); } public function sendRequest(RequestInterface $request): ResponseInterface @@ -24,11 +30,9 @@ public function sendRequest(RequestInterface $request): ResponseInterface $response = $this->client->sendRequest($request); - $this->metrics->add(new MetricSubject( - 'http', - 'send_request', - sprintf('Wait of response from %s', $request->getUri()->getHost()), - ), $timer->finish()); + $this->metrics->add('http_send_request', new Gauge($timer->finish(), [ + 'host' => $request->getUri()->getHost(), + ])); return $response; } @@ -41,11 +45,7 @@ public function sendAsyncRequests(array $requests): array $hosts = $this->getHosts($requests)->implode(', '); - $this->metrics->add(new MetricSubject( - 'http', - 'send_request', - sprintf('Wait of response from %s for %d async requests', $hosts, count($requests)), - ), $timer->finish()); + $this->metrics->add('http_send_request', new Gauge($timer->finish())); return $responses; } diff --git a/src/Infrastructure/Logger/MetricableLogger.php b/src/Infrastructure/Logger/MetricableLogger.php index 6381d64eb..c4e19e713 100644 --- a/src/Infrastructure/Logger/MetricableLogger.php +++ b/src/Infrastructure/Logger/MetricableLogger.php @@ -22,7 +22,7 @@ public static function create(MetricManager $manager): self { $counter = new IncCounter(); - $manager->add(new MetricSubject('logger', 'logger_logs_count', 'Logs count'), $counter); + $manager->registerWithSample(new MetricSubject('logger', 'logs_count', 'Logs count'), $counter); return new self($counter); } diff --git a/src/Infrastructure/Prometheus/PushGateway/PushGateway.php b/src/Infrastructure/Prometheus/PushGateway/PushGateway.php index 9901969f8..c7ef98bdd 100644 --- a/src/Infrastructure/Prometheus/PushGateway/PushGateway.php +++ b/src/Infrastructure/Prometheus/PushGateway/PushGateway.php @@ -2,6 +2,8 @@ namespace ArtARTs36\MergeRequestLinter\Infrastructure\Prometheus\PushGateway; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Record; + class PushGateway { public function __construct( @@ -11,7 +13,7 @@ public function __construct( } /** - * @param iterable $records + * @param iterable $records */ public function push(string $job, iterable $records): void { diff --git a/src/Infrastructure/Prometheus/PushGateway/Renderer.php b/src/Infrastructure/Prometheus/PushGateway/Renderer.php index 1fb8a154e..eec6543f7 100644 --- a/src/Infrastructure/Prometheus/PushGateway/Renderer.php +++ b/src/Infrastructure/Prometheus/PushGateway/Renderer.php @@ -2,40 +2,48 @@ namespace ArtARTs36\MergeRequestLinter\Infrastructure\Prometheus\PushGateway; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSample; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Record; +use ArtARTs36\Str\Facade\Str; + class Renderer { /** - * @param iterable $records + * @param iterable $records */ public function render(iterable $records): string { - $content = ''; + $content = []; foreach ($records as $metric) { - $value = $metric->value; + if (! isset($metric->samples[0])) { + continue; + } - $labelsString = $this->collectLabels($metric); + $content[] = "# HELP {$metric->subject->identity()} The number of items in the queue."; + $content[] = "# TYPE {$metric->subject->identity()} {$metric->samples[0]->getMetricType()->value}"; + $content[] = "\n"; - $content .= <<key} The number of items in the queue. -# TYPE {$metric->key} {$metric->type} + foreach ($metric->samples as $sample) { + $labelsString = $this->collectLabels($sample); -{$metric->key}{$labelsString} $value + $content[] = "{$metric->subject->identity()}{$labelsString} {$sample->getMetricValue()}"; + } -HTML; + $content[] = "\n"; } - return $content; + return Str::implode("\n", $content); } - private function collectLabels(Metric $metric): string + private function collectLabels(MetricSample $metric): string { - if (count($metric->labels) === 0) { + if (count($metric->getMetricLabels()) === 0) { return ''; } $labelsString = '{'; - $labels = $metric->labels; + $labels = $metric->getMetricLabels(); foreach ($labels as $labelKey => $labelValue) { $labelsString .= sprintf( diff --git a/src/Infrastructure/RequestFetcher/CiRequestFetcher.php b/src/Infrastructure/RequestFetcher/CiRequestFetcher.php index 1761fff73..f85730cb4 100644 --- a/src/Infrastructure/RequestFetcher/CiRequestFetcher.php +++ b/src/Infrastructure/RequestFetcher/CiRequestFetcher.php @@ -8,9 +8,9 @@ use ArtARTs36\MergeRequestLinter\Domain\Request\MergeRequest; use ArtARTs36\MergeRequestLinter\Domain\Request\MergeRequestFetcher; use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\CI\CiSystemFactory; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\StringMetric; final readonly class CiRequestFetcher implements MergeRequestFetcher { @@ -24,9 +24,9 @@ public function fetch(): MergeRequest { $ci = $this->systems->createCurrently(); - $this->metrics->add( + $this->metrics->registerWithSample( new MetricSubject('ci', 'used_systems', 'Used CI System'), - new StringMetric($ci->getName()), + IncCounter::one(['ci' => $ci->getName()]), ); try { diff --git a/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php b/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php index d2d970014..19630fe8c 100644 --- a/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php +++ b/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php @@ -25,7 +25,7 @@ public static function new(OperatorResolver $operatorResolver, MetricManager $me { $counter = new IncCounter(); - $metrics->add(new MetricSubject( + $metrics->registerWithSample(new MetricSubject( 'linter', 'skipped_rules', 'Skipped rules', diff --git a/src/Presentation/Console/Application/Application.php b/src/Presentation/Console/Application/Application.php index 22fae0093..4eb2703ad 100644 --- a/src/Presentation/Console/Application/Application.php +++ b/src/Presentation/Console/Application/Application.php @@ -2,8 +2,9 @@ namespace ArtARTs36\MergeRequestLinter\Presentation\Console\Application; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Gauge; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricProxy; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSampleProxy; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Time\Timer; use ArtARTs36\MergeRequestLinter\Version; @@ -23,15 +24,15 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI { $timer = Timer::start(); - $this->metrics->add( + $this->metrics->registerWithSample( new MetricSubject( 'console', - sprintf('time_execution_%s', $command->getName() ?? 'main'), - sprintf('Command "%s" execution', $command->getName()), + 'execution_time', + 'Command execution', ), - new MetricProxy(function () use ($timer) { - return $timer->finish(); - }), + new MetricSampleProxy(function () use ($timer) { + return new Gauge($timer->finish()); + }, ['command' => $command->getName() ?? 'main']), ); return parent::doRunCommand($command, $input, $output); diff --git a/src/Presentation/Console/Application/ApplicationFactory.php b/src/Presentation/Console/Application/ApplicationFactory.php index 55b9d4573..284f5f4a2 100644 --- a/src/Presentation/Console/Application/ApplicationFactory.php +++ b/src/Presentation/Console/Application/ApplicationFactory.php @@ -189,7 +189,7 @@ private function registerHttpClientFactory(): ClientFactory private function registerMetricManager(): MetricManager { - $metrics = new MemoryMetricManager($this->container->get(ClockInterface::class)); + $metrics = new MemoryMetricManager(); $this->container->set(MetricManager::class, $metrics); diff --git a/src/Presentation/Console/Command/LintCommand.php b/src/Presentation/Console/Command/LintCommand.php index 40e43688a..c5dcdd376 100644 --- a/src/Presentation/Console/Command/LintCommand.php +++ b/src/Presentation/Console/Command/LintCommand.php @@ -120,7 +120,7 @@ private function printMetrics(StyleInterface $style, LintResult $result, bool $f ->metrics ->describe() ->mapToArray( - static fn (Record $record) => new Metric($record->subject->wrapTitle(), $record->value->getMetricValue()), + static fn ($_, Record $record) => new Metric($record->subject->wrapTitle(), isset($record->samples[0]) ? $record->samples[0]->getMetricValue() : 'null'), ), ); } diff --git a/src/Shared/DataStructure/ArrayMap.php b/src/Shared/DataStructure/ArrayMap.php index 211ad033a..af7dfba14 100644 --- a/src/Shared/DataStructure/ArrayMap.php +++ b/src/Shared/DataStructure/ArrayMap.php @@ -149,6 +149,21 @@ public function toArray(): array return $this->items; } + /** + * @param callable(K, V): mixed $mapper + * @return array + */ + public function mapToArray(callable $mapper): array + { + $items = []; + + foreach ($this->items as $key => $value) { + $items[] = $mapper($key, $value); + } + + return $items; + } + public function __debugInfo(): array { return [ diff --git a/src/Shared/Metrics/Manager/MemoryMetricManager.php b/src/Shared/Metrics/Manager/MemoryMetricManager.php index 1ecba7ce5..aa692090c 100644 --- a/src/Shared/Metrics/Manager/MemoryMetricManager.php +++ b/src/Shared/Metrics/Manager/MemoryMetricManager.php @@ -2,38 +2,46 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager; -use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Metric; +use ArtARTs36\MergeRequestLinter\Shared\DataStructure\ArrayMap; +use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Map; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSample; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Record; -use Psr\Clock\ClockInterface; class MemoryMetricManager implements MetricManager { /** - * @var array + * @var array */ private array $records = []; - public function __construct( - private readonly ClockInterface $clock, - ) { + public function register(MetricSubject $subject): void + { + $this->records[$subject->identity()] = new Record($subject, []); } - public function add(MetricSubject $subject, Metric $value): self + public function registerWithSample(MetricSubject $subject, MetricSample $sample): void { - $this->records[] = new Record( - $subject, - $value, - $this->clock->now(), - ); + $this->records[$subject->identity()] = new Record($subject, [$sample]); + } + + public function add(string $subjectIdentity, MetricSample $value): self + { + if (! isset($this->records[$subjectIdentity])) { + throw new \LogicException(sprintf( + 'Metric with subject identity "%s" not registered', + $subjectIdentity, + )); + } + + $this->records[$subjectIdentity]->samples[] = $value; return $this; } - public function describe(): Arrayee + public function describe(): Map { - return new Arrayee($this->records); + return new ArrayMap($this->records); } } diff --git a/src/Shared/Metrics/Manager/NullMetricManager.php b/src/Shared/Metrics/Manager/NullMetricManager.php index efa63762a..7257a31d9 100644 --- a/src/Shared/Metrics/Manager/NullMetricManager.php +++ b/src/Shared/Metrics/Manager/NullMetricManager.php @@ -3,7 +3,7 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Metric; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSample; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; @@ -12,7 +12,7 @@ */ class NullMetricManager implements MetricManager { - public function add(MetricSubject $subject, Metric $value): MetricManager + public function add(MetricSubject $subject, MetricSample $value): MetricManager { return $this; } diff --git a/src/Shared/Metrics/Value/AbstractMetricSample.php b/src/Shared/Metrics/Value/AbstractMetricSample.php new file mode 100644 index 000000000..50f7551eb --- /dev/null +++ b/src/Shared/Metrics/Value/AbstractMetricSample.php @@ -0,0 +1,17 @@ + */ + protected array $labels = []; + + /** + * @return array + */ + public function getMetricLabels(): array + { + return $this->labels; + } +} diff --git a/src/Shared/Metrics/Value/Counter.php b/src/Shared/Metrics/Value/Counter.php index 423144aca..4bedd088c 100644 --- a/src/Shared/Metrics/Value/Counter.php +++ b/src/Shared/Metrics/Value/Counter.php @@ -5,7 +5,7 @@ /** * Interface for Metric Counter. */ -interface Counter extends Metric +interface Counter extends MetricSample { /** * Increment metric value. diff --git a/src/Shared/Metrics/Value/Gauge.php b/src/Shared/Metrics/Value/Gauge.php new file mode 100644 index 000000000..da68b8706 --- /dev/null +++ b/src/Shared/Metrics/Value/Gauge.php @@ -0,0 +1,22 @@ +value"; + } +} diff --git a/src/Shared/Metrics/Value/IncCounter.php b/src/Shared/Metrics/Value/IncCounter.php index 17d269ae4..18e247857 100644 --- a/src/Shared/Metrics/Value/IncCounter.php +++ b/src/Shared/Metrics/Value/IncCounter.php @@ -2,13 +2,25 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Value; -class IncCounter implements Counter +final class IncCounter extends AbstractMetricSample implements Counter { + /** + * @param array $labels + */ public function __construct( private int $count = 0, + protected array $labels = [] ) { } + /** + * @param array $labels + */ + public static function one(array $labels = []): self + { + return new self(1, $labels); + } + /** * @param \Countable|array $countable */ @@ -22,6 +34,11 @@ public function inc(): void ++$this->count; } + public function getMetricType(): MetricType + { + return MetricType::Counter; + } + public function getMetricValue(): string { return "$this->count"; diff --git a/src/Shared/Metrics/Value/MetricManager.php b/src/Shared/Metrics/Value/MetricManager.php index cf6fa9139..cf307bbf6 100644 --- a/src/Shared/Metrics/Value/MetricManager.php +++ b/src/Shared/Metrics/Value/MetricManager.php @@ -2,7 +2,7 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Value; -use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; +use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Map; /** * Interface for managing metrics (time execution, etc.). @@ -10,14 +10,24 @@ interface MetricManager { /** - * Add new metric. + * Register metric subject. + */ + public function register(MetricSubject $subject): void; + + /** + * Register metric subject with sample. + */ + public function registerWithSample(MetricSubject $subject, MetricSample $sample): void; + + /** + * Add new metric sample. * @return $this */ - public function add(MetricSubject $subject, Metric $value): self; + public function add(string $subjectIdentity, MetricSample $value): self; /** * Describe metrics. - * @return Arrayee + * @return Map */ - public function describe(): Arrayee; + public function describe(): Map; } diff --git a/src/Shared/Metrics/Value/Metric.php b/src/Shared/Metrics/Value/MetricSample.php similarity index 50% rename from src/Shared/Metrics/Value/Metric.php rename to src/Shared/Metrics/Value/MetricSample.php index 507fe83fa..0df2b778c 100644 --- a/src/Shared/Metrics/Value/Metric.php +++ b/src/Shared/Metrics/Value/MetricSample.php @@ -5,8 +5,18 @@ /** * Interface for metricable objects. */ -interface Metric +interface MetricSample { + /** + * Get a metric type. + */ + public function getMetricType(): MetricType; + + /** + * @return array + */ + public function getMetricLabels(): array; + /** * Get metric value in string. */ diff --git a/src/Shared/Metrics/Value/MetricProxy.php b/src/Shared/Metrics/Value/MetricSampleProxy.php similarity index 54% rename from src/Shared/Metrics/Value/MetricProxy.php rename to src/Shared/Metrics/Value/MetricSampleProxy.php index ce7419843..902bcf19b 100644 --- a/src/Shared/Metrics/Value/MetricProxy.php +++ b/src/Shared/Metrics/Value/MetricSampleProxy.php @@ -2,24 +2,30 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Value; -class MetricProxy implements Metric +class MetricSampleProxy extends AbstractMetricSample implements MetricSample { - private ?Metric $metric = null; + private ?MetricSample $metric = null; /** - * @param \Closure(): Metric $callback + * @param \Closure(): MetricSample $callback */ public function __construct( private readonly \Closure $callback, + protected array $labels = [], ) { } + public function getMetricType(): MetricType + { + return $this->retrieve()->getMetricType(); + } + public function getMetricValue(): string { return $this->retrieve()->getMetricValue(); } - private function retrieve(): Metric + private function retrieve(): MetricSample { if ($this->metric === null) { $this->metric = ($this->callback)(); diff --git a/src/Shared/Metrics/Value/MetricType.php b/src/Shared/Metrics/Value/MetricType.php new file mode 100644 index 000000000..ce9e7419d --- /dev/null +++ b/src/Shared/Metrics/Value/MetricType.php @@ -0,0 +1,9 @@ + $samples + */ public function __construct( - public MetricSubject $subject, - public Metric $value, - public \DateTimeInterface $date, + public readonly MetricSubject $subject, + public array $samples, ) { } } diff --git a/src/Shared/Metrics/Value/StringMetric.php b/src/Shared/Metrics/Value/StringMetric.php deleted file mode 100644 index 326277f33..000000000 --- a/src/Shared/Metrics/Value/StringMetric.php +++ /dev/null @@ -1,16 +0,0 @@ -value; - } -} diff --git a/src/Shared/Time/Duration.php b/src/Shared/Time/Duration.php index 17ff85fac..c1b5e5563 100644 --- a/src/Shared/Time/Duration.php +++ b/src/Shared/Time/Duration.php @@ -2,9 +2,7 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Time; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Metric; - -readonly class Duration implements Metric +readonly class Duration { public function __construct( public float $seconds, @@ -13,11 +11,6 @@ public function __construct( public function __toString(): string { - return "$this->seconds" . 's'; - } - - public function getMetricValue(): string - { - return (string) $this; + return "$this->seconds"; } } diff --git a/tests/Unit/Shared/Metrics/Value/MetricProxyTest.php b/tests/Unit/Shared/Metrics/Value/MetricSampleProxyTest.php similarity index 65% rename from tests/Unit/Shared/Metrics/Value/MetricProxyTest.php rename to tests/Unit/Shared/Metrics/Value/MetricSampleProxyTest.php index 3a63e80ff..68a678d6c 100644 --- a/tests/Unit/Shared/Metrics/Value/MetricProxyTest.php +++ b/tests/Unit/Shared/Metrics/Value/MetricSampleProxyTest.php @@ -2,21 +2,21 @@ namespace ArtARTs36\MergeRequestLinter\Tests\Unit\Shared\Metrics\Value; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Metric; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricProxy; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSample; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSampleProxy; use ArtARTs36\MergeRequestLinter\Tests\TestCase; final class MetricProxyTest extends TestCase { /** - * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricProxy::getMetricValue - * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricProxy::retrieve - * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricProxy::__construct + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSampleProxy::getMetricValue + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSampleProxy::retrieve + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSampleProxy::__construct */ public function testGetMetricValue(): void { - $proxy = new MetricProxy(function () { - return new class () implements Metric { + $proxy = new MetricSampleProxy(function () { + return new class () implements MetricSample { public function getMetricValue(): string { return 'test-value'; From 524895fb0122c8213966ba43ec425a1c2abeae63 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Wed, 27 Sep 2023 18:43:57 +0300 Subject: [PATCH 04/34] move storage --- src/Application/Linter/Linter.php | 3 +- src/Application/Linter/LinterFactory.php | 2 +- src/Application/Linter/RunnerFactory.php | 2 +- .../PrometheusPushGatewayReporter.php | 4 +-- .../Report/Reporter/ReporterFactory.php | 12 ++++---- .../Loader/ArrayConfigLoaderFactory.php | 4 +-- .../Resolver/MetricableConfigResolver.php | 2 +- .../Http/Client/ClientFactory.php | 2 +- .../Http/Client/MetricableClient.php | 2 +- .../Logger/MetricableLogger.php | 2 +- .../Prometheus/PushGateway/Metric.php | 29 ------------------- .../RequestFetcher/CiRequestFetcher.php | 2 +- .../Rule/Factories/ConditionRuleFactory.php | 2 +- .../Console/Application/Application.php | 2 +- .../Application/ApplicationFactory.php | 2 +- .../Console/Command/LintCommand.php | 2 +- src/Providers/ReportProvider.php | 2 +- .../Metrics/Manager/MemoryMetricManager.php | 13 ++++++++- .../{Value => Manager}/MetricManager.php | 10 ++++++- .../Metrics/Manager/NullMetricManager.php | 1 - src/Shared/Metrics/Storage/MetricStorage.php | 18 ++++++++++++ src/Shared/Metrics/Storage/NullStorage.php | 11 +++++++ .../Storage/PrometheusPushGateway/Client.php} | 8 ++--- .../PrometheusPushGateway}/PushGateway.php | 4 +-- .../PrometheusPushGateway}/Renderer.php | 2 +- 25 files changed, 80 insertions(+), 63 deletions(-) delete mode 100644 src/Infrastructure/Prometheus/PushGateway/Metric.php rename src/Shared/Metrics/{Value => Manager}/MetricManager.php (64%) create mode 100644 src/Shared/Metrics/Storage/MetricStorage.php create mode 100644 src/Shared/Metrics/Storage/NullStorage.php rename src/{Infrastructure/Prometheus/PushGateway/PushGatewayClient.php => Shared/Metrics/Storage/PrometheusPushGateway/Client.php} (69%) rename src/{Infrastructure/Prometheus/PushGateway => Shared/Metrics/Storage/PrometheusPushGateway}/PushGateway.php (76%) rename src/{Infrastructure/Prometheus/PushGateway => Shared/Metrics/Storage/PrometheusPushGateway}/Renderer.php (95%) diff --git a/src/Application/Linter/Linter.php b/src/Application/Linter/Linter.php index 06c7fe493..c5871ca37 100644 --- a/src/Application/Linter/Linter.php +++ b/src/Application/Linter/Linter.php @@ -19,9 +19,8 @@ use ArtARTs36\MergeRequestLinter\Domain\Rule\Rule; use ArtARTs36\MergeRequestLinter\Domain\Rule\Rules; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Gauge; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Time\Timer; use Psr\EventDispatcher\EventDispatcherInterface; diff --git a/src/Application/Linter/LinterFactory.php b/src/Application/Linter/LinterFactory.php index 158045672..502204c65 100644 --- a/src/Application/Linter/LinterFactory.php +++ b/src/Application/Linter/LinterFactory.php @@ -4,7 +4,7 @@ use ArtARTs36\MergeRequestLinter\Domain\Configuration\Config; use ArtARTs36\MergeRequestLinter\Domain\Linter\Linter; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; use Psr\EventDispatcher\EventDispatcherInterface; class LinterFactory diff --git a/src/Application/Linter/RunnerFactory.php b/src/Application/Linter/RunnerFactory.php index 3eeb92b8d..05b8a3a23 100644 --- a/src/Application/Linter/RunnerFactory.php +++ b/src/Application/Linter/RunnerFactory.php @@ -22,7 +22,7 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\RequestFetcher\CiRequestFetcher; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\ArrayMap; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Map; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Time\Clock; class RunnerFactory implements LinterRunnerFactory diff --git a/src/Application/Report/Reporter/PrometheusPushGatewayReporter.php b/src/Application/Report/Reporter/PrometheusPushGatewayReporter.php index 5dcb73940..69eb658e0 100644 --- a/src/Application/Report/Reporter/PrometheusPushGatewayReporter.php +++ b/src/Application/Report/Reporter/PrometheusPushGatewayReporter.php @@ -4,8 +4,8 @@ use ArtARTs36\MergeRequestLinter\Domain\Linter\LintResult; use ArtARTs36\MergeRequestLinter\Domain\Request\MergeRequest; -use ArtARTs36\MergeRequestLinter\Infrastructure\Prometheus\PushGateway\PushGateway; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\PushGateway; class PrometheusPushGatewayReporter implements Reporter { diff --git a/src/Application/Report/Reporter/ReporterFactory.php b/src/Application/Report/Reporter/ReporterFactory.php index 10fa93689..fbe5726eb 100644 --- a/src/Application/Report/Reporter/ReporterFactory.php +++ b/src/Application/Report/Reporter/ReporterFactory.php @@ -3,11 +3,11 @@ namespace ArtARTs36\MergeRequestLinter\Application\Report\Reporter; use ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\ClientGuzzleWrapper; -use ArtARTs36\MergeRequestLinter\Infrastructure\Prometheus\PushGateway\PushGateway; -use ArtARTs36\MergeRequestLinter\Infrastructure\Prometheus\PushGateway\PushGatewayClient; -use ArtARTs36\MergeRequestLinter\Infrastructure\Prometheus\PushGateway\Renderer; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; -use GuzzleHttp\Client; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\PushGateway; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\Client; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\Renderer; +use GuzzleHttp\Client as HttpClient; use Psr\Log\LoggerInterface; class ReporterFactory @@ -23,7 +23,7 @@ public function create(string $type, array $params): Reporter if ($type === 'prometheusPushGateway') { return new PrometheusPushGatewayReporter( $this->metrics, - new PushGateway(new PushGatewayClient(new ClientGuzzleWrapper(new Client(), $this->logger)), new Renderer()), + new PushGateway(new Client(new ClientGuzzleWrapper(new HttpClient(), $this->logger)), new Renderer()), ); } } diff --git a/src/Infrastructure/Configuration/Loader/ArrayConfigLoaderFactory.php b/src/Infrastructure/Configuration/Loader/ArrayConfigLoaderFactory.php index 82e1706e9..70a7a560b 100644 --- a/src/Infrastructure/Configuration/Loader/ArrayConfigLoaderFactory.php +++ b/src/Infrastructure/Configuration/Loader/ArrayConfigLoaderFactory.php @@ -35,9 +35,9 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Rule\Factories\RuleFactory; use ArtARTs36\MergeRequestLinter\Infrastructure\Rule\Resolver; use ArtARTs36\MergeRequestLinter\Infrastructure\Text\Decoder\DecoderFactory; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; -use ArtARTs36\MergeRequestLinter\Shared\Reflection\ParameterMapBuilder; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Reflection\Instantiator\Finder; +use ArtARTs36\MergeRequestLinter\Shared\Reflection\ParameterMapBuilder; use ArtARTs36\MergeRequestLinter\Shared\Reflection\TypeResolver\ResolverFactory; class ArrayConfigLoaderFactory diff --git a/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php b/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php index 1b2e20e9d..c5ebfe046 100644 --- a/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php +++ b/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php @@ -4,8 +4,8 @@ use ArtARTs36\MergeRequestLinter\Domain\Configuration\Config; use ArtARTs36\MergeRequestLinter\Infrastructure\Configuration\User; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Gauge; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Time\Timer; diff --git a/src/Infrastructure/Http/Client/ClientFactory.php b/src/Infrastructure/Http/Client/ClientFactory.php index 05daf9eb1..ad876dc3e 100644 --- a/src/Infrastructure/Http/Client/ClientFactory.php +++ b/src/Infrastructure/Http/Client/ClientFactory.php @@ -6,7 +6,7 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Http\Client; use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Http\HttpClientFactory; use ArtARTs36\MergeRequestLinter\Infrastructure\Http\Exceptions\HttpClientTypeNotSupported; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; use GuzzleHttp\Client as GuzzleClient; use Psr\Log\LoggerInterface; diff --git a/src/Infrastructure/Http/Client/MetricableClient.php b/src/Infrastructure/Http/Client/MetricableClient.php index d29931d17..536a7f3ad 100644 --- a/src/Infrastructure/Http/Client/MetricableClient.php +++ b/src/Infrastructure/Http/Client/MetricableClient.php @@ -4,8 +4,8 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Http\Client; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Gauge; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Time\Timer; use Psr\Http\Message\RequestInterface; diff --git a/src/Infrastructure/Logger/MetricableLogger.php b/src/Infrastructure/Logger/MetricableLogger.php index c4e19e713..900c77ddf 100644 --- a/src/Infrastructure/Logger/MetricableLogger.php +++ b/src/Infrastructure/Logger/MetricableLogger.php @@ -2,9 +2,9 @@ namespace ArtARTs36\MergeRequestLinter\Infrastructure\Logger; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Counter; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use Psr\Log\LoggerInterface; use Psr\Log\LoggerTrait; diff --git a/src/Infrastructure/Prometheus/PushGateway/Metric.php b/src/Infrastructure/Prometheus/PushGateway/Metric.php deleted file mode 100644 index b0b4976c5..000000000 --- a/src/Infrastructure/Prometheus/PushGateway/Metric.php +++ /dev/null @@ -1,29 +0,0 @@ - $labels - */ - public function __construct( - public string $type, - public string $key, - public string $help, - public array $labels, - public int|string|float $value, - ) { - } - - /** - * @param array $labels - */ - public static function gauge(string $key, string $help, array $labels, int|string|float $value): self - { - return new self('gauge', $key, $help, $labels, $value); - } -} diff --git a/src/Infrastructure/RequestFetcher/CiRequestFetcher.php b/src/Infrastructure/RequestFetcher/CiRequestFetcher.php index f85730cb4..4da52922e 100644 --- a/src/Infrastructure/RequestFetcher/CiRequestFetcher.php +++ b/src/Infrastructure/RequestFetcher/CiRequestFetcher.php @@ -8,8 +8,8 @@ use ArtARTs36\MergeRequestLinter\Domain\Request\MergeRequest; use ArtARTs36\MergeRequestLinter\Domain\Request\MergeRequestFetcher; use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\CI\CiSystemFactory; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; final readonly class CiRequestFetcher implements MergeRequestFetcher diff --git a/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php b/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php index 19630fe8c..1cc82feb7 100644 --- a/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php +++ b/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php @@ -5,9 +5,9 @@ use ArtARTs36\MergeRequestLinter\Application\Rule\Rules\ConditionRule; use ArtARTs36\MergeRequestLinter\Domain\Rule\Rule; use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Condition\OperatorResolver; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Counter; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; /** diff --git a/src/Presentation/Console/Application/Application.php b/src/Presentation/Console/Application/Application.php index 4eb2703ad..9907f2fc7 100644 --- a/src/Presentation/Console/Application/Application.php +++ b/src/Presentation/Console/Application/Application.php @@ -2,8 +2,8 @@ namespace ArtARTs36\MergeRequestLinter\Presentation\Console\Application; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Gauge; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSampleProxy; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Time\Timer; diff --git a/src/Presentation/Console/Application/ApplicationFactory.php b/src/Presentation/Console/Application/ApplicationFactory.php index 284f5f4a2..a8cc30fd9 100644 --- a/src/Presentation/Console/Application/ApplicationFactory.php +++ b/src/Presentation/Console/Application/ApplicationFactory.php @@ -47,7 +47,7 @@ use ArtARTs36\MergeRequestLinter\Shared\Events\EventManager; use ArtARTs36\MergeRequestLinter\Shared\File\Directory; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MemoryMetricManager; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Reflection\TypeResolver\ResolverFactory; use ArtARTs36\MergeRequestLinter\Shared\Time\Clock; use ArtARTs36\MergeRequestLinter\Shared\Time\LocalClock; diff --git a/src/Presentation/Console/Command/LintCommand.php b/src/Presentation/Console/Command/LintCommand.php index c5dcdd376..2838c276c 100644 --- a/src/Presentation/Console/Command/LintCommand.php +++ b/src/Presentation/Console/Command/LintCommand.php @@ -18,7 +18,7 @@ use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; use ArtARTs36\MergeRequestLinter\Shared\Events\EventManager; use ArtARTs36\MergeRequestLinter\Shared\File\Bytes; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Record; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputInterface; diff --git a/src/Providers/ReportProvider.php b/src/Providers/ReportProvider.php index 4e5f34589..bf9b66c71 100644 --- a/src/Providers/ReportProvider.php +++ b/src/Providers/ReportProvider.php @@ -6,7 +6,7 @@ use ArtARTs36\MergeRequestLinter\Domain\Linter\LintFinishedEvent; use ArtARTs36\MergeRequestLinter\Shared\Events\CallbackListener; use ArtARTs36\MergeRequestLinter\Shared\Events\EventManager; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; diff --git a/src/Shared/Metrics/Manager/MemoryMetricManager.php b/src/Shared/Metrics/Manager/MemoryMetricManager.php index aa692090c..db6329eda 100644 --- a/src/Shared/Metrics/Manager/MemoryMetricManager.php +++ b/src/Shared/Metrics/Manager/MemoryMetricManager.php @@ -4,8 +4,9 @@ use ArtARTs36\MergeRequestLinter\Shared\DataStructure\ArrayMap; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Map; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\MetricStorage; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\NullStorage; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSample; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Record; @@ -16,6 +17,11 @@ class MemoryMetricManager implements MetricManager */ private array $records = []; + public function __construct( + private readonly MetricStorage $storage = new NullStorage(), + ) { + } + public function register(MetricSubject $subject): void { $this->records[$subject->identity()] = new Record($subject, []); @@ -44,4 +50,9 @@ public function describe(): Map { return new ArrayMap($this->records); } + + public function flush(string $id): void + { + $this->storage->commit($id, $this->records); + } } diff --git a/src/Shared/Metrics/Value/MetricManager.php b/src/Shared/Metrics/Manager/MetricManager.php similarity index 64% rename from src/Shared/Metrics/Value/MetricManager.php rename to src/Shared/Metrics/Manager/MetricManager.php index cf307bbf6..7886b5105 100644 --- a/src/Shared/Metrics/Value/MetricManager.php +++ b/src/Shared/Metrics/Manager/MetricManager.php @@ -1,8 +1,11 @@ */ public function describe(): Map; + + /** + * Flush records to persistent storage. + */ + public function flush(string $id): void; } diff --git a/src/Shared/Metrics/Manager/NullMetricManager.php b/src/Shared/Metrics/Manager/NullMetricManager.php index 7257a31d9..4860465cf 100644 --- a/src/Shared/Metrics/Manager/NullMetricManager.php +++ b/src/Shared/Metrics/Manager/NullMetricManager.php @@ -4,7 +4,6 @@ use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSample; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; /** diff --git a/src/Shared/Metrics/Storage/MetricStorage.php b/src/Shared/Metrics/Storage/MetricStorage.php new file mode 100644 index 000000000..1b0e09d21 --- /dev/null +++ b/src/Shared/Metrics/Storage/MetricStorage.php @@ -0,0 +1,18 @@ + $records + */ + public function commit(string $id, array $records): void; +} diff --git a/src/Shared/Metrics/Storage/NullStorage.php b/src/Shared/Metrics/Storage/NullStorage.php new file mode 100644 index 000000000..8e264b736 --- /dev/null +++ b/src/Shared/Metrics/Storage/NullStorage.php @@ -0,0 +1,11 @@ + Date: Wed, 27 Sep 2023 19:15:44 +0300 Subject: [PATCH 05/34] refactor --- .../Metrics/RequestMetricsFlusher.php | 23 ++++++++++++ .../PrometheusPushGatewayReporter.php | 25 ------------- src/Application/Report/Reporter/Reporter.php | 11 ------ .../Report/Reporter/ReporterFactory.php | 30 ---------------- src/Application/Report/ReporterHandler.php | 28 --------------- src/Providers/ReportProvider.php | 36 +++++++++++++------ .../Metrics/Manager/MemoryMetricManager.php | 12 ------- src/Shared/Metrics/Manager/MetricManager.php | 5 --- .../PrometheusPushGateway/PushGateway.php | 7 ++-- 9 files changed, 52 insertions(+), 125 deletions(-) create mode 100644 src/Application/Metrics/RequestMetricsFlusher.php delete mode 100644 src/Application/Report/Reporter/PrometheusPushGatewayReporter.php delete mode 100644 src/Application/Report/Reporter/Reporter.php delete mode 100644 src/Application/Report/Reporter/ReporterFactory.php delete mode 100644 src/Application/Report/ReporterHandler.php diff --git a/src/Application/Metrics/RequestMetricsFlusher.php b/src/Application/Metrics/RequestMetricsFlusher.php new file mode 100644 index 000000000..1508df2ed --- /dev/null +++ b/src/Application/Metrics/RequestMetricsFlusher.php @@ -0,0 +1,23 @@ +uri, time())); + + $this->storage->commit($transactionId, $this->metrics->describe()->toArray()); + } +} diff --git a/src/Application/Report/Reporter/PrometheusPushGatewayReporter.php b/src/Application/Report/Reporter/PrometheusPushGatewayReporter.php deleted file mode 100644 index 69eb658e0..000000000 --- a/src/Application/Report/Reporter/PrometheusPushGatewayReporter.php +++ /dev/null @@ -1,25 +0,0 @@ -uri, time()); - $jobIdHash = md5($jobId); - - $this->client->push($jobIdHash, $this->metrics->describe()); - } -} diff --git a/src/Application/Report/Reporter/Reporter.php b/src/Application/Report/Reporter/Reporter.php deleted file mode 100644 index 6e34b0b01..000000000 --- a/src/Application/Report/Reporter/Reporter.php +++ /dev/null @@ -1,11 +0,0 @@ -metrics, - new PushGateway(new Client(new ClientGuzzleWrapper(new HttpClient(), $this->logger)), new Renderer()), - ); - } - } -} diff --git a/src/Application/Report/ReporterHandler.php b/src/Application/Report/ReporterHandler.php deleted file mode 100644 index 34c070b19..000000000 --- a/src/Application/Report/ReporterHandler.php +++ /dev/null @@ -1,28 +0,0 @@ -reporter->report($event->request, $event->result); - } -} diff --git a/src/Providers/ReportProvider.php b/src/Providers/ReportProvider.php index bf9b66c71..6edfdc1a3 100644 --- a/src/Providers/ReportProvider.php +++ b/src/Providers/ReportProvider.php @@ -2,13 +2,19 @@ namespace ArtARTs36\MergeRequestLinter\Providers; -use ArtARTs36\MergeRequestLinter\Application\Report\Reporter\ReporterFactory; +use ArtARTs36\MergeRequestLinter\Application\Linter\Events\ConfigResolvedEvent; +use ArtARTs36\MergeRequestLinter\Application\Metrics\MetricsFlushHandler; +use ArtARTs36\MergeRequestLinter\Application\Metrics\RequestMetricsFlusher; use ArtARTs36\MergeRequestLinter\Domain\Linter\LintFinishedEvent; +use ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\ClientFactory; use ArtARTs36\MergeRequestLinter\Shared\Events\CallbackListener; use ArtARTs36\MergeRequestLinter\Shared\Events\EventManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\MetricStorage; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\Client; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\PushGateway; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\Renderer; use Psr\Container\ContainerInterface; -use Psr\Log\LoggerInterface; final class ReportProvider extends Provider { @@ -16,20 +22,28 @@ public function provide(): void { $this ->container - ->bind(ReporterFactory::class, static function (ContainerInterface $container) { - return new ReporterFactory( - $container->get(MetricManager::class), - $container->get(LoggerInterface::class), - ); - }); + ->get(EventManager::class) + ->listen(ConfigResolvedEvent::class, new CallbackListener('register metric storage', function (ConfigResolvedEvent $event) { + $this->container->bind(MetricStorage::class, static function (ContainerInterface $container) use ($event) { + $httpClient = $container->get(ClientFactory::class)->create($event->config->config->httpClient); + + return new PushGateway( + new Client($httpClient), + new Renderer(), + ); + }); + })); $this ->container ->get(EventManager::class) - ->listen(LintFinishedEvent::class, new CallbackListener('reporter', function (LintFinishedEvent $event) { - $factory = $this->container->get(ReporterFactory::class); + ->listen(LintFinishedEvent::class, new CallbackListener('metrics_flush', function (LintFinishedEvent $event) { + $flusher = new RequestMetricsFlusher( + $this->container->get(MetricManager::class), + $this->container->get(MetricStorage::class), + ); - $factory->create('prometheusPushGateway', [])->report($event->request, $event->result); + $flusher->flush($event->request); })); } } diff --git a/src/Shared/Metrics/Manager/MemoryMetricManager.php b/src/Shared/Metrics/Manager/MemoryMetricManager.php index db6329eda..2863ce6f7 100644 --- a/src/Shared/Metrics/Manager/MemoryMetricManager.php +++ b/src/Shared/Metrics/Manager/MemoryMetricManager.php @@ -4,8 +4,6 @@ use ArtARTs36\MergeRequestLinter\Shared\DataStructure\ArrayMap; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Map; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\MetricStorage; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\NullStorage; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSample; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Record; @@ -17,11 +15,6 @@ class MemoryMetricManager implements MetricManager */ private array $records = []; - public function __construct( - private readonly MetricStorage $storage = new NullStorage(), - ) { - } - public function register(MetricSubject $subject): void { $this->records[$subject->identity()] = new Record($subject, []); @@ -50,9 +43,4 @@ public function describe(): Map { return new ArrayMap($this->records); } - - public function flush(string $id): void - { - $this->storage->commit($id, $this->records); - } } diff --git a/src/Shared/Metrics/Manager/MetricManager.php b/src/Shared/Metrics/Manager/MetricManager.php index 7886b5105..1c071b0c0 100644 --- a/src/Shared/Metrics/Manager/MetricManager.php +++ b/src/Shared/Metrics/Manager/MetricManager.php @@ -33,9 +33,4 @@ public function add(string $subjectIdentity, MetricSample $value): self; * @return Map */ public function describe(): Map; - - /** - * Flush records to persistent storage. - */ - public function flush(string $id): void; } diff --git a/src/Shared/Metrics/Storage/PrometheusPushGateway/PushGateway.php b/src/Shared/Metrics/Storage/PrometheusPushGateway/PushGateway.php index 7dd9fc488..f68cdd0d1 100644 --- a/src/Shared/Metrics/Storage/PrometheusPushGateway/PushGateway.php +++ b/src/Shared/Metrics/Storage/PrometheusPushGateway/PushGateway.php @@ -2,9 +2,10 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\MetricStorage; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Record; -class PushGateway +class PushGateway implements MetricStorage { public function __construct( private readonly Client $client, @@ -15,10 +16,10 @@ public function __construct( /** * @param iterable $records */ - public function push(string $job, iterable $records): void + public function commit(string $id, iterable $records): void { $data = $this->renderer->render($records); - $this->client->replace($job, $data); + $this->client->replace($id, $data); } } From 33ddb7aa8469b7887bec07144f8ac7737244714b Mon Sep 17 00:00:00 2001 From: artarts36 Date: Wed, 27 Sep 2023 19:19:57 +0300 Subject: [PATCH 06/34] refactor --- src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php b/src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php index f301df61b..4fd90386d 100644 --- a/src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php +++ b/src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php @@ -2,7 +2,7 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway; -use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Http\Client as HttpClient; +use Psr\Http\Client\ClientInterface as HttpClient; use GuzzleHttp\Psr7\Request; class Client From 4e800a727ac5c8c03f5cfaeedbc889682440e552 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Wed, 27 Sep 2023 19:53:12 +0300 Subject: [PATCH 07/34] move flusher --- .../Metrics/RequestMetricFlusher.php} | 4 ++-- src/Providers/ReportProvider.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/{Application/Metrics/RequestMetricsFlusher.php => Infrastructure/Metrics/RequestMetricFlusher.php} (86%) diff --git a/src/Application/Metrics/RequestMetricsFlusher.php b/src/Infrastructure/Metrics/RequestMetricFlusher.php similarity index 86% rename from src/Application/Metrics/RequestMetricsFlusher.php rename to src/Infrastructure/Metrics/RequestMetricFlusher.php index 1508df2ed..544f5d4d0 100644 --- a/src/Application/Metrics/RequestMetricsFlusher.php +++ b/src/Infrastructure/Metrics/RequestMetricFlusher.php @@ -1,12 +1,12 @@ container ->get(EventManager::class) ->listen(LintFinishedEvent::class, new CallbackListener('metrics_flush', function (LintFinishedEvent $event) { - $flusher = new RequestMetricsFlusher( + $flusher = new RequestMetricFlusher( $this->container->get(MetricManager::class), $this->container->get(MetricStorage::class), ); From 48a35020ea877d4effc49943336fc0cf7b1f8548 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Wed, 27 Sep 2023 19:53:47 +0300 Subject: [PATCH 08/34] rename provider --- src/Presentation/Console/Application/ApplicationFactory.php | 4 ++-- src/Providers/{ReportProvider.php => MetricsProvider.php} | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) rename src/Providers/{ReportProvider.php => MetricsProvider.php} (94%) diff --git a/src/Presentation/Console/Application/ApplicationFactory.php b/src/Presentation/Console/Application/ApplicationFactory.php index a8cc30fd9..b49bd1dce 100644 --- a/src/Presentation/Console/Application/ApplicationFactory.php +++ b/src/Presentation/Console/Application/ApplicationFactory.php @@ -41,7 +41,7 @@ use ArtARTs36\MergeRequestLinter\Providers\CommentProvider; use ArtARTs36\MergeRequestLinter\Providers\EventDispatcherProvider; use ArtARTs36\MergeRequestLinter\Providers\NotificationsProvider; -use ArtARTs36\MergeRequestLinter\Providers\ReportProvider; +use ArtARTs36\MergeRequestLinter\Providers\MetricsProvider; use ArtARTs36\MergeRequestLinter\Providers\RuleProvider; use ArtARTs36\MergeRequestLinter\Providers\ServiceProvider; use ArtARTs36\MergeRequestLinter\Shared\Events\EventManager; @@ -62,7 +62,7 @@ class ApplicationFactory NotificationsProvider::class, RuleProvider::class, CommentProvider::class, - ReportProvider::class, + MetricsProvider::class, ]; public function __construct( diff --git a/src/Providers/ReportProvider.php b/src/Providers/MetricsProvider.php similarity index 94% rename from src/Providers/ReportProvider.php rename to src/Providers/MetricsProvider.php index 5b85560cd..06f7cfd4f 100644 --- a/src/Providers/ReportProvider.php +++ b/src/Providers/MetricsProvider.php @@ -3,7 +3,6 @@ namespace ArtARTs36\MergeRequestLinter\Providers; use ArtARTs36\MergeRequestLinter\Application\Linter\Events\ConfigResolvedEvent; -use ArtARTs36\MergeRequestLinter\Application\Metrics\MetricsFlushHandler; use ArtARTs36\MergeRequestLinter\Domain\Linter\LintFinishedEvent; use ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\ClientFactory; use ArtARTs36\MergeRequestLinter\Infrastructure\Metrics\RequestMetricFlusher; @@ -16,7 +15,7 @@ use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\Renderer; use Psr\Container\ContainerInterface; -final class ReportProvider extends Provider +final class MetricsProvider extends Provider { public function provide(): void { From e33bd6c284dba268812f685ab80c38d2141d8f48 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Wed, 27 Sep 2023 20:31:20 +0300 Subject: [PATCH 09/34] add report config --- .mr-linter.yml | 5 ++ src/Domain/Configuration/Config.php | 5 +- src/Domain/Configuration/MetricsConfig.php | 14 ++++++ .../Configuration/MetricsStorageConfig.php | 12 +++++ .../Loader/Mapper/ArrayConfigHydrator.php | 49 +++++++++++++++++++ src/Providers/MetricsProvider.php | 2 +- .../Storage/PrometheusPushGateway/Client.php | 3 +- .../PrometheusPushGateway/PushGateway.php | 2 +- 8 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 src/Domain/Configuration/MetricsConfig.php create mode 100644 src/Domain/Configuration/MetricsStorageConfig.php diff --git a/.mr-linter.yml b/.mr-linter.yml index 2dbb2fb07..a61008897 100644 --- a/.mr-linter.yml +++ b/.mr-linter.yml @@ -105,6 +105,11 @@ ci: credentials: token: 'env(MR_LINTER_GITHUB_HTTP_TOKEN)' +metrics: + storage: + prometheusPushGateway: + address: http://host.docker.internal:9091 + comments: strategy: 'single' messages: diff --git a/src/Domain/Configuration/Config.php b/src/Domain/Configuration/Config.php index 60a5a39d5..aeb320cb5 100644 --- a/src/Domain/Configuration/Config.php +++ b/src/Domain/Configuration/Config.php @@ -17,12 +17,14 @@ public const SUBJECT_NOTIFICATIONS = 4; public const SUBJECT_LINTER = 5; public const SUBJECT_COMMENTS = 6; + public const SUBJECT_METRICS = 7; public const SUBJECT_ALL = self::SUBJECT_RULES | self::SUBJECT_CI_SETTINGS | self::SUBJECT_HTTP_CLIENT | self::SUBJECT_NOTIFICATIONS | self::SUBJECT_LINTER | - self::SUBJECT_COMMENTS; + self::SUBJECT_COMMENTS | + self::SUBJECT_METRICS; /** * @param Map $settings @@ -34,6 +36,7 @@ public function __construct( public NotificationsConfig $notifications, public LinterConfig $linter, public CommentsConfig $comments, + public MetricsConfig $metrics, ) { } } diff --git a/src/Domain/Configuration/MetricsConfig.php b/src/Domain/Configuration/MetricsConfig.php new file mode 100644 index 000000000..2a8403620 --- /dev/null +++ b/src/Domain/Configuration/MetricsConfig.php @@ -0,0 +1,14 @@ +createLinterConfig($data['linter'] ?? []), $this->createCommentsConfig($data['comments'] ?? []), + $this->createMetricsConfig($data), ); } @@ -155,4 +158,50 @@ private function createCommentsConfig(array $config): CommentsConfig $messages, ); } + + /** + * @param array $config + */ + private function createMetricsConfig(array $config): MetricsConfig + { + if (! array_key_exists('metrics', $config)) { + return new MetricsConfig(new MetricsStorageConfig('null', 'null')); + } + + if (! is_array($config['metrics'])) { + throw ConfigInvalidException::invalidType('metrics', 'array', gettype($config['metrics'])); + } + + if (! array_key_exists('storage', $config['metrics'])) { + throw ConfigInvalidException::keyNotSet('metrics.storage'); + } + + if (! is_array($config['metrics']['storage'])) { + throw ConfigInvalidException::invalidType( + 'metrics.storage', + 'array', + gettype($config['metrics']['storage']), + ); + } + + if (count($config['metrics']['storage']) === 0) { + throw new ConfigInvalidException('Config[metrics.storage] must be not empty'); + } + + $storageName = array_key_first($config['metrics']['storage']); + $storage = $config['metrics']['storage'][$storageName]; + + if (empty($storage['address'])) { + throw new ConfigInvalidException('Config[metrics.storage.address] must be not empty'); + } + + if (! is_string($storage['address'])) { + throw new ConfigInvalidException('Config[metrics.storage.address] must be string'); + } + + return new MetricsConfig(new MetricsStorageConfig( + $storageName, + $storage['address'], + )); + } } diff --git a/src/Providers/MetricsProvider.php b/src/Providers/MetricsProvider.php index 06f7cfd4f..2d2071fd9 100644 --- a/src/Providers/MetricsProvider.php +++ b/src/Providers/MetricsProvider.php @@ -27,7 +27,7 @@ public function provide(): void $httpClient = $container->get(ClientFactory::class)->create($event->config->config->httpClient); return new PushGateway( - new Client($httpClient), + new Client($httpClient, $event->config->config->metrics->storage->address), new Renderer(), ); }); diff --git a/src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php b/src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php index 4fd90386d..267ea961e 100644 --- a/src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php +++ b/src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php @@ -9,12 +9,13 @@ class Client { public function __construct( private readonly HttpClient $http, + private readonly string $address, ) { } public function replace(string $job, string $data): void { - $url = "http://host.docker.internal:9091/metrics/job/{$job}"; + $url = sprintf("%s/metrics/job/%s", $this->address, $job); $this->http->sendRequest(new Request('POST', $url, body: $data)); } diff --git a/src/Shared/Metrics/Storage/PrometheusPushGateway/PushGateway.php b/src/Shared/Metrics/Storage/PrometheusPushGateway/PushGateway.php index f68cdd0d1..ea7b5e2c8 100644 --- a/src/Shared/Metrics/Storage/PrometheusPushGateway/PushGateway.php +++ b/src/Shared/Metrics/Storage/PrometheusPushGateway/PushGateway.php @@ -5,7 +5,7 @@ use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\MetricStorage; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Record; -class PushGateway implements MetricStorage +final class PushGateway implements MetricStorage { public function __construct( private readonly Client $client, From 3e388ba9fa09b8ed52a44ad4ad6c3ffcbed3005b Mon Sep 17 00:00:00 2001 From: artarts36 Date: Wed, 27 Sep 2023 20:56:59 +0300 Subject: [PATCH 10/34] add metric storage factory --- .../Configuration/MetricsStorageConfig.php | 6 ++++ .../Metrics/MetricStorageFactory.php | 31 +++++++++++++++++++ src/Providers/MetricsProvider.php | 9 +++--- 3 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 src/Infrastructure/Metrics/MetricStorageFactory.php diff --git a/src/Domain/Configuration/MetricsStorageConfig.php b/src/Domain/Configuration/MetricsStorageConfig.php index ddc263cc7..6b0af64d4 100644 --- a/src/Domain/Configuration/MetricsStorageConfig.php +++ b/src/Domain/Configuration/MetricsStorageConfig.php @@ -4,6 +4,12 @@ readonly class MetricsStorageConfig { + public const NAME_PROMETHEUS_PUSH_GATEWAY = 'prometheusPushGateway'; + public const NAME_NULL = 'null'; + + /** + * @param self::NAME_* $name + */ public function __construct( public string $name, public string $address, diff --git a/src/Infrastructure/Metrics/MetricStorageFactory.php b/src/Infrastructure/Metrics/MetricStorageFactory.php new file mode 100644 index 000000000..cda0d7b86 --- /dev/null +++ b/src/Infrastructure/Metrics/MetricStorageFactory.php @@ -0,0 +1,31 @@ +name === MetricsStorageConfig::NAME_PROMETHEUS_PUSH_GATEWAY) { + return new PushGateway( + new Client($this->httpClient, $config->address), + new Renderer(), + ); + } + + return new NullStorage(); + } +} diff --git a/src/Providers/MetricsProvider.php b/src/Providers/MetricsProvider.php index 2d2071fd9..14644ef11 100644 --- a/src/Providers/MetricsProvider.php +++ b/src/Providers/MetricsProvider.php @@ -5,11 +5,13 @@ use ArtARTs36\MergeRequestLinter\Application\Linter\Events\ConfigResolvedEvent; use ArtARTs36\MergeRequestLinter\Domain\Linter\LintFinishedEvent; use ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\ClientFactory; +use ArtARTs36\MergeRequestLinter\Infrastructure\Metrics\MetricStorageFactory; use ArtARTs36\MergeRequestLinter\Infrastructure\Metrics\RequestMetricFlusher; use ArtARTs36\MergeRequestLinter\Shared\Events\CallbackListener; use ArtARTs36\MergeRequestLinter\Shared\Events\EventManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\MetricStorage; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\NullStorage; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\Client; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\PushGateway; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\Renderer; @@ -18,7 +20,7 @@ final class MetricsProvider extends Provider { public function provide(): void - { + {; $this ->container ->get(EventManager::class) @@ -26,10 +28,7 @@ public function provide(): void $this->container->bind(MetricStorage::class, static function (ContainerInterface $container) use ($event) { $httpClient = $container->get(ClientFactory::class)->create($event->config->config->httpClient); - return new PushGateway( - new Client($httpClient, $event->config->config->metrics->storage->address), - new Renderer(), - ); + return (new MetricStorageFactory($httpClient))->create($event->config->config->metrics->storage); }); })); From ee82e2d1cba17babaccb56a1951c0b86f13b8a17 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Wed, 27 Sep 2023 21:05:20 +0300 Subject: [PATCH 11/34] add metric registerer --- src/Application/Linter/Linter.php | 4 +-- .../Http/Client/MetricableClient.php | 4 +-- .../Logger/MetricableLogger.php | 6 ++-- .../RequestFetcher/CiRequestFetcher.php | 6 ++-- .../Rule/Factories/ConditionRuleFactory.php | 4 +-- src/Providers/MetricsProvider.php | 4 --- src/Shared/Metrics/Manager/MetricManager.php | 20 +------------ .../Metrics/Manager/MetricRegisterer.php | 28 +++++++++++++++++++ 8 files changed, 41 insertions(+), 35 deletions(-) create mode 100644 src/Shared/Metrics/Manager/MetricRegisterer.php diff --git a/src/Application/Linter/Linter.php b/src/Application/Linter/Linter.php index c5871ca37..9749204f7 100644 --- a/src/Application/Linter/Linter.php +++ b/src/Application/Linter/Linter.php @@ -19,7 +19,7 @@ use ArtARTs36\MergeRequestLinter\Domain\Rule\Rule; use ArtARTs36\MergeRequestLinter\Domain\Rule\Rules; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricRegisterer; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Gauge; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Time\Timer; @@ -31,7 +31,7 @@ public function __construct( private Rules $rules, private LinterOptions $options, private EventDispatcherInterface $events, - private MetricManager $metrics, + private MetricRegisterer $metrics, ) { } diff --git a/src/Infrastructure/Http/Client/MetricableClient.php b/src/Infrastructure/Http/Client/MetricableClient.php index 536a7f3ad..69fee2bba 100644 --- a/src/Infrastructure/Http/Client/MetricableClient.php +++ b/src/Infrastructure/Http/Client/MetricableClient.php @@ -4,7 +4,7 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Http\Client; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricRegisterer; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Gauge; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Time\Timer; @@ -15,7 +15,7 @@ class MetricableClient implements Client { public function __construct( private readonly Client $client, - private readonly MetricManager $metrics, + private readonly MetricRegisterer $metrics, ) { $this->metrics->register(new MetricSubject( 'http', diff --git a/src/Infrastructure/Logger/MetricableLogger.php b/src/Infrastructure/Logger/MetricableLogger.php index 900c77ddf..6cad86c54 100644 --- a/src/Infrastructure/Logger/MetricableLogger.php +++ b/src/Infrastructure/Logger/MetricableLogger.php @@ -2,7 +2,7 @@ namespace ArtARTs36\MergeRequestLinter\Infrastructure\Logger; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricRegisterer; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Counter; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; @@ -18,11 +18,11 @@ public function __construct( ) { } - public static function create(MetricManager $manager): self + public static function create(MetricRegisterer $metrics): self { $counter = new IncCounter(); - $manager->registerWithSample(new MetricSubject('logger', 'logs_count', 'Logs count'), $counter); + $metrics->registerWithSample(new MetricSubject('logger', 'logs_count', 'Logs count'), $counter); return new self($counter); } diff --git a/src/Infrastructure/RequestFetcher/CiRequestFetcher.php b/src/Infrastructure/RequestFetcher/CiRequestFetcher.php index 4da52922e..56882a393 100644 --- a/src/Infrastructure/RequestFetcher/CiRequestFetcher.php +++ b/src/Infrastructure/RequestFetcher/CiRequestFetcher.php @@ -8,15 +8,15 @@ use ArtARTs36\MergeRequestLinter\Domain\Request\MergeRequest; use ArtARTs36\MergeRequestLinter\Domain\Request\MergeRequestFetcher; use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\CI\CiSystemFactory; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricRegisterer; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; final readonly class CiRequestFetcher implements MergeRequestFetcher { public function __construct( - private CiSystemFactory $systems, - private MetricManager $metrics, + private CiSystemFactory $systems, + private MetricRegisterer $metrics, ) { } diff --git a/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php b/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php index 1cc82feb7..013eabb5c 100644 --- a/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php +++ b/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php @@ -5,7 +5,7 @@ use ArtARTs36\MergeRequestLinter\Application\Rule\Rules\ConditionRule; use ArtARTs36\MergeRequestLinter\Domain\Rule\Rule; use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Condition\OperatorResolver; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricRegisterer; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Counter; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; @@ -21,7 +21,7 @@ public function __construct( ) { } - public static function new(OperatorResolver $operatorResolver, MetricManager $metrics): self + public static function new(OperatorResolver $operatorResolver, MetricRegisterer $metrics): self { $counter = new IncCounter(); diff --git a/src/Providers/MetricsProvider.php b/src/Providers/MetricsProvider.php index 14644ef11..91cbe71cb 100644 --- a/src/Providers/MetricsProvider.php +++ b/src/Providers/MetricsProvider.php @@ -11,10 +11,6 @@ use ArtARTs36\MergeRequestLinter\Shared\Events\EventManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\MetricStorage; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\NullStorage; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\Client; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\PushGateway; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\Renderer; use Psr\Container\ContainerInterface; final class MetricsProvider extends Provider diff --git a/src/Shared/Metrics/Manager/MetricManager.php b/src/Shared/Metrics/Manager/MetricManager.php index 1c071b0c0..cdac31ba1 100644 --- a/src/Shared/Metrics/Manager/MetricManager.php +++ b/src/Shared/Metrics/Manager/MetricManager.php @@ -3,31 +3,13 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Map; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSample; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Record; /** * Interface for managing metrics (time execution, etc.). */ -interface MetricManager +interface MetricManager extends MetricRegisterer { - /** - * Register metric subject. - */ - public function register(MetricSubject $subject): void; - - /** - * Register metric subject with sample. - */ - public function registerWithSample(MetricSubject $subject, MetricSample $sample): void; - - /** - * Add new metric sample. - * @return $this - */ - public function add(string $subjectIdentity, MetricSample $value): self; - /** * Describe metrics. * @return Map diff --git a/src/Shared/Metrics/Manager/MetricRegisterer.php b/src/Shared/Metrics/Manager/MetricRegisterer.php new file mode 100644 index 000000000..593d0a440 --- /dev/null +++ b/src/Shared/Metrics/Manager/MetricRegisterer.php @@ -0,0 +1,28 @@ + Date: Thu, 28 Sep 2023 03:45:14 +0300 Subject: [PATCH 12/34] refactor metrics --- src/Application/Linter/Linter.php | 17 ++++--- src/Application/Rule/Rules/ConditionRule.php | 12 +++-- .../Resolver/MetricableConfigResolver.php | 12 +++-- .../Http/Client/ClientFactory.php | 2 +- .../Http/Client/MetricableClient.php | 46 +++++++++++++------ .../Logger/MetricableLogger.php | 9 ++-- .../RequestFetcher/CiRequestFetcher.php | 10 ++-- .../Rule/Factories/ConditionRuleFactory.php | 15 +++--- .../Console/Application/Application.php | 40 ++++++++++------ .../Application/ApplicationFactory.php | 2 +- .../Console/Command/LintCommand.php | 8 ++-- .../Metrics/Collector/AbstractCollector.php | 16 +++++++ .../Metrics/Collector/AbstractVector.php | 45 ++++++++++++++++++ src/Shared/Metrics/Collector/Collector.php | 15 ++++++ src/Shared/Metrics/Collector/Counter.php | 34 ++++++++++++++ .../Metrics/Collector/CounterVector.php | 41 +++++++++++++++++ src/Shared/Metrics/Collector/Gauge.php | 31 +++++++++++++ src/Shared/Metrics/Collector/GaugeVector.php | 21 +++++++++ .../Metrics/Collector/LabeledCollector.php | 16 +++++++ src/Shared/Metrics/Collector/LabelsHash.php | 20 ++++++++ .../{Value => Collector}/MetricSubject.php | 2 +- .../{Value => Collector}/MetricType.php | 2 +- src/Shared/Metrics/Collector/Sample.php | 15 ++++++ .../Metrics/Manager/MemoryMetricManager.php | 41 +++++++++-------- src/Shared/Metrics/Manager/MetricManager.php | 4 +- .../Metrics/Manager/MetricRegisterer.php | 19 +++----- .../Metrics/Manager/NullMetricManager.php | 2 +- src/Shared/Metrics/Storage/MetricStorage.php | 6 +-- src/Shared/Metrics/Storage/NullStorage.php | 2 +- .../PrometheusPushGateway/PushGateway.php | 8 +--- .../PrometheusPushGateway/Renderer.php | 30 ++++++------ .../Metrics/Value/AbstractMetricSample.php | 17 ------- src/Shared/Metrics/Value/Counter.php | 14 ------ src/Shared/Metrics/Value/Gauge.php | 22 --------- src/Shared/Metrics/Value/IncCounter.php | 46 ------------------- src/Shared/Metrics/Value/MetricSample.php | 24 ---------- .../Metrics/Value/MetricSampleProxy.php | 36 --------------- src/Shared/Metrics/Value/NullCounter.php | 23 ---------- src/Shared/Metrics/Value/Record.php | 15 ------ .../Rule/Rules/ConditionRuleTest.php | 7 ++- .../Unit/Infrastructure/Rule/ResolverTest.php | 15 +++--- .../Shared/Metrics/Collector/CounterTest.php | 25 ++++++++++ .../Manager/MemoryMetricManagerTest.php | 11 +++-- .../Metrics/Value/MemoryCounterTest.php | 35 -------------- .../Metrics/Value/MetricSampleProxyTest.php | 29 ------------ 45 files changed, 458 insertions(+), 404 deletions(-) create mode 100644 src/Shared/Metrics/Collector/AbstractCollector.php create mode 100644 src/Shared/Metrics/Collector/AbstractVector.php create mode 100644 src/Shared/Metrics/Collector/Collector.php create mode 100644 src/Shared/Metrics/Collector/Counter.php create mode 100644 src/Shared/Metrics/Collector/CounterVector.php create mode 100644 src/Shared/Metrics/Collector/Gauge.php create mode 100644 src/Shared/Metrics/Collector/GaugeVector.php create mode 100644 src/Shared/Metrics/Collector/LabeledCollector.php create mode 100644 src/Shared/Metrics/Collector/LabelsHash.php rename src/Shared/Metrics/{Value => Collector}/MetricSubject.php (88%) rename src/Shared/Metrics/{Value => Collector}/MetricType.php (58%) create mode 100644 src/Shared/Metrics/Collector/Sample.php delete mode 100644 src/Shared/Metrics/Value/AbstractMetricSample.php delete mode 100644 src/Shared/Metrics/Value/Counter.php delete mode 100644 src/Shared/Metrics/Value/Gauge.php delete mode 100644 src/Shared/Metrics/Value/IncCounter.php delete mode 100644 src/Shared/Metrics/Value/MetricSample.php delete mode 100644 src/Shared/Metrics/Value/MetricSampleProxy.php delete mode 100644 src/Shared/Metrics/Value/NullCounter.php delete mode 100644 src/Shared/Metrics/Value/Record.php create mode 100644 tests/Unit/Shared/Metrics/Collector/CounterTest.php delete mode 100644 tests/Unit/Shared/Metrics/Value/MemoryCounterTest.php delete mode 100644 tests/Unit/Shared/Metrics/Value/MetricSampleProxyTest.php diff --git a/src/Application/Linter/Linter.php b/src/Application/Linter/Linter.php index 9749204f7..4dd3fa7dc 100644 --- a/src/Application/Linter/Linter.php +++ b/src/Application/Linter/Linter.php @@ -19,9 +19,9 @@ use ArtARTs36\MergeRequestLinter\Domain\Rule\Rule; use ArtARTs36\MergeRequestLinter\Domain\Rule\Rules; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Counter; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricRegisterer; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Gauge; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Time\Timer; use Psr\EventDispatcher\EventDispatcherInterface; @@ -39,7 +39,7 @@ public function run(MergeRequest $request): LintResult { $timer = Timer::start(); - $this->addMetricUsedRules(); + $this->addMetricUsedRules($request); $this->events->dispatch(new LintStartedEvent($request)); @@ -93,14 +93,17 @@ public function run(MergeRequest $request): LintResult return $result; } - private function addMetricUsedRules(): void + private function addMetricUsedRules(MergeRequest $request): void { $this ->metrics - ->registerWithSample( + ->register(new Counter( new MetricSubject('linter', 'used_rules', 'Used rules'), - new Gauge($this->rules->count()), - ); + [ + 'request' => (string) $request->uri, + ], + $this->rules->count(), + )); } /** diff --git a/src/Application/Rule/Rules/ConditionRule.php b/src/Application/Rule/Rules/ConditionRule.php index 1809bb872..f7730ef9c 100644 --- a/src/Application/Rule/Rules/ConditionRule.php +++ b/src/Application/Rule/Rules/ConditionRule.php @@ -5,15 +5,14 @@ use ArtARTs36\MergeRequestLinter\Domain\Condition\ConditionOperator; use ArtARTs36\MergeRequestLinter\Domain\Request\MergeRequest; use ArtARTs36\MergeRequestLinter\Domain\Rule\Rule; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Counter; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\NullCounter; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\CounterVector; class ConditionRule extends OneRuleDecoratorRule { public function __construct( Rule $rule, private readonly ConditionOperator $operator, - private readonly Counter $skippedRules = new NullCounter(), + private readonly CounterVector $skippedRules, ) { parent::__construct($rule); } @@ -21,7 +20,12 @@ public function __construct( public function lint(MergeRequest $request): array { if (! $this->operator->check($request)) { - $this->skippedRules->inc(); + $this + ->skippedRules + ->add([ + 'rule' => $this->getName(), + ]) + ->inc(); return []; } diff --git a/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php b/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php index c5ebfe046..812c6ffbb 100644 --- a/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php +++ b/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php @@ -4,9 +4,8 @@ use ArtARTs36\MergeRequestLinter\Domain\Configuration\Config; use ArtARTs36\MergeRequestLinter\Infrastructure\Configuration\User; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Gauge; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Time\Timer; class MetricableConfigResolver implements \ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Configuration\ConfigResolver @@ -23,9 +22,12 @@ public function resolve(User $user, int $configSubjects = Config::SUBJECT_ALL): $config = $this->resolver->resolve($user, $configSubjects); - $this->metrics->registerWithSample( - new MetricSubject('config', 'resolving_time', 'Duration of config resolving'), - new Gauge($timer->finish()), + $this->metrics->register( + new \ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Gauge( + new MetricSubject('config', 'resolving_time', 'Duration of config resolving'), + [], + $timer->finish()->seconds, + ), ); return $config; diff --git a/src/Infrastructure/Http/Client/ClientFactory.php b/src/Infrastructure/Http/Client/ClientFactory.php index ad876dc3e..82ace3715 100644 --- a/src/Infrastructure/Http/Client/ClientFactory.php +++ b/src/Infrastructure/Http/Client/ClientFactory.php @@ -23,7 +23,7 @@ public function create(HttpClientConfig $config): Client if ($config->type === HttpClientConfig::TYPE_GUZZLE) { $wrapper = new ClientGuzzleWrapper(new GuzzleClient($config->params), $this->logger); - return new MetricableClient($wrapper, $this->metrics); + return MetricableClient::make($wrapper, $this->metrics); } if ($config->type === HttpClientConfig::TYPE_NULL) { diff --git a/src/Infrastructure/Http/Client/MetricableClient.php b/src/Infrastructure/Http/Client/MetricableClient.php index 69fee2bba..13202f7c6 100644 --- a/src/Infrastructure/Http/Client/MetricableClient.php +++ b/src/Infrastructure/Http/Client/MetricableClient.php @@ -4,24 +4,32 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Http\Client; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\GaugeVector; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricRegisterer; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Gauge; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Time\Timer; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -class MetricableClient implements Client +final class MetricableClient implements Client { public function __construct( - private readonly Client $client, - private readonly MetricRegisterer $metrics, + private readonly Client $client, + private readonly GaugeVector $observer, ) { - $this->metrics->register(new MetricSubject( - 'http', - 'send_request', - 'Wait of response' - )); + } + + public static function make(Client $client, MetricRegisterer $metrics): self + { + $observer = $metrics->getOrRegister('http_send_request', static function () { + return new GaugeVector(new MetricSubject( + 'http', + 'send_request', + 'Wait of response' + )); + }); + + return new self($client, $observer); } public function sendRequest(RequestInterface $request): ResponseInterface @@ -30,9 +38,12 @@ public function sendRequest(RequestInterface $request): ResponseInterface $response = $this->client->sendRequest($request); - $this->metrics->add('http_send_request', new Gauge($timer->finish(), [ - 'host' => $request->getUri()->getHost(), - ])); + $this + ->observer + ->add([ + 'host' => $request->getUri()->getHost(), + ]) + ->set($timer->finish()->seconds); return $response; } @@ -43,9 +54,14 @@ public function sendAsyncRequests(array $requests): array $responses = $this->client->sendAsyncRequests($requests); - $hosts = $this->getHosts($requests)->implode(', '); + $hosts = $this->getHosts($requests)->implode(','); - $this->metrics->add('http_send_request', new Gauge($timer->finish())); + $this + ->observer + ->add([ + 'host' => $hosts, + ]) + ->set($timer->finish()->seconds); return $responses; } diff --git a/src/Infrastructure/Logger/MetricableLogger.php b/src/Infrastructure/Logger/MetricableLogger.php index 6cad86c54..b18fed367 100644 --- a/src/Infrastructure/Logger/MetricableLogger.php +++ b/src/Infrastructure/Logger/MetricableLogger.php @@ -2,10 +2,9 @@ namespace ArtARTs36\MergeRequestLinter\Infrastructure\Logger; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricRegisterer; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Counter; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Counter; use Psr\Log\LoggerInterface; use Psr\Log\LoggerTrait; @@ -20,9 +19,9 @@ public function __construct( public static function create(MetricRegisterer $metrics): self { - $counter = new IncCounter(); + $counter = new Counter(new MetricSubject('logger', 'logs_count', 'Logs count')); - $metrics->registerWithSample(new MetricSubject('logger', 'logs_count', 'Logs count'), $counter); + $metrics->register($counter); return new self($counter); } diff --git a/src/Infrastructure/RequestFetcher/CiRequestFetcher.php b/src/Infrastructure/RequestFetcher/CiRequestFetcher.php index 56882a393..78f6f595c 100644 --- a/src/Infrastructure/RequestFetcher/CiRequestFetcher.php +++ b/src/Infrastructure/RequestFetcher/CiRequestFetcher.php @@ -8,9 +8,9 @@ use ArtARTs36\MergeRequestLinter\Domain\Request\MergeRequest; use ArtARTs36\MergeRequestLinter\Domain\Request\MergeRequestFetcher; use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\CI\CiSystemFactory; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\CounterVector; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricRegisterer; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; final readonly class CiRequestFetcher implements MergeRequestFetcher { @@ -24,11 +24,13 @@ public function fetch(): MergeRequest { $ci = $this->systems->createCurrently(); - $this->metrics->registerWithSample( + $metric = CounterVector::once( new MetricSubject('ci', 'used_systems', 'Used CI System'), - IncCounter::one(['ci' => $ci->getName()]), + ['ci' => $ci->getName()], ); + $this->metrics->register($metric); + try { return $ci->getCurrentlyMergeRequest(); } catch (CurrentlyNotMergeRequestException $e) { diff --git a/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php b/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php index 013eabb5c..4db0a7c2f 100644 --- a/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php +++ b/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php @@ -5,10 +5,9 @@ use ArtARTs36\MergeRequestLinter\Application\Rule\Rules\ConditionRule; use ArtARTs36\MergeRequestLinter\Domain\Rule\Rule; use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Condition\OperatorResolver; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\CounterVector; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricRegisterer; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Counter; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; /** * @phpstan-import-type Conditions from OperatorResolver @@ -17,19 +16,19 @@ class ConditionRuleFactory { public function __construct( private readonly OperatorResolver $operatorResolver, - private readonly Counter $skippedRulesCounter, + private readonly CounterVector $skippedRulesCounter, ) { } public static function new(OperatorResolver $operatorResolver, MetricRegisterer $metrics): self { - $counter = new IncCounter(); - - $metrics->registerWithSample(new MetricSubject( + $counter = new CounterVector(new MetricSubject( 'linter', 'skipped_rules', 'Skipped rules', - ), $counter); + )); + + $metrics->register($counter); return new self($operatorResolver, $counter); } diff --git a/src/Presentation/Console/Application/Application.php b/src/Presentation/Console/Application/Application.php index 9907f2fc7..f88ab5886 100644 --- a/src/Presentation/Console/Application/Application.php +++ b/src/Presentation/Console/Application/Application.php @@ -2,10 +2,9 @@ namespace ArtARTs36\MergeRequestLinter\Presentation\Console\Application; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\GaugeVector; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Gauge; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSampleProxy; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Time\Timer; use ArtARTs36\MergeRequestLinter\Version; use Symfony\Component\Console\Command\Command; @@ -15,26 +14,37 @@ class Application extends \Symfony\Component\Console\Application { public function __construct( - private readonly MetricManager $metrics, + private readonly GaugeVector $observer, ) { parent::__construct('Merge Request Linter', Version::VERSION); } + public static function make(MetricManager $metrics): self + { + $observer = new GaugeVector(new MetricSubject( + 'console', + 'command_execution_time', + 'Command execution', + )); + + $metrics->register($observer); + + return new self( + $observer, + ); + } + protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output) { $timer = Timer::start(); - $this->metrics->registerWithSample( - new MetricSubject( - 'console', - 'execution_time', - 'Command execution', - ), - new MetricSampleProxy(function () use ($timer) { - return new Gauge($timer->finish()); - }, ['command' => $command->getName() ?? 'main']), - ); + $status = parent::doRunCommand($command, $input, $output); + + $this + ->observer + ->add(['command' => $command->getName() ?? 'main']) + ->set($timer->finish()->seconds); - return parent::doRunCommand($command, $input, $output); + return $status; } } diff --git a/src/Presentation/Console/Application/ApplicationFactory.php b/src/Presentation/Console/Application/ApplicationFactory.php index b49bd1dce..205f7409b 100644 --- a/src/Presentation/Console/Application/ApplicationFactory.php +++ b/src/Presentation/Console/Application/ApplicationFactory.php @@ -121,7 +121,7 @@ public function create(OutputInterface $output): Application $this->registerTextRenderer(); - $application = new Application($metrics); + $application = Application::make($metrics); $application->add(new LintCommand($metrics, $events, new LintTaskHandler( $configResolver, diff --git a/src/Presentation/Console/Command/LintCommand.php b/src/Presentation/Console/Command/LintCommand.php index 2838c276c..15155c9ec 100644 --- a/src/Presentation/Console/Command/LintCommand.php +++ b/src/Presentation/Console/Command/LintCommand.php @@ -18,8 +18,8 @@ use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; use ArtARTs36\MergeRequestLinter\Shared\Events\EventManager; use ArtARTs36\MergeRequestLinter\Shared\File\Bytes; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Collector; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Record; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -119,9 +119,9 @@ private function printMetrics(StyleInterface $style, LintResult $result, bool $f $this ->metrics ->describe() - ->mapToArray( - static fn ($_, Record $record) => new Metric($record->subject->wrapTitle(), isset($record->samples[0]) ? $record->samples[0]->getMetricValue() : 'null'), - ), + ->mapToArray(static function ($_, Collector $collector) { + return new Metric($collector->getSubject()->wrapTitle(), isset($collector->getSamples()[0]) ? $collector->getSamples()[0]->value : 'null'); + }), ); } diff --git a/src/Shared/Metrics/Collector/AbstractCollector.php b/src/Shared/Metrics/Collector/AbstractCollector.php new file mode 100644 index 000000000..088387285 --- /dev/null +++ b/src/Shared/Metrics/Collector/AbstractCollector.php @@ -0,0 +1,16 @@ +subject; + } +} diff --git a/src/Shared/Metrics/Collector/AbstractVector.php b/src/Shared/Metrics/Collector/AbstractVector.php new file mode 100644 index 000000000..4e6a8db51 --- /dev/null +++ b/src/Shared/Metrics/Collector/AbstractVector.php @@ -0,0 +1,45 @@ + */ + private array $collectors = []; + + /** + * @param callable(array $labels): C $factory + * @param array $labels + * @return C + */ + final protected function attach(callable $factory, array $labels): Collector + { + $labelsHash = LabelsHash::hash($labels); + + if (array_key_exists($labelsHash, $this->collectors)) { + return $this->collectors[$labelsHash]; + } + + $collector = $factory($labels); + + $this->collectors[$labelsHash] = $collector; + + return $collector; + } + + public function getSamples(): array + { + $samples = []; + + foreach ($this->collectors as $counter) { + foreach ($counter->getSamples() as $sample) { + $samples[] = $sample; + } + } + + return $samples; + } +} diff --git a/src/Shared/Metrics/Collector/Collector.php b/src/Shared/Metrics/Collector/Collector.php new file mode 100644 index 000000000..382fcf779 --- /dev/null +++ b/src/Shared/Metrics/Collector/Collector.php @@ -0,0 +1,15 @@ + + */ + public function getSamples(): array; +} diff --git a/src/Shared/Metrics/Collector/Counter.php b/src/Shared/Metrics/Collector/Counter.php new file mode 100644 index 000000000..22b460234 --- /dev/null +++ b/src/Shared/Metrics/Collector/Counter.php @@ -0,0 +1,34 @@ + $labels + */ + public function __construct( + MetricSubject $subject, + array $labels = [], + private int $value = 0, + ) { + parent::__construct($subject, $labels); + } + + public function inc(int $val = 1): void + { + $this->value += $val; + } + + public function getSamples(): array + { + return [ + new Sample($this->value, $this->labels), + ]; + } + + public function getMetricType(): MetricType + { + return MetricType::Counter; + } +} \ No newline at end of file diff --git a/src/Shared/Metrics/Collector/CounterVector.php b/src/Shared/Metrics/Collector/CounterVector.php new file mode 100644 index 000000000..22a75cb91 --- /dev/null +++ b/src/Shared/Metrics/Collector/CounterVector.php @@ -0,0 +1,41 @@ + + */ +final class CounterVector extends AbstractVector +{ + public static function null(): self + { + return new CounterVector(new MetricSubject('', '', '')); + } + + /** + * @param array $labels + */ + public static function once(MetricSubject $subject, array $labels): self + { + $vector = new CounterVector($subject); + + $vector->add($labels)->inc(); + + return $vector; + } + + /** + * @param array $labels + */ + public function add(array $labels): Counter + { + return $this->attach(function (array $labels) { + return new Counter($this->getSubject(), $labels); + }, $labels); + } + + public function getMetricType(): MetricType + { + return MetricType::Counter; + } +} diff --git a/src/Shared/Metrics/Collector/Gauge.php b/src/Shared/Metrics/Collector/Gauge.php new file mode 100644 index 000000000..ce9ed3eef --- /dev/null +++ b/src/Shared/Metrics/Collector/Gauge.php @@ -0,0 +1,31 @@ +value = $value; + } + + public function getSamples(): array + { + return [ + new Sample($this->value, $this->labels), + ]; + } + + public function getMetricType(): MetricType + { + return MetricType::Gauge; + } +} diff --git a/src/Shared/Metrics/Collector/GaugeVector.php b/src/Shared/Metrics/Collector/GaugeVector.php new file mode 100644 index 000000000..8f0cd23aa --- /dev/null +++ b/src/Shared/Metrics/Collector/GaugeVector.php @@ -0,0 +1,21 @@ + $labels + */ + public function add(array $labels): Gauge + { + return $this->attach(function (array $labels) { + return new Gauge($this->getSubject(), $labels); + }, $labels); + } + + public function getMetricType(): MetricType + { + return MetricType::Gauge; + } +} diff --git a/src/Shared/Metrics/Collector/LabeledCollector.php b/src/Shared/Metrics/Collector/LabeledCollector.php new file mode 100644 index 000000000..126877ede --- /dev/null +++ b/src/Shared/Metrics/Collector/LabeledCollector.php @@ -0,0 +1,16 @@ + $labels + */ + public function __construct( + MetricSubject $subject, + protected readonly array $labels, + ) { + parent::__construct($subject); + } +} diff --git a/src/Shared/Metrics/Collector/LabelsHash.php b/src/Shared/Metrics/Collector/LabelsHash.php new file mode 100644 index 000000000..c2038f0ad --- /dev/null +++ b/src/Shared/Metrics/Collector/LabelsHash.php @@ -0,0 +1,20 @@ + $labels + */ + public static function hash(array $labels): string + { + $hash = ''; + + foreach ($labels as $key => $value) { + $hash .= $key . '-' . $value; + } + + return $hash; + } +} diff --git a/src/Shared/Metrics/Value/MetricSubject.php b/src/Shared/Metrics/Collector/MetricSubject.php similarity index 88% rename from src/Shared/Metrics/Value/MetricSubject.php rename to src/Shared/Metrics/Collector/MetricSubject.php index fddd46c93..98cb4d935 100644 --- a/src/Shared/Metrics/Value/MetricSubject.php +++ b/src/Shared/Metrics/Collector/MetricSubject.php @@ -1,6 +1,6 @@ $labels + */ + public function __construct( + public readonly string|int|float $value, + public readonly array $labels, + ) { + } +} diff --git a/src/Shared/Metrics/Manager/MemoryMetricManager.php b/src/Shared/Metrics/Manager/MemoryMetricManager.php index 2863ce6f7..4065f6fc4 100644 --- a/src/Shared/Metrics/Manager/MemoryMetricManager.php +++ b/src/Shared/Metrics/Manager/MemoryMetricManager.php @@ -4,43 +4,44 @@ use ArtARTs36\MergeRequestLinter\Shared\DataStructure\ArrayMap; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Map; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSample; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Record; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Collector; -class MemoryMetricManager implements MetricManager +final class MemoryMetricManager implements MetricManager { /** - * @var array + * @var array */ - private array $records = []; + private array $collectors = []; - public function register(MetricSubject $subject): void + public function getOrRegister(string $key, callable $collectorCreator): Collector { - $this->records[$subject->identity()] = new Record($subject, []); - } + if (array_key_exists($key, $this->collectors)) { + return $this->collectors[$key]; + } - public function registerWithSample(MetricSubject $subject, MetricSample $sample): void - { - $this->records[$subject->identity()] = new Record($subject, [$sample]); + $collector = $collectorCreator(); + + $this->register($collector); + + return $collector; } - public function add(string $subjectIdentity, MetricSample $value): self + public function register(Collector $collector): void { - if (! isset($this->records[$subjectIdentity])) { + $key = $collector->getSubject()->identity(); + + if (array_key_exists($key, $this->collectors)) { throw new \LogicException(sprintf( - 'Metric with subject identity "%s" not registered', - $subjectIdentity, + 'Collector for metric with key "%s" already registered', + $key, )); } - $this->records[$subjectIdentity]->samples[] = $value; - - return $this; + $this->collectors[$key] = $collector; } public function describe(): Map { - return new ArrayMap($this->records); + return new ArrayMap($this->collectors); } } diff --git a/src/Shared/Metrics/Manager/MetricManager.php b/src/Shared/Metrics/Manager/MetricManager.php index cdac31ba1..6e52a6077 100644 --- a/src/Shared/Metrics/Manager/MetricManager.php +++ b/src/Shared/Metrics/Manager/MetricManager.php @@ -3,7 +3,7 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Map; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Record; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Collector; /** * Interface for managing metrics (time execution, etc.). @@ -12,7 +12,7 @@ interface MetricManager extends MetricRegisterer { /** * Describe metrics. - * @return Map + * @return Map */ public function describe(): Map; } diff --git a/src/Shared/Metrics/Manager/MetricRegisterer.php b/src/Shared/Metrics/Manager/MetricRegisterer.php index 593d0a440..087bd9832 100644 --- a/src/Shared/Metrics/Manager/MetricRegisterer.php +++ b/src/Shared/Metrics/Manager/MetricRegisterer.php @@ -2,8 +2,7 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSample; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Collector; /** * Interface for managing metrics (time execution, etc.). @@ -11,18 +10,14 @@ interface MetricRegisterer { /** - * Register metric subject. + * @template C of Collector + * @param callable(): C $collectorCreator + * @return C */ - public function register(MetricSubject $subject): void; + public function getOrRegister(string $key, callable $collectorCreator): Collector; /** - * Register metric subject with sample. + * Register collector. */ - public function registerWithSample(MetricSubject $subject, MetricSample $sample): void; - - /** - * Add new metric sample. - * @return $this - */ - public function add(string $subjectIdentity, MetricSample $value): self; + public function register(Collector $collector): void; } diff --git a/src/Shared/Metrics/Manager/NullMetricManager.php b/src/Shared/Metrics/Manager/NullMetricManager.php index 4860465cf..e4db3c2e7 100644 --- a/src/Shared/Metrics/Manager/NullMetricManager.php +++ b/src/Shared/Metrics/Manager/NullMetricManager.php @@ -3,8 +3,8 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSample; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; /** * @codeCoverageIgnore diff --git a/src/Shared/Metrics/Storage/MetricStorage.php b/src/Shared/Metrics/Storage/MetricStorage.php index 1b0e09d21..2ad28b15c 100644 --- a/src/Shared/Metrics/Storage/MetricStorage.php +++ b/src/Shared/Metrics/Storage/MetricStorage.php @@ -2,7 +2,7 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Record; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Collector; /** * Metric Storage. @@ -12,7 +12,7 @@ interface MetricStorage /** * Commit metric records. * - * @param array $records + * @param array $collectors */ - public function commit(string $id, array $records): void; + public function commit(string $id, array $collectors): void; } diff --git a/src/Shared/Metrics/Storage/NullStorage.php b/src/Shared/Metrics/Storage/NullStorage.php index 8e264b736..0ebb6bafe 100644 --- a/src/Shared/Metrics/Storage/NullStorage.php +++ b/src/Shared/Metrics/Storage/NullStorage.php @@ -4,7 +4,7 @@ final class NullStorage implements MetricStorage { - public function commit(string $id, array $records): void + public function commit(string $id, array $collectors): void { // null } diff --git a/src/Shared/Metrics/Storage/PrometheusPushGateway/PushGateway.php b/src/Shared/Metrics/Storage/PrometheusPushGateway/PushGateway.php index ea7b5e2c8..f81ab0f21 100644 --- a/src/Shared/Metrics/Storage/PrometheusPushGateway/PushGateway.php +++ b/src/Shared/Metrics/Storage/PrometheusPushGateway/PushGateway.php @@ -3,7 +3,6 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\MetricStorage; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Record; final class PushGateway implements MetricStorage { @@ -13,12 +12,9 @@ public function __construct( ) { } - /** - * @param iterable $records - */ - public function commit(string $id, iterable $records): void + public function commit(string $id, iterable $collectors): void { - $data = $this->renderer->render($records); + $data = $this->renderer->render($collectors); $this->client->replace($id, $data); } diff --git a/src/Shared/Metrics/Storage/PrometheusPushGateway/Renderer.php b/src/Shared/Metrics/Storage/PrometheusPushGateway/Renderer.php index 9ac30a81b..d797de33b 100644 --- a/src/Shared/Metrics/Storage/PrometheusPushGateway/Renderer.php +++ b/src/Shared/Metrics/Storage/PrometheusPushGateway/Renderer.php @@ -2,32 +2,36 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSample; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Record; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Collector; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Sample; use ArtARTs36\Str\Facade\Str; class Renderer { /** - * @param iterable $records + * @param iterable $collectors */ - public function render(iterable $records): string + public function render(iterable $collectors): string { $content = []; - foreach ($records as $metric) { - if (! isset($metric->samples[0])) { + foreach ($collectors as $collector) { + $samples = $collector->getSamples(); + + if (count($samples) === 0) { continue; } - $content[] = "# HELP {$metric->subject->identity()} The number of items in the queue."; - $content[] = "# TYPE {$metric->subject->identity()} {$metric->samples[0]->getMetricType()->value}"; + $key = $collector->getSubject()->identity(); + + $content[] = "# HELP $key The number of items in the queue."; + $content[] = "# TYPE $key {$collector->getMetricType()->value}"; $content[] = "\n"; - foreach ($metric->samples as $sample) { + foreach ($samples as $sample) { $labelsString = $this->collectLabels($sample); - $content[] = "{$metric->subject->identity()}{$labelsString} {$sample->getMetricValue()}"; + $content[] = "$key$labelsString $sample->value"; } $content[] = "\n"; @@ -36,14 +40,14 @@ public function render(iterable $records): string return Str::implode("\n", $content); } - private function collectLabels(MetricSample $metric): string + private function collectLabels(Sample $metric): string { - if (count($metric->getMetricLabels()) === 0) { + if (count($metric->labels) === 0) { return ''; } $labelsString = '{'; - $labels = $metric->getMetricLabels(); + $labels = $metric->labels; foreach ($labels as $labelKey => $labelValue) { $labelsString .= sprintf( diff --git a/src/Shared/Metrics/Value/AbstractMetricSample.php b/src/Shared/Metrics/Value/AbstractMetricSample.php deleted file mode 100644 index 50f7551eb..000000000 --- a/src/Shared/Metrics/Value/AbstractMetricSample.php +++ /dev/null @@ -1,17 +0,0 @@ - */ - protected array $labels = []; - - /** - * @return array - */ - public function getMetricLabels(): array - { - return $this->labels; - } -} diff --git a/src/Shared/Metrics/Value/Counter.php b/src/Shared/Metrics/Value/Counter.php deleted file mode 100644 index 4bedd088c..000000000 --- a/src/Shared/Metrics/Value/Counter.php +++ /dev/null @@ -1,14 +0,0 @@ -value"; - } -} diff --git a/src/Shared/Metrics/Value/IncCounter.php b/src/Shared/Metrics/Value/IncCounter.php deleted file mode 100644 index 18e247857..000000000 --- a/src/Shared/Metrics/Value/IncCounter.php +++ /dev/null @@ -1,46 +0,0 @@ - $labels - */ - public function __construct( - private int $count = 0, - protected array $labels = [] - ) { - } - - /** - * @param array $labels - */ - public static function one(array $labels = []): self - { - return new self(1, $labels); - } - - /** - * @param \Countable|array $countable - */ - public static function create(\Countable|array $countable): self - { - return new self(count($countable)); - } - - public function inc(): void - { - ++$this->count; - } - - public function getMetricType(): MetricType - { - return MetricType::Counter; - } - - public function getMetricValue(): string - { - return "$this->count"; - } -} diff --git a/src/Shared/Metrics/Value/MetricSample.php b/src/Shared/Metrics/Value/MetricSample.php deleted file mode 100644 index 0df2b778c..000000000 --- a/src/Shared/Metrics/Value/MetricSample.php +++ /dev/null @@ -1,24 +0,0 @@ - - */ - public function getMetricLabels(): array; - - /** - * Get metric value in string. - */ - public function getMetricValue(): string; -} diff --git a/src/Shared/Metrics/Value/MetricSampleProxy.php b/src/Shared/Metrics/Value/MetricSampleProxy.php deleted file mode 100644 index 902bcf19b..000000000 --- a/src/Shared/Metrics/Value/MetricSampleProxy.php +++ /dev/null @@ -1,36 +0,0 @@ -retrieve()->getMetricType(); - } - - public function getMetricValue(): string - { - return $this->retrieve()->getMetricValue(); - } - - private function retrieve(): MetricSample - { - if ($this->metric === null) { - $this->metric = ($this->callback)(); - } - - return $this->metric; - } -} diff --git a/src/Shared/Metrics/Value/NullCounter.php b/src/Shared/Metrics/Value/NullCounter.php deleted file mode 100644 index cef8f6cd0..000000000 --- a/src/Shared/Metrics/Value/NullCounter.php +++ /dev/null @@ -1,23 +0,0 @@ - $samples - */ - public function __construct( - public readonly MetricSubject $subject, - public array $samples, - ) { - } -} diff --git a/tests/Unit/Application/Rule/Rules/ConditionRuleTest.php b/tests/Unit/Application/Rule/Rules/ConditionRuleTest.php index e513f2a34..2400ce3a0 100644 --- a/tests/Unit/Application/Rule/Rules/ConditionRuleTest.php +++ b/tests/Unit/Application/Rule/Rules/ConditionRuleTest.php @@ -4,7 +4,7 @@ use ArtARTs36\MergeRequestLinter\Application\Rule\Rules\ConditionRule; use ArtARTs36\MergeRequestLinter\Domain\Condition\ConditionOperator; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\CounterVector; use ArtARTs36\MergeRequestLinter\Tests\Mocks\MockConditionOperator; use ArtARTs36\MergeRequestLinter\Tests\Mocks\SuccessRule; use ArtARTs36\MergeRequestLinter\Tests\TestCase; @@ -35,7 +35,7 @@ public function testLintIncSkipRulesMetric(ConditionOperator $operator, int $exp $rule = new ConditionRule( new SuccessRule(), $operator, - $counter = new IncCounter(), + $counter = CounterVector::null(), ); $rule->lint($this->makeMergeRequest()); @@ -52,6 +52,7 @@ public function testGetDefinition(): void $rule = new ConditionRule( $subRule = new SuccessRule(), MockConditionOperator::true(), + CounterVector::null(), ); self::assertEquals($subRule->getDefinition(), $rule->getDefinition()); @@ -66,6 +67,7 @@ public function testGetName(): void $rule = new ConditionRule( $subRule = new SuccessRule(), MockConditionOperator::true(), + CounterVector::null(), ); self::assertEquals($subRule->getName(), $rule->getName()); @@ -80,6 +82,7 @@ public function testGetDecoratedRules(): void $rule = new ConditionRule( $subRule = new SuccessRule(), MockConditionOperator::true(), + CounterVector::null(), ); self::assertEquals([$subRule], $rule->getDecoratedRules()); diff --git a/tests/Unit/Infrastructure/Rule/ResolverTest.php b/tests/Unit/Infrastructure/Rule/ResolverTest.php index 76bd296e1..303cdd04b 100644 --- a/tests/Unit/Infrastructure/Rule/ResolverTest.php +++ b/tests/Unit/Infrastructure/Rule/ResolverTest.php @@ -11,6 +11,7 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Rule\Factories\RuleFactory; use ArtARTs36\MergeRequestLinter\Infrastructure\Rule\Resolver; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\ArrayMap; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\CounterVector; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\NullCounter; use ArtARTs36\MergeRequestLinter\Shared\Reflection\Instantiator\Finder; use ArtARTs36\MergeRequestLinter\Shared\Reflection\ParameterMapBuilder; @@ -31,7 +32,7 @@ public function testResolveOnRuleNotFound(): void { $resolver = new Resolver(new ArrayMap([ 'success' => SuccessRule::class, - ]), new RuleFactory(new ParameterMapBuilder(new MockTypeResolver()), new Finder()), new ConditionRuleFactory(new MockOperatorResolver(), new NullCounter())); + ]), new RuleFactory(new ParameterMapBuilder(new MockTypeResolver()), new Finder()), new ConditionRuleFactory(new MockOperatorResolver(), CounterVector::null())); self::expectException(RuleNotFound::class); @@ -47,7 +48,7 @@ public function testResolveOnManyConfigurations(): void { $resolver = new Resolver(new ArrayMap([ 'success' => SuccessRule::class, - ]), new RuleFactory(new ParameterMapBuilder(new MockTypeResolver()), new Finder()), new ConditionRuleFactory(new MockOperatorResolver(), new NullCounter())); + ]), new RuleFactory(new ParameterMapBuilder(new MockTypeResolver()), new Finder()), new ConditionRuleFactory(new MockOperatorResolver(), CounterVector::null())); $gotRule = $resolver->resolve('success', [ [ @@ -69,7 +70,7 @@ public function testResolveNonCriticalRule(): void { $resolver = new Resolver(new ArrayMap([ 'success' => SuccessRule::class, - ]), new RuleFactory(new ParameterMapBuilder(new MockTypeResolver()), new Finder()), new ConditionRuleFactory(new MockOperatorResolver(), new NullCounter())); + ]), new RuleFactory(new ParameterMapBuilder(new MockTypeResolver()), new Finder()), new ConditionRuleFactory(new MockOperatorResolver(), CounterVector::null())); $gotRule = $resolver->resolve('success', ['critical' => false]); @@ -84,7 +85,7 @@ public function testResolveOnCriticalParamNonBoolean(): void { $resolver = new Resolver(new ArrayMap([ 'success' => SuccessRule::class, - ]), new RuleFactory(new ParameterMapBuilder(new MockTypeResolver()), new Finder()), new ConditionRuleFactory(new MockOperatorResolver(), new NullCounter())); + ]), new RuleFactory(new ParameterMapBuilder(new MockTypeResolver()), new Finder()), new ConditionRuleFactory(new MockOperatorResolver(), CounterVector::null())); self::expectExceptionMessage('Failed to create Rule with name "success": param "critical" must be boolean'); @@ -107,7 +108,7 @@ public function testResolveConditionRule(): void ), new Finder(), ), - new ConditionRuleFactory(new MockOperatorResolver(MockConditionOperator::true()), new NullCounter()), + new ConditionRuleFactory(new MockOperatorResolver(MockConditionOperator::true()), CounterVector::null()), ); $gotRule = $resolver->resolve('success', ['when' => [ @@ -135,7 +136,7 @@ public function testResolveOnParamWhenNonArray(): void ), new Finder(), ), - new ConditionRuleFactory(new MockOperatorResolver(MockConditionOperator::true()), new NullCounter()), + new ConditionRuleFactory(new MockOperatorResolver(MockConditionOperator::true()), CounterVector::null()), ); self::expectExceptionMessage('Config[rules.success.when] has invalid type. Expected type: array, actual: string'); @@ -160,7 +161,7 @@ public function testResolveOnFactoryWhenFailed(): void 'success' => SuccessRule::class, ]), $ruleFactory, - new ConditionRuleFactory(new MockOperatorResolver(MockConditionOperator::true()), new NullCounter()), + new ConditionRuleFactory(new MockOperatorResolver(MockConditionOperator::true()), CounterVector::null()), ); self::expectException(CreatingRuleException::class); diff --git a/tests/Unit/Shared/Metrics/Collector/CounterTest.php b/tests/Unit/Shared/Metrics/Collector/CounterTest.php new file mode 100644 index 000000000..415893b7b --- /dev/null +++ b/tests/Unit/Shared/Metrics/Collector/CounterTest.php @@ -0,0 +1,25 @@ +inc(); + + self::assertEquals([new Sample(1, [])], $counter->getSamples()); + } +} diff --git a/tests/Unit/Shared/Metrics/Manager/MemoryMetricManagerTest.php b/tests/Unit/Shared/Metrics/Manager/MemoryMetricManagerTest.php index 340bcaeb6..539a42ed1 100644 --- a/tests/Unit/Shared/Metrics/Manager/MemoryMetricManagerTest.php +++ b/tests/Unit/Shared/Metrics/Manager/MemoryMetricManagerTest.php @@ -2,9 +2,10 @@ namespace ArtARTs36\MergeRequestLinter\Tests\Unit\Shared\Metrics\Manager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\CounterVector; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MemoryMetricManager; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Record; use ArtARTs36\MergeRequestLinter\Shared\Time\LocalClock; use ArtARTs36\MergeRequestLinter\Tests\Mocks\QueueClock; @@ -13,16 +14,16 @@ final class MemoryMetricManagerTest extends TestCase { /** - * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MemoryMetricManager::add + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MemoryMetricManager::register * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MemoryMetricManager::__construct */ - public function testAdd(): void + public function testRegister(): void { - $manager = new MemoryMetricManager(LocalClock::utc()); + $manager = new MemoryMetricManager(); self::assertCount(0, $manager->describe()); - $manager->add(new MetricSubject('', '', ''), new IncCounter()); + $manager->register(CounterVector::once(new MetricSubject('', '', ''), [])); self::assertCount(1, $manager->describe()); } diff --git a/tests/Unit/Shared/Metrics/Value/MemoryCounterTest.php b/tests/Unit/Shared/Metrics/Value/MemoryCounterTest.php deleted file mode 100644 index 28729e91e..000000000 --- a/tests/Unit/Shared/Metrics/Value/MemoryCounterTest.php +++ /dev/null @@ -1,35 +0,0 @@ -getMetricValue()); - } - - /** - * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter::inc - * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter::getMetricValue - * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter::__construct - */ - public function testInc(): void - { - $counter = new IncCounter(2); - - $counter->inc(); - - self::assertEquals('3', $counter->getMetricValue()); - } -} diff --git a/tests/Unit/Shared/Metrics/Value/MetricSampleProxyTest.php b/tests/Unit/Shared/Metrics/Value/MetricSampleProxyTest.php deleted file mode 100644 index 68a678d6c..000000000 --- a/tests/Unit/Shared/Metrics/Value/MetricSampleProxyTest.php +++ /dev/null @@ -1,29 +0,0 @@ -getMetricValue()); - } -} From adcb011af0283c654ff2f560fda87c3c5d837a69 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 04:06:01 +0300 Subject: [PATCH 13/34] add metric handler for rule events --- .../Metrics/RuleLintStateMetricHandler.php | 53 +++++++++++++++++++ src/Providers/MetricsProvider.php | 21 ++++++++ 2 files changed, 74 insertions(+) create mode 100644 src/Application/Rule/Metrics/RuleLintStateMetricHandler.php diff --git a/src/Application/Rule/Metrics/RuleLintStateMetricHandler.php b/src/Application/Rule/Metrics/RuleLintStateMetricHandler.php new file mode 100644 index 000000000..8a76a047e --- /dev/null +++ b/src/Application/Rule/Metrics/RuleLintStateMetricHandler.php @@ -0,0 +1,53 @@ +register($counter); + + return new self($counter); + } + + public function handle(RuleWasSuccessfulEvent|RuleWasFailedEvent $event): void + { + if ($event instanceof RuleWasSuccessfulEvent) { + $this + ->counter + ->add([ + 'rule' => $event->ruleName, + 'state' => 'true', + ]) + ->inc(); + + return; + } + + $this + ->counter + ->add([ + 'rule' => $event->ruleName, + 'state' => 'fail', + ]) + ->inc(); + } +} diff --git a/src/Providers/MetricsProvider.php b/src/Providers/MetricsProvider.php index 91cbe71cb..8c36192b0 100644 --- a/src/Providers/MetricsProvider.php +++ b/src/Providers/MetricsProvider.php @@ -3,7 +3,10 @@ namespace ArtARTs36\MergeRequestLinter\Providers; use ArtARTs36\MergeRequestLinter\Application\Linter\Events\ConfigResolvedEvent; +use ArtARTs36\MergeRequestLinter\Application\Rule\Metrics\RuleLintStateMetricHandler; use ArtARTs36\MergeRequestLinter\Domain\Linter\LintFinishedEvent; +use ArtARTs36\MergeRequestLinter\Domain\Linter\RuleWasFailedEvent; +use ArtARTs36\MergeRequestLinter\Domain\Linter\RuleWasSuccessfulEvent; use ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\ClientFactory; use ArtARTs36\MergeRequestLinter\Infrastructure\Metrics\MetricStorageFactory; use ArtARTs36\MergeRequestLinter\Infrastructure\Metrics\RequestMetricFlusher; @@ -39,5 +42,23 @@ public function provide(): void $flusher->flush($event->request); })); + + $this->container->bind(RuleLintStateMetricHandler::class, static function (ContainerInterface $container) { + return RuleLintStateMetricHandler::make($container->get(MetricManager::class)); + }); + + $this + ->container + ->get(EventManager::class) + ->listen(RuleWasSuccessfulEvent::class, new CallbackListener('rule_lint_successful_state_metric', function (RuleWasSuccessfulEvent $event) { + $this->container->get(RuleLintStateMetricHandler::class)->handle($event); + })); + + $this + ->container + ->get(EventManager::class) + ->listen(RuleWasFailedEvent::class, new CallbackListener('rule_lint_failed_state_metric', function (RuleWasFailedEvent $event) { + $this->container->get(RuleLintStateMetricHandler::class)->handle($event); + })); } } From 72cfb7f1df0517dfda89eadec83ebaba4407faa4 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 04:17:57 +0300 Subject: [PATCH 14/34] fix stat-analyse issues --- .../Http/Client/MetricableClient.php | 12 +++++------ src/Shared/Metrics/Collector/GaugeVector.php | 3 +++ .../Metrics/Manager/MemoryMetricManager.php | 15 +++++++++++--- .../Metrics/Manager/MetricRegisterer.php | 4 ++-- .../Metrics/Manager/NullMetricManager.php | 20 ++++++++++++------- .../PrometheusPushGateway/Renderer.php | 2 +- 6 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/Infrastructure/Http/Client/MetricableClient.php b/src/Infrastructure/Http/Client/MetricableClient.php index 13202f7c6..f31f6295d 100644 --- a/src/Infrastructure/Http/Client/MetricableClient.php +++ b/src/Infrastructure/Http/Client/MetricableClient.php @@ -21,13 +21,11 @@ public function __construct( public static function make(Client $client, MetricRegisterer $metrics): self { - $observer = $metrics->getOrRegister('http_send_request', static function () { - return new GaugeVector(new MetricSubject( - 'http', - 'send_request', - 'Wait of response' - )); - }); + $observer = $metrics->getOrRegister(new GaugeVector(new MetricSubject( + 'http', + 'send_request', + 'Wait of response' + ))); return new self($client, $observer); } diff --git a/src/Shared/Metrics/Collector/GaugeVector.php b/src/Shared/Metrics/Collector/GaugeVector.php index 8f0cd23aa..09217eda5 100644 --- a/src/Shared/Metrics/Collector/GaugeVector.php +++ b/src/Shared/Metrics/Collector/GaugeVector.php @@ -2,6 +2,9 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector; +/** + * @template-extends AbstractVector + */ final class GaugeVector extends AbstractVector { /** diff --git a/src/Shared/Metrics/Manager/MemoryMetricManager.php b/src/Shared/Metrics/Manager/MemoryMetricManager.php index 4065f6fc4..6cc545c32 100644 --- a/src/Shared/Metrics/Manager/MemoryMetricManager.php +++ b/src/Shared/Metrics/Manager/MemoryMetricManager.php @@ -13,14 +13,23 @@ final class MemoryMetricManager implements MetricManager */ private array $collectors = []; - public function getOrRegister(string $key, callable $collectorCreator): Collector + public function getOrRegister(Collector $collector): Collector { + $key = $collector->getSubject()->identity(); + if (array_key_exists($key, $this->collectors)) { + if (get_class($this->collectors[$key]) !== get_class($collector)) { + throw new \LogicException(sprintf( + 'Already registered collector "%s" with type "%s". Expected type: %s', + $key, + $this->collectors[$key]::class, + $collector::class, + )); + } + return $this->collectors[$key]; } - $collector = $collectorCreator(); - $this->register($collector); return $collector; diff --git a/src/Shared/Metrics/Manager/MetricRegisterer.php b/src/Shared/Metrics/Manager/MetricRegisterer.php index 087bd9832..cf0690f97 100644 --- a/src/Shared/Metrics/Manager/MetricRegisterer.php +++ b/src/Shared/Metrics/Manager/MetricRegisterer.php @@ -11,10 +11,10 @@ interface MetricRegisterer { /** * @template C of Collector - * @param callable(): C $collectorCreator + * @param C $collector * @return C */ - public function getOrRegister(string $key, callable $collectorCreator): Collector; + public function getOrRegister(Collector $collector): Collector; /** * Register collector. diff --git a/src/Shared/Metrics/Manager/NullMetricManager.php b/src/Shared/Metrics/Manager/NullMetricManager.php index e4db3c2e7..6b8cbf8f9 100644 --- a/src/Shared/Metrics/Manager/NullMetricManager.php +++ b/src/Shared/Metrics/Manager/NullMetricManager.php @@ -2,22 +2,28 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager; -use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSample; +use ArtARTs36\MergeRequestLinter\Shared\DataStructure\ArrayMap; +use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Map; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Collector; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\CounterVector; /** * @codeCoverageIgnore */ class NullMetricManager implements MetricManager { - public function add(MetricSubject $subject, MetricSample $value): MetricManager + public function getOrRegister(Collector $collector): Collector { - return $this; + return $collector; } - public function describe(): Arrayee + public function register(Collector $collector): void { - return new Arrayee([]); + // + } + + public function describe(): Map + { + return new ArrayMap([]); } } diff --git a/src/Shared/Metrics/Storage/PrometheusPushGateway/Renderer.php b/src/Shared/Metrics/Storage/PrometheusPushGateway/Renderer.php index d797de33b..fa4d3d977 100644 --- a/src/Shared/Metrics/Storage/PrometheusPushGateway/Renderer.php +++ b/src/Shared/Metrics/Storage/PrometheusPushGateway/Renderer.php @@ -53,7 +53,7 @@ private function collectLabels(Sample $metric): string $labelsString .= sprintf( '%s=%s', $labelKey, - is_string($labelValue) ? ('"'. $labelValue .'"') : $labelValue, + is_numeric($labelValue) ? $labelValue : ('"'. $labelValue .'"'), ); if (next($labels) !== false) { From f1413ffceff3f99c1553e04dc93bb44b011ab6aa Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 04:36:02 +0300 Subject: [PATCH 15/34] print metrics --- .../Http/Client/MetricableClient.php | 3 +- .../RequestFetcher/CiRequestFetcher.php | 2 +- .../Console/Command/LintCommand.php | 30 ++++++++++++++----- .../Metrics/Collector/MetricSubject.php | 24 +++++++++++++-- 4 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/Infrastructure/Http/Client/MetricableClient.php b/src/Infrastructure/Http/Client/MetricableClient.php index f31f6295d..58622559c 100644 --- a/src/Infrastructure/Http/Client/MetricableClient.php +++ b/src/Infrastructure/Http/Client/MetricableClient.php @@ -24,7 +24,8 @@ public static function make(Client $client, MetricRegisterer $metrics): self $observer = $metrics->getOrRegister(new GaugeVector(new MetricSubject( 'http', 'send_request', - 'Wait of response' + 'Wait of response', + 'Wait of response :host:', ))); return new self($client, $observer); diff --git a/src/Infrastructure/RequestFetcher/CiRequestFetcher.php b/src/Infrastructure/RequestFetcher/CiRequestFetcher.php index 78f6f595c..13ecc2b3b 100644 --- a/src/Infrastructure/RequestFetcher/CiRequestFetcher.php +++ b/src/Infrastructure/RequestFetcher/CiRequestFetcher.php @@ -25,7 +25,7 @@ public function fetch(): MergeRequest $ci = $this->systems->createCurrently(); $metric = CounterVector::once( - new MetricSubject('ci', 'used_systems', 'Used CI System'), + new MetricSubject('ci', 'used_systems', 'Used CI systems', 'Used CI systems: :ci:'), ['ci' => $ci->getName()], ); diff --git a/src/Presentation/Console/Command/LintCommand.php b/src/Presentation/Console/Command/LintCommand.php index 15155c9ec..90b105a16 100644 --- a/src/Presentation/Console/Command/LintCommand.php +++ b/src/Presentation/Console/Command/LintCommand.php @@ -115,14 +115,28 @@ private function printMetrics(StyleInterface $style, LintResult $result, bool $f ]); if ($fullMetrics) { - $metrics = $metrics->merge( - $this - ->metrics - ->describe() - ->mapToArray(static function ($_, Collector $collector) { - return new Metric($collector->getSubject()->wrapTitle(), isset($collector->getSamples()[0]) ? $collector->getSamples()[0]->value : 'null'); - }), - ); + $readMetrics = []; + + foreach ($this->metrics->describe() as $collector) { + if ($collector->getSubject()->key === 'rule_lint_state') { + continue; + } + + foreach ($collector->getSamples() as $sample) { + $metric = new Metric( + $collector->getSubject()->readableTitle($sample->labels), + "$sample->value", + ); + + if ($collector->getSubject()->category === 'linter') { + array_unshift($readMetrics, $metric); + } else { + $readMetrics[] = $metric; + } + } + } + + $metrics = $metrics->merge($readMetrics); } $this->metricPrinter->print(new SymfonyTablePrinter($style), $metrics); diff --git a/src/Shared/Metrics/Collector/MetricSubject.php b/src/Shared/Metrics/Collector/MetricSubject.php index 98cb4d935..06a5207e0 100644 --- a/src/Shared/Metrics/Collector/MetricSubject.php +++ b/src/Shared/Metrics/Collector/MetricSubject.php @@ -13,6 +13,7 @@ public function __construct( public string $category, public string $key, public string $title, + public string $placeholder = '', ) { } @@ -21,8 +22,27 @@ public function identity(): string return sprintf('%s_%s', $this->category, $this->key); } - public function wrapTitle(): string + /** + * @param array $labels + */ + public function readableTitle(array $labels): string { - return sprintf('[%s] %s', Str::upFirstSymbol($this->category), $this->title); + if (Str::isEmpty($this->placeholder)) { + return sprintf('[%s] %s', Str::upFirstSymbol($this->category), $this->title); + } + + $replacesKeys = []; + $replacesValues = []; + + foreach ($labels as $key => $value) { + $replacesKeys[] = ':' . $key . ':'; + $replacesValues[] = $value; + } + + return sprintf( + '[%s] %s', + Str::upFirstSymbol($this->category), + str_replace($replacesKeys, $replacesValues, $this->placeholder), + ); } } From 714222e3d5690fb9f4afc4727666242fff2c73e3 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 04:40:30 +0300 Subject: [PATCH 16/34] fix stat analyse --- src/Domain/Configuration/MetricsStorageConfig.php | 7 ++++++- .../Configuration/Loader/Mapper/ArrayConfigHydrator.php | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Domain/Configuration/MetricsStorageConfig.php b/src/Domain/Configuration/MetricsStorageConfig.php index 6b0af64d4..e154c1998 100644 --- a/src/Domain/Configuration/MetricsStorageConfig.php +++ b/src/Domain/Configuration/MetricsStorageConfig.php @@ -7,8 +7,13 @@ public const NAME_PROMETHEUS_PUSH_GATEWAY = 'prometheusPushGateway'; public const NAME_NULL = 'null'; + public const NAMES = [ + self::NAME_PROMETHEUS_PUSH_GATEWAY, + self::NAME_NULL, + ]; + /** - * @param self::NAME_* $name + * @param value-of $name */ public function __construct( public string $name, diff --git a/src/Infrastructure/Configuration/Loader/Mapper/ArrayConfigHydrator.php b/src/Infrastructure/Configuration/Loader/Mapper/ArrayConfigHydrator.php index 8acdea9bc..638208e37 100644 --- a/src/Infrastructure/Configuration/Loader/Mapper/ArrayConfigHydrator.php +++ b/src/Infrastructure/Configuration/Loader/Mapper/ArrayConfigHydrator.php @@ -189,6 +189,14 @@ private function createMetricsConfig(array $config): MetricsConfig } $storageName = array_key_first($config['metrics']['storage']); + + if (! in_array($storageName, MetricsStorageConfig::NAMES, true)) { + throw new ConfigInvalidException(sprintf( + 'Config[metrics.storage] name must be of [%s]', + implode(', ', MetricsStorageConfig::NAMES), + )); + } + $storage = $config['metrics']['storage'][$storageName]; if (empty($storage['address'])) { From 42cc3f606b3b6c1c459128ebf7162c29e7b876d7 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 04:45:12 +0300 Subject: [PATCH 17/34] fix test part --- src/Shared/Metrics/Collector/Counter.php | 3 +++ src/Shared/Metrics/Collector/CounterVector.php | 3 +++ src/Shared/Metrics/Collector/Gauge.php | 3 +++ src/Shared/Metrics/Collector/GaugeVector.php | 3 +++ src/Shared/Time/Duration.php | 2 +- tests/TestCase.php | 5 +++++ tests/Unit/Shared/Time/DurationTest.php | 10 ---------- 7 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/Shared/Metrics/Collector/Counter.php b/src/Shared/Metrics/Collector/Counter.php index 22b460234..98aa26182 100644 --- a/src/Shared/Metrics/Collector/Counter.php +++ b/src/Shared/Metrics/Collector/Counter.php @@ -27,6 +27,9 @@ public function getSamples(): array ]; } + /** + * @codeCoverageIgnore + */ public function getMetricType(): MetricType { return MetricType::Counter; diff --git a/src/Shared/Metrics/Collector/CounterVector.php b/src/Shared/Metrics/Collector/CounterVector.php index 22a75cb91..d85529948 100644 --- a/src/Shared/Metrics/Collector/CounterVector.php +++ b/src/Shared/Metrics/Collector/CounterVector.php @@ -34,6 +34,9 @@ public function add(array $labels): Counter }, $labels); } + /** + * @codeCoverageIgnore + */ public function getMetricType(): MetricType { return MetricType::Counter; diff --git a/src/Shared/Metrics/Collector/Gauge.php b/src/Shared/Metrics/Collector/Gauge.php index ce9ed3eef..ae16c9bac 100644 --- a/src/Shared/Metrics/Collector/Gauge.php +++ b/src/Shared/Metrics/Collector/Gauge.php @@ -24,6 +24,9 @@ public function getSamples(): array ]; } + /** + * @codeCoverageIgnore + */ public function getMetricType(): MetricType { return MetricType::Gauge; diff --git a/src/Shared/Metrics/Collector/GaugeVector.php b/src/Shared/Metrics/Collector/GaugeVector.php index 09217eda5..2a9cdc6b2 100644 --- a/src/Shared/Metrics/Collector/GaugeVector.php +++ b/src/Shared/Metrics/Collector/GaugeVector.php @@ -17,6 +17,9 @@ public function add(array $labels): Gauge }, $labels); } + /** + * @codeCoverageIgnore + */ public function getMetricType(): MetricType { return MetricType::Gauge; diff --git a/src/Shared/Time/Duration.php b/src/Shared/Time/Duration.php index c1b5e5563..457059ce3 100644 --- a/src/Shared/Time/Duration.php +++ b/src/Shared/Time/Duration.php @@ -11,6 +11,6 @@ public function __construct( public function __toString(): string { - return "$this->seconds"; + return "{$this->seconds}s"; } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 3fb1520ec..571a51b03 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -7,6 +7,8 @@ use ArtARTs36\MergeRequestLinter\Domain\Configuration\Config; use ArtARTs36\MergeRequestLinter\Domain\Configuration\HttpClientConfig; use ArtARTs36\MergeRequestLinter\Domain\Configuration\LinterConfig; +use ArtARTs36\MergeRequestLinter\Domain\Configuration\MetricsConfig; +use ArtARTs36\MergeRequestLinter\Domain\Configuration\MetricsStorageConfig; use ArtARTs36\MergeRequestLinter\Domain\Configuration\NotificationsConfig; use ArtARTs36\MergeRequestLinter\Domain\Linter\LinterOptions; use ArtARTs36\MergeRequestLinter\Domain\Linter\LintResult; @@ -47,6 +49,9 @@ protected function makeConfig(array $rules): Config CommentsPostStrategy::Null, [], ), + new MetricsConfig( + new MetricsStorageConfig(MetricsStorageConfig::NAME_NULL, 'null'), + ), ); } diff --git a/tests/Unit/Shared/Time/DurationTest.php b/tests/Unit/Shared/Time/DurationTest.php index c6411e38c..e66f168da 100644 --- a/tests/Unit/Shared/Time/DurationTest.php +++ b/tests/Unit/Shared/Time/DurationTest.php @@ -17,14 +17,4 @@ public function testToString(): void self::assertEquals('0.12s', (string) $duration); } - /** - * @covers \ArtARTs36\MergeRequestLinter\Shared\Time\Duration::getMetricValue - * @covers \ArtARTs36\MergeRequestLinter\Shared\Time\Duration::__construct - */ - public function testToGetMetricValue(): void - { - $duration = new Duration(0.12); - - self::assertEquals('0.12s', $duration->getMetricValue()); - } } From 45c861942fb409ebfac66fdcbd4a7efc93b5b3a3 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 11:18:58 +0300 Subject: [PATCH 18/34] rename manager to registry --- src/Application/Linter/Linter.php | 4 ++-- src/Application/Linter/LinterFactory.php | 4 ++-- src/Application/Linter/RunnerFactory.php | 16 ++++++++-------- .../Rule/Metrics/RuleLintStateMetricHandler.php | 4 ++-- .../Loader/ArrayConfigLoaderFactory.php | 14 +++++++------- .../Resolver/MetricableConfigResolver.php | 4 ++-- src/Infrastructure/Http/Client/ClientFactory.php | 6 +++--- .../Http/Client/MetricableClient.php | 4 ++-- src/Infrastructure/Logger/MetricableLogger.php | 4 ++-- .../Metrics/RequestMetricFlusher.php | 6 +++--- .../RequestFetcher/CiRequestFetcher.php | 6 +++--- .../Rule/Factories/ConditionRuleFactory.php | 4 ++-- .../Console/Application/Application.php | 4 ++-- .../Console/Application/ApplicationFactory.php | 14 +++++++------- src/Presentation/Console/Command/LintCommand.php | 8 ++++---- src/Providers/MetricsProvider.php | 6 +++--- .../CollectorRegisterer.php} | 4 ++-- .../CollectorRegistry.php} | 4 ++-- .../MemoryRegistry.php} | 4 ++-- .../NullRegistry.php} | 4 ++-- .../Feature/Console/Command/LintCommandTest.php | 4 ++-- tests/Mocks/MockRunnerFactory.php | 4 ++-- .../Application/Linter/LinterFactoryTest.php | 4 ++-- tests/Unit/Application/Linter/LinterTest.php | 8 ++++---- .../Linter/Runner/RunnerFactoryTest.php | 6 +++--- .../Application/Linter/Runner/RunnerTest.php | 12 ++++++------ .../Infrastructure/Http/ClientFactoryTest.php | 6 +++--- .../Infrastructure/Http/MetricableClientTest.php | 6 +++--- .../RequestFetcher/CiRequestFetcherTest.php | 8 ++++---- .../Rule/Factories/ConditionRuleFactoryTest.php | 8 ++++---- .../Metrics/Manager/MemoryMetricManagerTest.php | 14 +++++++------- 31 files changed, 102 insertions(+), 102 deletions(-) rename src/Shared/Metrics/{Manager/MetricRegisterer.php => Registry/CollectorRegisterer.php} (81%) rename src/Shared/Metrics/{Manager/MetricManager.php => Registry/CollectorRegistry.php} (72%) rename src/Shared/Metrics/{Manager/MemoryMetricManager.php => Registry/MemoryRegistry.php} (92%) rename src/Shared/Metrics/{Manager/NullMetricManager.php => Registry/NullRegistry.php} (83%) diff --git a/src/Application/Linter/Linter.php b/src/Application/Linter/Linter.php index 4dd3fa7dc..c9eea6b21 100644 --- a/src/Application/Linter/Linter.php +++ b/src/Application/Linter/Linter.php @@ -21,7 +21,7 @@ use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Counter; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricRegisterer; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegisterer; use ArtARTs36\MergeRequestLinter\Shared\Time\Timer; use Psr\EventDispatcher\EventDispatcherInterface; @@ -31,7 +31,7 @@ public function __construct( private Rules $rules, private LinterOptions $options, private EventDispatcherInterface $events, - private MetricRegisterer $metrics, + private CollectorRegisterer $metrics, ) { } diff --git a/src/Application/Linter/LinterFactory.php b/src/Application/Linter/LinterFactory.php index 502204c65..4b769c706 100644 --- a/src/Application/Linter/LinterFactory.php +++ b/src/Application/Linter/LinterFactory.php @@ -4,14 +4,14 @@ use ArtARTs36\MergeRequestLinter\Domain\Configuration\Config; use ArtARTs36\MergeRequestLinter\Domain\Linter\Linter; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegistry; use Psr\EventDispatcher\EventDispatcherInterface; class LinterFactory { public function __construct( private readonly EventDispatcherInterface $events, - private readonly MetricManager $metrics, + private readonly CollectorRegistry $metrics, ) { } diff --git a/src/Application/Linter/RunnerFactory.php b/src/Application/Linter/RunnerFactory.php index 05b8a3a23..f6c024fbb 100644 --- a/src/Application/Linter/RunnerFactory.php +++ b/src/Application/Linter/RunnerFactory.php @@ -22,7 +22,7 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\RequestFetcher\CiRequestFetcher; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\ArrayMap; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Map; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegistry; use ArtARTs36\MergeRequestLinter\Shared\Time\Clock; class RunnerFactory implements LinterRunnerFactory @@ -31,13 +31,13 @@ class RunnerFactory implements LinterRunnerFactory * @param Map> $ciSystems */ public function __construct( - protected Environment $environment, - protected Map $ciSystems, - protected ContextLogger $logger, - protected MetricManager $metrics, - protected ClientFactory $clientFactory, - protected Clock $clock, - protected MapContainer $container = new MapContainer(), + protected Environment $environment, + protected Map $ciSystems, + protected ContextLogger $logger, + protected CollectorRegistry $metrics, + protected ClientFactory $clientFactory, + protected Clock $clock, + protected MapContainer $container = new MapContainer(), ) { } diff --git a/src/Application/Rule/Metrics/RuleLintStateMetricHandler.php b/src/Application/Rule/Metrics/RuleLintStateMetricHandler.php index 8a76a047e..cdeccc4db 100644 --- a/src/Application/Rule/Metrics/RuleLintStateMetricHandler.php +++ b/src/Application/Rule/Metrics/RuleLintStateMetricHandler.php @@ -6,7 +6,7 @@ use ArtARTs36\MergeRequestLinter\Domain\Linter\RuleWasSuccessfulEvent; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\CounterVector; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricRegisterer; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegisterer; class RuleLintStateMetricHandler { @@ -15,7 +15,7 @@ public function __construct( ) { } - public static function make(MetricRegisterer $registerer): self + public static function make(CollectorRegisterer $registerer): self { $counter = new CounterVector(new MetricSubject( 'linter', diff --git a/src/Infrastructure/Configuration/Loader/ArrayConfigLoaderFactory.php b/src/Infrastructure/Configuration/Loader/ArrayConfigLoaderFactory.php index 70a7a560b..ab59bb44c 100644 --- a/src/Infrastructure/Configuration/Loader/ArrayConfigLoaderFactory.php +++ b/src/Infrastructure/Configuration/Loader/ArrayConfigLoaderFactory.php @@ -35,7 +35,7 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Rule\Factories\RuleFactory; use ArtARTs36\MergeRequestLinter\Infrastructure\Rule\Resolver; use ArtARTs36\MergeRequestLinter\Infrastructure\Text\Decoder\DecoderFactory; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegistry; use ArtARTs36\MergeRequestLinter\Shared\Reflection\Instantiator\Finder; use ArtARTs36\MergeRequestLinter\Shared\Reflection\ParameterMapBuilder; use ArtARTs36\MergeRequestLinter\Shared\Reflection\TypeResolver\ResolverFactory; @@ -48,12 +48,12 @@ class ArrayConfigLoaderFactory ]; public function __construct( - private readonly FileSystem $fileSystem, - private readonly Environment $environment, - private readonly MetricManager $metrics, - private readonly ResolverFactory $argumentResolverFactory, - private readonly MapContainer $container, - private readonly DecoderFactory $decoderFactory = new DecoderFactory(), + private readonly FileSystem $fileSystem, + private readonly Environment $environment, + private readonly CollectorRegistry $metrics, + private readonly ResolverFactory $argumentResolverFactory, + private readonly MapContainer $container, + private readonly DecoderFactory $decoderFactory = new DecoderFactory(), ) { } diff --git a/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php b/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php index 812c6ffbb..97c8cd620 100644 --- a/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php +++ b/src/Infrastructure/Configuration/Resolver/MetricableConfigResolver.php @@ -5,14 +5,14 @@ use ArtARTs36\MergeRequestLinter\Domain\Configuration\Config; use ArtARTs36\MergeRequestLinter\Infrastructure\Configuration\User; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegistry; use ArtARTs36\MergeRequestLinter\Shared\Time\Timer; class MetricableConfigResolver implements \ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Configuration\ConfigResolver { public function __construct( private readonly \ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Configuration\ConfigResolver $resolver, - private readonly MetricManager $metrics, + private readonly CollectorRegistry $metrics, ) { } diff --git a/src/Infrastructure/Http/Client/ClientFactory.php b/src/Infrastructure/Http/Client/ClientFactory.php index 82ace3715..cd38470ea 100644 --- a/src/Infrastructure/Http/Client/ClientFactory.php +++ b/src/Infrastructure/Http/Client/ClientFactory.php @@ -6,15 +6,15 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Http\Client; use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Http\HttpClientFactory; use ArtARTs36\MergeRequestLinter\Infrastructure\Http\Exceptions\HttpClientTypeNotSupported; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegistry; use GuzzleHttp\Client as GuzzleClient; use Psr\Log\LoggerInterface; class ClientFactory implements HttpClientFactory { public function __construct( - private readonly MetricManager $metrics, - private readonly LoggerInterface $logger, + private readonly CollectorRegistry $metrics, + private readonly LoggerInterface $logger, ) { } diff --git a/src/Infrastructure/Http/Client/MetricableClient.php b/src/Infrastructure/Http/Client/MetricableClient.php index 58622559c..fed887239 100644 --- a/src/Infrastructure/Http/Client/MetricableClient.php +++ b/src/Infrastructure/Http/Client/MetricableClient.php @@ -6,7 +6,7 @@ use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\GaugeVector; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricRegisterer; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegisterer; use ArtARTs36\MergeRequestLinter\Shared\Time\Timer; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; @@ -19,7 +19,7 @@ public function __construct( ) { } - public static function make(Client $client, MetricRegisterer $metrics): self + public static function make(Client $client, CollectorRegisterer $metrics): self { $observer = $metrics->getOrRegister(new GaugeVector(new MetricSubject( 'http', diff --git a/src/Infrastructure/Logger/MetricableLogger.php b/src/Infrastructure/Logger/MetricableLogger.php index b18fed367..d21b44a9c 100644 --- a/src/Infrastructure/Logger/MetricableLogger.php +++ b/src/Infrastructure/Logger/MetricableLogger.php @@ -3,7 +3,7 @@ namespace ArtARTs36\MergeRequestLinter\Infrastructure\Logger; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricRegisterer; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegisterer; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Counter; use Psr\Log\LoggerInterface; use Psr\Log\LoggerTrait; @@ -17,7 +17,7 @@ public function __construct( ) { } - public static function create(MetricRegisterer $metrics): self + public static function create(CollectorRegisterer $metrics): self { $counter = new Counter(new MetricSubject('logger', 'logs_count', 'Logs count')); diff --git a/src/Infrastructure/Metrics/RequestMetricFlusher.php b/src/Infrastructure/Metrics/RequestMetricFlusher.php index 544f5d4d0..b41fb88d8 100644 --- a/src/Infrastructure/Metrics/RequestMetricFlusher.php +++ b/src/Infrastructure/Metrics/RequestMetricFlusher.php @@ -3,14 +3,14 @@ namespace ArtARTs36\MergeRequestLinter\Infrastructure\Metrics; use ArtARTs36\MergeRequestLinter\Domain\Request\MergeRequest; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegistry; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\MetricStorage; class RequestMetricFlusher { public function __construct( - private readonly MetricManager $metrics, - private readonly MetricStorage $storage, + private readonly CollectorRegistry $metrics, + private readonly MetricStorage $storage, ) { } diff --git a/src/Infrastructure/RequestFetcher/CiRequestFetcher.php b/src/Infrastructure/RequestFetcher/CiRequestFetcher.php index 13ecc2b3b..e4639e1fe 100644 --- a/src/Infrastructure/RequestFetcher/CiRequestFetcher.php +++ b/src/Infrastructure/RequestFetcher/CiRequestFetcher.php @@ -10,13 +10,13 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\CI\CiSystemFactory; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\CounterVector; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricRegisterer; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegisterer; final readonly class CiRequestFetcher implements MergeRequestFetcher { public function __construct( - private CiSystemFactory $systems, - private MetricRegisterer $metrics, + private CiSystemFactory $systems, + private CollectorRegisterer $metrics, ) { } diff --git a/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php b/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php index 4db0a7c2f..d66f8c96d 100644 --- a/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php +++ b/src/Infrastructure/Rule/Factories/ConditionRuleFactory.php @@ -7,7 +7,7 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Condition\OperatorResolver; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\CounterVector; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricRegisterer; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegisterer; /** * @phpstan-import-type Conditions from OperatorResolver @@ -20,7 +20,7 @@ public function __construct( ) { } - public static function new(OperatorResolver $operatorResolver, MetricRegisterer $metrics): self + public static function new(OperatorResolver $operatorResolver, CollectorRegisterer $metrics): self { $counter = new CounterVector(new MetricSubject( 'linter', diff --git a/src/Presentation/Console/Application/Application.php b/src/Presentation/Console/Application/Application.php index f88ab5886..a06a67732 100644 --- a/src/Presentation/Console/Application/Application.php +++ b/src/Presentation/Console/Application/Application.php @@ -4,7 +4,7 @@ use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\GaugeVector; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegistry; use ArtARTs36\MergeRequestLinter\Shared\Time\Timer; use ArtARTs36\MergeRequestLinter\Version; use Symfony\Component\Console\Command\Command; @@ -19,7 +19,7 @@ public function __construct( parent::__construct('Merge Request Linter', Version::VERSION); } - public static function make(MetricManager $metrics): self + public static function make(CollectorRegistry $metrics): self { $observer = new GaugeVector(new MetricSubject( 'console', diff --git a/src/Presentation/Console/Application/ApplicationFactory.php b/src/Presentation/Console/Application/ApplicationFactory.php index 205f7409b..d43396833 100644 --- a/src/Presentation/Console/Application/ApplicationFactory.php +++ b/src/Presentation/Console/Application/ApplicationFactory.php @@ -46,8 +46,8 @@ use ArtARTs36\MergeRequestLinter\Providers\ServiceProvider; use ArtARTs36\MergeRequestLinter\Shared\Events\EventManager; use ArtARTs36\MergeRequestLinter\Shared\File\Directory; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MemoryMetricManager; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegistry; use ArtARTs36\MergeRequestLinter\Shared\Reflection\TypeResolver\ResolverFactory; use ArtARTs36\MergeRequestLinter\Shared\Time\Clock; use ArtARTs36\MergeRequestLinter\Shared\Time\LocalClock; @@ -177,7 +177,7 @@ private function registerTextRenderer(): void private function registerHttpClientFactory(): ClientFactory { $factory = new ClientFactory( - $this->container->get(MetricManager::class), + $this->container->get(CollectorRegistry::class), $this->container->get(LoggerInterface::class), ); @@ -187,11 +187,11 @@ private function registerHttpClientFactory(): ClientFactory return $factory; } - private function registerMetricManager(): MetricManager + private function registerMetricManager(): CollectorRegistry { - $metrics = new MemoryMetricManager(); + $metrics = new MemoryRegistry(); - $this->container->set(MetricManager::class, $metrics); + $this->container->set(CollectorRegistry::class, $metrics); return $metrics; } @@ -205,7 +205,7 @@ private function registerFileSystem(): FileSystem return $fs; } - private function createLogger(OutputInterface $output, MetricManager $metricManager): ContextLogger + private function createLogger(OutputInterface $output, CollectorRegistry $metricManager): ContextLogger { $loggers = [ MetricableLogger::create($metricManager), diff --git a/src/Presentation/Console/Command/LintCommand.php b/src/Presentation/Console/Command/LintCommand.php index 90b105a16..1291e031d 100644 --- a/src/Presentation/Console/Command/LintCommand.php +++ b/src/Presentation/Console/Command/LintCommand.php @@ -19,7 +19,7 @@ use ArtARTs36\MergeRequestLinter\Shared\Events\EventManager; use ArtARTs36\MergeRequestLinter\Shared\File\Bytes; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Collector; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegistry; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -35,10 +35,10 @@ final class LintCommand extends Command protected static $defaultDescription = 'Run lint to current merge request'; public function __construct( - protected MetricManager $metrics, - protected EventManager $events, + protected CollectorRegistry $metrics, + protected EventManager $events, private readonly LintTaskHandler $handler, - protected readonly NotePrinter $notePrinter = new NotePrinter(), + protected readonly NotePrinter $notePrinter = new NotePrinter(), protected readonly MetricPrinter $metricPrinter = new MetricPrinter(), ) { parent::__construct(); diff --git a/src/Providers/MetricsProvider.php b/src/Providers/MetricsProvider.php index 8c36192b0..442492490 100644 --- a/src/Providers/MetricsProvider.php +++ b/src/Providers/MetricsProvider.php @@ -12,7 +12,7 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Metrics\RequestMetricFlusher; use ArtARTs36\MergeRequestLinter\Shared\Events\CallbackListener; use ArtARTs36\MergeRequestLinter\Shared\Events\EventManager; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegistry; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\MetricStorage; use Psr\Container\ContainerInterface; @@ -36,7 +36,7 @@ public function provide(): void ->get(EventManager::class) ->listen(LintFinishedEvent::class, new CallbackListener('metrics_flush', function (LintFinishedEvent $event) { $flusher = new RequestMetricFlusher( - $this->container->get(MetricManager::class), + $this->container->get(CollectorRegistry::class), $this->container->get(MetricStorage::class), ); @@ -44,7 +44,7 @@ public function provide(): void })); $this->container->bind(RuleLintStateMetricHandler::class, static function (ContainerInterface $container) { - return RuleLintStateMetricHandler::make($container->get(MetricManager::class)); + return RuleLintStateMetricHandler::make($container->get(CollectorRegistry::class)); }); $this diff --git a/src/Shared/Metrics/Manager/MetricRegisterer.php b/src/Shared/Metrics/Registry/CollectorRegisterer.php similarity index 81% rename from src/Shared/Metrics/Manager/MetricRegisterer.php rename to src/Shared/Metrics/Registry/CollectorRegisterer.php index cf0690f97..bb56f7b4c 100644 --- a/src/Shared/Metrics/Manager/MetricRegisterer.php +++ b/src/Shared/Metrics/Registry/CollectorRegisterer.php @@ -1,13 +1,13 @@ diff --git a/src/Shared/Metrics/Manager/NullMetricManager.php b/src/Shared/Metrics/Registry/NullRegistry.php similarity index 83% rename from src/Shared/Metrics/Manager/NullMetricManager.php rename to src/Shared/Metrics/Registry/NullRegistry.php index 6b8cbf8f9..3264b4c71 100644 --- a/src/Shared/Metrics/Manager/NullMetricManager.php +++ b/src/Shared/Metrics/Registry/NullRegistry.php @@ -1,6 +1,6 @@ makeConfig([new SuccessRule()])), diff --git a/tests/Mocks/MockRunnerFactory.php b/tests/Mocks/MockRunnerFactory.php index f7512ae92..f3eec616a 100644 --- a/tests/Mocks/MockRunnerFactory.php +++ b/tests/Mocks/MockRunnerFactory.php @@ -8,7 +8,7 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\CI\CiSystemFactory; use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Linter\LinterRunnerFactory; use ArtARTs36\MergeRequestLinter\Infrastructure\RequestFetcher\CiRequestFetcher; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\NullMetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\NullRegistry; final class MockRunnerFactory implements LinterRunnerFactory { @@ -19,6 +19,6 @@ public function __construct(private CiSystemFactory $ciSystemFactory) public function create(Config $config): LinterRunner { - return new Runner(new CiRequestFetcher($this->ciSystemFactory, new NullMetricManager())); + return new Runner(new CiRequestFetcher($this->ciSystemFactory, new NullRegistry())); } } diff --git a/tests/Unit/Application/Linter/LinterFactoryTest.php b/tests/Unit/Application/Linter/LinterFactoryTest.php index a1c19fa7a..7d4e444d1 100644 --- a/tests/Unit/Application/Linter/LinterFactoryTest.php +++ b/tests/Unit/Application/Linter/LinterFactoryTest.php @@ -13,7 +13,7 @@ use ArtARTs36\MergeRequestLinter\Domain\Linter\LinterOptions; use ArtARTs36\MergeRequestLinter\Domain\Rule\Rules; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\ArrayMap; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\NullMetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\NullRegistry; use ArtARTs36\MergeRequestLinter\Tests\Mocks\NullEventDispatcher; use ArtARTs36\MergeRequestLinter\Tests\TestCase; @@ -27,7 +27,7 @@ public function testCreate(): void { $factory = new LinterFactory( new NullEventDispatcher(), - new NullMetricManager(), + new NullRegistry(), ); $gotLinter = $factory->create(new Config( diff --git a/tests/Unit/Application/Linter/LinterTest.php b/tests/Unit/Application/Linter/LinterTest.php index 11900ec34..830412560 100644 --- a/tests/Unit/Application/Linter/LinterTest.php +++ b/tests/Unit/Application/Linter/LinterTest.php @@ -17,7 +17,7 @@ use ArtARTs36\MergeRequestLinter\Domain\Rule\RuleDefinition; use ArtARTs36\MergeRequestLinter\Domain\Rule\Rules; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\NullMetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\NullRegistry; use ArtARTs36\MergeRequestLinter\Shared\Time\Duration; use ArtARTs36\MergeRequestLinter\Tests\Mocks\EmptyNote; use ArtARTs36\MergeRequestLinter\Tests\Mocks\ExceptionRule; @@ -45,7 +45,7 @@ public function testRunOnException(): void ]), new LinterOptions(false), new NullEventDispatcher(), - new NullMetricManager(), + new NullRegistry(), ); $result = $linter->run($this->makeMergeRequest()); @@ -167,7 +167,7 @@ public function testRun(Rules $rules, LinterOptions $options, array $expectedEve $rules, $options, $eventDispatcher, - new NullMetricManager(), + new NullRegistry(), ); $result = $linter->run($this->makeMergeRequest()); @@ -209,7 +209,7 @@ public function testRunOnEvaluatorCrashedException(): void ]), new LinterOptions(), $eventDispatcher, - new NullMetricManager(), + new NullRegistry(), ); $gotLintResult = $linter->run($this->makeMergeRequest()); diff --git a/tests/Unit/Application/Linter/Runner/RunnerFactoryTest.php b/tests/Unit/Application/Linter/Runner/RunnerFactoryTest.php index c19eec6ed..6b6d53ae1 100644 --- a/tests/Unit/Application/Linter/Runner/RunnerFactoryTest.php +++ b/tests/Unit/Application/Linter/Runner/RunnerFactoryTest.php @@ -8,7 +8,7 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Environment\Environments\NullEnvironment; use ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\ClientFactory; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\ArrayMap; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\NullMetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\NullRegistry; use ArtARTs36\MergeRequestLinter\Shared\Time\LocalClock; use ArtARTs36\MergeRequestLinter\Tests\TestCase; @@ -25,8 +25,8 @@ public function testCreate(): void new NullEnvironment(), new ArrayMap([]), LoggerFactory::null(), - new NullMetricManager(), - new ClientFactory(new NullMetricManager(), LoggerFactory::null()), + new NullRegistry(), + new ClientFactory(new NullRegistry(), LoggerFactory::null()), LocalClock::utc(), ); diff --git a/tests/Unit/Application/Linter/Runner/RunnerTest.php b/tests/Unit/Application/Linter/Runner/RunnerTest.php index 568023432..ffb09fe6d 100644 --- a/tests/Unit/Application/Linter/Runner/RunnerTest.php +++ b/tests/Unit/Application/Linter/Runner/RunnerTest.php @@ -13,7 +13,7 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Ci\Exceptions\CiNotSupported; use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\CI\CiSystemFactory; use ArtARTs36\MergeRequestLinter\Infrastructure\RequestFetcher\CiRequestFetcher; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\NullMetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\NullRegistry; use ArtARTs36\MergeRequestLinter\Tests\Mocks\MockCi; use ArtARTs36\MergeRequestLinter\Tests\Mocks\NullEventDispatcher; use ArtARTs36\MergeRequestLinter\Tests\Mocks\SuccessRule; @@ -32,7 +32,7 @@ public function createCurrently(): CiSystem { throw new CiNotSupported(); } - }, new NullMetricManager())); + }, new NullRegistry())); $result = $runner->run($this->createLinter()); @@ -51,7 +51,7 @@ public function createCurrently(): CiSystem { return new MockCi(); } - }, new NullMetricManager())); + }, new NullRegistry())); $result = $runner->run($this->createLinter()); @@ -73,7 +73,7 @@ public function createCurrently(): CiSystem { throw new \Exception(); } - }, new NullMetricManager())); + }, new NullRegistry())); $result = $runner->run($this->createLinter()); @@ -100,7 +100,7 @@ public function createCurrently(): CiSystem { return new MockCi($this->request); } - }, new NullMetricManager())); + }, new NullRegistry())); $result = $runner->run($this->createLinter([ new SuccessRule(), @@ -115,7 +115,7 @@ private function createLinter(array $rules = []): Linter new Rules($rules), new LinterOptions(false), new NullEventDispatcher(), - new NullMetricManager(), + new NullRegistry(), ); } } diff --git a/tests/Unit/Infrastructure/Http/ClientFactoryTest.php b/tests/Unit/Infrastructure/Http/ClientFactoryTest.php index 378568ce6..514c5f0a7 100644 --- a/tests/Unit/Infrastructure/Http/ClientFactoryTest.php +++ b/tests/Unit/Infrastructure/Http/ClientFactoryTest.php @@ -7,7 +7,7 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\ClientFactory; use ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\MetricableClient; use ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\NullClient; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\NullMetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\NullRegistry; use ArtARTs36\MergeRequestLinter\Tests\TestCase; final class ClientFactoryTest extends TestCase @@ -28,7 +28,7 @@ public function providerForTestCreate(): array */ public function testCreate(HttpClientConfig $config, string $expectedClass): void { - $factory = new ClientFactory(new NullMetricManager(), LoggerFactory::null()); + $factory = new ClientFactory(new NullRegistry(), LoggerFactory::null()); self::assertInstanceOf($expectedClass, $factory->create($config)); } @@ -42,7 +42,7 @@ public function testCreateOnNotSupported(): void { self::expectExceptionMessage('HTTP Client with type "non-exists-client-type" not supported'); - $factory = new ClientFactory(new NullMetricManager(), LoggerFactory::null()); + $factory = new ClientFactory(new NullRegistry(), LoggerFactory::null()); $factory->create(new HttpClientConfig('non-exists-client-type', [])); } diff --git a/tests/Unit/Infrastructure/Http/MetricableClientTest.php b/tests/Unit/Infrastructure/Http/MetricableClientTest.php index b700c70a0..a7847fd21 100644 --- a/tests/Unit/Infrastructure/Http/MetricableClientTest.php +++ b/tests/Unit/Infrastructure/Http/MetricableClientTest.php @@ -4,7 +4,7 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\MetricableClient; use ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\NullClient; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MemoryMetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry; use ArtARTs36\MergeRequestLinter\Shared\Time\LocalClock; use ArtARTs36\MergeRequestLinter\Tests\TestCase; use GuzzleHttp\Psr7\Request; @@ -17,7 +17,7 @@ final class MetricableClientTest extends TestCase */ public function testSendRequest(): void { - $client = new MetricableClient(new NullClient(), $metrics = new MemoryMetricManager(LocalClock::utc())); + $client = new MetricableClient(new NullClient(), $metrics = new MemoryRegistry(LocalClock::utc())); $client->sendRequest(new Request('GET', 'http://site.ru')); @@ -32,7 +32,7 @@ public function testSendRequest(): void */ public function testSendAsyncRequest(): void { - $client = new MetricableClient(new NullClient(), $metrics = new MemoryMetricManager(LocalClock::utc())); + $client = new MetricableClient(new NullClient(), $metrics = new MemoryRegistry(LocalClock::utc())); $client->sendAsyncRequests(['k' => new Request('GET', 'http://site.ru')]); diff --git a/tests/Unit/Infrastructure/RequestFetcher/CiRequestFetcherTest.php b/tests/Unit/Infrastructure/RequestFetcher/CiRequestFetcherTest.php index 90a5b8e92..917a7c20d 100644 --- a/tests/Unit/Infrastructure/RequestFetcher/CiRequestFetcherTest.php +++ b/tests/Unit/Infrastructure/RequestFetcher/CiRequestFetcherTest.php @@ -5,7 +5,7 @@ use ArtARTs36\MergeRequestLinter\Domain\CI\CiSystem; use ArtARTs36\MergeRequestLinter\Domain\CI\FetchMergeRequestException; use ArtARTs36\MergeRequestLinter\Infrastructure\RequestFetcher\CiRequestFetcher; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MemoryMetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry; use ArtARTs36\MergeRequestLinter\Shared\Time\LocalClock; use ArtARTs36\MergeRequestLinter\Tests\Mocks\MockCi; use ArtARTs36\MergeRequestLinter\Tests\Mocks\MockCiSystemFactory; @@ -22,7 +22,7 @@ public function testFetchAddMetric(): void { $fetcher = new CiRequestFetcher( new MockCiSystemFactory(new MockCi($this->makeMergeRequest())), - $metrics = new MemoryMetricManager(LocalClock::utc()), + $metrics = new MemoryRegistry(LocalClock::utc()), ); $fetcher->fetch(); @@ -37,7 +37,7 @@ public function testFetchOnCurrentlyNotMergeRequestException(): void { $fetcher = new CiRequestFetcher( new MockCiSystemFactory(new MockCi()), - new MemoryMetricManager(LocalClock::utc()), + new MemoryRegistry(LocalClock::utc()), ); self::expectExceptionMessageMatches('/Fetch current merge request from (.*) was failed/i'); @@ -58,7 +58,7 @@ public function testFetchOnGettingMergeRequestException(): void $fetcher = new CiRequestFetcher( new MockCiSystemFactory($ci), - new MemoryMetricManager(LocalClock::utc()), + new MemoryRegistry(LocalClock::utc()), ); self::expectExceptionMessageMatches('/Fetch current merge request from (.*) was failed/i'); diff --git a/tests/Unit/Infrastructure/Rule/Factories/ConditionRuleFactoryTest.php b/tests/Unit/Infrastructure/Rule/Factories/ConditionRuleFactoryTest.php index 954a6a792..4f4084b5d 100644 --- a/tests/Unit/Infrastructure/Rule/Factories/ConditionRuleFactoryTest.php +++ b/tests/Unit/Infrastructure/Rule/Factories/ConditionRuleFactoryTest.php @@ -4,8 +4,8 @@ use ArtARTs36\MergeRequestLinter\Application\Rule\Rules\ConditionRule; use ArtARTs36\MergeRequestLinter\Infrastructure\Rule\Factories\ConditionRuleFactory; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MemoryMetricManager; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\NullMetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\NullRegistry; use ArtARTs36\MergeRequestLinter\Shared\Time\LocalClock; use ArtARTs36\MergeRequestLinter\Tests\Mocks\MockConditionOperator; use ArtARTs36\MergeRequestLinter\Tests\Mocks\MockOperatorResolver; @@ -22,7 +22,7 @@ public function testNew(): void { ConditionRuleFactory::new( new MockOperatorResolver(), - $metrics = new MemoryMetricManager(LocalClock::utc()), + $metrics = new MemoryRegistry(LocalClock::utc()), ); self::assertCount(1, $metrics->describe()); @@ -34,7 +34,7 @@ public function testNew(): void */ public function testCreate(): void { - $factory = ConditionRuleFactory::new(new MockOperatorResolver(new MockConditionOperator(true)), new NullMetricManager()); + $factory = ConditionRuleFactory::new(new MockOperatorResolver(new MockConditionOperator(true)), new NullRegistry()); $rule = $factory->create(new SuccessRule(), []); diff --git a/tests/Unit/Shared/Metrics/Manager/MemoryMetricManagerTest.php b/tests/Unit/Shared/Metrics/Manager/MemoryMetricManagerTest.php index 539a42ed1..9ad695ef4 100644 --- a/tests/Unit/Shared/Metrics/Manager/MemoryMetricManagerTest.php +++ b/tests/Unit/Shared/Metrics/Manager/MemoryMetricManagerTest.php @@ -4,7 +4,7 @@ use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\CounterVector; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MemoryMetricManager; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\IncCounter; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\Record; use ArtARTs36\MergeRequestLinter\Shared\Time\LocalClock; @@ -14,12 +14,12 @@ final class MemoryMetricManagerTest extends TestCase { /** - * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MemoryMetricManager::register - * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MemoryMetricManager::__construct + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry::register + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry::__construct */ public function testRegister(): void { - $manager = new MemoryMetricManager(); + $manager = new MemoryRegistry(); self::assertCount(0, $manager->describe()); @@ -43,13 +43,13 @@ public function providerForTestDescribe(): array } /** - * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MemoryMetricManager::describe - * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Manager\MemoryMetricManager::__construct + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry::describe + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry::__construct * @dataProvider providerForTestDescribe */ public function testDescribe(array $adds, array $expected): void { - $manager = new MemoryMetricManager( + $manager = new MemoryRegistry( new QueueClock(array_map(fn (Record $record) => $record->date, $expected)), ); From 9b820886978f625a6270a4d575daa909a1a10ee6 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 11:31:45 +0300 Subject: [PATCH 19/34] test --- src/Shared/Metrics/Collector/Gauge.php | 2 +- .../CollectorAlreadyRegisteredException.php | 9 ++ .../Metrics/Registry/CollectorRegisterer.php | 4 +- .../Metrics/Registry/CollectorRegistry.php | 2 +- .../Metrics/Registry/MemoryRegistry.php | 4 +- .../Manager/MemoryMetricManagerTest.php | 62 ------------- .../Metrics/Manager/MemoryRegistryTest.php | 90 +++++++++++++++++++ 7 files changed, 106 insertions(+), 67 deletions(-) create mode 100644 src/Shared/Metrics/Registry/CollectorAlreadyRegisteredException.php delete mode 100644 tests/Unit/Shared/Metrics/Manager/MemoryMetricManagerTest.php create mode 100644 tests/Unit/Shared/Metrics/Manager/MemoryRegistryTest.php diff --git a/src/Shared/Metrics/Collector/Gauge.php b/src/Shared/Metrics/Collector/Gauge.php index ae16c9bac..55cf5a0c3 100644 --- a/src/Shared/Metrics/Collector/Gauge.php +++ b/src/Shared/Metrics/Collector/Gauge.php @@ -6,7 +6,7 @@ final class Gauge extends LabeledCollector { public function __construct( MetricSubject $subject, - array $labels, + array $labels = [], private float $value = 0, ) { parent::__construct($subject, $labels); diff --git a/src/Shared/Metrics/Registry/CollectorAlreadyRegisteredException.php b/src/Shared/Metrics/Registry/CollectorAlreadyRegisteredException.php new file mode 100644 index 000000000..8c905f957 --- /dev/null +++ b/src/Shared/Metrics/Registry/CollectorAlreadyRegisteredException.php @@ -0,0 +1,9 @@ +collectors)) { if (get_class($this->collectors[$key]) !== get_class($collector)) { - throw new \LogicException(sprintf( + throw new CollectorAlreadyRegisteredException(sprintf( 'Already registered collector "%s" with type "%s". Expected type: %s', $key, $this->collectors[$key]::class, @@ -40,7 +40,7 @@ public function register(Collector $collector): void $key = $collector->getSubject()->identity(); if (array_key_exists($key, $this->collectors)) { - throw new \LogicException(sprintf( + throw new CollectorAlreadyRegisteredException(sprintf( 'Collector for metric with key "%s" already registered', $key, )); diff --git a/tests/Unit/Shared/Metrics/Manager/MemoryMetricManagerTest.php b/tests/Unit/Shared/Metrics/Manager/MemoryMetricManagerTest.php deleted file mode 100644 index 9ad695ef4..000000000 --- a/tests/Unit/Shared/Metrics/Manager/MemoryMetricManagerTest.php +++ /dev/null @@ -1,62 +0,0 @@ -describe()); - - $manager->register(CounterVector::once(new MetricSubject('', '', ''), [])); - - self::assertCount(1, $manager->describe()); - } - - public function providerForTestDescribe(): array - { - return [ - [ - [ - [$subject1 = new MetricSubject('', 'k', 'n'), $metric1 = new IncCounter()], - ], - [ - new Record($subject1, $metric1, new \DateTimeImmutable()), - ], - ], - ]; - } - - /** - * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry::describe - * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry::__construct - * @dataProvider providerForTestDescribe - */ - public function testDescribe(array $adds, array $expected): void - { - $manager = new MemoryRegistry( - new QueueClock(array_map(fn (Record $record) => $record->date, $expected)), - ); - - foreach ($adds as [$subject, $value]) { - $manager->add($subject, $value); - } - - self::assertEquals($expected, $manager->describe()->mapToArray(fn ($item) => $item)); - } -} diff --git a/tests/Unit/Shared/Metrics/Manager/MemoryRegistryTest.php b/tests/Unit/Shared/Metrics/Manager/MemoryRegistryTest.php new file mode 100644 index 000000000..7a1895080 --- /dev/null +++ b/tests/Unit/Shared/Metrics/Manager/MemoryRegistryTest.php @@ -0,0 +1,90 @@ + $counter1, + ], + ], + ]; + } + + /** + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry::register + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry::describe + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry::__construct + * @dataProvider providerForTestDescribe + */ + public function testDescribe(array $adds, array $expected): void + { + $manager = new MemoryRegistry(); + + foreach ($adds as $collector) { + $manager->register($collector); + } + + self::assertEquals($expected, $manager->describe()->toArray()); + } + + /** + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry::register + */ + public function testRegisterOnAlreadyRegistered(): void + { + $registry = new MemoryRegistry(); + + $registry->register(new Counter(new MetricSubject('test', 'collector', ''))); + + self::expectException(CollectorAlreadyRegisteredException::class); + + $registry->register(new Gauge(new MetricSubject('test', 'collector', ''))); + } + + /** + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry::getOrRegister + */ + public function testGetOrRegister(): void + { + $registry = new MemoryRegistry(); + + $registry->getOrRegister($first = new Counter(new MetricSubject('test', 'collector', ''))); + + $got = $registry->getOrRegister(new Counter(new MetricSubject('test', 'collector', ''))); + + self::assertEquals($first, $got); + } + + /** + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry::getOrRegister + */ + public function testGetOrRegisterOnAlreadyRegisteredWithDifferentType(): void + { + $registry = new MemoryRegistry(); + + $registry->getOrRegister(new Counter(new MetricSubject('test', 'collector', ''))); + + self::expectExceptionMessage('Already registered collector "test_collector" with type "ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Counter". Expected type: ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Gauge'); + + $registry->getOrRegister(new Gauge(new MetricSubject('test', 'collector', ''))); + } +} From 1659de30b59bb691e9e279eb690e049bb0b523a5 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 11:32:38 +0300 Subject: [PATCH 20/34] fix test namespace --- .../Shared/Metrics/{Manager => Registry}/MemoryRegistryTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests/Unit/Shared/Metrics/{Manager => Registry}/MemoryRegistryTest.php (99%) diff --git a/tests/Unit/Shared/Metrics/Manager/MemoryRegistryTest.php b/tests/Unit/Shared/Metrics/Registry/MemoryRegistryTest.php similarity index 99% rename from tests/Unit/Shared/Metrics/Manager/MemoryRegistryTest.php rename to tests/Unit/Shared/Metrics/Registry/MemoryRegistryTest.php index 7a1895080..6b3e1527f 100644 --- a/tests/Unit/Shared/Metrics/Manager/MemoryRegistryTest.php +++ b/tests/Unit/Shared/Metrics/Registry/MemoryRegistryTest.php @@ -1,6 +1,6 @@ Date: Thu, 28 Sep 2023 11:47:07 +0300 Subject: [PATCH 21/34] fix test --- .../Metrics/Collector/AbstractCollector.php | 7 +++++++ .../Unit/Application/Linter/LinterFactoryTest.php | 9 +-------- .../Linter/TaskHandlers/LintTaskHandlerTest.php | 11 +++-------- .../Application/Rule/Rules/ConditionRuleTest.php | 2 +- .../Infrastructure/Http/MetricableClientTest.php | 11 ++++++----- .../RequestFetcher/CiRequestFetcherTest.php | 15 +++++++++++---- .../Metrics/Registry/MemoryRegistryTest.php | 1 - 7 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/Shared/Metrics/Collector/AbstractCollector.php b/src/Shared/Metrics/Collector/AbstractCollector.php index 088387285..4ae76f316 100644 --- a/src/Shared/Metrics/Collector/AbstractCollector.php +++ b/src/Shared/Metrics/Collector/AbstractCollector.php @@ -13,4 +13,11 @@ public function getSubject(): MetricSubject { return $this->subject; } + + public function getFirstSampleValue(): null|string|int|float + { + $samples = $this->getSamples(); + + return isset($samples[0]) ? $samples[0]->value : null; + } } diff --git a/tests/Unit/Application/Linter/LinterFactoryTest.php b/tests/Unit/Application/Linter/LinterFactoryTest.php index 7d4e444d1..70d1b20b2 100644 --- a/tests/Unit/Application/Linter/LinterFactoryTest.php +++ b/tests/Unit/Application/Linter/LinterFactoryTest.php @@ -30,14 +30,7 @@ public function testCreate(): void new NullRegistry(), ); - $gotLinter = $factory->create(new Config( - new Rules([]), - new ArrayMap([]), - new HttpClientConfig(HttpClientConfig::TYPE_NULL, []), - new NotificationsConfig(new ArrayMap([]), new ArrayMap([])), - new LinterConfig(new LinterOptions()), - new CommentsConfig(CommentsPostStrategy::New, []), - )); + $gotLinter = $factory->create($this->makeConfig([])); self::assertInstanceOf(Linter::class, $gotLinter); } diff --git a/tests/Unit/Application/Linter/TaskHandlers/LintTaskHandlerTest.php b/tests/Unit/Application/Linter/TaskHandlers/LintTaskHandlerTest.php index 0adc64e9a..22a2df089 100644 --- a/tests/Unit/Application/Linter/TaskHandlers/LintTaskHandlerTest.php +++ b/tests/Unit/Application/Linter/TaskHandlers/LintTaskHandlerTest.php @@ -11,6 +11,8 @@ use ArtARTs36\MergeRequestLinter\Domain\Configuration\Config; use ArtARTs36\MergeRequestLinter\Domain\Configuration\HttpClientConfig; use ArtARTs36\MergeRequestLinter\Domain\Configuration\LinterConfig; +use ArtARTs36\MergeRequestLinter\Domain\Configuration\MetricsConfig; +use ArtARTs36\MergeRequestLinter\Domain\Configuration\MetricsStorageConfig; use ArtARTs36\MergeRequestLinter\Domain\Configuration\NotificationsConfig; use ArtARTs36\MergeRequestLinter\Domain\Linter\LinterOptions; use ArtARTs36\MergeRequestLinter\Domain\Linter\LintState; @@ -34,14 +36,7 @@ public function testHandle(): void ->expects(new InvokedCount(1)) ->method('resolve') ->willReturn($config = new ResolvedConfig( - new Config( - new Rules([]), - new ArrayMap([]), - new HttpClientConfig('', []), - new NotificationsConfig(new ArrayMap([]), new ArrayMap([])), - new LinterConfig(new LinterOptions()), - new CommentsConfig(CommentsPostStrategy::New, []), - ), + $this->makeConfig([]), '', )); diff --git a/tests/Unit/Application/Rule/Rules/ConditionRuleTest.php b/tests/Unit/Application/Rule/Rules/ConditionRuleTest.php index 2400ce3a0..ffc008ce3 100644 --- a/tests/Unit/Application/Rule/Rules/ConditionRuleTest.php +++ b/tests/Unit/Application/Rule/Rules/ConditionRuleTest.php @@ -40,7 +40,7 @@ public function testLintIncSkipRulesMetric(ConditionOperator $operator, int $exp $rule->lint($this->makeMergeRequest()); - self::assertEquals($expected, $counter->getMetricValue()); + self::assertEquals($expected, $counter->getFirstSampleValue()); } /** diff --git a/tests/Unit/Infrastructure/Http/MetricableClientTest.php b/tests/Unit/Infrastructure/Http/MetricableClientTest.php index a7847fd21..64a3c94a3 100644 --- a/tests/Unit/Infrastructure/Http/MetricableClientTest.php +++ b/tests/Unit/Infrastructure/Http/MetricableClientTest.php @@ -5,7 +5,6 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\MetricableClient; use ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\NullClient; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry; -use ArtARTs36\MergeRequestLinter\Shared\Time\LocalClock; use ArtARTs36\MergeRequestLinter\Tests\TestCase; use GuzzleHttp\Psr7\Request; @@ -13,30 +12,32 @@ final class MetricableClientTest extends TestCase { /** * @covers \ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\MetricableClient::sendRequest + * @covers \ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\MetricableClient::make * @covers \ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\MetricableClient::__construct */ public function testSendRequest(): void { - $client = new MetricableClient(new NullClient(), $metrics = new MemoryRegistry(LocalClock::utc())); + $client = MetricableClient::make(new NullClient(), $metrics = new MemoryRegistry()); $client->sendRequest(new Request('GET', 'http://site.ru')); self::assertCount(1, $metrics->describe()); - self::assertEquals('http_send_request', $metrics->describe()->first()->subject->key); + self::assertGreaterThan(0.0, $metrics->describe()->first()->getFirstSampleValue()); } /** * @covers \ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\MetricableClient::sendAsyncRequests + * @covers \ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\MetricableClient::make * @covers \ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\MetricableClient::__construct * @covers \ArtARTs36\MergeRequestLinter\Infrastructure\Http\Client\MetricableClient::getHosts */ public function testSendAsyncRequest(): void { - $client = new MetricableClient(new NullClient(), $metrics = new MemoryRegistry(LocalClock::utc())); + $client = MetricableClient::make(new NullClient(), $metrics = new MemoryRegistry()); $client->sendAsyncRequests(['k' => new Request('GET', 'http://site.ru')]); self::assertCount(1, $metrics->describe()); - self::assertEquals('http_send_request', $metrics->describe()->first()->subject->key); + self::assertGreaterThan(0.0, $metrics->describe()->first()->getFirstSampleValue()); } } diff --git a/tests/Unit/Infrastructure/RequestFetcher/CiRequestFetcherTest.php b/tests/Unit/Infrastructure/RequestFetcher/CiRequestFetcherTest.php index 917a7c20d..86dfcdb1d 100644 --- a/tests/Unit/Infrastructure/RequestFetcher/CiRequestFetcherTest.php +++ b/tests/Unit/Infrastructure/RequestFetcher/CiRequestFetcherTest.php @@ -5,6 +5,8 @@ use ArtARTs36\MergeRequestLinter\Domain\CI\CiSystem; use ArtARTs36\MergeRequestLinter\Domain\CI\FetchMergeRequestException; use ArtARTs36\MergeRequestLinter\Infrastructure\RequestFetcher\CiRequestFetcher; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\CounterVector; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Sample; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry; use ArtARTs36\MergeRequestLinter\Shared\Time\LocalClock; use ArtARTs36\MergeRequestLinter\Tests\Mocks\MockCi; @@ -22,12 +24,17 @@ public function testFetchAddMetric(): void { $fetcher = new CiRequestFetcher( new MockCiSystemFactory(new MockCi($this->makeMergeRequest())), - $metrics = new MemoryRegistry(LocalClock::utc()), + $metrics = new MemoryRegistry(), ); $fetcher->fetch(); - self::assertEquals('used_ci_system', $metrics->describe()->first()->subject->key); + self::assertInstanceOf(CounterVector::class, $firstMetric = $metrics->describe()->first()); + self::assertEquals([ + new Sample(1, [ + 'ci' => 'mock_ci', + ]), + ], $firstMetric->getSamples()); } /** @@ -37,7 +44,7 @@ public function testFetchOnCurrentlyNotMergeRequestException(): void { $fetcher = new CiRequestFetcher( new MockCiSystemFactory(new MockCi()), - new MemoryRegistry(LocalClock::utc()), + new MemoryRegistry(), ); self::expectExceptionMessageMatches('/Fetch current merge request from (.*) was failed/i'); @@ -58,7 +65,7 @@ public function testFetchOnGettingMergeRequestException(): void $fetcher = new CiRequestFetcher( new MockCiSystemFactory($ci), - new MemoryRegistry(LocalClock::utc()), + new MemoryRegistry(), ); self::expectExceptionMessageMatches('/Fetch current merge request from (.*) was failed/i'); diff --git a/tests/Unit/Shared/Metrics/Registry/MemoryRegistryTest.php b/tests/Unit/Shared/Metrics/Registry/MemoryRegistryTest.php index 6b3e1527f..fe32967f2 100644 --- a/tests/Unit/Shared/Metrics/Registry/MemoryRegistryTest.php +++ b/tests/Unit/Shared/Metrics/Registry/MemoryRegistryTest.php @@ -32,7 +32,6 @@ public function providerForTestDescribe(): array /** * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry::register * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry::describe - * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry::__construct * @dataProvider providerForTestDescribe */ public function testDescribe(array $adds, array $expected): void From 3ca3ae94130dab4586eb043935dabbf8380799e9 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 11:47:33 +0300 Subject: [PATCH 22/34] fix lint --- src/Presentation/Console/Command/LintCommand.php | 1 - src/Providers/MetricsProvider.php | 3 ++- src/Shared/Metrics/Collector/Collector.php | 12 +++++++++++- src/Shared/Metrics/Collector/Counter.php | 2 +- src/Shared/Metrics/Registry/CollectorRegisterer.php | 1 + src/Shared/Metrics/Registry/NullRegistry.php | 1 - tests/Unit/Application/Linter/LinterFactoryTest.php | 9 --------- .../Linter/TaskHandlers/LintTaskHandlerTest.php | 11 ----------- .../RequestFetcher/CiRequestFetcherTest.php | 1 - tests/Unit/Infrastructure/Rule/ResolverTest.php | 1 - 10 files changed, 15 insertions(+), 27 deletions(-) diff --git a/src/Presentation/Console/Command/LintCommand.php b/src/Presentation/Console/Command/LintCommand.php index 1291e031d..07de63b2c 100644 --- a/src/Presentation/Console/Command/LintCommand.php +++ b/src/Presentation/Console/Command/LintCommand.php @@ -18,7 +18,6 @@ use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Arrayee; use ArtARTs36\MergeRequestLinter\Shared\Events\EventManager; use ArtARTs36\MergeRequestLinter\Shared\File\Bytes; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Collector; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegistry; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputInterface; diff --git a/src/Providers/MetricsProvider.php b/src/Providers/MetricsProvider.php index 442492490..cc998ffa7 100644 --- a/src/Providers/MetricsProvider.php +++ b/src/Providers/MetricsProvider.php @@ -19,7 +19,8 @@ final class MetricsProvider extends Provider { public function provide(): void - {; + { + ; $this ->container ->get(EventManager::class) diff --git a/src/Shared/Metrics/Collector/Collector.php b/src/Shared/Metrics/Collector/Collector.php index 382fcf779..4c741bb3b 100644 --- a/src/Shared/Metrics/Collector/Collector.php +++ b/src/Shared/Metrics/Collector/Collector.php @@ -2,13 +2,23 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector; +/** + * Interface for Collector. + */ interface Collector { + /** + * Get subject. + */ public function getSubject(): MetricSubject; - + + /** + * Get metric type. + */ public function getMetricType(): MetricType; /** + * Get samples. * @return array */ public function getSamples(): array; diff --git a/src/Shared/Metrics/Collector/Counter.php b/src/Shared/Metrics/Collector/Counter.php index 98aa26182..9e118436e 100644 --- a/src/Shared/Metrics/Collector/Counter.php +++ b/src/Shared/Metrics/Collector/Counter.php @@ -34,4 +34,4 @@ public function getMetricType(): MetricType { return MetricType::Counter; } -} \ No newline at end of file +} diff --git a/src/Shared/Metrics/Registry/CollectorRegisterer.php b/src/Shared/Metrics/Registry/CollectorRegisterer.php index 4c6bc30cc..a8e5677ff 100644 --- a/src/Shared/Metrics/Registry/CollectorRegisterer.php +++ b/src/Shared/Metrics/Registry/CollectorRegisterer.php @@ -10,6 +10,7 @@ interface CollectorRegisterer { /** + * Get or register. * @template C of Collector * @param C $collector * @return C diff --git a/src/Shared/Metrics/Registry/NullRegistry.php b/src/Shared/Metrics/Registry/NullRegistry.php index 3264b4c71..2ee238925 100644 --- a/src/Shared/Metrics/Registry/NullRegistry.php +++ b/src/Shared/Metrics/Registry/NullRegistry.php @@ -5,7 +5,6 @@ use ArtARTs36\MergeRequestLinter\Shared\DataStructure\ArrayMap; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\Map; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Collector; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\CounterVector; /** * @codeCoverageIgnore diff --git a/tests/Unit/Application/Linter/LinterFactoryTest.php b/tests/Unit/Application/Linter/LinterFactoryTest.php index 70d1b20b2..568e4a4d6 100644 --- a/tests/Unit/Application/Linter/LinterFactoryTest.php +++ b/tests/Unit/Application/Linter/LinterFactoryTest.php @@ -4,15 +4,6 @@ use ArtARTs36\MergeRequestLinter\Application\Linter\Linter; use ArtARTs36\MergeRequestLinter\Application\Linter\LinterFactory; -use ArtARTs36\MergeRequestLinter\Domain\Configuration\CommentsConfig; -use ArtARTs36\MergeRequestLinter\Domain\Configuration\CommentsPostStrategy; -use ArtARTs36\MergeRequestLinter\Domain\Configuration\Config; -use ArtARTs36\MergeRequestLinter\Domain\Configuration\HttpClientConfig; -use ArtARTs36\MergeRequestLinter\Domain\Configuration\LinterConfig; -use ArtARTs36\MergeRequestLinter\Domain\Configuration\NotificationsConfig; -use ArtARTs36\MergeRequestLinter\Domain\Linter\LinterOptions; -use ArtARTs36\MergeRequestLinter\Domain\Rule\Rules; -use ArtARTs36\MergeRequestLinter\Shared\DataStructure\ArrayMap; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\NullRegistry; use ArtARTs36\MergeRequestLinter\Tests\Mocks\NullEventDispatcher; use ArtARTs36\MergeRequestLinter\Tests\TestCase; diff --git a/tests/Unit/Application/Linter/TaskHandlers/LintTaskHandlerTest.php b/tests/Unit/Application/Linter/TaskHandlers/LintTaskHandlerTest.php index 22a2df089..7f271c5a4 100644 --- a/tests/Unit/Application/Linter/TaskHandlers/LintTaskHandlerTest.php +++ b/tests/Unit/Application/Linter/TaskHandlers/LintTaskHandlerTest.php @@ -6,20 +6,9 @@ use ArtARTs36\MergeRequestLinter\Application\Linter\LinterFactory; use ArtARTs36\MergeRequestLinter\Application\Linter\TaskHandlers\LintTaskHandler; use ArtARTs36\MergeRequestLinter\Application\Linter\Tasks\LintTask; -use ArtARTs36\MergeRequestLinter\Domain\Configuration\CommentsConfig; -use ArtARTs36\MergeRequestLinter\Domain\Configuration\CommentsPostStrategy; -use ArtARTs36\MergeRequestLinter\Domain\Configuration\Config; -use ArtARTs36\MergeRequestLinter\Domain\Configuration\HttpClientConfig; -use ArtARTs36\MergeRequestLinter\Domain\Configuration\LinterConfig; -use ArtARTs36\MergeRequestLinter\Domain\Configuration\MetricsConfig; -use ArtARTs36\MergeRequestLinter\Domain\Configuration\MetricsStorageConfig; -use ArtARTs36\MergeRequestLinter\Domain\Configuration\NotificationsConfig; -use ArtARTs36\MergeRequestLinter\Domain\Linter\LinterOptions; use ArtARTs36\MergeRequestLinter\Domain\Linter\LintState; -use ArtARTs36\MergeRequestLinter\Domain\Rule\Rules; use ArtARTs36\MergeRequestLinter\Infrastructure\Configuration\Resolver\ResolvedConfig; use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Configuration\ConfigResolver; -use ArtARTs36\MergeRequestLinter\Shared\DataStructure\ArrayMap; use ArtARTs36\MergeRequestLinter\Tests\Mocks\MockCi; use ArtARTs36\MergeRequestLinter\Tests\Mocks\MockCiSystemFactory; use ArtARTs36\MergeRequestLinter\Tests\Mocks\MockEventDispatcher; diff --git a/tests/Unit/Infrastructure/RequestFetcher/CiRequestFetcherTest.php b/tests/Unit/Infrastructure/RequestFetcher/CiRequestFetcherTest.php index 86dfcdb1d..c6e7adf15 100644 --- a/tests/Unit/Infrastructure/RequestFetcher/CiRequestFetcherTest.php +++ b/tests/Unit/Infrastructure/RequestFetcher/CiRequestFetcherTest.php @@ -8,7 +8,6 @@ use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\CounterVector; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Sample; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\MemoryRegistry; -use ArtARTs36\MergeRequestLinter\Shared\Time\LocalClock; use ArtARTs36\MergeRequestLinter\Tests\Mocks\MockCi; use ArtARTs36\MergeRequestLinter\Tests\Mocks\MockCiSystemFactory; use ArtARTs36\MergeRequestLinter\Tests\TestCase; diff --git a/tests/Unit/Infrastructure/Rule/ResolverTest.php b/tests/Unit/Infrastructure/Rule/ResolverTest.php index 303cdd04b..5cde72200 100644 --- a/tests/Unit/Infrastructure/Rule/ResolverTest.php +++ b/tests/Unit/Infrastructure/Rule/ResolverTest.php @@ -12,7 +12,6 @@ use ArtARTs36\MergeRequestLinter\Infrastructure\Rule\Resolver; use ArtARTs36\MergeRequestLinter\Shared\DataStructure\ArrayMap; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\CounterVector; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\NullCounter; use ArtARTs36\MergeRequestLinter\Shared\Reflection\Instantiator\Finder; use ArtARTs36\MergeRequestLinter\Shared\Reflection\ParameterMapBuilder; use ArtARTs36\MergeRequestLinter\Tests\Mocks\MockConditionOperator; From 836d83649a3a17755e93260b805b5a5e0cb27132 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 11:54:10 +0300 Subject: [PATCH 23/34] add test --- src/Shared/Metrics/Collector/GaugeVector.php | 2 +- .../Shared/Metrics/Collector/GaugeTest.php | 26 +++++++++++++++++++ .../Metrics/Collector/GaugeVectorTest.php | 22 ++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 tests/Unit/Shared/Metrics/Collector/GaugeTest.php create mode 100644 tests/Unit/Shared/Metrics/Collector/GaugeVectorTest.php diff --git a/src/Shared/Metrics/Collector/GaugeVector.php b/src/Shared/Metrics/Collector/GaugeVector.php index 2a9cdc6b2..453efcc1b 100644 --- a/src/Shared/Metrics/Collector/GaugeVector.php +++ b/src/Shared/Metrics/Collector/GaugeVector.php @@ -10,7 +10,7 @@ final class GaugeVector extends AbstractVector /** * @param array $labels */ - public function add(array $labels): Gauge + public function add(array $labels = []): Gauge { return $this->attach(function (array $labels) { return new Gauge($this->getSubject(), $labels); diff --git a/tests/Unit/Shared/Metrics/Collector/GaugeTest.php b/tests/Unit/Shared/Metrics/Collector/GaugeTest.php new file mode 100644 index 000000000..a7e643153 --- /dev/null +++ b/tests/Unit/Shared/Metrics/Collector/GaugeTest.php @@ -0,0 +1,26 @@ +getFirstSampleValue()); + + $gauge->set(1); + + self::assertEquals(1, $gauge->getFirstSampleValue()); + } +} diff --git a/tests/Unit/Shared/Metrics/Collector/GaugeVectorTest.php b/tests/Unit/Shared/Metrics/Collector/GaugeVectorTest.php new file mode 100644 index 000000000..179720879 --- /dev/null +++ b/tests/Unit/Shared/Metrics/Collector/GaugeVectorTest.php @@ -0,0 +1,22 @@ +add(); + + self::assertEquals($subject, $createdGaugeFirst->getSubject()); + } +} From 391bb5f88f3d91c4c3ff8ed5986a558013328a99 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 13:03:37 +0300 Subject: [PATCH 24/34] add test --- src/Shared/Metrics/Collector/GaugeVector.php | 2 +- src/Shared/Metrics/Collector/MetricType.php | 3 +++ src/Shared/Metrics/Collector/Sample.php | 3 +++ .../Metrics/Collector/CounterVectorTest.php | 22 +++++++++++++++++++ .../Metrics/Collector/GaugeVectorTest.php | 2 +- 5 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 tests/Unit/Shared/Metrics/Collector/CounterVectorTest.php diff --git a/src/Shared/Metrics/Collector/GaugeVector.php b/src/Shared/Metrics/Collector/GaugeVector.php index 453efcc1b..2a9cdc6b2 100644 --- a/src/Shared/Metrics/Collector/GaugeVector.php +++ b/src/Shared/Metrics/Collector/GaugeVector.php @@ -10,7 +10,7 @@ final class GaugeVector extends AbstractVector /** * @param array $labels */ - public function add(array $labels = []): Gauge + public function add(array $labels): Gauge { return $this->attach(function (array $labels) { return new Gauge($this->getSubject(), $labels); diff --git a/src/Shared/Metrics/Collector/MetricType.php b/src/Shared/Metrics/Collector/MetricType.php index 70ac3eb9b..a4f4aea0e 100644 --- a/src/Shared/Metrics/Collector/MetricType.php +++ b/src/Shared/Metrics/Collector/MetricType.php @@ -2,6 +2,9 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector; +/** + * @codeCoverageIgnore + */ enum MetricType: string { case Gauge = 'Gauge'; diff --git a/src/Shared/Metrics/Collector/Sample.php b/src/Shared/Metrics/Collector/Sample.php index bcada9e95..ab5b838a5 100644 --- a/src/Shared/Metrics/Collector/Sample.php +++ b/src/Shared/Metrics/Collector/Sample.php @@ -2,6 +2,9 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector; +/** + * @codeCoverageIgnore + */ class Sample { /** diff --git a/tests/Unit/Shared/Metrics/Collector/CounterVectorTest.php b/tests/Unit/Shared/Metrics/Collector/CounterVectorTest.php new file mode 100644 index 000000000..33d49e799 --- /dev/null +++ b/tests/Unit/Shared/Metrics/Collector/CounterVectorTest.php @@ -0,0 +1,22 @@ +add(['k' => 'v']); + + self::assertEquals($subject, $createdCounter->getSubject()); + } +} diff --git a/tests/Unit/Shared/Metrics/Collector/GaugeVectorTest.php b/tests/Unit/Shared/Metrics/Collector/GaugeVectorTest.php index 179720879..41256d336 100644 --- a/tests/Unit/Shared/Metrics/Collector/GaugeVectorTest.php +++ b/tests/Unit/Shared/Metrics/Collector/GaugeVectorTest.php @@ -15,7 +15,7 @@ public function testAdd(): void { $vector = new GaugeVector($subject = new MetricSubject('test', 'collector', '')); - $createdGaugeFirst = $vector->add(); + $createdGaugeFirst = $vector->add([]); self::assertEquals($subject, $createdGaugeFirst->getSubject()); } From 075778895aad3262ac8e929a589a0463f739c960 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 14:11:39 +0300 Subject: [PATCH 25/34] rename var --- src/Shared/Metrics/Collector/AbstractVector.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Shared/Metrics/Collector/AbstractVector.php b/src/Shared/Metrics/Collector/AbstractVector.php index 4e6a8db51..c7cb35ce7 100644 --- a/src/Shared/Metrics/Collector/AbstractVector.php +++ b/src/Shared/Metrics/Collector/AbstractVector.php @@ -34,8 +34,8 @@ public function getSamples(): array { $samples = []; - foreach ($this->collectors as $counter) { - foreach ($counter->getSamples() as $sample) { + foreach ($this->collectors as $collector) { + foreach ($collector->getSamples() as $sample) { $samples[] = $sample; } } From eeb229655ec0f0b7ff06f86f8be9f10a5dbece8f Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 20:07:44 +0300 Subject: [PATCH 26/34] add test --- .../Collector/AbstractCollectorTest.php | 60 +++++++++++++++++++ .../Metrics/Collector/AbstractVectorTest.php | 57 ++++++++++++++++++ .../Metrics/Collector/CounterVectorTest.php | 10 ++++ 3 files changed, 127 insertions(+) create mode 100644 tests/Unit/Shared/Metrics/Collector/AbstractCollectorTest.php create mode 100644 tests/Unit/Shared/Metrics/Collector/AbstractVectorTest.php diff --git a/tests/Unit/Shared/Metrics/Collector/AbstractCollectorTest.php b/tests/Unit/Shared/Metrics/Collector/AbstractCollectorTest.php new file mode 100644 index 000000000..0c59db4af --- /dev/null +++ b/tests/Unit/Shared/Metrics/Collector/AbstractCollectorTest.php @@ -0,0 +1,60 @@ + [ + 'existsSamples' => [], + 'expectedValue' => null, + ], + 'returns first sample value from array with length 1' => [ + 'existsSamples' => [ + new Sample('val', []), + ], + 'expectedValue' => 'val', + ], + 'returns first sample value from array with length 2' => [ + 'existsSamples' => [ + new Sample('val', []), + new Sample('val2', []), + ], + 'expectedValue' => 'val', + ], + ]; + } + + /** + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\AbstractCollector::getFirstSampleValue + * + * @dataProvider providerForTestGetFirstSampleValue + */ + public function testGetFirstSampleValue(array $existsSamples, int|float|string|null $expectedValue): void + { + $collector = new class ($existsSamples) extends AbstractCollector { + public function __construct(private array $samples) + { + parent::__construct(new MetricSubject('', '', '')); + } + + public function getSamples(): array + { + return $this->samples; + } + + public function getMetricType(): MetricType + {} + }; + + self::assertEquals($expectedValue, $collector->getFirstSampleValue()); + } +} diff --git a/tests/Unit/Shared/Metrics/Collector/AbstractVectorTest.php b/tests/Unit/Shared/Metrics/Collector/AbstractVectorTest.php new file mode 100644 index 000000000..d225e81d2 --- /dev/null +++ b/tests/Unit/Shared/Metrics/Collector/AbstractVectorTest.php @@ -0,0 +1,57 @@ + [ + 'subCollectors' => [], + 'samples' => [], + ], + 'collectors with samples' => [ + 'subCollectors' => [ + new Counter(new MetricSubject('', '', '')), + ], + 'samples' => [ + new Sample(0, []), + ], + ], + ]; + } + + /** + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\AbstractVector::getSamples + * + * @dataProvider providerForTestSamples + */ + public function testGetSamples(array $subCollectors, array $expectedSamples): void + { + $vector = new class ($subCollectors) extends AbstractVector { + public function __construct(array $collectors) + { + parent::__construct(new MetricSubject('', '', '')); + + foreach ($collectors as $collector) { + $this->attach(fn () => $collector, []); + } + } + + public function getMetricType(): MetricType + { + return MetricType::Counter; + } + }; + + self::assertEquals($expectedSamples, $vector->getSamples()); + } +} diff --git a/tests/Unit/Shared/Metrics/Collector/CounterVectorTest.php b/tests/Unit/Shared/Metrics/Collector/CounterVectorTest.php index 33d49e799..155e288c7 100644 --- a/tests/Unit/Shared/Metrics/Collector/CounterVectorTest.php +++ b/tests/Unit/Shared/Metrics/Collector/CounterVectorTest.php @@ -19,4 +19,14 @@ public function testAdd(): void self::assertEquals($subject, $createdCounter->getSubject()); } + + /** + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\CounterVector::null + */ + public function testNull(): void + { + $vector = CounterVector::null(); + + self::assertEquals(new MetricSubject('', '', ''), $vector->getSubject()); + } } From 93cacbc387ec5ee02a53bff11e24f301e352a9b0 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 20:15:01 +0300 Subject: [PATCH 27/34] add test for abstract vector --- tests/Mocks/MockCollector.php | 25 +++++++++++++++++++ .../Metrics/Collector/AbstractVectorTest.php | 24 ++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 tests/Mocks/MockCollector.php diff --git a/tests/Mocks/MockCollector.php b/tests/Mocks/MockCollector.php new file mode 100644 index 000000000..1888b6dc4 --- /dev/null +++ b/tests/Mocks/MockCollector.php @@ -0,0 +1,25 @@ +getSamples()); } + + /** + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\AbstractVector::attach + */ + public function testAttachExistsCollector(): void + { + $vector = new class(new MetricSubject('', '', '')) extends AbstractVector { + public function add(array $labels): Collector + { + return $this->attach(fn () => new MockCollector(), $labels); + } + + public function getMetricType(): MetricType + { + } + }; + + $collectorOne = $vector->add(['k' => 'v']); + $collectorTwo = $vector->add(['k' => 'v']); + + self::assertSame(spl_object_hash($collectorOne), spl_object_hash($collectorTwo)); + } } From f53bd6464cfdf62edd115999ab12009da8fd92de Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 20:40:13 +0300 Subject: [PATCH 28/34] add test for renderer --- .../Metrics/MetricStorageFactory.php | 8 +-- src/Shared/Metrics/Storage/MetricStorage.php | 2 +- src/Shared/Metrics/Storage/NullStorage.php | 3 + .../Storage/PrometheusPushGateway/Client.php | 27 +++----- .../PrometheusPushGateway/HttpClient.php | 22 ++++++ .../PrometheusPushGateway/PushGateway.php | 4 +- .../PrometheusPushGateway/Renderer.php | 2 +- tests/Mocks/MockCollector.php | 13 +++- .../Metrics/Storage/PushGatewayTest.php | 37 ++++++++++ .../Shared/Metrics/Storage/RendererTest.php | 68 +++++++++++++++++++ 10 files changed, 160 insertions(+), 26 deletions(-) create mode 100644 src/Shared/Metrics/Storage/PrometheusPushGateway/HttpClient.php create mode 100644 tests/Unit/Shared/Metrics/Storage/PushGatewayTest.php create mode 100644 tests/Unit/Shared/Metrics/Storage/RendererTest.php diff --git a/src/Infrastructure/Metrics/MetricStorageFactory.php b/src/Infrastructure/Metrics/MetricStorageFactory.php index cda0d7b86..2b5884c58 100644 --- a/src/Infrastructure/Metrics/MetricStorageFactory.php +++ b/src/Infrastructure/Metrics/MetricStorageFactory.php @@ -5,15 +5,15 @@ use ArtARTs36\MergeRequestLinter\Domain\Configuration\MetricsStorageConfig; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\MetricStorage; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\NullStorage; -use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\Client; +use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\HttpClient; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\PushGateway; use ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\Renderer; -use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Http\Client as HttpClient; +use ArtARTs36\MergeRequestLinter\Infrastructure\Contracts\Http\Client as Http; class MetricStorageFactory { public function __construct( - private readonly HttpClient $httpClient, + private readonly Http $httpClient, ) { } @@ -21,7 +21,7 @@ public function create(MetricsStorageConfig $config): MetricStorage { if ($config->name === MetricsStorageConfig::NAME_PROMETHEUS_PUSH_GATEWAY) { return new PushGateway( - new Client($this->httpClient, $config->address), + new HttpClient($this->httpClient, $config->address), new Renderer(), ); } diff --git a/src/Shared/Metrics/Storage/MetricStorage.php b/src/Shared/Metrics/Storage/MetricStorage.php index 2ad28b15c..e216431cd 100644 --- a/src/Shared/Metrics/Storage/MetricStorage.php +++ b/src/Shared/Metrics/Storage/MetricStorage.php @@ -10,7 +10,7 @@ interface MetricStorage { /** - * Commit metric records. + * Commit metric records to persistent storage. * * @param array $collectors */ diff --git a/src/Shared/Metrics/Storage/NullStorage.php b/src/Shared/Metrics/Storage/NullStorage.php index 0ebb6bafe..629e29e9d 100644 --- a/src/Shared/Metrics/Storage/NullStorage.php +++ b/src/Shared/Metrics/Storage/NullStorage.php @@ -2,6 +2,9 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage; +/** + * @codeCoverageIgnore + */ final class NullStorage implements MetricStorage { public function commit(string $id, array $collectors): void diff --git a/src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php b/src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php index 267ea961e..5fa51ecd0 100644 --- a/src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php +++ b/src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php @@ -2,21 +2,16 @@ namespace ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway; -use Psr\Http\Client\ClientInterface as HttpClient; -use GuzzleHttp\Psr7\Request; - -class Client +/** + * Interface for PushGateway Client. + */ +interface Client { - public function __construct( - private readonly HttpClient $http, - private readonly string $address, - ) { - } - - public function replace(string $job, string $data): void - { - $url = sprintf("%s/metrics/job/%s", $this->address, $job); - - $this->http->sendRequest(new Request('POST', $url, body: $data)); - } + /** + * Replace job metrics data. + * + * @param non-empty-string $job + * @param non-empty-string $data + */ + public function replace(string $job, string $data): void; } diff --git a/src/Shared/Metrics/Storage/PrometheusPushGateway/HttpClient.php b/src/Shared/Metrics/Storage/PrometheusPushGateway/HttpClient.php new file mode 100644 index 000000000..fc2effe88 --- /dev/null +++ b/src/Shared/Metrics/Storage/PrometheusPushGateway/HttpClient.php @@ -0,0 +1,22 @@ +address, $job); + + $this->http->sendRequest(new Request('POST', $url, body: $data)); + } +} diff --git a/src/Shared/Metrics/Storage/PrometheusPushGateway/PushGateway.php b/src/Shared/Metrics/Storage/PrometheusPushGateway/PushGateway.php index f81ab0f21..7f9e90d2c 100644 --- a/src/Shared/Metrics/Storage/PrometheusPushGateway/PushGateway.php +++ b/src/Shared/Metrics/Storage/PrometheusPushGateway/PushGateway.php @@ -7,8 +7,8 @@ final class PushGateway implements MetricStorage { public function __construct( - private readonly Client $client, - private readonly Renderer $renderer, + private readonly Client $client, + private readonly Renderer $renderer, ) { } diff --git a/src/Shared/Metrics/Storage/PrometheusPushGateway/Renderer.php b/src/Shared/Metrics/Storage/PrometheusPushGateway/Renderer.php index fa4d3d977..670bfe26c 100644 --- a/src/Shared/Metrics/Storage/PrometheusPushGateway/Renderer.php +++ b/src/Shared/Metrics/Storage/PrometheusPushGateway/Renderer.php @@ -24,7 +24,7 @@ public function render(iterable $collectors): string $key = $collector->getSubject()->identity(); - $content[] = "# HELP $key The number of items in the queue."; + $content[] = "# HELP $key {$collector->getSubject()->title}"; $content[] = "# TYPE $key {$collector->getMetricType()->value}"; $content[] = "\n"; diff --git a/tests/Mocks/MockCollector.php b/tests/Mocks/MockCollector.php index 1888b6dc4..c34c9da51 100644 --- a/tests/Mocks/MockCollector.php +++ b/tests/Mocks/MockCollector.php @@ -8,9 +8,18 @@ final class MockCollector implements Collector { + private readonly MetricSubject $metricSubject; + + public function __construct( + ?MetricSubject $metricSubject = null, + private readonly array $samples = [], + ) { + $this->metricSubject = $metricSubject ?? new MetricSubject('mock', 'collector', 'Mock title'); + } + public function getSubject(): MetricSubject { - // TODO: Implement getSubject() method. + return $this->metricSubject; } public function getMetricType(): MetricType @@ -20,6 +29,6 @@ public function getMetricType(): MetricType public function getSamples(): array { - // TODO: Implement getSamples() method. + return $this->samples; } } diff --git a/tests/Unit/Shared/Metrics/Storage/PushGatewayTest.php b/tests/Unit/Shared/Metrics/Storage/PushGatewayTest.php new file mode 100644 index 000000000..6c0d1af57 --- /dev/null +++ b/tests/Unit/Shared/Metrics/Storage/PushGatewayTest.php @@ -0,0 +1,37 @@ +createMock(Client::class); + $client + ->expects(new InvokedCount(1)) + ->method('replace') + ->with($id, $renderedVal); + + $renderer = $this->createMock(Renderer::class); + $renderer + ->expects(new InvokedCount(1)) + ->method('render') + ->willReturn($renderedVal); + + $gateway = new PushGateway($client, $renderer); + + $gateway->commit($id, []); + } +} diff --git a/tests/Unit/Shared/Metrics/Storage/RendererTest.php b/tests/Unit/Shared/Metrics/Storage/RendererTest.php new file mode 100644 index 000000000..6039d1388 --- /dev/null +++ b/tests/Unit/Shared/Metrics/Storage/RendererTest.php @@ -0,0 +1,68 @@ + [], + 'expectedContent' => '', + ], + [ + 'collectors' => [ + new MockCollector(), + ], + 'expectedContent' => '', + ], + [ + 'collectors' => [ + new Counter(new MetricSubject('test', 'collector', 'Super title'), [], 2), + ], + 'expectedContent' => "# HELP test_collector Super title +# TYPE test_collector Counter +\n +test_collector 2\n\n", + ], + [ + 'collectors' => [ + new Counter(new MetricSubject('test', 'collector', 'Super title'), ['label1' => 'value1'], 2), + ], + 'expectedContent' => "# HELP test_collector Super title +# TYPE test_collector Counter +\n +test_collector{label1=\"value1\"} 2\n\n", + ], + [ + 'collectors' => [ + new Counter(new MetricSubject('test', 'collector', 'Super title'), ['label1' => 'value1', 'label2' => 'value2'], 2), + ], + 'expectedContent' => "# HELP test_collector Super title +# TYPE test_collector Counter +\n +test_collector{label1=\"value1\",label2=\"value2\"} 2\n\n", + ], + ]; + } + + /** + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\Renderer::render + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\Renderer::collectLabels + * + * @dataProvider providerForTestRender + */ + public function testRender(array $collectors, string $expectedContent): void + { + $renderer = new Renderer(); + + self::assertEquals($expectedContent, $renderer->render($collectors)); + } +} From 46e696616a367eda77029a468de71448b92f14a4 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 20:42:05 +0300 Subject: [PATCH 29/34] add cov --- tests/Unit/Shared/Metrics/Storage/PushGatewayTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Unit/Shared/Metrics/Storage/PushGatewayTest.php b/tests/Unit/Shared/Metrics/Storage/PushGatewayTest.php index 6c0d1af57..5bff006ba 100644 --- a/tests/Unit/Shared/Metrics/Storage/PushGatewayTest.php +++ b/tests/Unit/Shared/Metrics/Storage/PushGatewayTest.php @@ -12,6 +12,7 @@ final class PushGatewayTest extends TestCase { /** * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\PushGateway::commit + * @covers \ArtARTs36\MergeRequestLinter\Shared\Metrics\Storage\PrometheusPushGateway\PushGateway::__construct */ public function testCommit(): void { From 598682e59c9416ac827929712899a588bcc8eef9 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 20:48:12 +0300 Subject: [PATCH 30/34] add test for pushgateway client --- .../Shared/Metrics/Storage/HttpClientTest.php | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 tests/Unit/Shared/Metrics/Storage/HttpClientTest.php diff --git a/tests/Unit/Shared/Metrics/Storage/HttpClientTest.php b/tests/Unit/Shared/Metrics/Storage/HttpClientTest.php new file mode 100644 index 000000000..b42a71bb4 --- /dev/null +++ b/tests/Unit/Shared/Metrics/Storage/HttpClientTest.php @@ -0,0 +1,32 @@ +replace('job-123', 'content'); + + self::assertNotNull($http->lastRequest()); + self::assertEquals( + 'http://push-gateway/metrics/job/job-123', + $http->lastRequest()->getUri()->__toString(), + ); + } +} From 776eaf24748c49954ed483330e8bc72450c7b8ac Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 20:48:44 +0300 Subject: [PATCH 31/34] move tests --- .../Storage/{ => PrometheusPushGateway}/HttpClientTest.php | 5 +---- .../Storage/{ => PrometheusPushGateway}/PushGatewayTest.php | 2 +- .../Storage/{ => PrometheusPushGateway}/RendererTest.php | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) rename tests/Unit/Shared/Metrics/Storage/{ => PrometheusPushGateway}/HttpClientTest.php (88%) rename tests/Unit/Shared/Metrics/Storage/{ => PrometheusPushGateway}/PushGatewayTest.php (97%) rename tests/Unit/Shared/Metrics/Storage/{ => PrometheusPushGateway}/RendererTest.php (98%) diff --git a/tests/Unit/Shared/Metrics/Storage/HttpClientTest.php b/tests/Unit/Shared/Metrics/Storage/PrometheusPushGateway/HttpClientTest.php similarity index 88% rename from tests/Unit/Shared/Metrics/Storage/HttpClientTest.php rename to tests/Unit/Shared/Metrics/Storage/PrometheusPushGateway/HttpClientTest.php index b42a71bb4..e84e669c8 100644 --- a/tests/Unit/Shared/Metrics/Storage/HttpClientTest.php +++ b/tests/Unit/Shared/Metrics/Storage/PrometheusPushGateway/HttpClientTest.php @@ -1,13 +1,10 @@ Date: Thu, 28 Sep 2023 20:52:28 +0300 Subject: [PATCH 32/34] remove metrics from config --- .mr-linter.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.mr-linter.yml b/.mr-linter.yml index a61008897..2dbb2fb07 100644 --- a/.mr-linter.yml +++ b/.mr-linter.yml @@ -105,11 +105,6 @@ ci: credentials: token: 'env(MR_LINTER_GITHUB_HTTP_TOKEN)' -metrics: - storage: - prometheusPushGateway: - address: http://host.docker.internal:9091 - comments: strategy: 'single' messages: From ff5842a278c322a2414755b4b268f0bae22670f8 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 20:57:41 +0300 Subject: [PATCH 33/34] fix stat analyse --- src/Shared/Metrics/Storage/MetricStorage.php | 1 + src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php | 1 - tests/Unit/Shared/Metrics/Collector/AbstractCollectorTest.php | 3 ++- tests/Unit/Shared/Metrics/Collector/AbstractVectorTest.php | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Shared/Metrics/Storage/MetricStorage.php b/src/Shared/Metrics/Storage/MetricStorage.php index e216431cd..a089d4705 100644 --- a/src/Shared/Metrics/Storage/MetricStorage.php +++ b/src/Shared/Metrics/Storage/MetricStorage.php @@ -12,6 +12,7 @@ interface MetricStorage /** * Commit metric records to persistent storage. * + * @param non-empty-string $id * @param array $collectors */ public function commit(string $id, array $collectors): void; diff --git a/src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php b/src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php index 5fa51ecd0..d9a160044 100644 --- a/src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php +++ b/src/Shared/Metrics/Storage/PrometheusPushGateway/Client.php @@ -11,7 +11,6 @@ interface Client * Replace job metrics data. * * @param non-empty-string $job - * @param non-empty-string $data */ public function replace(string $job, string $data): void; } diff --git a/tests/Unit/Shared/Metrics/Collector/AbstractCollectorTest.php b/tests/Unit/Shared/Metrics/Collector/AbstractCollectorTest.php index 0c59db4af..22a49df61 100644 --- a/tests/Unit/Shared/Metrics/Collector/AbstractCollectorTest.php +++ b/tests/Unit/Shared/Metrics/Collector/AbstractCollectorTest.php @@ -52,7 +52,8 @@ public function getSamples(): array } public function getMetricType(): MetricType - {} + { + } }; self::assertEquals($expectedValue, $collector->getFirstSampleValue()); diff --git a/tests/Unit/Shared/Metrics/Collector/AbstractVectorTest.php b/tests/Unit/Shared/Metrics/Collector/AbstractVectorTest.php index 9a3692ebf..2db57efd9 100644 --- a/tests/Unit/Shared/Metrics/Collector/AbstractVectorTest.php +++ b/tests/Unit/Shared/Metrics/Collector/AbstractVectorTest.php @@ -62,7 +62,7 @@ public function getMetricType(): MetricType */ public function testAttachExistsCollector(): void { - $vector = new class(new MetricSubject('', '', '')) extends AbstractVector { + $vector = new class (new MetricSubject('', '', '')) extends AbstractVector { public function add(array $labels): Collector { return $this->attach(fn () => new MockCollector(), $labels); From d18448713476f509d2e7173b3d82dc32ef533bc3 Mon Sep 17 00:00:00 2001 From: artarts36 Date: Thu, 28 Sep 2023 21:00:08 +0300 Subject: [PATCH 34/34] fix lint --- src/Shared/Metrics/Collector/Collector.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Shared/Metrics/Collector/Collector.php b/src/Shared/Metrics/Collector/Collector.php index 4c741bb3b..139f84b20 100644 --- a/src/Shared/Metrics/Collector/Collector.php +++ b/src/Shared/Metrics/Collector/Collector.php @@ -7,14 +7,14 @@ */ interface Collector { - /** - * Get subject. - */ + /** + * Get metric subject. + */ public function getSubject(): MetricSubject; - /** - * Get metric type. - */ + /** + * Get metric type. + */ public function getMetricType(): MetricType; /**