Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reporter #68

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a93cced
add prometheus reporter
ArtARTs36 Sep 26, 2023
8e82e4c
add category to metric subjct
ArtARTs36 Sep 27, 2023
198c8e1
add samples
ArtARTs36 Sep 27, 2023
524895f
move storage
ArtARTs36 Sep 27, 2023
5dc448b
refactor
ArtARTs36 Sep 27, 2023
33ddb7a
refactor
ArtARTs36 Sep 27, 2023
4e800a7
move flusher
ArtARTs36 Sep 27, 2023
48a3502
rename provider
ArtARTs36 Sep 27, 2023
e33bd6c
add report config
ArtARTs36 Sep 27, 2023
3e388ba
add metric storage factory
ArtARTs36 Sep 27, 2023
ee82e2d
add metric registerer
ArtARTs36 Sep 27, 2023
06f4522
refactor metrics
ArtARTs36 Sep 28, 2023
adcb011
add metric handler for rule events
ArtARTs36 Sep 28, 2023
72cfb7f
fix stat-analyse issues
ArtARTs36 Sep 28, 2023
f1413ff
print metrics
ArtARTs36 Sep 28, 2023
714222e
fix stat analyse
ArtARTs36 Sep 28, 2023
42cc3f6
fix test part
ArtARTs36 Sep 28, 2023
45c8619
rename manager to registry
ArtARTs36 Sep 28, 2023
9b82088
test
ArtARTs36 Sep 28, 2023
1659de3
fix test namespace
ArtARTs36 Sep 28, 2023
d43fdc9
fix test
ArtARTs36 Sep 28, 2023
3ca3ae9
fix lint
ArtARTs36 Sep 28, 2023
836d836
add test
ArtARTs36 Sep 28, 2023
391bb5f
add test
ArtARTs36 Sep 28, 2023
0757788
rename var
ArtARTs36 Sep 28, 2023
eeb2296
add test
ArtARTs36 Sep 28, 2023
93cacbc
add test for abstract vector
ArtARTs36 Sep 28, 2023
f53bd64
add test for renderer
ArtARTs36 Sep 28, 2023
46e6966
add cov
ArtARTs36 Sep 28, 2023
598682e
add test for pushgateway client
ArtARTs36 Sep 28, 2023
776eaf2
move tests
ArtARTs36 Sep 28, 2023
c4d9c4e
remove metrics from config
ArtARTs36 Sep 28, 2023
ff5842a
fix stat analyse
ArtARTs36 Sep 28, 2023
d184487
fix lint
ArtARTs36 Sep 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -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
11 changes: 11 additions & 0 deletions prom.yml
Original file line number Diff line number Diff line change
@@ -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'
28 changes: 15 additions & 13 deletions src/Application/Linter/Linter.php
Original file line number Diff line number Diff line change
Expand Up @@ -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\Value\IncCounter;
use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricManager;
use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\MetricSubject;
use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\Counter;
use ArtARTs36\MergeRequestLinter\Shared\Metrics\Collector\MetricSubject;
use ArtARTs36\MergeRequestLinter\Shared\Metrics\Registry\CollectorRegisterer;
use ArtARTs36\MergeRequestLinter\Shared\Time\Timer;
use Psr\EventDispatcher\EventDispatcherInterface;

Expand All @@ -31,15 +31,15 @@ public function __construct(
private Rules $rules,
private LinterOptions $options,
private EventDispatcherInterface $events,
private MetricManager $metrics,
private CollectorRegisterer $metrics,
) {
}

public function run(MergeRequest $request): LintResult
{
$timer = Timer::start();

$this->addMetricUsedRules();
$this->addMetricUsedRules($request);

$this->events->dispatch(new LintStartedEvent($request));

Expand Down Expand Up @@ -93,15 +93,17 @@ public function run(MergeRequest $request): LintResult
return $result;
}

