Skip to content

Commit

Permalink
[MetricsPower] Fix consumer issue, when redis not available
Browse files Browse the repository at this point in the history
  • Loading branch information
fractalzombie committed Apr 5, 2024
1 parent d016eab commit 17b9e84
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 4 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ bin/phpunit
###> project ###
Makefile
.idea
.fleet
.code
.DS_Store
**/.env
composer.lock
Expand Down
2 changes: 1 addition & 1 deletion Action/MetricsAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function __invoke(): Response
return new Response(
(new RenderTextFormat())->render($this->registry->getMetricFamilySamples()),
StatusCode::OK,
[Header::CONTENT_TYPE => RenderTextFormat::MIME_TYPE]
[Header::CONTENT_TYPE => RenderTextFormat::MIME_TYPE],
);
} catch (\Throwable $e) {
throw MetricsRenderException::fromThrowable($e);
Expand Down
4 changes: 3 additions & 1 deletion Helper/MetricalHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public static function getFirstOptions(object|string $target): ?OptionsInterface

public static function getCounterName(PrometheusOptions $options): string
{
return str_replace('-', '_', "{$options->topic}-{$options->name}");
return StringHelper::toSnakeCase(
str_replace('-', '_', "{$options->topic}_{$options->name}")
);
}
}
68 changes: 68 additions & 0 deletions Helper/StringHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

declare(strict_types=1);

/**
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* Copyright (c) 2024 Mykhailo Shtanko fractalzombie@gmail.com
*
* For the full copyright and license information, please view the LICENSE.MD
* file that was distributed with this source code.
*/

namespace FRZB\Component\MetricsPower\Helper;

use FRZB\Component\MetricsPower\Traits\WithPrivateEmptyConstructor;
use JetBrains\PhpStorm\Immutable;

/** @internal */
#[Immutable]
final class StringHelper
{
use WithPrivateEmptyConstructor;

public static function toSnakeCase(string $value): string
{
return strtolower(preg_replace('/[A-Z]/', '_\\0', lcfirst($value)));
}

public static function toKebabCase(string $value): string
{
return strtolower(preg_replace('/[A-Z]/', '-\\0', lcfirst($value)));
}

public static function toPascalCase(string $value): string
{
return str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $value)));
}

public static function toCamelCase(string $value): string
{
return lcfirst(str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $value))));
}

public static function contains(string $value, string $subValue): bool
{
return str_contains($value, $subValue);
}

public static function makePrefix(string $prefix, ?string $value = null, string $delimiter = '-'): string
{
return $value
? self::normalize($prefix).$delimiter.$value
: self::normalize($prefix);
}

public static function normalize(string $value): string
{
return strtolower(preg_replace('/[^a-zA-Z\\d_-]/', '-', $value));
}

public static function removeBrackets(string $value, array $brackets = ['[', ']']): string
{
return str_replace($brackets, '', $value);
}
}
5 changes: 5 additions & 0 deletions OptionsResolver/Resolver/PrometheusOptionsResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
use FRZB\Component\MetricsPower\Attribute\PrometheusOptions;
use FRZB\Component\MetricsPower\Exception\MetricsRegistrationException;
use FRZB\Component\MetricsPower\Helper\CounterHelper;
use FRZB\Component\MetricsPower\Logger\MetricsPowerLoggerInterface;
use Prometheus\Exception\MetricsRegistrationException as BaseMetricsRegistrationException;
use Prometheus\RegistryInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\Messenger\Event\AbstractWorkerMessageEvent;
use Symfony\Component\Messenger\Event\SendMessageToTransportsEvent;
Expand All @@ -37,6 +39,7 @@ public function __construct(
#[Autowire(env: 'PROMETHEUS_NAMESPACE')]
private readonly string $namespace,
private readonly RegistryInterface $registry,
private readonly ?MetricsPowerLoggerInterface $logger = null,
) {}

/** @throws MetricsRegistrationException */
Expand All @@ -56,6 +59,8 @@ public function resolve(AbstractWorkerMessageEvent|SendMessageToTransportsEvent
->inc($options->values);
} catch (BaseMetricsRegistrationException $e) {
throw MetricsRegistrationException::fromThrowable($e);
} catch (\Throwable $e) {
$this->logger?->error($event, $e);
}
}

Expand Down
97 changes: 97 additions & 0 deletions Tests/Unit/Helper/StringHelperTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

