Skip to content

Commit 37412d9

Browse files
Don't enable tracing unless the profiler is enabled
1 parent 904df78 commit 37412d9

File tree

19 files changed

+130
-7
lines changed

19 files changed

+130
-7
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
107107
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
108108
use Symfony\Component\HttpKernel\Log\DebugLoggerConfigurator;
109+
use Symfony\Component\HttpKernel\Profiler\ProfilerStateChecker;
109110
use Symfony\Component\JsonStreamer\Attribute\JsonStreamable;
110111
use Symfony\Component\JsonStreamer\JsonStreamWriter;
111112
use Symfony\Component\JsonStreamer\StreamReaderInterface;
@@ -963,6 +964,11 @@ private function registerProfilerConfiguration(array $config, ContainerBuilder $
963964
$loader->load('collectors.php');
964965
$loader->load('cache_debug.php');
965966

967+
if (!class_exists(ProfilerStateChecker::class)) {
968+
$container->removeDefinition('profiler.state_checker');
969+
$container->removeDefinition('profiler.is_disabled_state_checker');
970+
}
971+
966972
if ($this->isInitializedConfigEnabled('form')) {
967973
$loader->load('form_debug.php');
968974
}

src/Symfony/Bundle/FrameworkBundle/Resources/config/debug.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
service('debug.stopwatch'),
2626
service('logger')->nullOnInvalid(),
2727
service('.virtual_request_stack')->nullOnInvalid(),
28+
service('profiler.is_disabled_state_checker')->nullOnInvalid(),
2829
])
2930
->tag('monolog.logger', ['channel' => 'event'])
3031
->tag('kernel.reset', ['method' => 'reset'])

src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\HttpKernel\EventListener\ProfilerListener;
1717
use Symfony\Component\HttpKernel\Profiler\FileProfilerStorage;
1818
use Symfony\Component\HttpKernel\Profiler\Profiler;
19+
use Symfony\Component\HttpKernel\Profiler\ProfilerStateChecker;
1920

2021
return static function (ContainerConfigurator $container) {
2122
$container->services()
@@ -56,5 +57,16 @@
5657
->set('.virtual_request_stack', VirtualRequestStack::class)
5758
->args([service('request_stack')])
5859
->public()
60+
61+
->set('profiler.state_checker', ProfilerStateChecker::class)
62+
->args([
63+
service_locator(['profiler' => service('profiler')->ignoreOnUninitialized()]),
64+
param('kernel.runtime_mode.web'),
65+
])
66+
->tag('container.private', ['package' => 'symfony/framework-bundle', 'version' => '5.4'])
67+
68+
->set('profiler.is_disabled_state_checker', 'Closure')
69+
->factory(['Closure', 'fromCallable'])
70+
->args([[service('profiler.state_checker'), 'isProfilerDisabled']])
5971
;
6072
};