private function addMetricUsedRules(): void
private function addMetricUsedRules(MergeRequest $request): void
{
$this->metrics->add(
new MetricSubject(
'linter_used_rules',
'[Linter] Used rules',
),
IncCounter::create($this->rules),
);
$this
->metrics
->register(new Counter(
new MetricSubject('linter', 'used_rules', 'Used rules'),
[
'request' => (string) $request->uri,
],
$this->rules->count(),
));
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/Application/Linter/LinterFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

use ArtARTs36\MergeRequestLinter\Domain\Configuration\Config;
use ArtARTs36\MergeRequestLinter\Domain\Linter\Linter;
use ArtARTs36\MergeRequestLinter\Shared\Metrics\Value\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,
) {
}

Expand Down
16 changes: 8 additions & 8 deletions src/Application/Linter/RunnerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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\Registry\CollectorRegistry;
use ArtARTs36\MergeRequestLinter\Shared\Time\Clock;

class RunnerFactory implements LinterRunnerFactory
Expand All @@ -31,13 +31,13 @@ class RunnerFactory implements LinterRunnerFactory
* @param Map<string, class-string<CiSystem>> $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(),
) {
}

Expand Down
53 changes: 53 additions & 0 deletions src/Application/Rule/Metrics/RuleLintStateMetricHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace ArtARTs36\MergeRequestLinter\Application\Rule\Metrics;

use ArtARTs36\MergeRequestLinter\Domain\Linter\RuleWasFailedEvent;
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\Registry\CollectorRegisterer;

class RuleLintStateMetricHandler
{
public function __construct(
private readonly CounterVector $counter,
) {
}

public static function make(CollectorRegisterer $registerer): self
{
$counter = new CounterVector(new MetricSubject(
'linter',
'rule_lint_state',
'Rule lint state',
));

$registerer->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();
}
}
12 changes: 8 additions & 4 deletions src/Application/Rule/Rules/ConditionRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,27 @@
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);
}

public function lint(MergeRequest $request): array
{
if (! $this->operator->check($request)) {
$this->skippedRules->inc();
$this
->skippedRules
->add([
'rule' => $this->getName(),
])
->inc();

return [];
}
Expand Down
5 changes: 4 additions & 1 deletion src/Domain/Configuration/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -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<CiName, CiSettings> $settings
Expand All @@ -34,6 +36,7 @@ public function __construct(
public NotificationsConfig $notifications,
public LinterConfig $linter,
public CommentsConfig $comments,
public MetricsConfig $metrics,
) {
}
}
14 changes: 14 additions & 0 deletions src/Domain/Configuration/MetricsConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace ArtARTs36\MergeRequestLinter\Domain\Configuration;

/**
* @codeCoverageIgnore
*/
readonly class MetricsConfig
{
public function __construct(
public MetricsStorageConfig $storage,
) {
}
}
23 changes: 23 additions & 0 deletions src/Domain/Configuration/MetricsStorageConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace ArtARTs36\MergeRequestLinter\Domain\Configuration;

readonly class MetricsStorageConfig
{
public const NAME_PROMETHEUS_PUSH_GATEWAY = 'prometheusPushGateway';
public const NAME_NULL = 'null';

public const NAMES = [
self::NAME_PROMETHEUS_PUSH_GATEWAY,
self::NAME_NULL,
];

/**
* @param value-of<self::NAMES> $name
*/
public function __construct(
public string $name,
public string $address,
) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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\Registry\CollectorRegistry;
use ArtARTs36\MergeRequestLinter\Shared\Reflection\Instantiator\Finder;
use ArtARTs36\MergeRequestLinter\Shared\Reflection\ParameterMapBuilder;
use ArtARTs36\MergeRequestLinter\Shared\Reflection\TypeResolver\ResolverFactory;

class ArrayConfigLoaderFactory
Expand All @@ -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(),
) {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,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\Rule\Rules;
Expand Down Expand Up @@ -82,6 +84,7 @@ public function hydrate(array $data, int $subjects = Config::SUBJECT_ALL): Confi
$notifications,
$this->createLinterConfig($data['linter'] ?? []),
$this->createCommentsConfig($data['comments'] ?? []),
$this->createMetricsConfig($data),
);
}

Expand Down Expand Up @@ -155,4 +158,58 @@ private function createCommentsConfig(array $config): CommentsConfig
$messages,
);
}

/**
* @param array<string, mixed> $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']);

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'])) {
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'],
));
}
}
Loading