Skip to content

Commit

Permalink
Add new send_response_header option (#17)
Browse files Browse the repository at this point in the history
* Add new send_response_header option
- configure if the TraceServiceInterface::handleResponse method should be called, to add tracing data to the response object
  • Loading branch information
bram123 authored Dec 18, 2023
1 parent 230669c commit c7aa277
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 9 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ return [

By default, the bundle will use the [W3C TraceContext](https://www.w3.org/TR/trace-context/) standard to receive and pass on the traceId.
It's also possible to configure the bundle to setup custom request/response headers and custom ID generators.
Read more about the [TraceId configuration](docs/configuration/traceid.md) and [TraceContext configuration](docs/configuration/tracecontext.md) in the /docs pages.
Read more about all available configuration options on [TraceId configuration](docs/configuration/traceid.md) and [TraceContext configuration](docs/configuration/tracecontext.md) in the /docs pages.

## How it Works

Expand All @@ -47,8 +47,8 @@ lets you use trace ID's from somewhere higher up in the stack (like in the web
server itself).

If no trace ID is found, one is generated by the `TraceIdGeneratorInterface`.
In tracecontext modus In traceId modus, the IDs are generated according to the TraceContext standard.
The default generator in traceId modus creates version 4 UUIDs.
In tracecontext mode In traceId mode, the IDs are generated according to the TraceContext standard.
The default generator in traceId mode creates version 4 UUIDs.

On the way out, a response header can be set on the response as well using
the value(s) described above.
Expand Down Expand Up @@ -113,7 +113,7 @@ Here's an example of a template.
By default this bundle will check for services tagged with the `http_client.trace_id` tag and decorate them with the TraceAwareHttpClient.
When `tagDefaultClient` is enabled the default symfony http client will also be tagged and thus decorated.
This will add the trace header(s) to all outgoing requests for the tagged clients.
In traceId modus the header name can be changed with the `header` configuration option.
In traceId mode the header name can be changed with the `header` configuration option.

## About us

Expand Down
3 changes: 3 additions & 0 deletions docs/configuration/tracecontext.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ return static function (SymfonyTraceConfig $config): void {
// those values are ignored and new trace ID's are generated.
$config->trustRequestHeader(true);

// Whether to send the trace details in the response headers. This is turned on by default.
$config->sendResponseHeader(true);

// The service key of an object that implements
// DR\SymfonyTraceBundle\TraceStorageInterface
// Defaults to TraceStorage::class
Expand Down
3 changes: 3 additions & 0 deletions docs/configuration/traceid.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ return static function (SymfonyTraceConfig $config): void {
// those values are ignored.
$config->trustRequestHeader(true);

// Whether to send the trace details in the response headers. This is turned on by default.
$config->sendResponseHeader(true);

$config->traceid()
// The header which the bundle inspects for the incoming trace ID
// if this is not set an ID will be generated and set at this header
Expand Down
2 changes: 1 addition & 1 deletion phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
parameters:
ignoreErrors:
-
message: "#^Parameter \\#1 \\$mergedConfig \\(array\\{traceMode\\: 'tracecontext'\\|'traceid', traceid\\: array\\{request_header\\: string, response_header\\: string, generator_service\\: string\\|null\\}, trust_request_header\\: bool, storage_service\\: string\\|null, enable_monolog\\: bool, enable_console\\: bool, enable_messenger\\: bool, enable_twig\\: bool, \\.\\.\\.\\}\\) of method DR\\\\SymfonyTraceBundle\\\\DependencyInjection\\\\SymfonyTraceExtension\\:\\:loadInternal\\(\\) should be contravariant with parameter \\$mergedConfig \\(array\\) of method Symfony\\\\Component\\\\HttpKernel\\\\DependencyInjection\\\\ConfigurableExtension\\:\\:loadInternal\\(\\)$#"
message: "#^Parameter \\#1 \\$mergedConfig \\(array\\{traceMode\\: 'tracecontext'\\|'traceid', traceid\\: array\\{request_header\\: string, response_header\\: string, generator_service\\: string\\|null\\}, trust_request_header\\: bool, send_response_header\\: bool, storage_service\\: string\\|null, enable_monolog\\: bool, enable_console\\: bool, enable_messenger\\: bool, \\.\\.\\.\\}\\) of method DR\\\\SymfonyTraceBundle\\\\DependencyInjection\\\\SymfonyTraceExtension\\:\\:loadInternal\\(\\) should be contravariant with parameter \\$mergedConfig \\(array\\) of method Symfony\\\\Component\\\\HttpKernel\\\\DependencyInjection\\\\ConfigurableExtension\\:\\:loadInternal\\(\\)$#"
count: 1
path: src/DependencyInjection/SymfonyTraceExtension.php

Expand Down
4 changes: 4 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ public function getConfigTreeBuilder(): TreeBuilder
->defaultValue(true)
->info("Whether or not to trust the incoming request's `Trace-Id` header as a real ID")
->end()
->booleanNode('send_response_header')
->defaultValue(true)
->info("Whether or not to send a response header with the trace ID. Defaults to true")
->end()
->scalarNode('storage_service')
->info('The service name for trace ID storage. Defaults to `TraceStorage`')
->end()
Expand Down
2 changes: 2 additions & 0 deletions src/DependencyInjection/SymfonyTraceExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ final class SymfonyTraceExtension extends ConfigurableExtension
* generator_service: ?string,
* },
* trust_request_header: bool,
* send_response_header: bool,
* storage_service: ?string,
* enable_monolog: bool,
* enable_console: bool,
Expand Down Expand Up @@ -111,6 +112,7 @@ protected function loadInternal(array $mergedConfig, ContainerBuilder $container
->setArguments(
[
$mergedConfig['trust_request_header'],
$mergedConfig['send_response_header'],
new Reference($serviceId),
new Reference($storeId)
]
Expand Down
5 changes: 4 additions & 1 deletion src/EventSubscriber/TraceSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ final class TraceSubscriber implements EventSubscriberInterface
*/
public function __construct(
private readonly bool $trustRequest,
private readonly bool $sendResponseHeader,
private readonly TraceServiceInterface $traceService,
private readonly TraceStorageInterface $traceStorage,
) {
Expand Down Expand Up @@ -63,6 +64,8 @@ public function onResponse(ResponseEvent $event): void
return;
}

$this->traceService->handleResponse($event->getResponse(), $this->traceStorage->getTrace());
if ($this->sendResponseHeader) {
$this->traceService->handleResponse($event->getResponse(), $this->traceStorage->getTrace());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
use Symfony\Component\HttpKernel\KernelEvents;

#[CoversClass(TraceSubscriber::class)]
class TraceIdSubscriberTest extends TestCase
class TraceSubscriberTest extends TestCase
{
private TraceServiceInterface&MockObject $service;
private TraceStorageInterface&MockOBject $storage;
Expand All @@ -34,7 +34,7 @@ protected function setUp(): void
{
$this->service = $this->createMock(TraceServiceInterface::class);
$this->storage = $this->createMock(TraceStorageInterface::class);
$this->listener = new TraceSubscriber(true, $this->service, $this->storage);
$this->listener = new TraceSubscriber(true, true, $this->service, $this->storage);

$this->dispatcher = new EventDispatcher();
$this->dispatcher->addSubscriber($this->listener);
Expand Down Expand Up @@ -74,7 +74,7 @@ public function testListenerSetsTheTraceToStorageWhenFoundInRequestHeaders(): vo
public function testListenerIgnoresIncomingRequestHeadersWhenTrustRequestIsFalse(): void
{
$this->dispatcher->removeSubscriber($this->listener);
$this->dispatcher->addSubscriber(new TraceSubscriber(false, $this->service, $this->storage));
$this->dispatcher->addSubscriber(new TraceSubscriber(false, true, $this->service, $this->storage));

$trace = new TraceContext();
$this->service->expects(static::never())->method('supports');
Expand Down Expand Up @@ -124,4 +124,18 @@ public function testRequestSetsIdOnResponse(): void
KernelEvents::RESPONSE
);
}

public function testListenerDoesNothingToResponseWithoutMasterRequestWhenSendResponseHeaderIsFalse(): void
{
$this->dispatcher->removeSubscriber($this->listener);
$this->dispatcher->addSubscriber(new TraceSubscriber(false, false, $this->service, $this->storage));

$this->storage->expects(static::never())->method('getTrace');
$this->service->expects(static::never())->method('handleResponse');

$this->dispatcher->dispatch(
new ResponseEvent($this->kernel, $this->request, HttpKernelInterface::MAIN_REQUEST, $this->response),
KernelEvents::RESPONSE
);
}
}

0 comments on commit c7aa277

Please sign in to comment.