src/Symfony/Bundle/FrameworkBundle/Resources/config/validator_debug.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
->decorate('validator', null, 255)
2121
->args([
2222
service('debug.validator.inner'),
23+
service('profiler.is_disabled_state_checker')->nullOnInvalid(),
2324
])
2425
->tag('kernel.reset', [
2526
'method' => 'reset',

src/Symfony/Component/Cache/Adapter/TraceableAdapter.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class TraceableAdapter implements AdapterInterface, CacheInterface, NamespacedPo
3434

3535
public function __construct(
3636
protected AdapterInterface $pool,
37+
protected readonly ?\Closure $disabled = null,
3738
) {
3839
}
3940

@@ -45,6 +46,9 @@ public function get(string $key, callable $callback, ?float $beta = null, ?array
4546
if (!$this->pool instanceof CacheInterface) {
4647
throw new BadMethodCallException(\sprintf('Cannot call "%s::get()": this class doesn\'t implement "%s".', get_debug_type($this->pool), CacheInterface::class));
4748
}
49+
if ($this->disabled?->__invoke()) {
50+
return $this->pool->get($key, $callback, $beta, $metadata);
51+
}
4852

4953
$isHit = true;
5054
$callback = function (CacheItem $item, bool &$save) use ($callback, &$isHit) {
@@ -71,6 +75,9 @@ public function get(string $key, callable $callback, ?float $beta = null, ?array
7175

7276
public function getItem(mixed $key): CacheItem
7377
{
78+
if ($this->disabled?->__invoke()) {
79+
return $this->pool->getItem($key);
80+
}
7481
$event = $this->start(__FUNCTION__);
7582
try {
7683
$item = $this->pool->getItem($key);
@@ -88,6 +95,9 @@ public function getItem(mixed $key): CacheItem
8895

8996
public function hasItem(mixed $key): bool
9097
{
98+
if ($this->disabled?->__invoke()) {
99+
return $this->pool->hasItem($key);
100+
}
91101
$event = $this->start(__FUNCTION__);
92102
try {
93103
return $event->result[$key] = $this->pool->hasItem($key);
@@ -98,6 +108,9 @@ public function hasItem(mixed $key): bool
98108

99109
public function deleteItem(mixed $key): bool
100110
{
111+
if ($this->disabled?->__invoke()) {
112+
return $this->pool->deleteItem($key);
113+
}
101114
$event = $this->start(__FUNCTION__);
102115
try {
103116
return $event->result[$key] = $this->pool->deleteItem($key);
@@ -108,6 +121,9 @@ public function deleteItem(mixed $key): bool
108121

109122
public function save(CacheItemInterface $item): bool
110123
{
124+
if ($this->disabled?->__invoke()) {
125+
return $this->pool->save($item);
126+
}
111127
$event = $this->start(__FUNCTION__);
112128
try {
113129
return $event->result[$item->getKey()] = $this->pool->save($item);
@@ -118,6 +134,9 @@ public function save(CacheItemInterface $item): bool
118134

119135
public function saveDeferred(CacheItemInterface $item): bool
120136
{
137+
if ($this->disabled?->__invoke()) {
138+
return $this->pool->saveDeferred($item);
139+
}
121140
$event = $this->start(__FUNCTION__);
122141
try {
123142
return $event->result[$item->getKey()] = $this->pool->saveDeferred($item);
@@ -128,6 +147,9 @@ public function saveDeferred(CacheItemInterface $item): bool
128147

129148
public function getItems(array $keys = []): iterable
130149
{
150+
if ($this->disabled?->__invoke()) {
151+
return $this->pool->getItems($keys);
152+
}
131153
$event = $this->start(__FUNCTION__);
132154
try {
133155
$result = $this->pool->getItems($keys);
@@ -151,6 +173,9 @@ public function getItems(array $keys = []): iterable
151173

152174
public function clear(string $prefix = ''): bool
153175
{
176+
if ($this->disabled?->__invoke()) {
177+
return $this->pool->clear($prefix);
178+
}
154179
$event = $this->start(__FUNCTION__);
155180
try {
156181
if ($this->pool instanceof AdapterInterface) {
@@ -165,6 +190,9 @@ public function clear(string $prefix = ''): bool
165190

166191
public function deleteItems(array $keys): bool
167192
{
193+
if ($this->disabled?->__invoke()) {
194+
return $this->pool->deleteItems($keys);
195+
}
168196
$event = $this->start(__FUNCTION__);
169197
$event->result['keys'] = $keys;
170198
try {
@@ -176,6 +204,9 @@ public function deleteItems(array $keys): bool
176204

177205
public function commit(): bool
178206
{
207+
if ($this->disabled?->__invoke()) {
208+
return $this->pool->commit();
209+
}
179210
$event = $this->start(__FUNCTION__);
180211
try {
181212
return $event->result = $this->pool->commit();
@@ -189,6 +220,9 @@ public function prune(): bool
189220
if (!$this->pool instanceof PruneableInterface) {
190221
return false;
191222
}
223+
if ($this->disabled?->__invoke()) {
224+
return $this->pool->prune();
225+
}
192226
$event = $this->start(__FUNCTION__);
193227
try {
194228
return $event->result = $this->pool->prune();
@@ -208,6 +242,9 @@ public function reset(): void
208242

209243
public function delete(string $key): bool
210244
{
245+
if ($this->disabled?->__invoke()) {
246+
return $this->pool->deleteItem($key);
247+
}
211248
$event = $this->start(__FUNCTION__);
212249
try {
213250
return $event->result[$key] = $this->pool->deleteItem($key);

src/Symfony/Component/Cache/Adapter/TraceableTagAwareAdapter.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@
1818
*/
1919
class TraceableTagAwareAdapter extends TraceableAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface
2020
{
21-
public function __construct(TagAwareAdapterInterface $pool)
21+
public function __construct(TagAwareAdapterInterface $pool, ?\Closure $disabled = null)
2222
{
23-
parent::__construct($pool);
23+
parent::__construct($pool, $disabled);
2424
}
2525

2626
public function invalidateTags(array $tags): bool
2727
{
28+
if ($this->disabled?->__invoke()) {
29+
return $this->pool->invalidateTags($tags);
30+
}
2831
$event = $this->start(__FUNCTION__);
2932
try {
3033
return $event->result = $this->pool->invalidateTags($tags);

src/Symfony/Component/Cache/DependencyInjection/CacheCollectorPass.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ private function addToCollector(string $id, string $name, ContainerBuilder $cont
5252
if (!$definition->isPublic() || !$definition->isPrivate()) {
5353
$recorder->setPublic($definition->isPublic());
5454
}
55-
$recorder->setArguments([new Reference($innerId = $id.'.recorder_inner')]);
55+
$recorder->setArguments([new Reference($innerId = $id.'.recorder_inner'), new Reference('profiler.is_disabled_state_checker', ContainerBuilder::IGNORE_ON_INVALID_REFERENCE)]);
5656

5757
foreach ($definition->getMethodCalls() as [$method, $args]) {
5858
if ('setCallbackWrapper' !== $method || !$args[0] instanceof Definition || !($args[0]->getArguments()[2] ?? null) instanceof Definition) {

src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public function __construct(
4343
protected Stopwatch $stopwatch,
4444
protected ?LoggerInterface $logger = null,
4545
private ?RequestStack $requestStack = null,
46+
protected readonly ?\Closure $disabled = null,
4647
) {
4748
}
4849

@@ -103,6 +104,9 @@ public function hasListeners(?string $eventName = null): bool
103104

104105
public function dispatch(object $event, ?string $eventName = null): object
105106
{
107+
if ($this->disabled?->__invoke()) {
108+
return $this->dispatcher->dispatch($event, $eventName);
109+
}
106110
$eventName ??= $event::class;
107111

108112
$this->callStack ??= new \SplObjectStorage();

src/Symfony/Component/HttpClient/DependencyInjection/HttpClientPass.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function process(ContainerBuilder $container): void
2727

2828
foreach ($container->findTaggedServiceIds('http_client.client') as $id => $tags) {
2929
$container->register('.debug.'.$id, TraceableHttpClient::class)
30-
->setArguments([new Reference('.debug.'.$id.'.inner'), new Reference('debug.stopwatch', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)])
30+
->setArguments([new Reference('.debug.'.$id.'.inner'), new Reference('debug.stopwatch', ContainerInterface::IGNORE_ON_INVALID_REFERENCE), '%kernel.runtime_mode.web%'])
3131
->addTag('kernel.reset', ['method' => 'reset'])
3232
->setDecoratedService($id, null, 5);
3333
$container->getDefinition('data_collector.http_client')

src/Symfony/Component/HttpClient/Response/TraceableResponse.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class TraceableResponse implements ResponseInterface, StreamableInterface
3434
public function __construct(
3535
private HttpClientInterface $client,
3636
private ResponseInterface $response,
37-
private mixed &$content,
37+
private mixed &$content = false,
3838
private ?StopwatchEvent $event = null,
3939
) {
4040
}

src/Symfony/Component/HttpClient/TraceableHttpClient.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,17 @@ final class TraceableHttpClient implements HttpClientInterface, ResetInterface,
3131
public function __construct(
3232
private HttpClientInterface $client,
3333
private ?Stopwatch $stopwatch = null,
34+
private ?\Closure $disabled = null,
3435
) {
3536
$this->tracedRequests = new \ArrayObject();
3637
}
3738

3839
public function request(string $method, string $url, array $options = []): ResponseInterface
3940
{
41+
if ($this->disabled?->__invoke()) {
42+
return new TraceableResponse($this->client, $this->client->request($method, $url, $options));
43+
}
44+
4045
$content = null;
4146
$traceInfo = [];
4247
$this->tracedRequests[] = [

src/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ class TraceableEventDispatcher extends BaseTraceableEventDispatcher
2525
{
2626
protected function beforeDispatch(string $eventName, object $event): void
2727
{
28+
if ($this->disabled?->__invoke()) {
29+
return;
30+
}
2831
switch ($eventName) {
2932
case KernelEvents::REQUEST:
3033
$event->getRequest()->attributes->set('_stopwatch_token', bin2hex(random_bytes(3)));
@@ -57,6 +60,9 @@ protected function beforeDispatch(string $eventName, object $event): void
5760

5861
protected function afterDispatch(string $eventName, object $event): void
5962
{
63+
if ($this->disabled?->__invoke()) {
64+
return;
65+
}
6066
switch ($eventName) {
6167
case KernelEvents::CONTROLLER_ARGUMENTS:
6268
$this->stopwatch->start('controller', 'section');
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\HttpKernel\Profiler;
13+
14+
use Psr\Container\ContainerInterface;
15+
16+
class ProfilerStateChecker
17+
{
18+
public function __construct(
19+
private ContainerInterface $container,
20+
private bool $defaultEnabled,
21+
) {
22+
}
23+
24+
public function isProfilerEnabled(): bool
25+
{
26+
return $this->container->get('profiler')?->isEnabled() ?? $this->defaultEnabled;
27+
}
28+
29+
public function isProfilerDisabled(): bool
30+
{
31+
return !$this->isProfilerEnabled();
32+
}
33+
}

src/Symfony/Component/HttpKernel/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"php": ">=8.2",
2020
"symfony/deprecation-contracts": "^2.5|^3",
2121
"symfony/error-handler": "^6.4|^7.0",
22-
"symfony/event-dispatcher": "^6.4|^7.0",
22+
"symfony/event-dispatcher": "^7.3",
2323
"symfony/http-foundation": "^7.3",
2424
"symfony/polyfill-ctype": "^1.8",
2525
"psr/log": "^1|^2|^3"

src/Symfony/Component/Messenger/DependencyInjection/MessengerPass.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ private function registerBusToCollector(ContainerBuilder $container, string $bus
337337
{
338338
$container->setDefinition(
339339
$tracedBusId = 'debug.traced.'.$busId,
340-
(new Definition(TraceableMessageBus::class, [new Reference($tracedBusId.'.inner')]))->setDecoratedService($busId)
340+
(new Definition(TraceableMessageBus::class, [new Reference($tracedBusId.'.inner'), new Reference('profiler.is_disabled_state_checker', ContainerBuilder::IGNORE_ON_INVALID_REFERENCE)]))->setDecoratedService($busId)
341341
);
342342

343343
$container->getDefinition('data_collector.messenger')->addMethodCall('registerBus', [$busId, new Reference($tracedBusId)]);

src/Symfony/Component/Messenger/TraceableMessageBus.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,16 @@ class TraceableMessageBus implements MessageBusInterface
2020

2121
public function __construct(
2222
private MessageBusInterface $decoratedBus,
23+
protected readonly ?\Closure $disabled = null,
2324
) {
2425
}
2526

2627
public function dispatch(object $message, array $stamps = []): Envelope
2728
{
29+
if ($this->disabled?->__invoke()) {
30+
return $this->decoratedBus->dispatch($message, $stamps);
31+
}
32+
2833
$envelope = Envelope::wrap($message, $stamps);
2934
$context = [
3035
'stamps' => array_merge([], ...array_values($envelope->all())),

src/Symfony/Component/Validator/Validator/TraceableValidator.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class TraceableValidator implements ValidatorInterface, ResetInterface
2929

3030
public function __construct(
3131
private ValidatorInterface $validator,
32+
protected readonly ?\Closure $disabled = null,
3233
) {
3334
}
3435

@@ -56,6 +57,10 @@ public function validate(mixed $value, Constraint|array|null $constraints = null
5657
{
5758
$violations = $this->validator->validate($value, $constraints, $groups);
5859

60+
if ($this->disabled?->__invoke()) {
61+
return $violations;
62+
}
63+
5964
$trace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 7);
6065

6166
$file = $trace[0]['file'];

src/Symfony/Component/Workflow/Debug/TraceableWorkflow.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class TraceableWorkflow implements WorkflowInterface
3030
public function __construct(
3131
private readonly WorkflowInterface $workflow,
3232
private readonly Stopwatch $stopwatch,
33+
protected readonly ?\Closure $disabled = null,
3334
) {
3435
}
3536

@@ -90,6 +91,9 @@ public function getCalls(): array
9091

9192
private function callInner(string $method, array $args): mixed
9293
{
94+
if ($this->disabled?->__invoke()) {
95+
return $this->workflow->{$method}(...$args);
96+
}
9397
$sMethod = $this->workflow::class.'::'.$method;
9498
$this->stopwatch->start($sMethod, 'workflow');
9599

0 commit comments

Comments
 (0)