declare(strict_types=1);

/**
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* Copyright (c) 2024 Mykhailo Shtanko fractalzombie@gmail.com
*
* For the full copyright and license information, please view the LICENSE.MD
* file that was distributed with this source code.
*/

namespace FRZB\Component\MetricsPower\Tests\Unit\Helper;

use FRZB\Component\MetricsPower\Helper\StringHelper;

test('It cannot be created', fn () => new StringHelper())->expectException(\Error::class);

test('It can normalize prefix', function (string $prefix, string $expectedValue): void {
expect(StringHelper::normalize($prefix))->toBe($expectedValue);
})->with([
['some-domain.local', 'some-domain-local'],
['some%domain%local', 'some-domain-local'],
['some$domain$local', 'some-domain-local'],
['test-app.dev-tech.sub-domain.some-domain.cloud', 'test-app-dev-tech-sub-domain-some-domain-cloud'],
]);

test(
'It can make prefix',
function (string $prefix, string $expectedValue, ?string $value = null, ?string $delimiter = null): void {
expect(StringHelper::makePrefix($prefix, $value, $delimiter))->toBe($expectedValue);
}
)->with([
['some-domain.local', 'some-domain-local', null, '-'],
['some%domain%local', 'some-domain-local', null, '-'],
['some$domain$local', 'some-domain-local', null, '-'],
['test-app.dev-tech.sub-domain.some-domain.cloud', 'test-app-dev-tech-sub-domain-some-domain-cloud', null, '-'],
['some-domain.local', 'some-domain-local_prefix', 'prefix', '_'],
['some-domain.local', 'some-domain-local.prefix', 'prefix', '.'],
]);

test('It can convert to snake case', function (string $sourceValue, string $expectedValue): void {
expect(StringHelper::toSnakeCase($sourceValue))->toBe($expectedValue);
})->with([
['SomeTrueValue', 'some_true_value'],
['SomeValue', 'some_value'],
['someValue', 'some_value'],
]);

test('It can convert to pascal case', function (string $sourceValue, string $expectedValue): void {
expect(StringHelper::toPascalCase($sourceValue))->toBe($expectedValue);
})->with([
['camel_case_name', 'CamelCaseName'],
['camel_case', 'CamelCase'],
['camel', 'Camel'],
['camel-case', 'CamelCase'],
['camel-case-name', 'CamelCaseName'],
]);

test('It can convert to camel case', function (string $sourceValue, string $expectedValue): void {
expect(StringHelper::toCamelCase($sourceValue))->toBe($expectedValue);
})->with([
['camel_case_name', 'camelCaseName'],
['camel_case', 'camelCase'],
['camel', 'camel'],
['camel-case', 'camelCase'],
['camel-case-name', 'camelCaseName'],
]);

test('It can convert to kebab case', function (string $sourceValue, string $expectedValue): void {
expect(StringHelper::toKebabCase($sourceValue))->toBe($expectedValue);
})->with([
['SomeTrueValue', 'some-true-value'],
['SomeValue', 'some-value'],
['someValue', 'some-value'],
]);

test('It can check contains', function (string $sourceValue, string $subValue, bool $expectedValue): void {
expect(StringHelper::contains($sourceValue, $subValue))->toBe($expectedValue);
})->with([
['SomeTrueValue', 'True', true],
['Hello my kitty', 'my', true],
['Bye bye', 'ye', true],
['SomeTrueValue', 'False', false],
['Hello my kitty', 'notmy', false],
['Bye bye', 'hello', false],
]);

test('It can remove brackets', function (string $inputValue, string $expectedValue, array $brackets): void {
expect(StringHelper::removeBrackets($inputValue, $brackets))->toBe($expectedValue);
})->with([
'standard brackets' => ['[hello_world]', 'hello_world', ['[', ']']],
'curly brackets' => ['{hello_world}', 'hello_world', ['{', '}']],
]);
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
"sentry/sdk": "^4.0",
"symfony/serializer": "^6|^7",
"symfony/serializer-pack": "^1.3",
"symfony/expression-language": "^6|^7"

"symfony/expression-language": "^6|^7",
"amphp/log": "^2.0"
},
"require-dev": {
"phpunit/phpunit": "^10.5",
Expand Down

0 comments on commit 17b9e84

Please sign in to comment.