Skip to content

Commit 6583a64

Browse files
authored
Merge branch 'getsentry:master' into patch-1
2 parents f89db26 + b9df991 commit 6583a64

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1190
-129
lines changed

.cursor/rules/release-process.mdc

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
globs: CHANGELOG.md
3+
alwaysApply: false
4+
---
5+
# Sentry Symfony SDK Release Process
6+
7+
## Release Process
8+
9+
To prepare a new release (e.g., version 4.14.0):
10+
11+
1. **Update master branch**: Always ensure master is up-to-date first
12+
```bash
13+
git checkout master
14+
git pull origin master
15+
```
16+
17+
2. **Create release branch**: Create a branch named `prepare-X.Y.Z`
18+
```bash
19+
git checkout -b prepare-4.14.0
20+
```
21+
22+
3. **Find changes since last release**: Check commits since the last version tag
23+
```bash
24+
git log --oneline --no-merges 4.13.0..HEAD
25+
```
26+
27+
4. **Update CHANGELOG.md**: Add new version section with:
28+
- Version number and announcement text
29+
- Features section for new features
30+
- Bug Fixes section for bug fixes
31+
- Misc section for documentation/readme updates
32+
- Use format: `- Description [(#PR)](mdc:https:/github.com/getsentry/sentry-symfony/pull/PR)`
33+
34+
## CHANGELOG.md Format
35+
36+
```markdown
37+
## X.Y.Z
38+
39+
The Sentry SDK team is happy to announce the immediate availability of Sentry PHP SDK vX.Y.Z.
40+
41+
### Features
42+
43+
- New feature description [(#1234)](mdc:https:/github.com/getsentry/sentry-php/pull/1234)
44+
45+
### Bug Fixes
46+
47+
- Bug fix description [(#1235)](mdc:https:/github.com/getsentry/sentry-php/pull/1235)
48+
49+
### Misc
50+
51+
- Documentation/misc changes [(#1236)](mdc:https:/github.com/getsentry/sentry-php/pull/1236)
52+
```
53+
54+
## Committing Changes
55+
56+
After updating CHANGELOG.md:
57+
58+
1. **Stage only the changelog**: `git add CHANGELOG.md`
59+
2. **Create simple commit**: `git commit -m "Prepare X.Y.Z"`
60+
- Use simple commit message format
61+
- Don't include additional descriptions or generated tags
62+
63+
## Common Commands
64+
65+
- Check git status: `git status`
66+
- View recent commits: `git log --oneline -10`
67+
- Create branch: `git checkout -b branch-name`
68+
- Update from remote: `git pull origin master`

.github/workflows/publish-release.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
steps:
2121
- name: Get auth token
2222
id: token
23-
uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
23+
uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1
2424
with:
2525
app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }}
2626
private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }}

CHANGELOG.md

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,69 @@
11
# CHANGELOG
22

