Skip to content

Commit a80cd45

Browse files
authored
Merge pull request #15 from andrew-demb/denylist-operations-sampling
Provide way to disable sampling based on operation name
2 parents 66cc0ab + 647cd3b commit a80cd45

File tree

5 files changed

+130
-0
lines changed

5 files changed

+130
-0
lines changed

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,27 @@ return [
1212
// ...
1313
];
1414
```
15+
16+
## Denylist sampling operations
17+
18+
This feature allows to disable sampling for deny-listed operations.
19+
20+
It will be useful when your infrastructure initiates some operations which you are
21+
not insterested for tracking in Jaeger.
22+
23+
Operation names used in package configuration refers to first (parent) span operation name
24+
(https://www.jaegertracing.io/docs/latest/architecture/#span).
25+
26+
> Hint: if you use default name generator (class `\Jaeger\Symfony\Name\Generator\DefaultNameGenerator`),
27+
> your operation name for HTTP requests will be the same as matched symfony route name.
28+
29+
Example bundle config with denylist feature:
30+
31+
```yaml
32+
# config/jaeger.yaml
33+
jaeger:
34+
denylist:
35+
operation_names:
36+
- 'healthcheck'
37+
- 'metrics'
38+
```
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Jaeger\Symfony\DependencyInjection;
5+
6+
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
7+
use Symfony\Component\Config\Definition\ConfigurationInterface;
8+
9+
final class Configuration implements ConfigurationInterface
10+
{
11+
public function getConfigTreeBuilder(): TreeBuilder
12+
{
13+
$treeBuilder = new TreeBuilder('jaeger');
14+
if (true === method_exists($treeBuilder, 'getRootNode')) {
15+
$rootNode = $treeBuilder->getRootNode();
16+
} else {
17+
$rootNode = $treeBuilder->root('jaeger', 'array');
18+
}
19+
20+
// @formatter:off
21+
$rootNode
22+
->children()
23+
->arrayNode('denylist')
24+
->canBeEnabled()
25+
->children()
26+
->arrayNode('operation_names')
27+
->scalarPrototype()->end()
28+
->end()
29+
->end()
30+
->end()
31+
->end();
32+
// @formatter:on
33+
34+
return $treeBuilder;
35+
}
36+
}

src/DependencyInjection/JaegerExtension.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,13 @@ public function load(array $configs, ContainerBuilder $container)
1818
new FileLocator(__DIR__ . '/../Resources')
1919
);
2020
$loader->load('services.yml');
21+
22+
$configuration = new Configuration();
23+
$config = $this->processConfiguration($configuration, $configs);
24+
25+
if ($this->isConfigEnabled($container, $config['denylist'])) {
26+
$container->setParameter('jaeger.sampler.operation_denylist', $config['denylist']['operation_names']);
27+
$loader->load('denylist.yml');
28+
}
2129
}
2230
}

src/Resources/denylist.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
parameters:
2+
# Will be configured in DI extension
3+
# jaeger.sampler.operation_denylist: []
4+
5+
services:
6+
jaeger.sampler.denylist:
7+
class: Jaeger\Symfony\Sampler\DenylistOperationsSampler
8+
decorates: jaeger.sampler
9+
decoration_priority: 10
10+
arguments:
11+
- '@jaeger.sampler.denylist.inner'
12+
- '%jaeger.sampler.operation_denylist%'
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Jaeger\Symfony\Sampler;
5+
6+
use Jaeger\Sampler\SamplerDecisionTag;
7+
use Jaeger\Sampler\SamplerFlagsTag;
8+
use Jaeger\Sampler\SamplerInterface;
9+
use Jaeger\Sampler\SamplerParamTag;
10+
use Jaeger\Sampler\SamplerResult;
11+
use Jaeger\Sampler\SamplerTypeTag;
12+
13+
final class DenylistOperationsSampler implements SamplerInterface
14+
{
15+
private $sampler;
16+
17+
private $denylistedOperationsMap;
18+
19+
/**
20+
* @var SamplerInterface $sampler
21+
* @var string[] $denylistedOperations
22+
*/
23+
public function __construct(SamplerInterface $sampler, array $denylistedOperations)
24+
{
25+
$this->sampler = $sampler;
26+
$this->denylistedOperationsMap = \array_fill_keys($denylistedOperations, true);
27+
}
28+
29+
public function decide(int $traceId, string $operationName, string $debugId): SamplerResult
30+
{
31+
if ('' !== $debugId) {
32+
return $this->sampler->decide($traceId, $operationName, $debugId);
33+
}
34+
35+
if (false === \array_key_exists($operationName, $this->denylistedOperationsMap)) {
36+
return $this->sampler->decide($traceId, $operationName, $debugId);
37+
}
38+
39+
return new SamplerResult(
40+
false,
41+
0,
42+
[
43+
new SamplerTypeTag('denylist_operations'),
44+
new SamplerParamTag($operationName),
45+
new SamplerDecisionTag(false),
46+
new SamplerFlagsTag(0x00),
47+
]
48+
);
49+
}
50+
}

0 commit comments

Comments
 (0)