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

Name generator #16

Merged
merged 42 commits into from
Jun 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
fb79a4b
Allow arbitary generation of span names based on the route matched
allflame Apr 22, 2021
aafc787
Code style fixes and php language requirements update
allflame Apr 22, 2021
b545908
Updated minimum requirements to 7.4 (typed properties)
allflame Apr 22, 2021
0acf437
Fixed decorates alias reference
allflame Apr 22, 2021
28f27c8
Added controller name generator, some minor fixes
allflame Apr 22, 2021
4393596
Added README.md section for the name generation
allflame Apr 22, 2021
6f6e79b
Update src/Bridge/BackgroundSpanHandler.php
allflame Apr 22, 2021
e58a487
Update src/DependencyInjection/Configuration.php
allflame Apr 22, 2021
0ff0e54
More clear alternative in configuration parsing
allflame Apr 22, 2021
7c48c96
Merge remote-tracking branch 'origin/name-generator' into name-generator
allflame Apr 22, 2021
ffe81fe
Added missing declare(strict_types=1);
allflame Apr 22, 2021
03f3324
Changed to multiline in subsribedEvents
allflame Apr 22, 2021
b1a6307
Update src/Name/Generator/ControllerNameGenerator.php
allflame Apr 22, 2021
3847e7c
Update src/Name/Generator/ShortenGeneratorDecorator.php
allflame Apr 22, 2021
fed6e15
Update src/DependencyInjection/JaegerExtension.php
allflame Apr 22, 2021
b7e7411
Update src/Name/Generator/CommandNameGenerator.php
allflame Apr 22, 2021
cc6db45
Added docs for the regexp, moved regexp generation to the configuration
allflame Apr 22, 2021
b0f88cb
Merge remote-tracking branch 'origin/name-generator' into name-generator
allflame Apr 22, 2021
b8e1c05
Changed example
allflame Apr 22, 2021
8778259
Moved name generators one priority more
allflame Apr 22, 2021
aacf368
Update README.md
allflame Apr 26, 2021
43c37e3
Update src/Name/Generator/NameGeneratorChain.php
allflame Apr 26, 2021
aa23b3e
Update README.md
allflame Apr 26, 2021
3bf8e71
Update src/DependencyInjection/JaegerExtension.php
allflame Apr 26, 2021
ff41f3d
Added comments to priority
allflame Apr 26, 2021
345bc29
Merge remote-tracking branch 'origin/name-generator' into name-generator
allflame Apr 26, 2021
2b81358
Split shorten to be able to disable it by using max_length: ~
allflame Apr 26, 2021
bfcd631
:package: More appropriate name for configuration attribute
andrew-demb Jun 3, 2021
7b77d95
:lipstick: Add newlines for visual separation between blocks
andrew-demb Jun 3, 2021
26386d6
:package: Ensure retrieved data from event. Drop unused variable. Che…
andrew-demb Jun 3, 2021
a8701cf
:package: Ensure property have value always to avoid problems with no…
andrew-demb Jun 3, 2021
1dae2c1
:package: Better typing. Add mention about keys
andrew-demb Jun 3, 2021
9270a75
:package: Ensure property have value always to avoid problems with no…
andrew-demb Jun 3, 2021
ae6fdc7
:package: Ensure property have value always to avoid problems with no…
andrew-demb Jun 3, 2021
6a3902c
:package: Better typing. Add mention about keys
andrew-demb Jun 3, 2021
86515ed
:book: Add info about required interface
andrew-demb Jun 3, 2021
a38eceb
:bug: Fix invalid variable used
andrew-demb Jun 3, 2021
cb7e181
:package: Simplify a bit collecting a name generators
andrew-demb Jun 3, 2021
6e2ee36
:package: More return types
andrew-demb Jun 3, 2021
abf079c
:bug: Missed semicolon
andrew-demb Jun 14, 2021
9dddbbf
:package: Better typing for priority queue extractions
andrew-demb Jun 14, 2021
b90f1cd
Merge pull request #17 from andrew-demb/name-generator-suggestion
allflame Jun 29, 2021
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
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,29 @@ jaeger:
- 'healthcheck'
- 'metrics'
```


## Name generation options

You can configure custom name generators based on regular expression pattern, which will be evaluated for operation name.

Configuration for this feature looks like key-value list, where key - regexp pattern, value - custom name generator DI service id (see details below).

Name generator should implement an `Jaeger\Symfony\Name\Generator\NameGeneratorInterface` interface.
As a custom name generator you can specify a full DI service id, or just the suffix if your name generator service is named as `jaeger.name.generator.*`.
Keys are considered body of the regular expression pattern, do not put any modifiers (e.g. `/i`, `/g`) or slashes; `route` of the request or `name` of the command should match to use alternative generator.
Expressions are checked top to bottom, if no match is found, default generator will be used

Example bundle config with name generation feature:

```yaml
# config/jaeger.yaml
jaeger:
name_generator:
max_length: 32
command:
'^app:report:.+': 'my_service_generator_alias'
.* : 'controller'
allflame marked this conversation as resolved.
Show resolved Hide resolved
request:
'user_routes_\w+': 'my_service_generator_alias'
```
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
}
},
"require": {
"php": ">=7.1",
"php": ">=7.4",
"code-tool/jaeger-client-php": "^3.1",
"symfony/config": "^4.3|^5.0",
"symfony/console": "^4.3|^5.0",
Expand Down
10 changes: 4 additions & 6 deletions src/Bridge/BackgroundSpanHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use Jaeger\Http\HttpMethodTag;
use Jaeger\Http\HttpUriTag;
use Jaeger\Span\Span;
use Jaeger\Span\SpanInterface;
use Jaeger\Symfony\Tag\SymfonyBackgroundTag;
use Jaeger\Symfony\Tag\SymfonyComponentTag;
use Jaeger\Symfony\Tag\SymfonyVersionTag;
Expand All @@ -15,12 +15,9 @@

class BackgroundSpanHandler
{
/**
* @var Span
*/
private $span;
private ?SpanInterface $span = null;

private $tracer;
private TracerInterface $tracer;

public function __construct(TracerInterface $tracer)
{
Expand Down Expand Up @@ -50,6 +47,7 @@ public function flush(): BackgroundSpanHandler
return $this;
}
$this->span->finish();
$this->span = null;

return $this;
}
Expand Down
8 changes: 4 additions & 4 deletions src/Bridge/GlobalSpanListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,29 @@

class GlobalSpanListener implements EventSubscriberInterface
{
private $handler;
private GlobalSpanHandler $handler;

public function __construct(GlobalSpanHandler $handler)
{
$this->handler = $handler;
}

public static function getSubscribedEvents()
public static function getSubscribedEvents(): array
{
return [
RequestEvent::class => ['onRequest', 30],
TerminateEvent::class => ['onTerminate', 4096],
];
}

public function onTerminate()
public function onTerminate(): GlobalSpanListener
{
$this->handler->finish();

return $this;
}

public function onRequest(RequestEvent $event)
public function onRequest(RequestEvent $event): GlobalSpanListener
{
if (false === $event->isMasterRequest()) {
return $this;
Expand Down
4 changes: 2 additions & 2 deletions src/Bridge/HandlerFlushListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ public function __construct(BackgroundSpanHandler $backgroundHandler, GlobalSpan
$this->globalHandler = $globalHandler;
}

public static function getSubscribedEvents()
public static function getSubscribedEvents(): array
{
return [TerminateEvent::class => ['onTerminate', -16384],];
return [TerminateEvent::class => ['onTerminate', -16384]];
}

public function onTerminate()
Expand Down
5 changes: 4 additions & 1 deletion src/Context/Extractor/ContextExtractorChain.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ public function extract(): ?SpanContext
{
$queue = clone $this->queue;
while (false === $queue->isEmpty()) {
if (null !== ($context = $queue->extract()->extract())) {
/** @var ContextExtractorInterface $extractor */
$extractor = $queue->extract();
$context = $extractor->extract();
if (null !== $context) {
return $context;
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/Debug/Extractor/DebugExtractorChain.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ public function getDebug(): string
{
$queue = clone $this->queue;
while (false === $queue->isEmpty()) {
if ('' !== ($debugId = $queue->extract()->getDebug())) {
/** @var DebugExtractorInterface $extractor */
$extractor = $queue->extract();
$debugId = $extractor->getDebug();
if ('' !== $debugId) {
return $debugId;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/DependencyInjection/CodecRegistryCompilerPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class CodecRegistryCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
public function process(ContainerBuilder $container): void
{
if (false === $container->hasDefinition('jaeger.codec.registry')) {
throw new \RuntimeException(
Expand Down
14 changes: 14 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ public function getConfigTreeBuilder(): TreeBuilder
->end()
->end()
->end()
->arrayNode('name_generator')
->canBeEnabled()
->children()
->integerNode('max_length')->defaultValue(64)->end()
->arrayNode('command')
->useAttributeAsKey('pattern')
->scalarPrototype()->end()
->end()
->arrayNode('request')
->useAttributeAsKey('pattern')
->scalarPrototype()->end()
->end()
->end()
->end()
->end();
// @formatter:on

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class ContextExtractorChainCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
public function process(ContainerBuilder $container): void
{
if (false === $container->hasDefinition('jaeger.context.extractor.chain')) {
throw new \RuntimeException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class DebugExtractorChainCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
public function process(ContainerBuilder $container): void
{
if (false === $container->hasDefinition('jaeger.debug.extractor.chain')) {
throw new \RuntimeException(
Expand Down
41 changes: 39 additions & 2 deletions src/DependencyInjection/JaegerExtension.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?php

declare(strict_types=1);

namespace Jaeger\Symfony\DependencyInjection;
Expand All @@ -8,10 +7,11 @@
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Reference;

class JaegerExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
public function load(array $configs, ContainerBuilder $container): void
{
$loader = new YamlFileLoader(
$container,
Expand All @@ -26,5 +26,42 @@ public function load(array $configs, ContainerBuilder $container)
$container->setParameter('jaeger.sampler.operation_denylist', $config['denylist']['operation_names']);
$loader->load('denylist.yml');
}

if ($this->isConfigEnabled($container, $config['name_generator'])) {
if ($config['name_generator']['max_length']) {
$loader->load('shorten.yml');
$container->setParameter('jaeger.name.max_length', $config['name_generator']['max_length']);
}

foreach ($config['name_generator']['request'] as $pattern => $customGeneratorId) {
$regexp = \sprintf('/%s/', $pattern);

$shortenedGeneratorId = \sprintf('jaeger.name.generator.%s', $customGeneratorId);
if ($container->has($shortenedGeneratorId)) {
$customGeneratorId = $shortenedGeneratorId;
}

$container->getDefinition('jaeger.name.generator.request')
->addMethodCall(
'add',
[$regexp, new Reference($customGeneratorId)]
);
}

foreach ($config['name_generator']['command'] as $pattern => $customGeneratorId) {
$regexp = \sprintf('/%s/', $pattern);

$shortenedGeneratorId = \sprintf('jaeger.name.generator.%s', $customGeneratorId);
if ($container->has($shortenedGeneratorId)) {
$customGeneratorId = $shortenedGeneratorId;
}

$container->getDefinition('jaeger.name.generator.command')
->addMethodCall(
'add',
[$regexp, new Reference($customGeneratorId)]
);
}
}
}
}
2 changes: 1 addition & 1 deletion src/DependencyInjection/NameGeneratorChainCompilerPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class NameGeneratorChainCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
public function process(ContainerBuilder $container): void
{
if (false === $container->hasDefinition('jaeger.name.generator.chain')) {
throw new \RuntimeException(
Expand Down
2 changes: 1 addition & 1 deletion src/JaegerBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

class JaegerBundle extends Bundle
{
public function build(ContainerBuilder $container)
public function build(ContainerBuilder $container): void
{
parent::build($container);
$container
Expand Down
19 changes: 19 additions & 0 deletions src/Name/Generator/AbstractGeneratorDecorator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
declare(strict_types=1);

allflame marked this conversation as resolved.
Show resolved Hide resolved
namespace Jaeger\Symfony\Name\Generator;

abstract class AbstractGeneratorDecorator implements NameGeneratorInterface
{
private NameGeneratorInterface $generator;

public function __construct(NameGeneratorInterface $generator)
{
$this->generator = $generator;
}

public function generate(): string
{
return $this->generator->generate();
}
}
71 changes: 71 additions & 0 deletions src/Name/Generator/CommandNameGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
declare(strict_types=1);

namespace Jaeger\Symfony\Name\Generator;

use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class CommandNameGenerator implements NameGeneratorInterface, EventSubscriberInterface
{
/**
* @var NameGeneratorInterface[] Key - regexp, value - name generator
*/
private array $generators;

private string $name = '';

/**
* @param NameGeneratorInterface[] $generators Key - regexp, value - name generator
*/
public function __construct(array $generators = [])
{
$this->generators = $generators;
}

public function add(string $regexp, NameGeneratorInterface $generator): CommandNameGenerator
{
$this->generators[$regexp] = $generator;

return $this;
}

public static function getSubscribedEvents(): array
{
return [
// Subscribe after route was resolved and request attributes were set
ConsoleCommandEvent::class => ['onCommand', 31],
ConsoleTerminateEvent::class => ['onTerminate'],
];
}

public function onCommand(ConsoleCommandEvent $event): void
{
if (null === $command = $event->getCommand()) {
return;
}

$this->name = (string)$command->getName();
}

public function onTerminate(): CommandNameGenerator
{
$this->name = '';

return $this;
}

public function generate(): string
{
foreach ($this->generators as $regexp => $generator) {
if (false === \preg_match($regexp, $this->name)) {
continue;
}

return $generator->generate();
}

return '';
}
}
37 changes: 37 additions & 0 deletions src/Name/Generator/ControllerNameGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);

namespace Jaeger\Symfony\Name\Generator;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\TerminateEvent;

class ControllerNameGenerator implements NameGeneratorInterface, EventSubscriberInterface
{
private string $controller = '';

public static function getSubscribedEvents(): array
{
return [
// Subscribe after route was resolved and request attributes were set
RequestEvent::class => ['onRequest', 31],
allflame marked this conversation as resolved.
Show resolved Hide resolved
TerminateEvent::class => ['onTerminate', -16384],
];
}

public function onRequest(RequestEvent $event): void
{
$this->controller = (string)$event->getRequest()->attributes->get('_controller', '');
}

public function onTerminate(): void
{
$this->controller = '';
}

public function generate(): string
{
return $this->controller;
}
}
Loading