3+
## 5.5.0
4+
5+
The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v5.5.0.
6+
7+
### Features
8+
9+
- Enable auto-instrumentation for the Symfony Cache Component [(#942)](https://github.com/getsentry/sentry-symfony/pull/942)
10+
- Add a new config flag to reset breadcrumbs between Symfony messages [(#946)](https://github.com/getsentry/sentry-symfony/pull/946)
11+
```yaml
12+
sentry:
13+
messenger:
14+
isolate_breadcrumbs_by_message: true
15+
```
16+
- Allow to pass in callbacks to configure SDK integrations [(#947)](https://github.com/getsentry/sentry-symfony/pull/947)
17+
```yaml
18+
services:
19+
App\IntegrationCallback:
20+
factory: ['App\IntegrationCallback', 'factory']
21+
22+
sentry:
23+
options:
24+
integrations: 'App\IntegrationCallback'
25+
```
26+
27+
## 5.4.1
28+
29+
The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v5.4.1.
30+
31+
### Bug Fixes
32+
33+
- Support named arguments in BufferFlushPass. [(#948)](https://github.com/getsentry/sentry-symfony/pull/948)
34+
35+
## 5.4.0
36+
37+
The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v5.4.0.
38+
39+
### Features
40+
41+
- Introduce Sentry Structured Logging support. [(#940)](https://github.com/getsentry/sentry-symfony/pull/940)
42+
43+
```yaml
44+
sentry:
45+
options:
46+
enable_logs: true
47+
48+
services:
49+
Sentry\SentryBundle\Monolog\LogsHandler:
50+
arguments:
51+
- !php/const Monolog\Logger::INFO
52+
53+
monolog:
54+
handlers:
55+
sentry_logs:
56+
type: service
57+
id: Sentry\SentryBundle\Monolog\LogsHandler
58+
```
59+
60+
### Bug Fixes
61+
62+
- Add buffer flusher for sentry monolog handler. [(#936)](https://github.com/getsentry/sentry-symfony/pull/936)
63+
364
## 5.3.1
465
5-
The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v5.3.0.
66+
The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v5.3.1.
667
768
### Bug Fixes
869

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"php": "^7.2||^8.0",
1616
"guzzlehttp/psr7": "^2.1.1",
1717
"jean85/pretty-package-versions": "^1.5||^2.0",
18-
"sentry/sentry": "^4.15.0",
18+
"sentry/sentry": "^4.15.2",
1919
"symfony/cache-contracts": "^1.1||^2.4||^3.0",
2020
"symfony/config": "^4.4.20||^5.0.11||^6.0||^7.0",
2121
"symfony/console": "^4.4.20||^5.0.11||^6.0||^7.0",

phpstan-baseline.neon

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ parameters:
6767

6868
-
6969
message: "#^Cannot access offset 'integrations' on mixed\\.$#"
70-
count: 2
70+
count: 1
7171
path: src/DependencyInjection/SentryExtension.php
7272

7373
-
@@ -105,11 +105,6 @@ parameters:
105105
count: 11
106106
path: src/DependencyInjection/SentryExtension.php
107107

108-
-
109-
message: "#^Parameter \\#1 \\$integrations of method Sentry\\\\SentryBundle\\\\DependencyInjection\\\\SentryExtension\\:\\:configureIntegrationsOption\\(\\) expects array\\<string\\>, mixed given\\.$#"
110-
count: 1
111-
path: src/DependencyInjection/SentryExtension.php
112-
113108
-
114109
message: "#^Parameter \\#2 \\$array of function array_map expects array, mixed given\\.$#"
115110
count: 1
@@ -424,3 +419,8 @@ parameters:
424419
message: "#^Parameter \\#2 \\$responses of static method Sentry\\\\SentryBundle\\\\Tracing\\\\HttpClient\\\\AbstractTraceableResponse\\:\\:stream\\(\\) expects iterable\\<Sentry\\\\SentryBundle\\\\Tracing\\\\HttpClient\\\\AbstractTraceableResponse\\>, array\\<int, stdClass\\> given\\.$#"
425420
count: 1
426421
path: tests/Tracing/HttpClient/TraceableResponseTest.php
422+
423+
-
424+
message: "#^Call to method PHPUnit\\\\Framework\\\\Assert\\:\\:assertCount\\(\\) with 1 and array\\{\\} will always evaluate to false\\.$#"
425+
count: 2
426+
path: tests/End2End/TracingCacheEnd2EndTest.php

src/DependencyInjection/Compiler/BufferFlushPass.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ private function findSentryBufferHandlers(ContainerBuilder $container): array
4545
$arguments = $definition->getArguments();
4646
if (!empty($arguments)) {
4747
// The first argument of BufferHandler is the HandlerInterface, which
48-
// can be a SentryHandler.
49-
$firstArgument = $arguments[0];
48+
// can be a SentryHandler. Missing argument will be ignored.
49+
$firstArgument = $arguments[0] ?? $arguments['$handler'] ?? null;
5050

5151
if ($firstArgument instanceof Reference) {
5252
$referencedServiceId = (string) $firstArgument;

src/DependencyInjection/Configuration.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ public function getConfigTreeBuilder(): TreeBuilder
5959
->fixXmlConfig('ignore_transaction')
6060
->fixXmlConfig('prefix', 'prefixes')
6161
->children()
62-
->arrayNode('integrations')
63-
->scalarPrototype()->end()
62+
->variableNode('integrations')
63+
->defaultValue([])
6464
->end()
6565
->booleanNode('default_integrations')->end()
6666
->arrayNode('prefixes')
@@ -183,6 +183,7 @@ private function addMessengerSection(ArrayNodeDefinition $rootNode): void
183183
->{interface_exists(MessageBusInterface::class) ? 'canBeDisabled' : 'canBeEnabled'}()
184184
->children()
185185
->booleanNode('capture_soft_fails')->defaultTrue()->end()
186+
->booleanNode('isolate_breadcrumbs_by_message')->defaultFalse()->end()
186187
->end()
187188
->end()
188189
->end();

src/DependencyInjection/SentryExtension.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,17 @@ private function registerConfiguration(ContainerBuilder $container, array $confi
146146
$options['http_client'] = new Reference($options['http_client']);
147147
}
148148

149-
$container->getDefinition(IntegrationConfigurator::class)
150-
->setArgument(0, $this->configureIntegrationsOption($options['integrations'], $config))
151-
->setArgument(1, $config['register_error_handler']);
149+
if (\is_string($options['integrations']) && '' !== $options['integrations']) {
150+
$container->getDefinition(IntegrationConfigurator::class)
151+
->setArgument(0, new Reference($options['integrations']))
152+
->setArgument(1, $config['register_error_handler']);
153+
} else {
154+
$integrations = \is_array($options['integrations']) ? $options['integrations'] : [];
155+
156+
$container->getDefinition(IntegrationConfigurator::class)
157+
->setArgument(0, $this->configureIntegrationsOption($integrations, $config))
158+
->setArgument(1, $config['register_error_handler']);
159+
}
152160
$options['integrations'] = new Reference(IntegrationConfigurator::class);
153161

154162
$container
@@ -200,7 +208,7 @@ private function registerMessengerListenerConfiguration(ContainerBuilder $contai
200208
return;
201209
}
202210

203-
$container->getDefinition(MessengerListener::class)->setArgument(1, $config['capture_soft_fails']);
211+
$container->getDefinition(MessengerListener::class)->setArgument(1, $config['capture_soft_fails'])->setArgument(2, $config['isolate_breadcrumbs_by_message']);
204212
}
205213

206214
/**

src/EventListener/MessengerListener.php

Lines changed: 58 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Sentry\State\Scope;
1212
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
1313
use Symfony\Component\Messenger\Event\WorkerMessageHandledEvent;
14+
use Symfony\Component\Messenger\Event\WorkerMessageReceivedEvent;
1415
use Symfony\Component\Messenger\Exception\DelayedMessageHandlingException;
1516
use Symfony\Component\Messenger\Exception\HandlerFailedException;
1617
use Symfony\Component\Messenger\Exception\WrappedExceptionsInterface;
@@ -30,15 +31,25 @@ final class MessengerListener
3031
private $captureSoftFails;
3132

3233
/**
33-
* @param HubInterface $hub The current hub
34-
* @param bool $captureSoftFails Whether to capture errors thrown
35-
* while processing a message that
36-
* will be retried
34+
* @var bool When this is enabled, a new scope is pushed on the stack when a message
35+
* is received and will pop it again after the message was finished (either success or fail).
36+
* This allows us to have breadcrumbs only for one message and no breadcrumb is leaked into
37+
* future messages.
3738
*/
38-
public function __construct(HubInterface $hub, bool $captureSoftFails = true)
39+
private $isolateBreadcrumbsByMessage;
40+
41+
/**
42+
* @param HubInterface $hub The current hub
43+
* @param bool $captureSoftFails Whether to capture errors thrown
44+
* while processing a message that
45+
* will be retried
46+
* @param bool $isolateBreadcrumbsByMessage Whether messages should have isolated breadcrumbs
47+
*/
48+
public function __construct(HubInterface $hub, bool $captureSoftFails = true, bool $isolateBreadcrumbsByMessage = false)
3949
{
4050
$this->hub = $hub;
4151
$this->captureSoftFails = $captureSoftFails;
52+
$this->isolateBreadcrumbsByMessage = $isolateBreadcrumbsByMessage;
4253
}
4354

4455
/**
@@ -48,28 +59,36 @@ public function __construct(HubInterface $hub, bool $captureSoftFails = true)
4859
*/
4960
public function handleWorkerMessageFailedEvent(WorkerMessageFailedEvent $event): void
5061
{
51-
if (!$this->captureSoftFails && $event->willRetry()) {
52-
return;
53-
}
62+
try {
63+
if (!$this->captureSoftFails && $event->willRetry()) {
64+
return;
65+
}
5466

55-
$this->hub->withScope(function (Scope $scope) use ($event): void {
56-
$envelope = $event->getEnvelope();
57-
$exception = $event->getThrowable();
67+
$this->hub->withScope(function (Scope $scope) use ($event): void {
68+
$envelope = $event->getEnvelope();
69+
$exception = $event->getThrowable();
5870

59-
$scope->setTag('messenger.receiver_name', $event->getReceiverName());
60-
$scope->setTag('messenger.message_class', \get_class($envelope->getMessage()));
71+
$scope->setTag('messenger.receiver_name', $event->getReceiverName());
72+
$scope->setTag('messenger.message_class', \get_class($envelope->getMessage()));
6173

62-
/** @var BusNameStamp|null $messageBusStamp */
63-
$messageBusStamp = $envelope->last(BusNameStamp::class);
74+
/** @var BusNameStamp|null $messageBusStamp */
75+
$messageBusStamp = $envelope->last(BusNameStamp::class);
6476

65-
if (null !== $messageBusStamp) {
66-
$scope->setTag('messenger.message_bus', $messageBusStamp->getBusName());
67-
}
77+
if (null !== $messageBusStamp) {
78+
$scope->setTag('messenger.message_bus', $messageBusStamp->getBusName());
79+
}
6880

69-
$this->captureException($exception, $event->willRetry());
70-
});
81+
$this->captureException($exception, $event->willRetry());
82+
});
7183

72-
$this->flushClient();
84+
$this->flushClient();
85+
} finally {
86+
// We always want to pop the scope at the end of this method to add the breadcrumbs
87+
// to any potential event that is produced.
88+
if ($this->isolateBreadcrumbsByMessage) {
89+
$this->hub->popScope();
90+
}
91+
}
7392
}
7493

7594
/**
@@ -82,6 +101,24 @@ public function handleWorkerMessageHandledEvent(WorkerMessageHandledEvent $event
82101
// Flush normally happens at shutdown... which only happens in the worker if it is run with a lifecycle limit
83102
// such as --time=X or --limit=Y. Flush immediately in a background worker.
84103
$this->flushClient();
104+
if ($this->isolateBreadcrumbsByMessage) {
105+
$this->hub->popScope();
106+
}
107+
}
108+
109+
/**
110+
* Method that will push a new scope on the hub to create message local breadcrumbs that will not
111+
* "leak" into future messages.
112+
*
113+
* @param WorkerMessageReceivedEvent $event
114+
*
115+
* @return void
116+
*/
117+
public function handleWorkerMessageReceivedEvent(WorkerMessageReceivedEvent $event): void
118+
{
119+
if ($this->isolateBreadcrumbsByMessage) {
120+
$this->hub->pushScope();
121+
}
85122
}
86123

87124
/**

0 commit comments

Comments
 (0)