From 18a35bedcca37b58e0316b59c8697a0d724c70e8 Mon Sep 17 00:00:00 2001 From: Michi Hoffmann Date: Mon, 8 Apr 2024 10:03:31 +0200 Subject: [PATCH 01/57] Symfony SDK 5.0.0 (#821) --- .github/workflows/static-analysis.yaml | 6 +- CHANGELOG.md | 463 +----------------- Makefile | 21 - README.md | 143 +----- composer.json | 54 +- phpstan-baseline.neon | 39 +- src/DependencyInjection/Configuration.php | 40 +- src/DependencyInjection/SentryExtension.php | 55 +-- src/EventListener/ConsoleCommandListener.php | 20 - src/EventListener/TracingRequestListener.php | 17 +- src/Integration/RequestFetcher.php | 10 +- src/Resources/config/schema/sentry-1.0.xsd | 14 +- src/Resources/config/services.xml | 9 - .../DBAL/TracingDriverConnectionForV2V3.php | 7 - .../AbstractTraceableHttpClient.php | 11 +- src/Transport/TransportFactory.php | 65 --- src/Twig/SentryExtension.php | 10 + .../DependencyInjection/ConfigurationTest.php | 5 +- .../DependencyInjection/Fixtures/php/full.php | 24 +- .../DependencyInjection/Fixtures/xml/full.xml | 18 +- .../DependencyInjection/Fixtures/yml/full.yml | 30 +- .../SentryExtensionTest.php | 98 ++-- tests/End2End/App/config.yml | 11 +- tests/End2End/End2EndTest.php | 6 +- tests/End2End/StubTransport.php | 52 ++ tests/End2End/StubTransportFactory.php | 61 --- tests/End2End/TracingEnd2EndTest.php | 2 +- .../ConsoleCommandListenerTest.php | 23 - .../TracingRequestListenerTest.php | 38 +- .../TracingSubRequestListenerTest.php | 1 - .../HttpClient/TraceableHttpClientTest.php | 41 +- .../HttpClient/TraceableResponseTest.php | 8 + tests/Transport/TransportFactoryTest.php | 100 ---- tests/Twig/SentryExtensionTest.php | 62 ++- 34 files changed, 401 insertions(+), 1163 deletions(-) delete mode 100644 Makefile delete mode 100644 src/EventListener/ConsoleCommandListener.php delete mode 100644 src/Transport/TransportFactory.php create mode 100644 tests/End2End/StubTransport.php delete mode 100644 tests/End2End/StubTransportFactory.php delete mode 100644 tests/EventListener/ConsoleCommandListenerTest.php delete mode 100644 tests/Transport/TransportFactoryTest.php diff --git a/.github/workflows/static-analysis.yaml b/.github/workflows/static-analysis.yaml index e9012b41..0b44c29d 100644 --- a/.github/workflows/static-analysis.yaml +++ b/.github/workflows/static-analysis.yaml @@ -30,7 +30,7 @@ jobs: composer-options: --prefer-dist - name: Run script - run: composer phpcs + run: vendor/bin/php-cs-fixer fix --verbose --diff --dry-run phpstan: name: PHPStan @@ -50,7 +50,7 @@ jobs: composer-options: --prefer-dist - name: Run script - run: composer phpstan + run: vendor/bin/phpstan analyse psalm: name: Psalm @@ -70,4 +70,4 @@ jobs: composer-options: --prefer-dist - name: Run script - run: composer psalm -- --php-version=8.0 + run: vendor/bin/psalm --php-version=8.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ec8b451..6767db3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,470 +1,13 @@ # Changelog -## 4.14.0 +## 5.0.0 -The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v4.14.0. +The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v5.0.0. -### Features - -- Add support for `doctrine/dbal: ^4.0` [(#811)](https://github.com/getsentry/sentry-symfony/pull/811) - -### Bug Fixes - -- Fix overwritting `DbalTracingPass` [(#808)](https://github.com/getsentry/sentry-symfony/pull/808) -- Use `AbstractDriverMiddleware` [(#810)](https://github.com/getsentry/sentry-symfony/pull/810) - -## 4.13.2 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v4.13.2. - -### Bug Fixes - -- Fix detection of the installed version of `symfony/http-client` [(#797)](https://github.com/getsentry/sentry-symfony/pull/797) - -## 4.13.1 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v4.13.1. - -### Bug Fixes - -- Fix the HTTP client decoration when no `http_client` service is registered [(#792)](https://github.com/getsentry/sentry-symfony/pull/792) - -## 4.13.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v4.13.0. - -### Features - -- Add support for Symfony 7 [(#761)](https://github.com/getsentry/sentry-symfony/pull/761) - -### Bug Fixes - -- Fix the decoration of the HTTP client when tracing is enabled [(#786)](https://github.com/getsentry/sentry-symfony/pull/786) - -## 4.12.0 - -### Features - -- Add support for `symfony/psr-http-message-bridge: ^6.4` [(#750)](https://github.com/getsentry/sentry-symfony/pull/750) -- Report individual exceptions from `DelayedMessageHandlingException` [(#760)](https://github.com/getsentry/sentry-symfony/pull/760) - -## 4.11.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v4.11.0. - -### Bug Fixes - -- Silence `TokenInterface::isAuthenticated` deprecation in `LoginListener` [(#755)](https://github.com/getsentry/sentry-symfony/pull/755) - -### Misc - -- Prefer the `SENTRY_RELEASE` environment variable over the package root version [(#753)](https://github.com/getsentry/sentry-symfony/pull/753) - -## 4.10.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v4.10.0. - -### Features - -- Tracing without Performance [(#742)](https://github.com/getsentry/sentry-symfony/pull/742) - - The SDK will now continue a trace from incoming HTTP requests, even if performance is not enabled. - To continue a trace outward, you may attach the Sentry tracing headers to any HTTP client request. - You can fetch the required header values by calling \Sentry\getBaggage() and \Sentry\getTraceparent(). - -- Add `ignore_exceptions` and `ignore_transactions` options [(#724)](https://github.com/getsentry/sentry-symfony/pull/724) - -### Misc - -- Improve setting logged-in users on the scope [(#720)](https://github.com/getsentry/sentry-symfony/pull/720) -- Move DB span tags to span data [(#743)](https://github.com/getsentry/sentry-symfony/pull/743) -- Set the span status when tracing an HTTP client request [(#748)](https://github.com/getsentry/sentry-symfony/pull/748) - -## 4.9.2 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v4.9.2. - -### Bug Fixes - -- We decided to revert two previous PRs that aimed to remove deprecation warnings during test runs [(#736)](https://github.com/getsentry/sentry-symfony/pull/736) - - - Revert: Add a new Doctrine DBAL tracing driver that does not implement the deprecated `VersionAwarePlatformDriver` [(#723)](https://github.com/getsentry/sentry-symfony/pull/723) - - Revert: Fix a regression in `TracingDriverForV32` by adding `VersionAwarePlatformDriver::createDatabasePlatformForVersion` [(#731)](https://github.com/getsentry/sentry-symfony/pull/731) - -We are sorry for the inconvenience caused by these changes. - -## 4.9.1 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v4.9.1. - -### Bug Fixes - -- Fix a regression in `TracingDriverForV32` by adding `VersionAwarePlatformDriver::createDatabasePlatformForVersion` [(#731)](https://github.com/getsentry/sentry-symfony/pull/731) - -## 4.9.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v4.9.0. +### Breaking Changes ### Features -- Add a new Doctrine DBAL tracing driver that does not implement the deprecated `VersionAwarePlatformDriver` [(#723)](https://github.com/getsentry/sentry-symfony/pull/723) - - The driver is automatically picked if `doctrine/dbal` version `3.2.0` or higher is installed. - ### Bug Fixes -- Fix config type of `http_connect_timeout`and `http_timeout` options [(#721)](https://github.com/getsentry/sentry-symfony/pull/721) - ### Misc - -- Bump the underlying PHP SDK to version `^3.19` [(#725)](https://github.com/getsentry/sentry-symfony/pull/725) - -## 4.8.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v4.8.0. - -### Features - -- Set cache keys as span descriptions [(#677)](https://github.com/getsentry/sentry-symfony/pull/677) - - To better identify the source of a cache operation, we now set the cache key as the description of `cache` op spans. - -### Bug Fixes - -- Add direct dependency for `guzzlehttp/psr7` [(#708)](https://github.com/getsentry/sentry-symfony/pull/708) -- Drop `kernel.build_dir` param below Symfony 5.2 [(#711)](https://github.com/getsentry/sentry-symfony/pull/711) - -## 4.7.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v4.7.0. - -### Features - -- Add `profiles_sample_rate` config option [(#698)](https://github.com/getsentry/sentry-symfony/pull/698) - - With this new config option, you can now use our new profiling feature in Symfony as well. - Please consult https://github.com/getsentry/sentry-php/releases/3.15.0 for setup instructions. - -## 4.6.0 - -The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v4.6.0. -This release contains a colorful bouquet of new features. - -### Features - -- Report exceptions to Sentry as unhandled by default [(#674)](https://github.com/getsentry/sentry-symfony/pull/674) - - All unhandled exceptions will now be marked as `handled: false`. You can query for such events on the issues list page, - by searching for `error.handled:false`. - -- Exceptions from messages which will be retried are sent to Sentry as handled [(#674)](https://github.com/getsentry/sentry-symfony/pull/674) - - All unhandled exceptions happening on the message bus will now be unpacked and reported individually. - The `WorkerMessageFailedEvent::willRetry` property is used to determine the `handled` value of the event sent to Sentry. - -- Add `register_error_handler` config option [(#687)](https://github.com/getsentry/sentry-symfony/pull/687) - - With this option, you can disable the global error and exception handlers of the base PHP SDK. - If disabled, only events logged by Monolog will be sent to Sentry. - - ```yaml - sentry: - dsn: '%env(SENTRY_DSN)%' - register_error_listener: false - register_error_handler: false - - monolog: - handlers: - sentry: - type: sentry - level: !php/const Monolog\Logger::ERROR - hub_id: Sentry\State\HubInterface - ``` - -- Add `before_send_transaction` [(#691)](https://github.com/getsentry/sentry-symfony/pull/691) - - Similar to `before_send`, you can now apply additional logic for `transaction` events. - You can mutate the `transaction` event before it is sent to Sentry. If your callback returns `null`, - the event is dropped. - - ```yaml - sentry: - options: - before_send_transaction: 'sentry.callback.before_send_transaction' - - services: - sentry.callback.before_send_transaction: - class: 'App\Service\Sentry' - factory: [ '@App\Service\Sentry', 'getBeforeSendTransaction' ] - ``` - - ```php - >`. - - You may need to update your starred transactions as well as your dashboards due to this change. - -### Bug Fixes - -- Sanatize HTTP client spans [(#690)](https://github.com/getsentry/sentry-symfony/pull/690) - -## 4.5.0 (2022-11-28) - -- Symfony version 3.4 is no longer supported - - Drop Symfony support below 4.4 (#643) -- feat: Add support for tracing of Symfony HTTP client requests (#606) - - feat: Add support for HTTP client baggage propagation (#663) - - ref: Add proper HTTP client span descriptions (#680) -- feat: Support logging the impersonator user, if any (#647) -- ref: Use a constant for the SDK version (#662) - -## 4.4.0 (2022-10-20) - -- feat: Add support for Dynamic Sampling (#665) - -## 4.3.1 (2022-10-10) - -- fix: Update span ops (#655) - -## 4.3.0 (2022-05-30) - -- Fix compatibility issue with Symfony `>= 6.1.0` (#635) -- Add `TracingDriverConnectionInterface::getNativeConnection()` method to get the original driver connection (#597) -- Add `options.http_timeout` and `options.http_connect_timeout` configuration options (#593) - -## 4.2.10 (2022-05-17) - -- Fix compatibility issue with Twig >= 3.4.0 (#628) - -## 4.2.9 (2022-05-03) - -- Fix deprecation notice thrown when instrumenting the `PDOStatement::bindParam()` method and passing `$length = null` on DBAL `2.x` (#613) - -## 4.2.8 (2022-03-31) - -- Fix compatibility issue with Doctrine Bundle `>= 2.6.0` (#608) - -## 4.2.7 (2022-02-18) - -- Fix deprecation notice thrown when instrumenting the `PDOStatement::bindParam()` method and passing `$length = null` (#586) - -## 4.2.6 (2022-01-10) - -- Add support for `symfony/cache-contracts` package version `3.x` (#588) - -## 4.2.5 (2021-12-13) - -- Add support for Symfony 6 (#566) -- Fix fatal errors logged twice on Symfony `3.4` (#570) - -## 4.2.4 (2021-10-20) - -- Add return typehints to the methods of the `SentryExtension` class to prepare for Symfony 6 (#563) -- Fix setting the IP address on the user context when it's not available (#565) -- Fix wrong method existence check in `TracingDriverConnection::errorCode()` (#568) -- Fix decoration of the Doctrine DBAL connection when it implemented the `ServerInfoAwareConnection` interface (#567) - -## 4.2.3 (2021-09-21) - -- Fix: Test if `TracingStatement` exists before attempting to create the class alias, otherwise it breaks when opcache is enabled. (#552) -- Fix: Pass logger from `logger` config option to `TransportFactory` (#555) -- Improve the compatibility layer with Doctrine DBAL to avoid deprecations notices (#553) - -## 4.2.2 (2021-08-30) - -- Fix missing instrumentation of the `Statement::execute()` method of Doctrine DBAL (#548) - -## 4.2.1 (2021-08-24) - -- Fix return type for `TracingDriver::getDatabase()` method (#541) -- Avoid throwing exception from the `TraceableCacheAdapterTrait::prune()` and `TraceableCacheAdapterTrait::reset()` methods when the decorated adapter does not implement the respective interfaces (#543) - -## 4.2.0 (2021-08-12) - -- Log the bus name, receiver name and message class name as event tags when using Symfony Messenger (#492) -- Make the transport factory configurable in the bundle's config (#504) -- Add the `sentry_trace_meta()` Twig function to print the `sentry-trace` HTML meta tag (#510) -- Make the list of commands for which distributed tracing is active configurable (#515) -- Introduce `TracingDriverConnection::getWrappedConnection()` (#536) -- Add the `logger` config option to ease setting a PSR-3 logger to debug the SDK (#538) -- Bump requirement for DBAL tracing to `^2.13|^3`; simplify the DBAL tracing feature (#527) - -## 4.1.4 (2021-06-18) - -- Fix decoration of cache adapters inheriting parent service (#525) -- Fix extraction of the username of the logged-in user in Symfony `5.3` (#518) - -## 4.1.3 (2021-05-31) - -- Fix missing require of the `symfony/cache-contracts` package (#506) - -## 4.1.2 (2021-05-17) - -- Fix the check of the existence of the `CacheItem` class while attempting to enable the cache instrumentation (#501) - -## 4.1.1 (2021-05-10) - -- Fix the conditions to automatically enable the cache instrumentation when possible (#487) -- Fix deprecations triggered by Symfony `5.3` (#489) -- Fix fatal error when the `SERVER_PROTOCOL` header is missing (#495) - -## 4.1.0 (2021-04-19) - -- Avoid failures when the `RequestFetcher` fails to translate the `Request` (#472) -- Add support for distributed tracing of Symfony request events (#423) -- Add support for distributed tracing of Twig template rendering (#430) -- Add support for distributed tracing of SQL queries while using Doctrine DBAL (#426) -- Add support for distributed tracing when running a console command (#455) -- Add support for distributed tracing of cache pools (#477) -- Add the full CLI command string to the extra context (#352) -- Deprecate the `Sentry\SentryBundle\EventListener\ConsoleCommandListener` class in favor of its parent class `Sentry\SentryBundle\EventListener\ConsoleListener` (#429) -- Lower the required version of `symfony/psr-http-message-bridge` to allow installing it on a project that uses Symfony `3.4.x` components only (#480) - -## 4.0.3 (2021-03-03) - -- Fix regression from #454 for `null` value on DSN not disabling Sentry (#457) - -## 4.0.2 (2021-03-03) - -- Add `kernel.project_dir` to `prefixes` default value to trim paths to the project root (#434) -- Fix `null`, `false` or empty value not disabling Sentry (#454) - -## 4.0.1 (2021-01-26) - -- Add missing `capture-soft-fails` option to the XSD schema for the XML config (#417) -- Fix regression that send PII even when the `send_default_pii` option is off (#425) -- Fix capture of console errors when the `register_error_listener` option is disabled (#427) - -## 4.0.0 (2021-01-19) - -**Breaking Change**: This version uses the [envelope endpoint](https://develop.sentry.dev/sdk/envelopes/). If you are -using an on-premise installation it requires Sentry version `>= v20.6.0` to work. If you are using -[sentry.io](https://sentry.io) nothing will change and no action is needed. - -- Enable back all error listeners from base SDK integration (#322) -- Add `options.traces_sampler` and `options.traces_sample_rate` configuration options (#385) -- [BC BREAK] Remove the `options.project_root` configuration option. Instead of setting it, use a combination of `options.in_app_include` and `options.in_app_exclude` (#385) -- [BC BREAK] Remove the `options.excluded_exceptions` configuration option. Instead of setting it, configure the `IgnoreErrorsIntegration` integration (#385) -- [BC BREAK] Refactorize the `ConsoleCommandListener`, `ErrorListener`, `RequestListener` and `SubRequestListener` event listeners (#387) -- Registered the CLI commands as lazy services (#373) -- [BC BREAK] Refactorize the configuration tree and the definitions of some container services (#401) -- Support the XML format for the bundle configuration (#401) -- PHP 8 support (#399, thanks to @Yozhef) -- Retrieve the request from the `RequestStack` when using the `RequestIntegration` integration (#361) -- Reorganize the folder structure and change CS standard (#405) -- [BC BREAK] Remove the `monolog` configuration option. Instead, register the service manually (#406) -- [BC BREAK] Remove the `listener_priorities` configuration option. Instead, use a compiler pass to change the priority of the listeners (#407) -- Prefer usage of the existing `Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface` service for the `RequestFetcher` class (#409) -- [BC BREAK] Change the priorities of the `RequestListener` and `SubRequestListener` listeners (#414) - -## 3.5.3 (2020-10-13) - -- Refactors and fixes class aliases for more robustness (#315 #359, thanks to @guilliamxavier) - -## 3.5.2 (2020-07-08) - -- Use `jean85/pretty-package-versions` `^1.5` to leverage the new `getRootPackageVersion` method (c8799ac) -- Fix support for PHP preloading (#354, thanks to @annuh) -- Fix `capture_soft_fails: false` option for the Messenger (#353) - -## 3.5.1 (2020-05-07) - -- Capture events using the `Hub` in the `MessengerListener` to avoid loosing `Scope` data (#339, thanks to @sh41) -- Capture multiple events if multiple exceptions are generated in a Messenger Worker context (#340, thanks to @emarref) - -## 3.5.0 (2020-05-04) - -- Capture and flush messages in a Messenger Worker context (#326, thanks to @emarref) -- Support Composer 2 (#335) -- Avoid issues with dependency lower bound, fix #331 (#335) - -## 3.4.4 (2020-03-16) - -- Improve `release` option default value (#325) - -## 3.4.3 (2020-02-03) - -- Change default of `in_app_include` to empty, due to getsentry/sentry-php#958 (#311) -- Improve class_alias robustness (#315) - -## 3.4.2 (2020-01-29) - -- Remove space from classname used with `class_alias` (#313) - -## 3.4.1 (2020-01-24) - -- Fix issue due to usage of `class_alias` to fix deprecations, which could break BC layers of third party packages (#309, thanks to @scheb) - -## 3.4.0 (2020-01-20) - -- Add support for `sentry/sentry` 2.3 (#298) -- Drop support for `sentry/sentry` < 2.3 (#298) -- Add support to `in_app_include` client option (#298) -- Remap `excluded_exceptions` option to use the new `IgnoreErrorsIntegration` (#298) - -## 3.3.2 (2020-01-16) - -- Fix issue with exception listener under Symfony 4.3 (#301) - -## 3.3.1 (2020-01-14) - -- Fixed Release - -## 3.3.0 (2020-01-14) - -- Add support for Symfony 5.0 (#266, thanks to @Big-Shark) -- Drop support for Symfony < 3.4 (#277) -- Add default value for the `release` option, using the detected root package version (#291 #292, thanks to @Ocramius) - -## 3.2.1 (2019-12-19) - -- Fix handling of command with no name on `ConsoleListener` (#261) -- Remove check by AuthorizationChecker in `RequestListener` (#264) -- Fixed undefined variable in `RequestListener` (#263) - -## 3.2.0 (2019-10-04) - -- Add forward compatibility with Symfony 5 (#235, thanks to @garak) -- Fix Hub initialization for `ErrorListener` (#243, thanks to @teohhanhui) -- Fix compatibility with sentry/sentry 2.2+ (#244) -- Add support for `class_serializers` option (#245) -- Add support for `max_request_body_size` option (#249) -- Add option to disable the error listener completely (#247, thanks to @HypeMC) -- Add options to register the Monolog Handler (#247, thanks to @HypeMC) - -## 3.1.0 (2019-07-02) - -- Add support for Symfony 2.8 (#233, thanks to @nocive) -- Fix handling of ESI requests (#213, thanks to @franmomu) - -## 3.0.0 (2019-05-10) - -- Add the `sentry:test` command, to test if the Sentry SDK is functioning properly. - -## 3.0.0-beta2 (2019-03-22) - -- Disable Sentry's ErrorHandler, and report all errors using Symfony's events (#204) - -## 3.0.0-beta1 (2019-03-06) - -The 3.0 major release has multiple breaking changes. The most notable one is the upgrade to the 2.0 base SDK client. -Refer to the [UPGRADE-3.0.md](https://github.com/getsentry/sentry-symfony/blob/master/UPGRADE-3.0.md) document for a -detailed explanation. diff --git a/Makefile b/Makefile deleted file mode 100644 index 4f116379..00000000 --- a/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -.PHONY: pre-commit-check - -cs: - vendor/bin/php-cs-fixer fix --verbose - -cs-dry-run: - vendor/bin/php-cs-fixer fix --verbose --dry-run - -phpstan: - vendor/bin/phpstan analyze - -psalm: - vendor/bin/psalm - -test: - vendor/bin/phpunit - -pre-commit-check: cs phpstan psalm test - -setup-git: - git config branch.autosetuprebase always diff --git a/README.md b/README.md index 780d82e0..3190cf64 100644 --- a/README.md +++ b/README.md @@ -20,153 +20,38 @@ This is the official Symfony SDK for [Sentry](https://getsentry.com/). ## Getting Started -Using this `sentry-symfony` SDK provides you with the following benefits: - - * Quickly integrate and configure Sentry for your Symfony app - * Out of the box, each event will contain the following data by default - - The currently authenticated user - - The Symfony environment - ### Install -To install the SDK you will need to be using [Composer]([https://getcomposer.org/) -in your project. To install it please see the [docs](https://getcomposer.org/download/). +Install the SDK using [Composer](https://getcomposer.org/). ```bash composer require sentry/sentry-symfony ``` -If you're using the [Symfony Flex](https://symfony.com/doc/current/setup/flex.html) Composer plugin, you might encounter a message similar to this: - -``` -The recipe for this package comes from the "contrib" repository, which is open to community contributions. -Review the recipe at https://github.com/symfony/recipes-contrib/tree/master/sentry/sentry-symfony/3.0 - -Do you want to execute this recipe? -``` - -Just type `y`, press return, and the procedure will continue. - -**Caution:** Due to a bug in the [`SensioFrameworkExtra`](https://github.com/sensiolabs/SensioFrameworkExtraBundle) bundle, affecting version 6.0 and below, you might run into a missing `Nyholm\Psr7\Factory\Psr17Factory::class` error while executing the commands mentioned above. -If you are not using the PSR-7 bridge, you can work around this issue by changing the configuration of the bundle as follows: - -```yaml -sensio_framework_extra: - psr_message: - enabled: false -``` - -For more details about the issue see https://github.com/sensiolabs/SensioFrameworkExtraBundle/pull/710. - -### Enable the Bundle - -If you installed the package using the Flex recipe, the bundle will be automatically enabled. Otherwise, enable it by adding it to the list -of registered bundles in the `Kernel.php` file of your project: - -```php -class AppKernel extends \Symfony\Component\HttpKernel\Kernel -{ - public function registerBundles(): array - { - return [ - // ... - new \Sentry\SentryBundle\SentryBundle(), - ]; - } - - // ... -} -``` - -The bundle will be enabled in all environments by default. -To enable event reporting, you'll need to add a DSN (see the next step). - ### Configure -Add the [Sentry DSN](https://docs.sentry.io/quickstart/#configure-the-dsn) of your project. -If you're using Symfony 3.4, add the DSN to your `app/config/config_prod.yml` file. -For Symfony 4 or newer, add the DSN to your `config/packages/sentry.yaml` file. - -Keep in mind that by leaving the `dsn` value empty (or undeclared), you will disable Sentry's event reporting. - -```yaml -sentry: - dsn: "https://public:secret@sentry.example.com/1" - messenger: - enabled: true # flushes Sentry messages at the end of each message handling - capture_soft_fails: true # captures exceptions marked for retry too - options: - environment: '%kernel.environment%' - release: '%env(VERSION)%' #your app version -``` - -The parameter `options` allows to fine-tune exceptions. To discover more options, please refer to -[the Unified APIs](https://docs.sentry.io/development/sdk-dev/unified-api/#options) options and -the [PHP specific](https://docs.sentry.io/platforms/php/#php-specific-options) ones. - -#### Optional: use custom HTTP factory/transport - -Since the SDK 2.0 uses HTTPlug to remain transport-agnostic, you need to install two packages that provide -[`php-http/async-client-implementation`](https://packagist.org/providers/php-http/async-client-implementation) -and [`psr/http-message-implementation`](https://packagist.org/providers/psr/http-message-implementation). - -This bundle depends on `sentry/sdk`, which is a metapackage that already solves this need, requiring our suggested HTTP -packages: the Symfony HTTP client (`symfony/http-client`) and Guzzle's message factories (`http-interop/http-factory-guzzle`). +Add the [Sentry DSN](https://docs.sentry.io/quickstart/#configure-the-dsn) to your `.env` file. -If you want to use a different HTTP client or message factory, you can override the `sentry/sdk` package by adding the following to your `composer.json` after the `require` section: - -```json - "replace": { - "sentry/sdk": "*" - } ``` - -For example when you want to use Guzzle's components: - -```bash -composer require php-http/guzzle6-adapter guzzlehttp/psr7 +###> sentry/sentry-symfony ### +SENTRY_DSN="https://public@sentry.example.com/1" +###< sentry/sentry-symfony ### ``` -If you don't have a compatible HTTP client and/or message factory implementation installed `php-http/discovery` will try to install it for you using a Composer plugin. - -## Maintained versions +### Usgae - * 4.x is actively maintained and developed on the master branch, and uses Sentry SDK 3.0; - * 3.x is supported only for fixes and uses Sentry SDK 2.0; - * 2.x is no longer maintained; from this version onwards it requires Symfony 3+ and PHP 7.1+; - * 1.x is no longer maintained; you can use it for Symfony < 2.8 and PHP 5.6/7.0; - * 0.8.x is no longer maintained. - -### Upgrading to 4.0 - -The 4.0 version of the bundle uses the newest version (3.x) of the underlying Sentry SDK. If you need to migrate from previous versions, please check the `UPGRADE-4.0.md` document. - -#### Custom serializers - -The option class_serializers can be used to send customized objects serialization. -```yml -sentry: - options: - class_serializers: - YourValueObject: 'ValueObjectSerializer' -``` - -Several serializers can be added and the serializable check is done by using the **instanceof** type operator. -The serializer must implement the `__invoke` method, which needs to return an **array**, containing the information that should be send to Sentry. The class name is always sent by default. - -Serializer example: ```php -final class ValueObjectSerializer -{ - public function __invoke(YourValueObject $vo): array - { - return [ - 'value' => $vo->value() - ]; - } +use function Sentry\captureException; + +try { + $this->functionThatMayFail(); +} catch (\Throwable $exception) { + captureException($exception); } ``` +## Symfony Version Compatibility + ## Contributing to the SDK Please refer to [CONTRIBUTING.md](CONTRIBUTING.md). diff --git a/composer.json b/composer.json index 80e74ddc..7809d603 100644 --- a/composer.json +++ b/composer.json @@ -7,28 +7,15 @@ "license": "MIT", "authors": [ { - "name": "David Cramer", - "email": "dcramer@gmail.com" - }, - { - "name": "Alessandro Lai", - "email": "alessandro.lai85@gmail.com" + "name": "Sentry", + "email": "accounts@sentry.io" } ], - "config": { - "sort-packages": true, - "allow-plugins": { - "composer/package-versions-deprecated": true, - "phpstan/extension-installer": true, - "php-http/discovery": false - } - }, "require": { "php": "^7.2||^8.0", - "guzzlehttp/psr7": "^1.7 || ^2.0", - "jean85/pretty-package-versions": "^1.5 || ^2.0", - "sentry/sdk": "^3.6", - "sentry/sentry": "^3.22.1", + "guzzlehttp/psr7": "^2.1.1", + "jean85/pretty-package-versions": "^1.5||^2.0", + "sentry/sentry": "^4.6.1", "symfony/cache-contracts": "^1.1||^2.4||^3.0", "symfony/config": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/console": "^4.4.20||^5.0.11||^6.0||^7.0", @@ -83,24 +70,23 @@ } }, "scripts": { - "tests": [ - "vendor/bin/phpunit --verbose" + "check": [ + "@cs-check", + "@phpstan", + "@psalm", + "@tests" ], - "phpcs": [ - "vendor/bin/php-cs-fixer fix --verbose --diff --dry-run" - ], - "phpstan": [ - "vendor/bin/phpstan analyse" - ], - "psalm": [ - "vendor/bin/psalm" - ] + "tests": "vendor/bin/phpunit --verbose", + "cs-check": "vendor/bin/php-cs-fixer fix --verbose --diff --dry-run", + "cs-fix": "vendor/bin/php-cs-fixer fix --verbose --diff", + "phpstan": "vendor/bin/phpstan analyse", + "psalm": "vendor/bin/psalm" }, - "extra": { - "branch-alias": { - "releases/3.2.x": "3.2.x-dev", - "releases/2.x": "2.x-dev", - "releases/1.x": "1.x-dev" + "config": { + "sort-packages": true, + "allow-plugins": { + "composer/package-versions-deprecated": true, + "phpstan/extension-installer": true } } } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index d2ecc82a..a3147cca 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -15,6 +15,16 @@ parameters: count: 1 path: src/DependencyInjection/SentryExtension.php + - + message: "#^Cannot access offset 'before_send_check_in' on mixed\\.$#" + count: 1 + path: src/DependencyInjection/SentryExtension.php + + - + message: "#^Cannot access offset 'before_send_metrics' on mixed\\.$#" + count: 1 + path: src/DependencyInjection/SentryExtension.php + - message: "#^Cannot access offset 'before_send…' on mixed\\.$#" count: 1 @@ -45,6 +55,11 @@ parameters: count: 1 path: src/DependencyInjection/SentryExtension.php + - + message: "#^Cannot access offset 'http_client' on mixed\\.$#" + count: 1 + path: src/DependencyInjection/SentryExtension.php + - message: "#^Cannot access offset 'in_app_exclude' on mixed\\.$#" count: 2 @@ -61,7 +76,7 @@ parameters: path: src/DependencyInjection/SentryExtension.php - - message: "#^Class Symfony\\\\Component\\\\Debug\\\\Exception\\\\FatalErrorException not found\\.$#" + message: "#^Cannot access offset 'transport' on mixed\\.$#" count: 1 path: src/DependencyInjection/SentryExtension.php @@ -77,7 +92,7 @@ parameters: - message: "#^Parameter \\#1 \\$id of class Symfony\\\\Component\\\\DependencyInjection\\\\Reference constructor expects string, mixed given\\.$#" - count: 6 + count: 9 path: src/DependencyInjection/SentryExtension.php - @@ -130,11 +145,6 @@ parameters: count: 4 path: src/DependencyInjection/SentryExtension.php - - - message: "#^Parameter \\#2 \\$registerErrorListener of method Sentry\\\\SentryBundle\\\\DependencyInjection\\\\SentryExtension\\:\\:configureErrorListenerIntegration\\(\\) expects bool, mixed given\\.$#" - count: 1 - path: src/DependencyInjection/SentryExtension.php - - message: "#^Parameter \\#2 \\$useDefaultIntegrations of method Sentry\\\\SentryBundle\\\\DependencyInjection\\\\SentryExtension\\:\\:configureRequestIntegration\\(\\) expects bool, mixed given\\.$#" count: 1 @@ -150,11 +160,6 @@ parameters: count: 1 path: src/EventListener/AbstractTracingRequestListener.php - - - message: "#^Class Sentry\\\\SentryBundle\\\\EventListener\\\\ConsoleCommandListener extends @final class Sentry\\\\SentryBundle\\\\EventListener\\\\ConsoleListener\\.$#" - count: 1 - path: src/EventListener/ConsoleCommandListener.php - - message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpKernel\\\\Event\\\\KernelEvent\\:\\:isMasterRequest\\(\\)\\.$#" count: 1 @@ -255,11 +260,6 @@ parameters: count: 1 path: tests/DependencyInjection/Fixtures/php/release_option_fallback_to_env_var.php - - - message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#" - count: 1 - path: tests/DependencyInjection/SentryExtensionTest.php - - message: "#^Cannot access offset 'dsn' on mixed\\.$#" count: 1 @@ -275,11 +275,6 @@ parameters: count: 1 path: tests/DependencyInjection/SentryExtensionTest.php - - - message: "#^Class Symfony\\\\Component\\\\Debug\\\\Exception\\\\FatalErrorException not found\\.$#" - count: 1 - path: tests/DependencyInjection/SentryExtensionTest.php - - message: "#^Class Symfony\\\\Bundle\\\\FrameworkBundle\\\\Client not found\\.$#" count: 1 diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 717d8ada..ca095895 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -7,7 +7,6 @@ use Doctrine\Bundle\DoctrineBundle\DoctrineBundle; use Sentry\Options; use Sentry\SentryBundle\ErrorTypesParser; -use Sentry\Transport\TransportFactoryInterface; use Symfony\Bundle\TwigBundle\TwigBundle; use Symfony\Component\Cache\CacheItem; use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; @@ -43,7 +42,7 @@ public function getConfigTreeBuilder(): TreeBuilder $rootNode ->children() ->scalarNode('dsn') - ->info('If this value is not provided, the SDK will try to read it from the SENTRY_DSN environment variable. If that variable also does not exist, the SDK will just not send any events.') + ->info('If this value is not provided, the SDK will try to read it from the SENTRY_DSN environment variable. If that variable also does not exist, the SDK will not send any events.') ->end() ->booleanNode('register_error_listener')->defaultTrue()->end() ->booleanNode('register_error_handler')->defaultTrue()->end() @@ -51,10 +50,6 @@ public function getConfigTreeBuilder(): TreeBuilder ->info('The service ID of the PSR-3 logger used to log messages coming from the SDK client. Be aware that setting the same logger of the application may create a circular loop when an event fails to be sent.') ->defaultNull() ->end() - ->scalarNode('transport_factory') - ->info('The service ID of the transport factory used by the default SDK client.') - ->defaultValue(TransportFactoryInterface::class) - ->end() ->arrayNode('options') ->addDefaultsIfNotSet() ->fixXmlConfig('integration') @@ -69,7 +64,6 @@ public function getConfigTreeBuilder(): TreeBuilder ->scalarPrototype()->end() ->end() ->booleanNode('default_integrations')->end() - ->integerNode('send_attempts')->min(0)->end() ->arrayNode('prefixes') ->defaultValue(array_merge(['%kernel.project_dir%'], array_filter(explode(\PATH_SEPARATOR, get_include_path() ?: '')))) ->scalarPrototype()->end() @@ -79,33 +73,46 @@ public function getConfigTreeBuilder(): TreeBuilder ->max(1.0) ->info('The sampling factor to apply to events. A value of 0 will deny sending any event, and a value of 1 will send all events.') ->end() + ->booleanNode('enable_tracing')->end() ->floatNode('traces_sample_rate') ->min(0.0) ->max(1.0) ->info('The sampling factor to apply to transactions. A value of 0 will deny sending any transaction, and a value of 1 will send all transactions.') ->end() + ->scalarNode('traces_sampler')->end() ->floatNode('profiles_sample_rate') ->min(0.0) ->max(1.0) ->info('The sampling factor to apply to profiles. A value of 0 will deny sending any profiles, and a value of 1 will send all profiles. Profiles are sampled in relation to traces_sample_rate') ->end() - ->scalarNode('traces_sampler')->end() - ->variableNode('trace_propagation_targets')->end() ->booleanNode('attach_stacktrace')->end() + ->booleanNode('attach_metric_code_locations')->end() ->integerNode('context_lines')->min(0)->end() - ->booleanNode('enable_compression')->end() ->scalarNode('environment') ->cannotBeEmpty() ->defaultValue('%kernel.environment%') ->end() ->scalarNode('logger')->end() + ->booleanNode('spotlight')->end() + ->scalarNode('spotlight_url')->end() ->scalarNode('release') ->cannotBeEmpty() ->defaultValue('%env(default::SENTRY_RELEASE)%') ->end() ->scalarNode('server_name')->end() + ->arrayNode('ignore_exceptions') + ->scalarPrototype()->end() + ->beforeNormalization()->castToArray()->end() + ->end() + ->arrayNode('ignore_transactions') + ->scalarPrototype()->end() + ->beforeNormalization()->castToArray()->end() + ->end() ->scalarNode('before_send')->end() ->scalarNode('before_send_transaction')->end() + ->scalarNode('before_send_check_in')->end() + ->scalarNode('before_send_metrics')->end() + ->variableNode('trace_propagation_targets')->end() ->arrayNode('tags') ->useAttributeAsKey('name') ->normalizeKeys(false) @@ -132,7 +139,10 @@ public function getConfigTreeBuilder(): TreeBuilder ->end() ->booleanNode('send_default_pii')->end() ->integerNode('max_value_length')->min(0)->end() + ->scalarNode('transport')->end() + ->scalarNode('http_client')->end() ->scalarNode('http_proxy')->end() + ->scalarNode('http_proxy_authentication')->end() ->floatNode('http_connect_timeout') ->min(0) ->info('The maximum number of seconds to wait while trying to connect to a server. It works only when using the default transport.') @@ -141,6 +151,8 @@ public function getConfigTreeBuilder(): TreeBuilder ->min(0) ->info('The maximum execution time for the request+response as a whole. It works only when using the default transport.') ->end() + ->booleanNode('http_ssl_verify_peer')->end() + ->booleanNode('http_compression')->end() ->booleanNode('capture_silenced_errors')->end() ->enumNode('max_request_body_size') ->values([ @@ -155,14 +167,6 @@ public function getConfigTreeBuilder(): TreeBuilder ->normalizeKeys(false) ->scalarPrototype()->end() ->end() - ->arrayNode('ignore_exceptions') - ->scalarPrototype()->end() - ->beforeNormalization()->castToArray()->end() - ->end() - ->arrayNode('ignore_transactions') - ->scalarPrototype()->end() - ->beforeNormalization()->castToArray()->end() - ->end() ->end() ->end() ->end(); diff --git a/src/DependencyInjection/SentryExtension.php b/src/DependencyInjection/SentryExtension.php index a0d502a5..78f1faa4 100644 --- a/src/DependencyInjection/SentryExtension.php +++ b/src/DependencyInjection/SentryExtension.php @@ -9,7 +9,6 @@ use Psr\Log\NullLogger; use Sentry\Client; use Sentry\ClientBuilder; -use Sentry\Integration\IgnoreErrorsIntegration; use Sentry\Integration\IntegrationInterface; use Sentry\Integration\RequestFetcherInterface; use Sentry\Integration\RequestIntegration; @@ -26,17 +25,13 @@ use Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverMiddleware; use Sentry\SentryBundle\Tracing\Twig\TwigTracingExtension; use Sentry\Serializer\RepresentationSerializer; -use Sentry\Serializer\Serializer; -use Sentry\Transport\TransportFactoryInterface; use Symfony\Bundle\TwigBundle\TwigBundle; use Symfony\Component\Cache\CacheItem; use Symfony\Component\Config\FileLocator; -use Symfony\Component\Debug\Exception\FatalErrorException; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Loader; use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\ErrorHandler\Error\FatalError; use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension; @@ -111,6 +106,14 @@ private function registerConfiguration(ContainerBuilder $container, array $confi $options['before_send_transaction'] = new Reference($options['before_send_transaction']); } + if (isset($options['before_send_check_in'])) { + $options['before_send_check_in'] = new Reference($options['before_send_check_in']); + } + + if (isset($options['before_send_metrics'])) { + $options['before_send_metrics'] = new Reference($options['before_send_metrics']); + } + if (isset($options['before_breadcrumb'])) { $options['before_breadcrumb'] = new Reference($options['before_breadcrumb']); } @@ -121,6 +124,14 @@ private function registerConfiguration(ContainerBuilder $container, array $confi }, $options['class_serializers']); } + if (isset($options['transport'])) { + $options['transport'] = new Reference($options['transport']); + } + + if (isset($options['http_client'])) { + $options['http_client'] = new Reference($options['http_client']); + } + $container->getDefinition(IntegrationConfigurator::class) ->setArgument(0, $this->configureIntegrationsOption($options['integrations'], $config)) ->setArgument(1, $config['register_error_handler']); @@ -131,10 +142,6 @@ private function registerConfiguration(ContainerBuilder $container, array $confi ->setPublic(false) ->setArgument(0, $options); - $serializer = (new Definition(Serializer::class)) - ->setPublic(false) - ->setArgument(0, new Reference('sentry.client.options')); - $representationSerializerDefinition = (new Definition(RepresentationSerializer::class)) ->setPublic(false) ->setArgument(0, new Reference('sentry.client.options')); @@ -143,15 +150,10 @@ private function registerConfiguration(ContainerBuilder $container, array $confi ? new Reference(NullLogger::class, ContainerBuilder::IGNORE_ON_INVALID_REFERENCE) : new Reference($config['logger']); - $factoryBuilderDefinition = $container->getDefinition(TransportFactoryInterface::class); - $factoryBuilderDefinition->setArgument('$logger', $loggerReference); - $clientBuilderDefinition = (new Definition(ClientBuilder::class)) ->setArgument(0, new Reference('sentry.client.options')) ->addMethodCall('setSdkIdentifier', [SentryBundle::SDK_IDENTIFIER]) ->addMethodCall('setSdkVersion', [SentryBundle::SDK_VERSION]) - ->addMethodCall('setTransportFactory', [new Reference($config['transport_factory'])]) - ->addMethodCall('setSerializer', [$serializer]) ->addMethodCall('setRepresentationSerializer', [$representationSerializerDefinition]) ->addMethodCall('setLogger', [$loggerReference]); @@ -285,36 +287,11 @@ private function configureIntegrationsOption(array $integrations, array $config) return new Reference($value); }, $integrations); - $integrations = $this->configureErrorListenerIntegration($integrations, $config['register_error_listener']); $integrations = $this->configureRequestIntegration($integrations, $config['options']['default_integrations'] ?? true); return $integrations; } - /** - * @param array $integrations - * - * @return array - */ - private function configureErrorListenerIntegration(array $integrations, bool $registerErrorListener): array - { - if ($registerErrorListener && !$this->isIntegrationEnabled(IgnoreErrorsIntegration::class, $integrations)) { - // Prepend this integration to the beginning of the array so that - // we can save some performance by skipping the rest of the integrations - // if the error must be ignored - array_unshift($integrations, new Definition(IgnoreErrorsIntegration::class, [ - [ - 'ignore_exceptions' => [ - FatalError::class, - FatalErrorException::class, - ], - ], - ])); - } - - return $integrations; - } - /** * @param array $integrations * diff --git a/src/EventListener/ConsoleCommandListener.php b/src/EventListener/ConsoleCommandListener.php deleted file mode 100644 index 1f64ecb3..00000000 --- a/src/EventListener/ConsoleCommandListener.php +++ /dev/null @@ -1,20 +0,0 @@ -server->get('REQUEST_TIME_FLOAT', microtime(true)); $context = continueTrace( - $request->headers->get('sentry-trace', ''), + $request->headers->get('sentry-trace') ?? $request->headers->get('traceparent', ''), $request->headers->get('baggage', '') ); $context->setOp('http.server'); @@ -73,6 +74,7 @@ public function handleKernelTerminateEvent(TerminateEvent $event): void } $transaction->finish(); + metrics()->flush(); } /** @@ -86,7 +88,8 @@ private function getData(Request $request): array { $client = $this->hub->getClient(); $httpFlavor = $this->getHttpFlavor($request); - $tags = [ + + $data = [ 'net.host.port' => (string) $request->getPort(), 'http.request.method' => $request->getMethod(), 'http.url' => $request->getUri(), @@ -94,20 +97,20 @@ private function getData(Request $request): array ]; if (null !== $httpFlavor) { - $tags['http.flavor'] = $httpFlavor; + $data['http.flavor'] = $httpFlavor; } if (false !== filter_var($request->getHost(), \FILTER_VALIDATE_IP)) { - $tags['net.host.ip'] = $request->getHost(); + $data['net.host.ip'] = $request->getHost(); } else { - $tags['net.host.name'] = $request->getHost(); + $data['net.host.name'] = $request->getHost(); } if (null !== $request->getClientIp() && null !== $client && $client->getOptions()->shouldSendDefaultPii()) { - $tags['net.peer.ip'] = $request->getClientIp(); + $data['net.peer.ip'] = $request->getClientIp(); } - return $tags; + return $data; } /** diff --git a/src/Integration/RequestFetcher.php b/src/Integration/RequestFetcher.php index f5911b2c..af371783 100644 --- a/src/Integration/RequestFetcher.php +++ b/src/Integration/RequestFetcher.php @@ -4,7 +4,7 @@ namespace Sentry\SentryBundle\Integration; -use Http\Discovery\Psr17FactoryDiscovery; +use GuzzleHttp\Psr7\HttpFactory; use Psr\Http\Message\ServerRequestInterface; use Sentry\Integration\RequestFetcherInterface; use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory; @@ -38,10 +38,10 @@ public function __construct(RequestStack $requestStack, ?HttpMessageFactoryInter { $this->requestStack = $requestStack; $this->httpMessageFactory = $httpMessageFactory ?? new PsrHttpFactory( - Psr17FactoryDiscovery::findServerRequestFactory(), - Psr17FactoryDiscovery::findStreamFactory(), - Psr17FactoryDiscovery::findUploadedFileFactory(), - Psr17FactoryDiscovery::findResponseFactory() + new HttpFactory(), + new HttpFactory(), + new HttpFactory(), + new HttpFactory() ); } diff --git a/src/Resources/config/schema/sentry-1.0.xsd b/src/Resources/config/schema/sentry-1.0.xsd index 78ed5033..3bad5d57 100644 --- a/src/Resources/config/schema/sentry-1.0.xsd +++ b/src/Resources/config/schema/sentry-1.0.xsd @@ -35,28 +35,38 @@ - + + + + + + + + - + + + + diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 74682cc6..ef3ce7d8 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -9,15 +9,6 @@ - - - - - - null - - - diff --git a/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3.php b/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3.php index 2cb2513d..6e79102e 100644 --- a/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3.php +++ b/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3.php @@ -60,13 +60,6 @@ final class TracingDriverConnectionForV2V3 implements TracingDriverConnectionInt */ private $decoratedConnection; - /** - * @var array The span tags - * - * @deprecated since version 4.10, to be removed in 5.0. Use $spanData instead. - */ - private $spanTags = []; - /** * @var array The data to attach to the span */ diff --git a/src/Tracing/HttpClient/AbstractTraceableHttpClient.php b/src/Tracing/HttpClient/AbstractTraceableHttpClient.php index 4ee8f77a..1220600f 100644 --- a/src/Tracing/HttpClient/AbstractTraceableHttpClient.php +++ b/src/Tracing/HttpClient/AbstractTraceableHttpClient.php @@ -18,6 +18,7 @@ use function Sentry\getBaggage; use function Sentry\getTraceparent; +use function Sentry\getW3CTraceparent; /** * This is an implementation of the {@see HttpClientInterface} that decorates @@ -58,6 +59,7 @@ public function request(string $method, string $url, array $options = []): Respo if (self::shouldAttachTracingHeaders($client, $uri)) { $headers['baggage'] = getBaggage(); $headers['sentry-trace'] = getTraceparent(); + $headers['traceparent'] = getW3CTraceparent(); } $options['headers'] = $headers; @@ -93,6 +95,7 @@ public function request(string $method, string $url, array $options = []): Respo if (self::shouldAttachTracingHeaders($client, $uri)) { $headers['baggage'] = $childSpan->toBaggage(); $headers['sentry-trace'] = $childSpan->toTraceparent(); + $headers['traceparent'] = $childSpan->toW3CTraceparent(); } $options['headers'] = $headers; @@ -138,12 +141,8 @@ private static function shouldAttachTracingHeaders(?ClientInterface $client, Uri // Check if the request destination is allow listed in the trace_propagation_targets option. if ( - null !== $sdkOptions->getTracePropagationTargets() - // Due to BC, we treat an empty array (the default) as all hosts are allow listed - && ( - [] === $sdkOptions->getTracePropagationTargets() - || \in_array($uri->getHost(), $sdkOptions->getTracePropagationTargets()) - ) + null === $sdkOptions->getTracePropagationTargets() + || \in_array($uri->getHost(), $sdkOptions->getTracePropagationTargets()) ) { return true; } diff --git a/src/Transport/TransportFactory.php b/src/Transport/TransportFactory.php deleted file mode 100644 index 6ddd272b..00000000 --- a/src/Transport/TransportFactory.php +++ /dev/null @@ -1,65 +0,0 @@ -decoratedTransportFactory = new DefaultTransportFactory( - $streamFactory, - $requestFactory, - new HttpClientFactory( - $uriFactory, - $responseFactory, - $streamFactory, - $httpClient, - 'sentry.php.symfony', - SentryBundle::SDK_VERSION - ), - $logger - ); - } - - public function create(Options $options): TransportInterface - { - return $this->decoratedTransportFactory->create($options); - } -} diff --git a/src/Twig/SentryExtension.php b/src/Twig/SentryExtension.php index ba705155..2e4f31ed 100644 --- a/src/Twig/SentryExtension.php +++ b/src/Twig/SentryExtension.php @@ -10,6 +10,7 @@ use function Sentry\getBaggage; use function Sentry\getTraceparent; +use function Sentry\getW3CTraceparent; final class SentryExtension extends AbstractExtension { @@ -27,6 +28,7 @@ public function getFunctions(): array { return [ new TwigFunction('sentry_trace_meta', [$this, 'getTraceMeta'], ['is_safe' => ['html']]), + new TwigFunction('sentry_w3c_trace_meta', [$this, 'getW3CTraceMeta'], ['is_safe' => ['html']]), new TwigFunction('sentry_baggage_meta', [$this, 'getBaggageMeta'], ['is_safe' => ['html']]), ]; } @@ -39,6 +41,14 @@ public function getTraceMeta(): string return sprintf('', getTraceparent()); } + /** + * Returns an HTML meta tag named `traceparent`. + */ + public function getW3CTraceMeta(): string + { + return sprintf('', getW3CTraceparent()); + } + /** * Returns an HTML meta tag named `baggage`. */ diff --git a/tests/DependencyInjection/ConfigurationTest.php b/tests/DependencyInjection/ConfigurationTest.php index c5a6bea9..c993f6f2 100644 --- a/tests/DependencyInjection/ConfigurationTest.php +++ b/tests/DependencyInjection/ConfigurationTest.php @@ -23,12 +23,13 @@ public function testProcessConfigurationWithDefaultConfiguration(): void 'register_error_listener' => true, 'register_error_handler' => true, 'logger' => null, - 'transport_factory' => 'Sentry\\Transport\\TransportFactoryInterface', 'options' => [ 'integrations' => [], 'prefixes' => array_merge(['%kernel.project_dir%'], array_filter(explode(\PATH_SEPARATOR, get_include_path() ?: ''))), 'environment' => '%kernel.environment%', 'release' => '%env(default::SENTRY_RELEASE)%', + 'ignore_exceptions' => [], + 'ignore_transactions' => [], 'tags' => [], 'in_app_exclude' => [ '%kernel.cache_dir%', @@ -37,8 +38,6 @@ public function testProcessConfigurationWithDefaultConfiguration(): void ], 'in_app_include' => [], 'class_serializers' => [], - 'ignore_exceptions' => [], - 'ignore_transactions' => [], ], 'messenger' => [ 'enabled' => interface_exists(MessageBusInterface::class), diff --git a/tests/DependencyInjection/Fixtures/php/full.php b/tests/DependencyInjection/Fixtures/php/full.php index 7c69cc19..0f30c967 100644 --- a/tests/DependencyInjection/Fixtures/php/full.php +++ b/tests/DependencyInjection/Fixtures/php/full.php @@ -7,27 +7,32 @@ /** @var ContainerBuilder $container */ $container->loadFromExtension('sentry', [ 'dsn' => 'https://examplePublicKey@o0.ingest.sentry.io/0', - 'transport_factory' => 'App\\Sentry\\Transport\\TransportFactory', 'logger' => 'app.logger', 'options' => [ 'integrations' => ['App\\Sentry\\Integration\\FooIntegration'], 'default_integrations' => false, - 'send_attempts' => 1, 'prefixes' => ['%kernel.project_dir%'], 'sample_rate' => 1, + 'enable_tracing' => true, 'traces_sample_rate' => 1, - 'profiles_sample_rate' => 1, 'traces_sampler' => 'App\\Sentry\\Tracing\\TracesSampler', - 'trace_propagation_targets' => ['website.invalid'], + 'profiles_sample_rate' => 1, 'attach_stacktrace' => true, + 'attach_metric_code_locations' => true, 'context_lines' => 0, - 'enable_compression' => true, 'environment' => 'development', 'logger' => 'php', + 'spotlight' => true, + 'spotlight_url' => 'http://localhost:8969', 'release' => '4.0.x-dev', 'server_name' => 'localhost', + 'ignore_exceptions' => ['Symfony\Component\HttpKernel\Exception\BadRequestHttpException'], + 'ignore_transactions' => ['GET tracing_ignored_transaction'], 'before_send' => 'App\\Sentry\\BeforeSendCallback', 'before_send_transaction' => 'App\\Sentry\\BeforeSendTransactionCallback', + 'before_send_check_in' => 'App\\Sentry\\BeforeSendCheckInCallback', + 'before_send_metrics' => 'App\\Sentry\\BeforeSendMetricsCallback', + 'trace_propagation_targets' => ['website.invalid'], 'tags' => [ 'context' => 'development', ], @@ -38,14 +43,17 @@ 'in_app_include' => ['%kernel.project_dir%'], 'send_default_pii' => true, 'max_value_length' => 255, + 'transport' => 'App\\Sentry\\Transport', + 'http_client' => 'App\\Sentry\\HttpClient', 'http_proxy' => 'proxy.example.com:8080', - 'http_timeout' => 10, + 'http_proxy_authentication' => 'user:password', 'http_connect_timeout' => 15, + 'http_timeout' => 10, + 'http_ssl_verify_peer' => true, + 'http_compression' => true, 'capture_silenced_errors' => true, 'max_request_body_size' => 'none', 'class_serializers' => ['App\\FooClass' => 'App\\Sentry\\Serializer\\FooClassSerializer'], - 'ignore_exceptions' => ['Symfony\Component\HttpKernel\Exception\BadRequestHttpException'], - 'ignore_transactions' => ['GET tracing_ignored_transaction'], ], 'messenger' => [ 'enabled' => true, diff --git a/tests/DependencyInjection/Fixtures/xml/full.xml b/tests/DependencyInjection/Fixtures/xml/full.xml index f9d84f93..88d01372 100644 --- a/tests/DependencyInjection/Fixtures/xml/full.xml +++ b/tests/DependencyInjection/Fixtures/xml/full.xml @@ -8,32 +8,40 @@ diff --git a/tests/DependencyInjection/Fixtures/yml/full.yml b/tests/DependencyInjection/Fixtures/yml/full.yml index d2f13c5e..8da66d50 100644 --- a/tests/DependencyInjection/Fixtures/yml/full.yml +++ b/tests/DependencyInjection/Fixtures/yml/full.yml @@ -1,29 +1,36 @@ sentry: dsn: https://examplePublicKey@o0.ingest.sentry.io/0 - transport_factory: App\Sentry\Transport\TransportFactory logger: app.logger options: integrations: - App\Sentry\Integration\FooIntegration default_integrations: false - send_attempts: 1 prefixes: - '%kernel.project_dir%' sample_rate: 1 + enable_tracing: true traces_sample_rate: 1 - profiles_sample_rate: 1 traces_sampler: App\Sentry\Tracing\TracesSampler - trace_propagation_targets: - - 'website.invalid' + profiles_sample_rate: 1 attach_stacktrace: true + attach_metric_code_locations: true context_lines: 0 - enable_compression: true environment: development logger: php + spotlight: true + spotlight_url: http://localhost:8969 release: 4.0.x-dev server_name: localhost + ignore_exceptions: + - Symfony\Component\HttpKernel\Exception\BadRequestHttpException + ignore_transactions: + - GET tracing_ignored_transaction before_send: App\Sentry\BeforeSendCallback before_send_transaction: App\Sentry\BeforeSendTransactionCallback + before_send_check_in: App\Sentry\BeforeSendCheckInCallback + before_send_metrics: App\Sentry\BeforeSendMetricsCallback + trace_propagation_targets: + - 'website.invalid' tags: context: development error_types: !php/const E_ALL @@ -35,17 +42,18 @@ sentry: - '%kernel.project_dir%' send_default_pii: true max_value_length: 255 + transport: App\Sentry\Transport + http_client: App\Sentry\HttpClient http_proxy: proxy.example.com:8080 - http_timeout: 10 + http_proxy_authentication: user:password http_connect_timeout: 15 + http_timeout: 10 + http_ssl_verify_peer: true + http_compression: true capture_silenced_errors: true max_request_body_size: 'none' class_serializers: App\FooClass: App\Sentry\Serializer\FooClassSerializer - ignore_exceptions: - - Symfony\Component\HttpKernel\Exception\BadRequestHttpException - ignore_transactions: - - GET tracing_ignored_transaction messenger: enabled: true capture_soft_fails: false diff --git a/tests/DependencyInjection/SentryExtensionTest.php b/tests/DependencyInjection/SentryExtensionTest.php index cfb2b0b6..bf9aeff7 100644 --- a/tests/DependencyInjection/SentryExtensionTest.php +++ b/tests/DependencyInjection/SentryExtensionTest.php @@ -9,7 +9,6 @@ use PHPUnit\Framework\TestCase; use Psr\Log\NullLogger; use Sentry\ClientInterface; -use Sentry\Integration\IgnoreErrorsIntegration; use Sentry\Options; use Sentry\SentryBundle\DependencyInjection\SentryExtension; use Sentry\SentryBundle\EventListener\ConsoleListener; @@ -26,11 +25,8 @@ use Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverMiddleware; use Sentry\SentryBundle\Tracing\Twig\TwigTracingExtension; use Sentry\Serializer\RepresentationSerializer; -use Sentry\Serializer\Serializer; -use Sentry\Transport\TransportFactoryInterface; use Symfony\Bundle\TwigBundle\TwigBundle; use Symfony\Component\Console\ConsoleEvents; -use Symfony\Component\Debug\Exception\FatalErrorException; use Symfony\Component\DependencyInjection\Compiler\ResolveParameterPlaceHoldersPass; use Symfony\Component\DependencyInjection\Compiler\ResolveTaggedIteratorArgumentPass; use Symfony\Component\DependencyInjection\Compiler\ValidateEnvPlaceholdersPass; @@ -38,7 +34,6 @@ use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\ErrorHandler\Error\FatalError; use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\HttpClient\TraceableHttpClient; use Symfony\Component\HttpKernel\KernelEvents; @@ -203,25 +198,38 @@ public function testClientIsCreatedFromOptions(): void $container = $this->createContainerFromFixture('full'); $optionsDefinition = $container->getDefinition('sentry.client.options'); $expectedOptions = [ + 'dsn' => 'https://examplePublicKey@o0.ingest.sentry.io/0', 'integrations' => new Reference(IntegrationConfigurator::class), 'default_integrations' => false, - 'send_attempts' => 1, 'prefixes' => [$container->getParameter('kernel.project_dir')], 'sample_rate' => 1, + 'enable_tracing' => true, 'traces_sample_rate' => 1, - 'profiles_sample_rate' => 1, 'traces_sampler' => new Reference('App\\Sentry\\Tracing\\TracesSampler'), - 'trace_propagation_targets' => ['website.invalid'], + 'profiles_sample_rate' => 1, 'attach_stacktrace' => true, + 'attach_metric_code_locations' => true, 'context_lines' => 0, - 'enable_compression' => true, 'environment' => 'development', 'logger' => 'php', + 'spotlight' => true, + 'spotlight_url' => 'http://localhost:8969', 'release' => '4.0.x-dev', 'server_name' => 'localhost', + 'ignore_exceptions' => [ + 'Symfony\Component\HttpKernel\Exception\BadRequestHttpException', + ], + 'ignore_transactions' => [ + 'GET tracing_ignored_transaction', + ], 'before_send' => new Reference('App\\Sentry\\BeforeSendCallback'), 'before_send_transaction' => new Reference('App\\Sentry\\BeforeSendTransactionCallback'), - 'tags' => ['context' => 'development'], + 'before_send_check_in' => new Reference('App\\Sentry\\BeforeSendCheckInCallback'), + 'before_send_metrics' => new Reference('App\\Sentry\\BeforeSendMetricsCallback'), + 'trace_propagation_targets' => ['website.invalid'], + 'tags' => [ + 'context' => 'development', + ], 'error_types' => \E_ALL, 'max_breadcrumbs' => 1, 'before_breadcrumb' => new Reference('App\\Sentry\\BeforeBreadcrumbCallback'), @@ -229,21 +237,19 @@ public function testClientIsCreatedFromOptions(): void 'in_app_include' => [$container->getParameter('kernel.project_dir')], 'send_default_pii' => true, 'max_value_length' => 255, + 'transport' => new Reference('App\\Sentry\\Transport'), + 'http_client' => new Reference('App\\Sentry\\HttpClient'), 'http_proxy' => 'proxy.example.com:8080', + 'http_proxy_authentication' => 'user:password', 'http_timeout' => 10, 'http_connect_timeout' => 15, + 'http_ssl_verify_peer' => true, + 'http_compression' => true, 'capture_silenced_errors' => true, 'max_request_body_size' => 'none', 'class_serializers' => [ 'App\\FooClass' => new Reference('App\\Sentry\\Serializer\\FooClassSerializer'), ], - 'dsn' => 'https://examplePublicKey@o0.ingest.sentry.io/0', - 'ignore_exceptions' => [ - 'Symfony\Component\HttpKernel\Exception\BadRequestHttpException', - ], - 'ignore_transactions' => [ - 'GET tracing_ignored_transaction', - ], ]; $this->assertSame(Options::class, $optionsDefinition->getClass()); @@ -251,14 +257,6 @@ public function testClientIsCreatedFromOptions(): void $integrationConfiguratorDefinition = $container->getDefinition(IntegrationConfigurator::class); $expectedIntegrations = [ - new Definition(IgnoreErrorsIntegration::class, [ - [ - 'ignore_exceptions' => [ - FatalError::class, - FatalErrorException::class, - ], - ], - ]), new Reference('App\\Sentry\\Integration\\FooIntegration'), ]; @@ -274,32 +272,15 @@ public function testClientIsCreatedFromOptions(): void $methodCalls = $factory[0]->getMethodCalls(); - $this->assertCount(6, $methodCalls); + $this->assertCount(4, $methodCalls); $this->assertDefinitionMethodCallAt($methodCalls[0], 'setSdkIdentifier', [SentryBundle::SDK_IDENTIFIER]); $this->assertDefinitionMethodCallAt($methodCalls[1], 'setSdkVersion', [SentryBundle::SDK_VERSION]); - $this->assertDefinitionMethodCallAt($methodCalls[2], 'setTransportFactory', [new Reference('App\\Sentry\\Transport\\TransportFactory')]); - $this->assertDefinitionMethodCallAt($methodCalls[5], 'setLogger', [new Reference('app.logger')]); - - $this->assertSame('setSerializer', $methodCalls[3][0]); - $this->assertInstanceOf(Definition::class, $methodCalls[3][1][0]); - $this->assertSame(Serializer::class, $methodCalls[3][1][0]->getClass()); - $this->assertEquals($methodCalls[3][1][0]->getArgument(0), new Reference('sentry.client.options')); - - $this->assertSame('setRepresentationSerializer', $methodCalls[4][0]); - $this->assertInstanceOf(Definition::class, $methodCalls[4][1][0]); - $this->assertSame(RepresentationSerializer::class, $methodCalls[4][1][0]->getClass()); - $this->assertEquals($methodCalls[4][1][0]->getArgument(0), new Reference('sentry.client.options')); - } + $this->assertDefinitionMethodCallAt($methodCalls[3], 'setLogger', [new Reference('app.logger')]); - public function testLoggerIsPassedToTransportFactory(): void - { - $container = $this->createContainerFromFixture('full'); - - $transportFactoryDefinition = $container->findDefinition(TransportFactoryInterface::class); - $logger = $transportFactoryDefinition->getArgument('$logger'); - - $this->assertInstanceOf(Reference::class, $logger); - $this->assertSame('app.logger', $logger->__toString()); + $this->assertSame('setRepresentationSerializer', $methodCalls[2][0]); + $this->assertInstanceOf(Definition::class, $methodCalls[2][1][0]); + $this->assertSame(RepresentationSerializer::class, $methodCalls[2][1][0]->getClass()); + $this->assertEquals($methodCalls[2][1][0]->getArgument(0), new Reference('sentry.client.options')); } public function testErrorTypesOptionIsParsedFromStringToIntegerValue(): void @@ -310,25 +291,6 @@ public function testErrorTypesOptionIsParsedFromStringToIntegerValue(): void $this->assertSame(\E_ALL & ~(\E_NOTICE | \E_STRICT | \E_DEPRECATED), $optionsDefinition->getArgument(0)['error_types']); } - public function testIgnoreErrorsIntegrationIsNotAddedTwiceIfAlreadyConfigured(): void - { - $container = $this->createContainerFromFixture('ignore_errors_integration_overridden'); - $integrations = $container->getDefinition(IntegrationConfigurator::class)->getArgument(0); - $ignoreErrorsIntegrationsCount = 0; - - foreach ($integrations as $integration) { - if ($integration instanceof Reference && IgnoreErrorsIntegration::class === (string) $integration) { - ++$ignoreErrorsIntegrationsCount; - } - - if ($integration instanceof Definition && IgnoreErrorsIntegration::class === $integration->getClass()) { - ++$ignoreErrorsIntegrationsCount; - } - } - - $this->assertSame(1, $ignoreErrorsIntegrationsCount); - } - /** * @dataProvider dsnOptionIsSetOnClientOptionsDataProvider * @@ -451,7 +413,7 @@ public function testLoggerOptionFallbackToNullLoggerIfNotSet(): void $methodCalls = $factory[0]->getMethodCalls(); - $this->assertDefinitionMethodCallAt($methodCalls[5], 'setLogger', [new Reference(NullLogger::class, ContainerBuilder::IGNORE_ON_INVALID_REFERENCE)]); + $this->assertDefinitionMethodCallAt($methodCalls[3], 'setLogger', [new Reference(NullLogger::class, ContainerBuilder::IGNORE_ON_INVALID_REFERENCE)]); } /** diff --git a/tests/End2End/App/config.yml b/tests/End2End/App/config.yml index 52837104..87aa6cf3 100644 --- a/tests/End2End/App/config.yml +++ b/tests/End2End/App/config.yml @@ -6,8 +6,12 @@ sentry: capture_silenced_errors: false error_types: E_ALL & ~E_USER_DEPRECATED traces_sample_rate: 0 - ignore_exceptions: 'Symfony\Component\HttpKernel\Exception\BadRequestHttpException' + ignore_exceptions: + - 'Symfony\Component\HttpKernel\Exception\BadRequestHttpException' + - 'Symfony\Component\ErrorHandler\Error\FatalError' + - 'Symfony\Component\Debug\Exception\FatalErrorException' ignore_transactions: 'GET tracing_ignored_transaction' + transport: 'Sentry\SentryBundle\Tests\End2End\StubTransport' framework: router: { resource: "%routing_config_dir%/routing.yml" } @@ -22,10 +26,7 @@ services: alias: Sentry\State\HubInterface public: true - Sentry\SentryBundle\Tests\End2End\StubTransportFactory: ~ - - Sentry\Transport\TransportFactoryInterface: - alias: Sentry\SentryBundle\Tests\End2End\StubTransportFactory + Sentry\SentryBundle\Tests\End2End\StubTransport: ~ Sentry\SentryBundle\Tests\End2End\App\Controller\MainController: autowire: true diff --git a/tests/End2End/End2EndTest.php b/tests/End2End/End2EndTest.php index 7eef4ffd..19ddfe06 100644 --- a/tests/End2End/End2EndTest.php +++ b/tests/End2End/End2EndTest.php @@ -207,10 +207,10 @@ public function testCommand(): void } $this->assertEventCount(1); - $this->assertCount(1, StubTransportFactory::$events); + $this->assertCount(1, StubTransport::$events); $this->assertSame( ['Full command' => 'main-command --option1 --option2=foo bar'], - StubTransportFactory::$events[0]->getExtra() + StubTransport::$events[0]->getExtra() ); } @@ -281,7 +281,7 @@ private function assertEventCount(int $expectedCount): void { $events = file_get_contents(self::SENT_EVENTS_LOG); $this->assertNotFalse($events, 'Cannot read sent events log'); - $listOfEvents = array_filter(explode(StubTransportFactory::SEPARATOR, trim($events))); + $listOfEvents = array_filter(explode(StubTransport::SEPARATOR, trim($events))); $this->assertCount($expectedCount, $listOfEvents, 'Wrong number of events sent: ' . \PHP_EOL . $events); } diff --git a/tests/End2End/StubTransport.php b/tests/End2End/StubTransport.php new file mode 100644 index 00000000..3f3b7644 --- /dev/null +++ b/tests/End2End/StubTransport.php @@ -0,0 +1,52 @@ +getMessage()) { + $message = $event->getMessage(); + } elseif ($event->getExceptions()) { + $message = $event->getExceptions()[0]->getValue(); + } elseif ($event->getTransaction()) { + $message = 'TRACING: ' . $event->getTransaction(); + foreach ($event->getSpans() as $i => $span) { + $message .= \PHP_EOL . $i . ') ' . $span->getDescription(); + } + } else { + $message = 'NO MESSAGE NOR EXCEPTIONS'; + } + + file_put_contents( + End2EndTest::SENT_EVENTS_LOG, + $event->getId() . ': ' . $message . \PHP_EOL . self::SEPARATOR . \PHP_EOL, + \FILE_APPEND + ); + + return new Result(ResultStatus::success(), $event); + } + + public function close(?int $timeout = null): Result + { + return new Result(ResultStatus::success()); + } +} diff --git a/tests/End2End/StubTransportFactory.php b/tests/End2End/StubTransportFactory.php deleted file mode 100644 index 061f068b..00000000 --- a/tests/End2End/StubTransportFactory.php +++ /dev/null @@ -1,61 +0,0 @@ -getMessage()) { - $message = $event->getMessage(); - } elseif ($event->getExceptions()) { - $message = $event->getExceptions()[0]->getValue(); - } elseif ($event->getTransaction()) { - $message = 'TRACING: ' . $event->getTransaction(); - foreach ($event->getSpans() as $i => $span) { - $message .= \PHP_EOL . $i . ') ' . $span->getDescription(); - } - } else { - $message = 'NO MESSAGE NOR EXCEPTIONS'; - } - - file_put_contents( - End2EndTest::SENT_EVENTS_LOG, - $event->getId() . ': ' . $message . \PHP_EOL . StubTransportFactory::SEPARATOR . \PHP_EOL, - \FILE_APPEND - ); - - return new FulfilledPromise(new Response(ResponseStatus::success(), $event)); - } - - public function close(?int $timeout = null): PromiseInterface - { - return new FulfilledPromise(true); - } - }; - } -} diff --git a/tests/End2End/TracingEnd2EndTest.php b/tests/End2End/TracingEnd2EndTest.php index b3204d0c..0a764b32 100644 --- a/tests/End2End/TracingEnd2EndTest.php +++ b/tests/End2End/TracingEnd2EndTest.php @@ -87,7 +87,7 @@ private function assertTracingEventCount(int $expectedCount): void { $events = file_get_contents(self::SENT_EVENTS_LOG); $this->assertNotFalse($events, 'Cannot read sent events log'); - $listOfTracingEvents = array_filter(explode(StubTransportFactory::SEPARATOR, trim($events)), static function (string $elem) { + $listOfTracingEvents = array_filter(explode(StubTransport::SEPARATOR, trim($events)), static function (string $elem) { return str_contains('TRACING', $elem); }); diff --git a/tests/EventListener/ConsoleCommandListenerTest.php b/tests/EventListener/ConsoleCommandListenerTest.php deleted file mode 100644 index e217dca4..00000000 --- a/tests/EventListener/ConsoleCommandListenerTest.php +++ /dev/null @@ -1,23 +0,0 @@ -freeze(); + + $transactionContext = new TransactionContext(); + $transactionContext->setTraceId(new TraceId('566e3688a61d4bc888951642d6f14a19')); + $transactionContext->setParentSpanId(new SpanId('566e3688a61d4bc8')); + $transactionContext->setParentSampled(true); + $transactionContext->setName('GET http://www.example.com/'); + $transactionContext->setSource(TransactionSource::url()); + $transactionContext->setOp('http.server'); + $transactionContext->setStartTimestamp(1613493597.010275); + $transactionContext->setData([ + 'net.host.port' => '80', + 'http.request.method' => 'GET', + 'http.url' => 'http://www.example.com/', + 'http.flavor' => '1.1', + 'route' => '', + 'net.host.name' => 'www.example.com', + ]); + $transactionContext->getMetadata()->setDynamicSamplingContext($samplingContext); + + yield 'request.headers.traceparent EXISTS' => [ + new Options(), + Request::create( + 'http://www.example.com', + 'GET', + [], + [], + [], + [ + 'REQUEST_TIME_FLOAT' => 1613493597.010275, + 'HTTP_traceparent' => '00-566e3688a61d4bc888951642d6f14a19-566e3688a61d4bc8-01', + ] + ), + $transactionContext, + ]; + $samplingContext = DynamicSamplingContext::fromHeader('sentry-trace_id=566e3688a61d4bc888951642d6f14a19,sentry-public_key=public,sentry-sample_rate=1'); $samplingContext->freeze(); @@ -432,7 +469,6 @@ public function testHandleResponseRequestEvent(): void )); $this->assertSame(SpanStatus::ok(), $transaction->getStatus()); - $this->assertSame(['http.status_code' => '200'], $transaction->getTags()); } public function testHandleResponseRequestEventDoesNothingIfNoTransactionIsSetOnHub(): void diff --git a/tests/EventListener/TracingSubRequestListenerTest.php b/tests/EventListener/TracingSubRequestListenerTest.php index 614dfc1c..ae54b342 100644 --- a/tests/EventListener/TracingSubRequestListenerTest.php +++ b/tests/EventListener/TracingSubRequestListenerTest.php @@ -224,7 +224,6 @@ public function testHandleResponseRequestEvent(): void )); $this->assertSame(SpanStatus::ok(), $span->getStatus()); - $this->assertSame(['http.status_code' => '200'], $span->getTags()); } public function testHandleResponseRequestEventDoesNothingIfNoTransactionIsSetOnHub(): void diff --git a/tests/Tracing/HttpClient/TraceableHttpClientTest.php b/tests/Tracing/HttpClient/TraceableHttpClientTest.php index af4b6bdc..31147116 100644 --- a/tests/Tracing/HttpClient/TraceableHttpClientTest.php +++ b/tests/Tracing/HttpClient/TraceableHttpClientTest.php @@ -8,7 +8,6 @@ use PHPUnit\Framework\TestCase; use Psr\Log\LoggerAwareInterface; use Psr\Log\NullLogger; -use Sentry\Client; use Sentry\ClientInterface; use Sentry\Options; use Sentry\SentryBundle\Tracing\HttpClient\AbstractTraceableResponse; @@ -23,7 +22,7 @@ use Sentry\Tracing\TraceId; use Sentry\Tracing\Transaction; use Sentry\Tracing\TransactionContext; -use Sentry\Transport\NullTransport; +use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\HttpClient\MockHttpClient; use Symfony\Component\HttpClient\Response\MockResponse; use Symfony\Contracts\HttpClient\HttpClientInterface; @@ -48,7 +47,7 @@ final class TraceableHttpClientTest extends TestCase public static function setUpBeforeClass(): void { - if (!self::isHttpClientPackageInstalled()) { + if (!class_exists(HttpClient::class)) { self::markTestSkipped('This test requires the "symfony/http-client" Composer package to be installed.'); } } @@ -66,8 +65,7 @@ public function testRequest(): void 'dsn' => 'http://public:secret@example.com/sentry/1', ]); $client = $this->createMock(ClientInterface::class); - $client - ->expects($this->once()) + $client->expects($this->once()) ->method('getOptions') ->willReturn($options); @@ -95,6 +93,7 @@ public function testRequest(): void $this->assertSame('GET', $response->getInfo('http_method')); $this->assertSame('https://username:password@www.example.com/test-page?foo=bar#baz', $response->getInfo('url')); $this->assertSame(['sentry-trace: ' . $spans[1]->toTraceparent()], $mockResponse->getRequestOptions()['normalized_headers']['sentry-trace']); + $this->assertSame(['traceparent: ' . $spans[1]->toW3CTraceparent()], $mockResponse->getRequestOptions()['normalized_headers']['traceparent']); $this->assertSame(['baggage: ' . $transaction->toBaggage()], $mockResponse->getRequestOptions()['normalized_headers']['baggage']); $this->assertNotNull($transaction->getSpanRecorder()); @@ -124,7 +123,7 @@ public function testRequestDoesNotContainTracingHeaders(): void { $options = new Options([ 'dsn' => 'http://public:secret@example.com/sentry/1', - 'trace_propagation_targets' => null, + 'trace_propagation_targets' => [], ]); $client = $this->createMock(ClientInterface::class); $client->expects($this->once()) @@ -151,6 +150,7 @@ public function testRequestDoesNotContainTracingHeaders(): void $this->assertSame('PUT', $response->getInfo('http_method')); $this->assertSame('https://www.example.com/test-page', $response->getInfo('url')); $this->assertArrayNotHasKey('sentry-trace', $mockResponse->getRequestOptions()['normalized_headers']); + $this->assertArrayNotHasKey('traceparent', $mockResponse->getRequestOptions()['normalized_headers']); $this->assertArrayNotHasKey('baggage', $mockResponse->getRequestOptions()['normalized_headers']); $this->assertNotNull($transaction->getSpanRecorder()); @@ -169,12 +169,16 @@ public function testRequestDoesNotContainTracingHeaders(): void public function testRequestDoesContainsTracingHeadersWithoutTransaction(): void { - $client = new Client(new Options([ + $options = new Options([ 'dsn' => 'http://public:secret@example.com/sentry/1', 'release' => '1.0.0', 'environment' => 'test', 'trace_propagation_targets' => ['www.example.com'], - ]), new NullTransport()); + ]); + $client = $this->createMock(ClientInterface::class); + $client->expects($this->exactly(5)) + ->method('getOptions') + ->willReturn($options); $propagationContext = PropagationContext::fromDefaults(); $propagationContext->setTraceId(new TraceId('566e3688a61d4bc888951642d6f14a19')); @@ -196,24 +200,28 @@ public function testRequestDoesContainsTracingHeadersWithoutTransaction(): void $this->assertSame('POST', $response->getInfo('http_method')); $this->assertSame('https://www.example.com/test-page', $response->getInfo('url')); $this->assertSame(['sentry-trace: 566e3688a61d4bc888951642d6f14a19-566e3688a61d4bc8'], $mockResponse->getRequestOptions()['normalized_headers']['sentry-trace']); + $this->assertSame(['traceparent: 00-566e3688a61d4bc888951642d6f14a19-566e3688a61d4bc8-00'], $mockResponse->getRequestOptions()['normalized_headers']['traceparent']); $this->assertSame(['baggage: sentry-trace_id=566e3688a61d4bc888951642d6f14a19,sentry-public_key=public,sentry-release=1.0.0,sentry-environment=test'], $mockResponse->getRequestOptions()['normalized_headers']['baggage']); } public function testRequestSetsUnknownErrorAsSpanStatusIfResponseStatusCodeIsUnavailable(): void { + $options = new Options([ + 'dsn' => 'http://public:secret@example.com/sentry/1', + ]); $client = $this->createMock(ClientInterface::class); - $client->expects($this->once()) + $client->expects($this->exactly(2)) ->method('getOptions') - ->willReturn(new Options(['dsn' => 'http://public:secret@example.com/sentry/1'])); + ->willReturn($options); - $transaction = new Transaction(new TransactionContext()); + $transaction = new Transaction(new TransactionContext(), $this->hub); $transaction->initSpanRecorder(); $this->hub->expects($this->once()) ->method('getSpan') ->willReturn($transaction); - $this->hub->expects($this->once()) + $this->hub->expects($this->exactly(2)) ->method('getClient') ->willReturn($client); @@ -353,13 +361,10 @@ public function testWithOptions(): void $this->assertSame('GET', $response->getInfo('http_method')); $this->assertSame('https://www.example.org/test-page', $response->getInfo('url')); } +} - private static function isHttpClientPackageInstalled(): bool +if (interface_exists(HttpClientInterface::class)) { + interface TestableHttpClientInterface extends HttpClientInterface, LoggerAwareInterface, ResetInterface { - return interface_exists(HttpClientInterface::class); } } - -interface TestableHttpClientInterface extends HttpClientInterface, LoggerAwareInterface, ResetInterface -{ -} diff --git a/tests/Tracing/HttpClient/TraceableResponseTest.php b/tests/Tracing/HttpClient/TraceableResponseTest.php index e67616d5..f8851137 100644 --- a/tests/Tracing/HttpClient/TraceableResponseTest.php +++ b/tests/Tracing/HttpClient/TraceableResponseTest.php @@ -12,6 +12,7 @@ use Sentry\Tracing\SpanContext; use Sentry\Tracing\Transaction; use Sentry\Tracing\TransactionContext; +use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\HttpClient\MockHttpClient; use Symfony\Component\HttpClient\Response\MockResponse; use Symfony\Contracts\HttpClient\HttpClientInterface; @@ -28,6 +29,13 @@ final class TraceableResponseTest extends TestCase */ private $hub; + public static function setUpBeforeClass(): void + { + if (!class_exists(HttpClient::class)) { + self::markTestSkipped('This test requires the "symfony/http-client" Composer package to be installed.'); + } + } + protected function setUp(): void { $this->client = $this->createMock(HttpClientInterface::class); diff --git a/tests/Transport/TransportFactoryTest.php b/tests/Transport/TransportFactoryTest.php deleted file mode 100644 index 667590dc..00000000 --- a/tests/Transport/TransportFactoryTest.php +++ /dev/null @@ -1,100 +0,0 @@ -create(new Options(['dsn' => 'http://public@example.com/sentry/1'])); - - $this->assertInstanceOf(HttpTransport::class, $transport); - - try { - $transport->send(Event::createEvent())->wait(); - - $this->fail('Failed asserting that the transport returns a rejected promise on error.'); - } catch (RejectionException $exception) { - $this->assertInstanceOf(Response::class, $exception->getReason()); - } - } - - public function testCreateWithCustomFactories(): void - { - $uriFactory = $this->createMock(UriFactoryInterface::class); - $requestFactory = $this->createMock(RequestFactoryInterface::class); - $responseFactory = $this->createMock(ResponseFactoryInterface::class); - $streamFactory = $this->createMock(StreamFactoryInterface::class); - $httpClient = $this->createMock(HttpAsyncClientInterface::class); - $logger = $this->createMock(LoggerInterface::class); - $transportFactory = new TransportFactory( - $uriFactory, - $requestFactory, - $responseFactory, - $streamFactory, - $httpClient, - $logger - ); - - $requestFactory->expects($this->once()) - ->method('createRequest') - ->willReturnCallback(static function (...$arguments): RequestInterface { - return Psr17FactoryDiscovery::findRequestFactory()->createRequest(...$arguments); - }); - - $streamFactory->expects($this->atLeastOnce()) - ->method('createStream') - ->willReturnCallback(static function (...$arguments): StreamInterface { - return Psr17FactoryDiscovery::findStreamFactory()->createStream(...$arguments); - }); - - $httpClient->expects($this->once()) - ->method('sendAsyncRequest') - ->willReturnCallback(static function (RequestInterface $request): HttpPromiseInterface { - return new RejectedPromise(new NetworkException('foo', $request)); - }); - - $logger->expects($this->once()) - ->method('error') - ->withAnyParameters(); - - $event = Event::createEvent(); - $transport = $transportFactory->create(new Options(['dsn' => 'http://public@example.com/sentry/1', 'send_attempts' => 0])); - - try { - $transport->send($event)->wait(); - - $this->fail('Failed asserting that the transport returns a rejected promise on error.'); - } catch (RejectionException $exception) { - /** @var Response $response */ - $response = $exception->getReason(); - - $this->assertInstanceOf(Response::class, $response); - $this->assertSame(ResponseStatus::failed(), $response->getStatus()); - $this->assertSame($event, $response->getEvent()); - } - } -} diff --git a/tests/Twig/SentryExtensionTest.php b/tests/Twig/SentryExtensionTest.php index f5bf7c75..861ca14c 100644 --- a/tests/Twig/SentryExtensionTest.php +++ b/tests/Twig/SentryExtensionTest.php @@ -5,7 +5,6 @@ namespace Sentry\SentryBundle\Tests\Twig; use PHPUnit\Framework\TestCase; -use Sentry\Client; use Sentry\ClientInterface; use Sentry\Options; use Sentry\SentryBundle\Twig\SentryExtension; @@ -17,7 +16,6 @@ use Sentry\Tracing\TraceId; use Sentry\Tracing\Transaction; use Sentry\Tracing\TransactionContext; -use Sentry\Transport\NullTransport; use Symfony\Bundle\TwigBundle\TwigBundle; use Twig\Environment; use Twig\Loader\ArrayLoader; @@ -68,10 +66,55 @@ public function testTraceMetaFunctionWithActiveSpan(): void $transaction = new Transaction(new TransactionContext()); $transaction->setTraceId(new TraceId('a3c01c41d7b94b90aee23edac90f4319')); $transaction->setSpanId(new SpanId('e69c2aef0ec34f2a')); + $transaction->setSampled(true); $hub->setSpan($transaction); - $this->assertSame('', $environment->render('foo.twig')); + $this->assertSame('', $environment->render('foo.twig')); + } + + public function testW3CTraceMetaFunctionWithNoActiveSpan(): void + { + $environment = new Environment(new ArrayLoader(['foo.twig' => '{{ sentry_w3c_trace_meta() }}'])); + $environment->addExtension(new SentryExtension()); + + $propagationContext = PropagationContext::fromDefaults(); + $propagationContext->setTraceId(new TraceId('566e3688a61d4bc888951642d6f14a19')); + $propagationContext->setSpanId(new SpanId('566e3688a61d4bc8')); + + $hub = new Hub(null, new Scope($propagationContext)); + + SentrySdk::setCurrentHub($hub); + + $this->assertSame('', $environment->render('foo.twig')); + } + + public function testW3CTraceMetaFunctionWithActiveSpan(): void + { + $environment = new Environment(new ArrayLoader(['foo.twig' => '{{ sentry_w3c_trace_meta() }}'])); + $environment->addExtension(new SentryExtension()); + + $client = $this->createMock(ClientInterface::class); + $client->expects($this->atLeastOnce()) + ->method('getOptions') + ->willReturn(new Options([ + 'traces_sample_rate' => 1.0, + 'release' => '1.0.0', + 'environment' => 'development', + ])); + + $hub = new Hub($client); + + SentrySdk::setCurrentHub($hub); + + $transaction = new Transaction(new TransactionContext()); + $transaction->setTraceId(new TraceId('a3c01c41d7b94b90aee23edac90f4319')); + $transaction->setSpanId(new SpanId('e69c2aef0ec34f2a')); + $transaction->setSampled(true); + + $hub->setSpan($transaction); + + $this->assertSame('', $environment->render('foo.twig')); } public function testBaggageMetaFunctionWithNoActiveSpan(): void @@ -103,11 +146,14 @@ public function testBaggageMetaFunctionWithActiveSpan(): void $environment = new Environment(new ArrayLoader(['foo.twig' => '{{ sentry_baggage_meta() }}'])); $environment->addExtension(new SentryExtension()); - $client = new Client(new Options([ - 'traces_sample_rate' => 1.0, - 'release' => '1.0.0', - 'environment' => 'development', - ]), new NullTransport()); + $client = $this->createMock(ClientInterface::class); + $client->expects($this->atLeastOnce()) + ->method('getOptions') + ->willReturn(new Options([ + 'traces_sample_rate' => 1.0, + 'release' => '1.0.0', + 'environment' => 'development', + ])); $hub = new Hub($client); From 0fd80a9c8ec8aea59a67fb5f208b3f65a045d9ce Mon Sep 17 00:00:00 2001 From: Michi Hoffmann Date: Tue, 9 Apr 2024 07:13:40 +0200 Subject: [PATCH 02/57] Prepare 5.0.0 (#829) --- CHANGELOG.md | 112 ++++++++++++++++++++++++++++++++++++++++++++++--- UPGRADE-5.0.md | 54 ++++++++++++++++++++++++ 2 files changed, 161 insertions(+), 5 deletions(-) create mode 100644 UPGRADE-5.0.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 6767db3e..27d2b5e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,115 @@ -# Changelog - ## 5.0.0 -The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v5.0.0. +The Sentry SDK team is thrilled to announce the immediate availability of Sentry Symfony SDK v5.0.0. + +### Breaking Change + +Please refer to the [UPGRADE-5.0.md](https://github.com/getsentry/sentry-symfony/blob/master/UPGRADE-5.0.md) guide for a complete list of breaking changes. + +This version adds support for the underlying [Sentry PHP SDK v4.0](https://github.com/getsentry/sentry-php). +Please refer to the PHP SDK [sentry-php/UPGRADE-4.0.md](https://github.com/getsentry/sentry-php/blob/master/UPGRADE-4.0.md) guide for a complete list of breaking changes. + +- This version exclusively uses the [envelope endpoint](https://develop.sentry.dev/sdk/envelopes/) to send event data to Sentry. + + If you are using [sentry.io](https://sentry.io), no action is needed. + If you are using an on-premise/self-hosted installation of Sentry, the minimum requirement is now version `>= v20.6.0`. + +- You need to have `ext-curl` installed to use the SDK. -### Breaking Changes +- The `IgnoreErrorsIntegration` integration was removed. Use the `ignore_exceptions` option instead. + Previously, both `Symfony\Component\ErrorHandler\Error\FatalError` and `Symfony\Component\Debug\Exception\FatalErrorException` were ignored by default. + To continue ignoring these exceptions, make the following changes to the config file: + + ```yaml + // config/packages/sentry.yaml + + sentry: + options: + ignore_exceptions: + - 'Symfony\Component\ErrorHandler\Error\FatalError' + - 'Symfony\Component\Debug\Exception\FatalErrorException' + ``` + + This option performs an [`is_a`](https://www.php.net/manual/en/function.is-a.php) check now, so you can also ignore more generic exceptions. ### Features -### Bug Fixes +- Add support for Sentry Developer Metrics [(#1619)](https://github.com/getsentry/sentry-php/pull/1619) + + ```php + use function Sentry\metrics; + + // Add 4 to a counter named hits + metrics()->increment(key: 'hits', value: 4); + + // Add 25 to a distribution named response_time with unit milliseconds + metrics()->distribution(key: 'response_time', value: 25, unit: MetricsUnit::millisecond()); + + // Add 2 to gauge named parallel_requests, tagged with type: "a" + metrics()->gauge(key: 'parallel_requests', value: 2, tags: ['type': 'a']); + + // Add a user's email to a set named users.sessions, tagged with role: "admin" + metrics()->set('users.sessions', 'jane.doe@example.com', null, ['role' => User::admin()]); + ``` + + Metrics are automatically sent to Sentry at the end of a request, hooking into Symfony's `kernel.terminate` event. + +- Add new fluent APIs [(#1601)](https://github.com/getsentry/sentry-php/pull/1601) + + ```php + // Before + $transactionContext = new TransactionContext(); + $transactionContext->setName('GET /example'); + $transactionContext->setOp('http.server'); + + // After + $transactionContext = (new TransactionContext()) + ->setName('GET /example'); + ->setOp('http.server'); + ``` + +- Simplify the breadcrumb API [(#1603)](https://github.com/getsentry/sentry-php/pull/1603) + + ```php + // Before + \Sentry\addBreadcrumb( + new \Sentry\Breadcrumb( + \Sentry\Breadcrumb::LEVEL_INFO, + \Sentry\Breadcrumb::TYPE_DEFAULT, + 'auth', // category + 'User authenticated', // message (optional) + ['user_id' => $userId] // data (optional) + ) + ); + + // After + \Sentry\addBreadcrumb( + category: 'auth', + message: 'User authenticated', // optional + metadata: ['user_id' => $userId], // optional + level: Breadcrumb::LEVEL_INFO, // set by default + type: Breadcrumb::TYPE_DEFAULT, // set by default + ); + ``` + +- New default cURL HTTP client [(#1589)](https://github.com/getsentry/sentry-php/pull/1589) + + The SDK now ships with its own HTTP client based on cURL. A few new options were added. + + ```yaml + // config/packages/sentry.yaml + + sentry: + options: + - http_proxy_authentication: 'username:password' // user name and password to use for proxy authentication + - http_ssl_verify_peer: false // default true, verify the peer's SSL certificate + - http_compression: false // default true, http request body compression + ``` + + To use a different client, you may use the `http_client` option. + To use a different transport, you may use the `transport` option. A custom transport must implement the `TransportInterface`. + If you use the `transport` option, the `http_client` option has no effect. ### Misc + +- The abandoned package `php-http/message-factory` was removed. diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md new file mode 100644 index 00000000..5737c2cc --- /dev/null +++ b/UPGRADE-5.0.md @@ -0,0 +1,54 @@ +# Upgrade 4.x to 5.0 + +This version adds support for the underlying [Sentry PHP SDK v4.0](https://github.com/getsentry/sentry-php). +Please refer to the PHP SDK [sentry-php/UPGRADE-4.0.md](https://github.com/getsentry/sentry-php/blob/master/UPGRADE-4.0.md) guide for a complete list of breaking changes. + +- This version exclusively uses the [envelope endpoint](https://develop.sentry.dev/sdk/envelopes/) to send event data to Sentry. + + If you are using [sentry.io](https://sentry.io), no action is needed. + If you are using an on-premise/self-hosted installation of Sentry, the minimum requirement is now version `>= v20.6.0`. + +- You need to have `ext-curl` installed to use the SDK. + +- The `IgnoreErrorsIntegration` integration was removed. Use the `ignore_exceptions` option instead. + Previously, both `Symfony\Component\ErrorHandler\Error\FatalError` and `Symfony\Component\Debug\Exception\FatalErrorException` were ignored by default. + To continue ignoring these exceptions, make the following changes to your `config/packages/sentry.yaml` file: + + ```yaml + // config/packages/sentry.yaml + + sentry: + options: + ignore_exceptions: + - 'Symfony\Component\ErrorHandler\Error\FatalError' + - 'Symfony\Component\Debug\Exception\FatalErrorException' + ``` + + This option performs an [`is_a`](https://www.php.net/manual/en/function.is-a.php) check now, so you can also ignore more generic exceptions. + +- Removed support for `guzzlehttp/psr7: ^1.8.4`. + +- The `RequestFetcher` now relies on `guzzlehttp/psr7: ^2.1.1`. + +- Continue traces from the W3C `traceparent` request header. +- Inject the W3C `traceparent` header on outgoing HTTP client calls. +- Added `Sentry\SentryBundle\Twig\SentryExtension::getW3CTraceMeta()`. + +- The new default value for the `sentry.options.trace_propagation_targets` option is now `null`. To not attach any headers to outgoing requests, set this option to `[]`. + +- Added the `sentry.options.enable_tracing` option. +- Added the `sentry.options.attach_metric_code_locations` option. +- Added the `sentry.options.spotlight` option. +- Added the `sentry.options.spotlight_url` option. +- Added the `sentry.options.transport` option. +- Added the `sentry.options.http_client` option. +- Added the `sentry.options.http_proxy_authentication` option. +- Added the `sentry.options.http_ssl_verify_peer` option. +- Added the `sentry.options.http_compression` option. + +- Removed the `sentry.transport_factory` option. Use `sentry.options.transport` to use a custom transport. +- Removed the `sentry.options.send_attempts` option. You may use a custom transport if you rely on this behaviour. +- Removed the `sentry.options.enable_compression` option. Use `sentry.options.http_compression` instead. + +- Removed `Sentry\SentryBundle\Transport\TransportFactory`. +- Removed `Sentry\State\HubInterface\Sentry\State\HubInterface`. From 0fdcda670e3a2674dfea98253800d213b9cd82ed Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Tue, 9 Apr 2024 05:14:27 +0000 Subject: [PATCH 03/57] release: 5.0.0 --- src/SentryBundle.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SentryBundle.php b/src/SentryBundle.php index 49264b62..693184e2 100644 --- a/src/SentryBundle.php +++ b/src/SentryBundle.php @@ -16,7 +16,7 @@ final class SentryBundle extends Bundle { public const SDK_IDENTIFIER = 'sentry.php.symfony'; - public const SDK_VERSION = '4.14.0'; + public const SDK_VERSION = '5.0.0'; public function build(ContainerBuilder $container): void { From 5d6aa2615383ae99fa96f090ed7040035801fdc1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 06:50:37 +0000 Subject: [PATCH 04/57] Bump codecov/codecov-action from 4.1.1 to 4.2.0 (#828) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alessandro Lai --- .github/workflows/tests.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index b9ff0431..6b90a205 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -96,7 +96,7 @@ jobs: run: vendor/bin/phpunit --coverage-clover=build/coverage-report.xml - name: Upload code coverage - uses: codecov/codecov-action@c16abc29c95fcf9174b58eb7e1abf4c866893bc8 # v4.1.1 + uses: codecov/codecov-action@7afa10ed9b269c561c2336fd862446844e0cbf71 # v4.2.0 with: file: build/coverage-report.xml token: ${{ secrets.CODECOV_TOKEN }} @@ -148,7 +148,7 @@ jobs: run: vendor/bin/phpunit --coverage-clover=build/coverage-report.xml - name: Upload code coverage - uses: codecov/codecov-action@c16abc29c95fcf9174b58eb7e1abf4c866893bc8 # v4.1.1 + uses: codecov/codecov-action@7afa10ed9b269c561c2336fd862446844e0cbf71 # v4.2.0 with: file: build/coverage-report.xml token: ${{ secrets.CODECOV_TOKEN }} From 07ee30d4ac5930ec10b7623ee9adc6b660c947dc Mon Sep 17 00:00:00 2001 From: Michi Hoffmann Date: Tue, 9 Apr 2024 09:13:25 +0200 Subject: [PATCH 05/57] Update README.md (#830) --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3190cf64..38a44d8c 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,8 @@ _Bad software is everywhere, and we're tired of it. Sentry is on a mission to he [![Total Downloads](https://poser.pugx.org/sentry/sentry-symfony/downloads)](https://packagist.org/packages/sentry/sentry-symfony) [![Monthly Downloads](https://poser.pugx.org/sentry/sentry-symfony/d/monthly)](https://packagist.org/packages/sentry/sentry-symfony) -![CI](https://github.com/getsentry/sentry-symfony/workflows/CI/badge.svg) [![Coverage Status][Master Code Coverage Image]][Master Code Coverage] +[![CI](https://github.com/getsentry/sentry-symfony/actions/workflows/tests.yaml/badge.svg)](https://github.com/getsentry/sentry-symfony/actions/workflows/tests.yaml) +[![Coverage Status][Master Code Coverage Image]][Master Code Coverage] [![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/cWnMQeA) This is the official Symfony SDK for [Sentry](https://getsentry.com/). From 1e9eb0e6d4ff03c78d214e08cbff0b3f309dd3ab Mon Sep 17 00:00:00 2001 From: Samuele Lilli Date: Wed, 10 Apr 2024 15:17:06 +0200 Subject: [PATCH 06/57] Update README.md (#832) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 38a44d8c..3def7600 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ SENTRY_DSN="https://public@sentry.example.com/1" ###< sentry/sentry-symfony ### ``` -### Usgae +### Usage ```php use function Sentry\captureException; From ef7b7cbf0ec8b137d6a6673540b3e29f515be002 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 08:58:13 +0200 Subject: [PATCH 07/57] Bump shivammathur/setup-php from 2.30.2 to 2.30.3 (#837) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/static-analysis.yaml | 6 +++--- .github/workflows/tests.yaml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/static-analysis.yaml b/.github/workflows/static-analysis.yaml index 0b44c29d..61a04779 100644 --- a/.github/workflows/static-analysis.yaml +++ b/.github/workflows/static-analysis.yaml @@ -20,7 +20,7 @@ jobs: uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Setup PHP - uses: shivammathur/setup-php@8872c784b04a1420e81191df5d64fbd59d3d3033 # v2.30.2 + uses: shivammathur/setup-php@efffd0e4f2504f936fcfe3b69293d31ce0e2fd7a # v2.30.3 with: php-version: '8.2' @@ -40,7 +40,7 @@ jobs: uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Setup PHP - uses: shivammathur/setup-php@8872c784b04a1420e81191df5d64fbd59d3d3033 # v2.30.2 + uses: shivammathur/setup-php@efffd0e4f2504f936fcfe3b69293d31ce0e2fd7a # v2.30.3 with: php-version: '8.3' @@ -60,7 +60,7 @@ jobs: uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Setup PHP - uses: shivammathur/setup-php@8872c784b04a1420e81191df5d64fbd59d3d3033 # v2.30.2 + uses: shivammathur/setup-php@efffd0e4f2504f936fcfe3b69293d31ce0e2fd7a # v2.30.3 with: php-version: '8.3' diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 6b90a205..d91bae2a 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -73,7 +73,7 @@ jobs: fetch-depth: 2 - name: Setup PHP - uses: shivammathur/setup-php@8872c784b04a1420e81191df5d64fbd59d3d3033 # v2.30.2 + uses: shivammathur/setup-php@efffd0e4f2504f936fcfe3b69293d31ce0e2fd7a # v2.30.3 with: php-version: ${{ matrix.php }} coverage: pcov @@ -126,7 +126,7 @@ jobs: uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: Setup PHP - uses: shivammathur/setup-php@8872c784b04a1420e81191df5d64fbd59d3d3033 # v2.30.2 + uses: shivammathur/setup-php@efffd0e4f2504f936fcfe3b69293d31ce0e2fd7a # v2.30.3 with: php-version: ${{ matrix.php }} coverage: pcov From 8a6541bb55ecb40d3a8ecf8d0ea9e8bbf0f14d77 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 06:59:38 +0000 Subject: [PATCH 08/57] Bump actions/checkout from 4.1.2 to 4.1.3 (#836) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alessandro Lai --- .github/workflows/publish-release.yaml | 2 +- .github/workflows/static-analysis.yaml | 6 +++--- .github/workflows/tests.yaml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-release.yaml b/.github/workflows/publish-release.yaml index 9f380b6c..51197303 100644 --- a/.github/workflows/publish-release.yaml +++ b/.github/workflows/publish-release.yaml @@ -19,7 +19,7 @@ jobs: name: Release version steps: - name: Checkout - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 with: token: ${{ secrets.GH_RELEASE_PAT }} fetch-depth: 0 diff --git a/.github/workflows/static-analysis.yaml b/.github/workflows/static-analysis.yaml index 61a04779..8fcd3128 100644 --- a/.github/workflows/static-analysis.yaml +++ b/.github/workflows/static-analysis.yaml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: Setup PHP uses: shivammathur/setup-php@efffd0e4f2504f936fcfe3b69293d31ce0e2fd7a # v2.30.3 @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: Setup PHP uses: shivammathur/setup-php@efffd0e4f2504f936fcfe3b69293d31ce0e2fd7a # v2.30.3 @@ -57,7 +57,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: Setup PHP uses: shivammathur/setup-php@efffd0e4f2504f936fcfe3b69293d31ce0e2fd7a # v2.30.3 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index d91bae2a..077a9463 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -68,7 +68,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 with: fetch-depth: 2 @@ -123,7 +123,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: Setup PHP uses: shivammathur/setup-php@efffd0e4f2504f936fcfe3b69293d31ce0e2fd7a # v2.30.3 From 36b3885a07529ba0786a04b575e2ab04ac0e0542 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Tue, 4 Jun 2024 12:59:57 +0200 Subject: [PATCH 09/57] Pin PHPStan (#849) --- .github/dependabot.yml | 10 ++++++++++ composer.json | 6 +++--- phpstan-baseline.neon | 5 +++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b88a67a7..bf79cc19 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,3 +4,13 @@ updates: directory: "/" schedule: interval: weekly + - package-ecosystem: "composer" + directory: "/" + allow: + - dependency-name: "*phpstan*" + schedule: + interval: weekly + groups: + composer: + patterns: + - "*phpstan*" diff --git a/composer.json b/composer.json index 7809d603..a2853e65 100644 --- a/composer.json +++ b/composer.json @@ -33,9 +33,9 @@ "friendsofphp/php-cs-fixer": "^2.19||^3.40", "masterminds/html5": "^2.8", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.3", - "phpstan/phpstan-phpunit": "^1.0", - "phpstan/phpstan-symfony": "^1.0", + "phpstan/phpstan": "1.11.3", + "phpstan/phpstan-phpunit": "1.4.0", + "phpstan/phpstan-symfony": "1.4.3", "phpunit/phpunit": "^8.5.14||^9.3.9", "symfony/browser-kit": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/cache": "^4.4.20||^5.0.11||^6.0||^7.0", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index a3147cca..4c723f1e 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -155,6 +155,11 @@ parameters: count: 2 path: src/DependencyInjection/SentryExtension.php + - + message: "#^Parameter \\#2 \\$callback of function preg_replace_callback expects callable\\(array\\\\)\\: string, Closure\\(array\\)\\: mixed given\\.$#" + count: 1 + path: src/ErrorTypesParser.php + - message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpKernel\\\\Event\\\\KernelEvent\\:\\:isMasterRequest\\(\\)\\.$#" count: 1 From 922e4492c37b41f0473ee8f8599e46403f161823 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 13:54:52 +0200 Subject: [PATCH 10/57] Bump shivammathur/setup-php from 2.30.3 to 2.30.5 (#848) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/static-analysis.yaml | 6 +++--- .github/workflows/tests.yaml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/static-analysis.yaml b/.github/workflows/static-analysis.yaml index 8fcd3128..e745ed13 100644 --- a/.github/workflows/static-analysis.yaml +++ b/.github/workflows/static-analysis.yaml @@ -20,7 +20,7 @@ jobs: uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: Setup PHP - uses: shivammathur/setup-php@efffd0e4f2504f936fcfe3b69293d31ce0e2fd7a # v2.30.3 + uses: shivammathur/setup-php@fc14643b0a99ee9db10a3c025a33d76544fa3761 # v2.30.5 with: php-version: '8.2' @@ -40,7 +40,7 @@ jobs: uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: Setup PHP - uses: shivammathur/setup-php@efffd0e4f2504f936fcfe3b69293d31ce0e2fd7a # v2.30.3 + uses: shivammathur/setup-php@fc14643b0a99ee9db10a3c025a33d76544fa3761 # v2.30.5 with: php-version: '8.3' @@ -60,7 +60,7 @@ jobs: uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: Setup PHP - uses: shivammathur/setup-php@efffd0e4f2504f936fcfe3b69293d31ce0e2fd7a # v2.30.3 + uses: shivammathur/setup-php@fc14643b0a99ee9db10a3c025a33d76544fa3761 # v2.30.5 with: php-version: '8.3' diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 077a9463..bcdbbe93 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -73,7 +73,7 @@ jobs: fetch-depth: 2 - name: Setup PHP - uses: shivammathur/setup-php@efffd0e4f2504f936fcfe3b69293d31ce0e2fd7a # v2.30.3 + uses: shivammathur/setup-php@fc14643b0a99ee9db10a3c025a33d76544fa3761 # v2.30.5 with: php-version: ${{ matrix.php }} coverage: pcov @@ -126,7 +126,7 @@ jobs: uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 - name: Setup PHP - uses: shivammathur/setup-php@efffd0e4f2504f936fcfe3b69293d31ce0e2fd7a # v2.30.3 + uses: shivammathur/setup-php@fc14643b0a99ee9db10a3c025a33d76544fa3761 # v2.30.5 with: php-version: ${{ matrix.php }} coverage: pcov From 875cae6388c44bf80b7331ebabf9ebaa195701fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 13:56:44 +0200 Subject: [PATCH 11/57] Bump actions/checkout from 4.1.3 to 4.1.6 (#846) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish-release.yaml | 2 +- .github/workflows/static-analysis.yaml | 6 +++--- .github/workflows/tests.yaml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-release.yaml b/.github/workflows/publish-release.yaml index 51197303..d378f49d 100644 --- a/.github/workflows/publish-release.yaml +++ b/.github/workflows/publish-release.yaml @@ -19,7 +19,7 @@ jobs: name: Release version steps: - name: Checkout - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 with: token: ${{ secrets.GH_RELEASE_PAT }} fetch-depth: 0 diff --git a/.github/workflows/static-analysis.yaml b/.github/workflows/static-analysis.yaml index e745ed13..eeb88d15 100644 --- a/.github/workflows/static-analysis.yaml +++ b/.github/workflows/static-analysis.yaml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - name: Setup PHP uses: shivammathur/setup-php@fc14643b0a99ee9db10a3c025a33d76544fa3761 # v2.30.5 @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - name: Setup PHP uses: shivammathur/setup-php@fc14643b0a99ee9db10a3c025a33d76544fa3761 # v2.30.5 @@ -57,7 +57,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - name: Setup PHP uses: shivammathur/setup-php@fc14643b0a99ee9db10a3c025a33d76544fa3761 # v2.30.5 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index bcdbbe93..56532d5f 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -68,7 +68,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 with: fetch-depth: 2 @@ -123,7 +123,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - name: Setup PHP uses: shivammathur/setup-php@fc14643b0a99ee9db10a3c025a33d76544fa3761 # v2.30.5 From 03cf7524736ece450f2827e663b2c422bab0b93c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 13:56:52 +0200 Subject: [PATCH 12/57] Bump codecov/codecov-action from 4.2.0 to 4.4.1 (#845) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/tests.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 56532d5f..4449c344 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -96,7 +96,7 @@ jobs: run: vendor/bin/phpunit --coverage-clover=build/coverage-report.xml - name: Upload code coverage - uses: codecov/codecov-action@7afa10ed9b269c561c2336fd862446844e0cbf71 # v4.2.0 + uses: codecov/codecov-action@125fc84a9a348dbcf27191600683ec096ec9021c # v4.4.1 with: file: build/coverage-report.xml token: ${{ secrets.CODECOV_TOKEN }} @@ -148,7 +148,7 @@ jobs: run: vendor/bin/phpunit --coverage-clover=build/coverage-report.xml - name: Upload code coverage - uses: codecov/codecov-action@7afa10ed9b269c561c2336fd862446844e0cbf71 # v4.2.0 + uses: codecov/codecov-action@125fc84a9a348dbcf27191600683ec096ec9021c # v4.4.1 with: file: build/coverage-report.xml token: ${{ secrets.CODECOV_TOKEN }} From 7a05d39c51da5eff2a88ee42e6bae9cf21498118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81ngel=20Guzm=C3=A1n=20Maeso?= Date: Tue, 4 Jun 2024 18:56:56 +0200 Subject: [PATCH 13/57] feat: avoid warnings with Psalm 6 (#842) --- psalm.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/psalm.xml b/psalm.xml index bb410780..71321eb0 100644 --- a/psalm.xml +++ b/psalm.xml @@ -3,6 +3,8 @@ errorLevel="4" memoizeMethodCallResults="true" errorBaseline="psalm-baseline.xml" + findUnusedBaselineEntry="false" + findUnusedCode="false" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" From 0c1148552fb3f781f17057eab39003e70b74c33f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81ngel=20Guzm=C3=A1n=20Maeso?= Date: Tue, 4 Jun 2024 19:53:56 +0200 Subject: [PATCH 14/57] fix(tests): deprecate warning in Symfony 5.4 for setAuthenticated (#847) Co-authored-by: Michi Hoffmann Co-authored-by: Alex Bouma --- phpstan-baseline.neon | 15 -- phpstan.neon | 1 + phpunit.xml | 12 +- src/ErrorTypesParser.php | 16 +- tests/End2End/App/Kernel.php | 7 + tests/End2End/App/deprecations_for_54.yml | 3 + tests/ErrorTypesParserTest.php | 3 + tests/EventListener/LoginListenerTest.php | 223 +++++++++++++++++----- 8 files changed, 205 insertions(+), 75 deletions(-) create mode 100644 tests/End2End/App/deprecations_for_54.yml diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 4c723f1e..be7174a9 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -155,11 +155,6 @@ parameters: count: 2 path: src/DependencyInjection/SentryExtension.php - - - message: "#^Parameter \\#2 \\$callback of function preg_replace_callback expects callable\\(array\\\\)\\: string, Closure\\(array\\)\\: mixed given\\.$#" - count: 1 - path: src/ErrorTypesParser.php - - message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpKernel\\\\Event\\\\KernelEvent\\:\\:isMasterRequest\\(\\)\\.$#" count: 1 @@ -300,11 +295,6 @@ parameters: count: 1 path: tests/EventListener/LoginListenerTest.php - - - message: "#^Parameter \\#1 \\$user of method Symfony\\\\Component\\\\Security\\\\Core\\\\Authentication\\\\Token\\\\AbstractToken\\:\\:setUser\\(\\) expects Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface, string\\|Stringable\\|Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserInterface given\\.$#" - count: 1 - path: tests/EventListener/LoginListenerTest.php - - message: "#^Parameter \\#2 \\$firewallName of class Symfony\\\\Component\\\\Security\\\\Core\\\\Authentication\\\\Token\\\\SwitchUserToken constructor expects string, null given\\.$#" count: 1 @@ -320,11 +310,6 @@ parameters: count: 1 path: tests/EventListener/LoginListenerTest.php - - - message: "#^Parameter \\#5 \\$originatedFromUri of class Symfony\\\\Component\\\\Security\\\\Core\\\\Authentication\\\\Token\\\\SwitchUserToken constructor expects string\\|null, Sentry\\\\SentryBundle\\\\Tests\\\\EventListener\\\\AuthenticatedTokenStub given\\.$#" - count: 1 - path: tests/EventListener/LoginListenerTest.php - - message: "#^Access to undefined constant Symfony\\\\Component\\\\HttpKernel\\\\HttpKernelInterface\\:\\:MASTER_REQUEST\\.$#" count: 6 diff --git a/phpstan.neon b/phpstan.neon index d5a9c0a4..3608367b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,6 +2,7 @@ includes: - phpstan-baseline.neon parameters: + reportUnmatchedIgnoredErrors: true level: 9 paths: - src diff --git a/phpunit.xml b/phpunit.xml index 72fe2378..e4dadb92 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -20,17 +20,11 @@ src + + src/aliases.php + - - - src - - src/aliases.php - - - - diff --git a/src/ErrorTypesParser.php b/src/ErrorTypesParser.php index aa31d486..ce0d7b90 100644 --- a/src/ErrorTypesParser.php +++ b/src/ErrorTypesParser.php @@ -54,7 +54,21 @@ private static function convertErrorConstants(string $value): string { $output = preg_replace_callback('/(E_[A-Z_]+)/', static function (array $matches) { if (\defined($matches[1])) { - return \constant($matches[1]); + $constant = \constant($matches[1]); + + if (\is_string($constant)) { + return $constant; + } elseif (\is_int($constant)) { + return (string) $constant; + } elseif (\is_array($constant)) { + return implode(' | ', array_map(static function ($value) { + return \is_string($value) ? $value : (string) $value; + }, $constant)); + } elseif (\is_object($constant)) { + return \get_class($constant); + } else { // Non-scalar values + return ''; + } } return $matches[0]; diff --git a/tests/End2End/App/Kernel.php b/tests/End2End/App/Kernel.php index 3f323d7e..c3467c61 100644 --- a/tests/End2End/App/Kernel.php +++ b/tests/End2End/App/Kernel.php @@ -44,6 +44,13 @@ public function registerContainerConfiguration(LoaderInterface $loader): void $loader->load(__DIR__ . '/deprecations_for_5.yml'); } + if (self::VERSION_ID >= 50400 && self::VERSION_ID <= 60000) { + // Check if class for Messenger is present (component symfony/messenger is not mandatory) + if (interface_exists(MessageBusInterface::class)) { + $loader->load(__DIR__ . '/deprecations_for_54.yml'); + } + } + if (self::VERSION_ID >= 60000) { $loader->load(__DIR__ . '/deprecations_for_6.yml'); } diff --git a/tests/End2End/App/deprecations_for_54.yml b/tests/End2End/App/deprecations_for_54.yml new file mode 100644 index 00000000..abd0417d --- /dev/null +++ b/tests/End2End/App/deprecations_for_54.yml @@ -0,0 +1,3 @@ +framework: + messenger: + reset_on_message: true diff --git a/tests/ErrorTypesParserTest.php b/tests/ErrorTypesParserTest.php index e30d6c78..9e3cd532 100644 --- a/tests/ErrorTypesParserTest.php +++ b/tests/ErrorTypesParserTest.php @@ -71,5 +71,8 @@ public function parseThrowsExceptionIfArgumentContainsInvalidCharactersDataProvi yield ['(']; yield [')']; yield ['()']; + // Non scalar values (probably misstypes, but still valid PHP code) + yield ['[8, 8192]']; + yield [\stdClass::class]; } } diff --git a/tests/EventListener/LoginListenerTest.php b/tests/EventListener/LoginListenerTest.php index 8092cc15..cfaf50aa 100644 --- a/tests/EventListener/LoginListenerTest.php +++ b/tests/EventListener/LoginListenerTest.php @@ -183,17 +183,33 @@ public function testHandleAuthenticationSuccessEvent(TokenInterface $token, ?Use public function authenticationTokenDataProvider(): \Generator { - yield 'If the username is already set on the User context, then it is not overridden' => [ - new AuthenticatedTokenStub(new UserWithIdentifierStub()), - new UserDataBag('bar_user'), - new UserDataBag('bar_user'), - ]; + if (version_compare(Kernel::VERSION, '5.4', '<')) { + yield 'If the username is already set on the User context, then it is not overridden' => [ + new LegacyAuthenticatedTokenStub(new UserWithIdentifierStub()), + new UserDataBag('bar_user'), + new UserDataBag('bar_user'), + ]; + } else { + yield 'If the username is already set on the User context, then it is not overridden' => [ + new AuthenticatedTokenStub(new UserWithIdentifierStub()), + new UserDataBag('bar_user'), + new UserDataBag('bar_user'), + ]; + } - yield 'If the username is not set on the User context, then it is retrieved from the token' => [ - new AuthenticatedTokenStub(new UserWithIdentifierStub()), - null, - new UserDataBag('foo_user'), - ]; + if (version_compare(Kernel::VERSION, '5.4', '<')) { + yield 'If the username is not set on the User context, then it is retrieved from the token' => [ + new LegacyAuthenticatedTokenStub(new UserWithIdentifierStub()), + null, + new UserDataBag('foo_user'), + ]; + } else { + yield 'If the username is not set on the User context, then it is retrieved from the token' => [ + new AuthenticatedTokenStub(new UserWithIdentifierStub()), + null, + new UserDataBag('foo_user'), + ]; + } yield 'If the user is being impersonated, then the username of the impersonator is set on the User context' => [ (static function (): SwitchUserToken { @@ -203,7 +219,8 @@ public function authenticationTokenDataProvider(): \Generator null, 'foo_provider', ['ROLE_USER'], - new AuthenticatedTokenStub(new UserWithIdentifierStub('bar_user')) + // @phpstan-ignore-next-line + new LegacyAuthenticatedTokenStub(new UserWithIdentifierStub('bar_user')) ); } @@ -228,28 +245,57 @@ public function authenticationTokenForSymfonyVersionLowerThan54DataProvider(): \ return; } - yield 'If the user is a string, then the value is used as-is' => [ - new AuthenticatedTokenStub('foo_user'), - null, - new UserDataBag('foo_user'), - ]; + if (version_compare(Kernel::VERSION, '5.0', '<')) { + yield 'If the user is a string, then the value is used as-is' => [ + new LegacyAuthenticatedTokenStub('foo_user'), + null, + new UserDataBag('foo_user'), + ]; + } else { + yield 'If the user is a string, then the value is used as-is' => [ + new AuthenticatedTokenStub('foo_user'), + null, + new UserDataBag('foo_user'), + ]; + } - yield 'If the user is an instance of the UserInterface interface but the getUserIdentifier() method does not exist, then the getUsername() method is invoked' => [ - new AuthenticatedTokenStub(new UserWithoutIdentifierStub()), - null, - new UserDataBag('foo_user'), - ]; + if (version_compare(Kernel::VERSION, '5.0', '<')) { + yield 'If the user is an instance of the UserInterface interface but the getUserIdentifier() method does not exist, then the getUsername() method is invoked' => [ + new LegacyAuthenticatedTokenStub(new UserWithoutIdentifierStub()), + null, + new UserDataBag('foo_user'), + ]; + } else { + yield 'If the user is an instance of the UserInterface interface but the getUserIdentifier() method does not exist, then the getUsername() method is invoked' => [ + new AuthenticatedTokenStub(new UserWithoutIdentifierStub()), + null, + new UserDataBag('foo_user'), + ]; + } - yield 'If the user is an object implementing the Stringable interface, then the __toString() method is invoked' => [ - new AuthenticatedTokenStub(new class() implements \Stringable { - public function __toString(): string - { - return 'foo_user'; - } - }), - null, - new UserDataBag('foo_user'), - ]; + if (version_compare(Kernel::VERSION, '5.0', '<')) { + yield 'If the user is an object implementing the Stringable interface, then the __toString() method is invoked' => [ + new LegacyAuthenticatedTokenStub(new class() implements \Stringable { + public function __toString(): string + { + return 'foo_user'; + } + }), + null, + new UserDataBag('foo_user'), + ]; + } else { + yield 'If the user is an object implementing the Stringable interface, then the __toString() method is invoked' => [ + new AuthenticatedTokenStub(new class() implements \Stringable { + public function __toString(): string + { + return 'foo_user'; + } + }), + null, + new UserDataBag('foo_user'), + ]; + } } public function testHandleKernelRequestEventDoesNothingIfRequestIsNotMain(): void @@ -312,14 +358,25 @@ public function testHandleLoginSuccessEventDoesNothingIfClientIsNotSetOnHub(): v $this->hub->expects($this->never()) ->method('configureScope'); - $this->listener->handleLoginSuccessEvent(new LoginSuccessEvent( - $this->createMock(AuthenticatorInterface::class), - new SelfValidatingPassport(new UserBadge('foo_passport_user')), - new AuthenticatedTokenStub(new UserWithIdentifierStub()), - new Request(), - null, - 'main' - )); + if (version_compare(Kernel::VERSION, '5.4', '<')) { + $this->listener->handleLoginSuccessEvent(new LoginSuccessEvent( + $this->createMock(AuthenticatorInterface::class), + new SelfValidatingPassport(new UserBadge('foo_passport_user')), + new LegacyAuthenticatedTokenStub(new UserWithIdentifierStub()), + new Request(), + null, + 'main' + )); + } else { + $this->listener->handleLoginSuccessEvent(new LoginSuccessEvent( + $this->createMock(AuthenticatorInterface::class), + new SelfValidatingPassport(new UserBadge('foo_passport_user')), + new AuthenticatedTokenStub(new UserWithIdentifierStub()), + new Request(), + null, + 'main' + )); + } } public function testHandleLoginSuccessEventDoesNothingIfSendingDefaultPiiIsDisabled(): void @@ -340,14 +397,25 @@ public function testHandleLoginSuccessEventDoesNothingIfSendingDefaultPiiIsDisab $this->hub->expects($this->never()) ->method('configureScope'); - $this->listener->handleLoginSuccessEvent(new LoginSuccessEvent( - $this->createMock(AuthenticatorInterface::class), - new SelfValidatingPassport(new UserBadge('foo_passport_user')), - new AuthenticatedTokenStub(new UserWithIdentifierStub()), - new Request(), - null, - 'main' - )); + if (version_compare(Kernel::VERSION, '5.4', '<')) { + $this->listener->handleLoginSuccessEvent(new LoginSuccessEvent( + $this->createMock(AuthenticatorInterface::class), + new SelfValidatingPassport(new UserBadge('foo_passport_user')), + new LegacyAuthenticatedTokenStub(new UserWithIdentifierStub()), + new Request(), + null, + 'main' + )); + } else { + $this->listener->handleLoginSuccessEvent(new LoginSuccessEvent( + $this->createMock(AuthenticatorInterface::class), + new SelfValidatingPassport(new UserBadge('foo_passport_user')), + new AuthenticatedTokenStub(new UserWithIdentifierStub()), + new Request(), + null, + 'main' + )); + } } public function testHandleAuthenticationSuccessEventDoesNothingIfTokenIsNotAuthenticated(): void @@ -378,7 +446,11 @@ public function testHandleAuthenticationSuccessEventDoesNothingIfClientIsNotSetO $this->hub->expects($this->never()) ->method('configureScope'); - $this->listener->handleAuthenticationSuccessEvent(new AuthenticationSuccessEvent(new AuthenticatedTokenStub(new UserWithIdentifierStub()))); + if (version_compare(Kernel::VERSION, '5.4', '<')) { + $this->listener->handleAuthenticationSuccessEvent(new AuthenticationSuccessEvent(new LegacyAuthenticatedTokenStub(new UserWithIdentifierStub()))); + } else { + $this->listener->handleAuthenticationSuccessEvent(new AuthenticationSuccessEvent(new AuthenticatedTokenStub(new UserWithIdentifierStub()))); + } } public function testHandleAuthenticationSuccessEventDoesNothingIfSendingDefaultPiiIsDisabled(): void @@ -399,7 +471,11 @@ public function testHandleAuthenticationSuccessEventDoesNothingIfSendingDefaultP $this->hub->expects($this->never()) ->method('configureScope'); - $this->listener->handleAuthenticationSuccessEvent(new AuthenticationSuccessEvent(new AuthenticatedTokenStub(new UserWithIdentifierStub()))); + if (version_compare(Kernel::VERSION, '5.4', '<')) { + $this->listener->handleAuthenticationSuccessEvent(new AuthenticationSuccessEvent(new LegacyAuthenticatedTokenStub(new UserWithIdentifierStub()))); + } else { + $this->listener->handleAuthenticationSuccessEvent(new AuthenticationSuccessEvent(new AuthenticatedTokenStub(new UserWithIdentifierStub()))); + } } } @@ -416,8 +492,47 @@ public function getCredentials(): ?string } } +class LegacyAuthenticatedTokenStub extends AbstractToken +{ + /** + * @var bool + * + * @phpstan-ignore-next-line + */ + private $authenticated = false; + + /** + * @param UserInterface|\Stringable|string|null $user + */ + public function __construct($user) + { + parent::__construct(); + + if (null !== $user) { + // @phpstan-ignore-next-line + $this->setUser($user); + } + + if (version_compare(Kernel::VERSION, '5.4', '<') && method_exists($this, 'setAuthenticated')) { + $this->setAuthenticated(true); + } else { + $this->authenticated = true; + } + } + + public function getCredentials(): ?string + { + return null; + } +} + final class AuthenticatedTokenStub extends AbstractToken { + /** + * @var bool + */ + private $authenticated = false; + /** * @param UserInterface|\Stringable|string|null $user */ @@ -426,14 +541,22 @@ public function __construct($user) parent::__construct(); if (null !== $user) { + // @phpstan-ignore-next-line $this->setUser($user); } - if (method_exists($this, 'setAuthenticated')) { + if (version_compare(Kernel::VERSION, '5.4', '<') && method_exists($this, 'setAuthenticated')) { $this->setAuthenticated(true); + } else { + $this->authenticated = true; } } + public function isAuthenticated(): bool + { + return $this->authenticated; + } + public function getCredentials(): ?string { return null; From 5de2b84421489e20c23c7678c69c3210dc7a223e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 21:24:51 +0200 Subject: [PATCH 15/57] Bump the composer group with 2 updates (#850) --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index a2853e65..9d8a5852 100644 --- a/composer.json +++ b/composer.json @@ -33,9 +33,9 @@ "friendsofphp/php-cs-fixer": "^2.19||^3.40", "masterminds/html5": "^2.8", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "1.11.3", + "phpstan/phpstan": "1.11.4", "phpstan/phpstan-phpunit": "1.4.0", - "phpstan/phpstan-symfony": "1.4.3", + "phpstan/phpstan-symfony": "1.4.4", "phpunit/phpunit": "^8.5.14||^9.3.9", "symfony/browser-kit": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/cache": "^4.4.20||^5.0.11||^6.0||^7.0", From b13881635f96fcf30844fe47ab11048af3b339a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81ngel=20Guzm=C3=A1n=20Maeso?= Date: Mon, 1 Jul 2024 23:04:12 +0200 Subject: [PATCH 16/57] fix: add missing method setCallbackWrapper (#841) Co-authored-by: Alex Bouma --- src/Tracing/Cache/TraceableCacheAdapterTrait.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Tracing/Cache/TraceableCacheAdapterTrait.php b/src/Tracing/Cache/TraceableCacheAdapterTrait.php index 0bf2bc2f..a479c0b9 100644 --- a/src/Tracing/Cache/TraceableCacheAdapterTrait.php +++ b/src/Tracing/Cache/TraceableCacheAdapterTrait.php @@ -190,4 +190,17 @@ private function traceFunction(string $spanOperation, \Closure $callback, string } } } + + /** + * @phpstan-param \Closure(CacheItem): CacheItem $callback + * @phpstan-param string $key + * + * @phpstan-return callable(): CacheItem + */ + private function setCallbackWrapper(callable $callback, string $key): callable + { + return function () use ($callback, $key): CacheItem { + return $callback($this->decoratedAdapter->getItem($key)); + }; + } } From 2057af224378ec7460d3a07d511e1c9421ddc17a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 11:51:24 +0200 Subject: [PATCH 17/57] Bump the composer group across 1 directory with 2 updates (#857) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alessandro Lai --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 9d8a5852..9c53bb8c 100644 --- a/composer.json +++ b/composer.json @@ -33,9 +33,9 @@ "friendsofphp/php-cs-fixer": "^2.19||^3.40", "masterminds/html5": "^2.8", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "1.11.4", + "phpstan/phpstan": "1.11.6", "phpstan/phpstan-phpunit": "1.4.0", - "phpstan/phpstan-symfony": "1.4.4", + "phpstan/phpstan-symfony": "1.4.5", "phpunit/phpunit": "^8.5.14||^9.3.9", "symfony/browser-kit": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/cache": "^4.4.20||^5.0.11||^6.0||^7.0", From bdcec61610694a0cfb04158095661e78ec4529ba Mon Sep 17 00:00:00 2001 From: Michi Hoffmann Date: Tue, 2 Jul 2024 11:52:47 +0200 Subject: [PATCH 18/57] Fix check if `symfony/http-client` is installed (#858) --- src/aliases.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/aliases.php b/src/aliases.php index fddd2689..92272bef 100644 --- a/src/aliases.php +++ b/src/aliases.php @@ -36,6 +36,7 @@ use Sentry\SentryBundle\Tracing\HttpClient\TraceableResponseForV6; use Symfony\Component\Cache\Adapter\AdapterInterface; use Symfony\Component\Cache\DoctrineProvider; +use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\HttpClient\Response\StreamableInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; @@ -78,7 +79,7 @@ class_alias(TracingDriverConnectionFactoryForV2V3::class, TracingDriverConnectio } } -if (!class_exists(TraceableResponse::class) && interface_exists(HttpClientInterface::class)) { +if (!class_exists(TraceableResponse::class) && class_exists(HttpClient::class)) { if (!interface_exists(StreamableInterface::class)) { class_alias(TraceableResponseForV4::class, TraceableResponse::class); class_alias(TraceableHttpClientForV4::class, TraceableHttpClient::class); From 903b8d187f7ad2a0df311e5c00e573a213ebfb09 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 08:55:49 +0200 Subject: [PATCH 19/57] Update phpstan/phpstan requirement from 1.11.6 to 1.11.7 in the composer group (#860) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 9c53bb8c..310fca13 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ "friendsofphp/php-cs-fixer": "^2.19||^3.40", "masterminds/html5": "^2.8", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "1.11.6", + "phpstan/phpstan": "1.11.7", "phpstan/phpstan-phpunit": "1.4.0", "phpstan/phpstan-symfony": "1.4.5", "phpunit/phpunit": "^8.5.14||^9.3.9", From 8821de1de0726718a901d3c12d66b8bff2cb387b Mon Sep 17 00:00:00 2001 From: Matthew T <20070360+mdtro@users.noreply.github.com> Date: Wed, 24 Jul 2024 02:00:30 -0500 Subject: [PATCH 20/57] ci: dependency review action (#864) --- .github/workflows/dependency-review.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/dependency-review.yml diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 00000000..24510de8 --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,19 @@ +name: 'Dependency Review' +on: + pull_request: + branches: ['master'] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: 'Checkout Repository' + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + - name: Dependency Review + uses: actions/dependency-review-action@5a2ce3f5b92ee19cbb1541a4984c76d921601d7c # v4.3.4 + with: + # Possible values: "critical", "high", "moderate", "low" + fail-on-severity: high From a19653cfa3267c7b33e676fdbad9cfc3d49d6bf5 Mon Sep 17 00:00:00 2001 From: Matthew T <20070360+mdtro@users.noreply.github.com> Date: Wed, 24 Jul 2024 12:52:56 -0500 Subject: [PATCH 21/57] Revert "ci: dependency review action" (#865) --- .github/workflows/dependency-review.yml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 .github/workflows/dependency-review.yml diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml deleted file mode 100644 index 24510de8..00000000 --- a/.github/workflows/dependency-review.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: 'Dependency Review' -on: - pull_request: - branches: ['master'] - -permissions: - contents: read - -jobs: - dependency-review: - runs-on: ubuntu-latest - steps: - - name: 'Checkout Repository' - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - name: Dependency Review - uses: actions/dependency-review-action@5a2ce3f5b92ee19cbb1541a4984c76d921601d7c # v4.3.4 - with: - # Possible values: "critical", "high", "moderate", "low" - fail-on-severity: high From c047da645e26b36394563a6d59fc19baa9735b77 Mon Sep 17 00:00:00 2001 From: Michi Hoffmann Date: Mon, 29 Jul 2024 13:14:04 +0200 Subject: [PATCH 22/57] Apply code style fixes (#868) --- src/Command/SentryTestCommand.php | 2 +- src/DependencyInjection/Compiler/DbalTracingPass.php | 6 +++--- src/ErrorTypesParser.php | 2 +- src/EventListener/AbstractTracingRequestListener.php | 2 +- src/EventListener/TracingRequestListener.php | 4 ++-- src/EventListener/TracingSubRequestListener.php | 2 +- src/Tracing/Cache/TraceableCacheAdapterForV2.php | 2 +- src/Tracing/Cache/TraceableCacheAdapterForV3.php | 2 +- src/Tracing/Cache/TraceableCacheAdapterTrait.php | 2 +- .../Cache/TraceableTagAwareCacheAdapterForV2.php | 2 +- .../Cache/TraceableTagAwareCacheAdapterForV3.php | 2 +- .../Doctrine/DBAL/TracingDriverConnectionForV2V3.php | 6 +++--- .../Doctrine/DBAL/TracingDriverConnectionForV4.php | 4 ++-- .../Doctrine/DBAL/TracingDriverMiddleware.php | 4 ++-- .../DBAL/TracingServerInfoAwareDriverConnection.php | 12 ++++++------ .../HttpClient/AbstractTraceableHttpClient.php | 2 +- src/Tracing/HttpClient/AbstractTraceableResponse.php | 2 +- src/Tracing/Twig/TwigTracingExtension.php | 2 +- src/Twig/SentryExtension.php | 6 +++--- .../Cache/AbstractTraceableCacheAdapterTest.php | 4 ++-- tests/Tracing/HttpClient/TraceableResponseTest.php | 2 +- 21 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/Command/SentryTestCommand.php b/src/Command/SentryTestCommand.php index 94ed9454..5c28a46e 100644 --- a/src/Command/SentryTestCommand.php +++ b/src/Command/SentryTestCommand.php @@ -25,7 +25,7 @@ public function __construct(?HubInterface $hub = null) parent::__construct(); if (null === $hub) { - @trigger_error(sprintf('Not passing an instance of the "%s" interface as argument of the constructor is deprecated since version 4.12 and will not work since version 5.0.', HubInterface::class), \E_USER_DEPRECATED); + @trigger_error(\sprintf('Not passing an instance of the "%s" interface as argument of the constructor is deprecated since version 4.12 and will not work since version 5.0.', HubInterface::class), \E_USER_DEPRECATED); } $this->hub = $hub ?? SentrySdk::getCurrentHub(); diff --git a/src/DependencyInjection/Compiler/DbalTracingPass.php b/src/DependencyInjection/Compiler/DbalTracingPass.php index e867a781..e4cbcdd7 100644 --- a/src/DependencyInjection/Compiler/DbalTracingPass.php +++ b/src/DependencyInjection/Compiler/DbalTracingPass.php @@ -45,8 +45,8 @@ public function process(ContainerBuilder $container): void } foreach ($connectionsToTrace as $connectionName) { - if (!\in_array(sprintf(self::CONNECTION_SERVICE_NAME_FORMAT, $connectionName), $connections, true)) { - throw new \InvalidArgumentException(sprintf('The Doctrine connection "%s" does not exists and cannot be instrumented.', $connectionName)); + if (!\in_array(\sprintf(self::CONNECTION_SERVICE_NAME_FORMAT, $connectionName), $connections, true)) { + throw new \InvalidArgumentException(\sprintf('The Doctrine connection "%s" does not exists and cannot be instrumented.', $connectionName)); } if (class_exists(Result::class)) { @@ -65,7 +65,7 @@ private function configureConnectionForDoctrineDBALVersion3(ContainerBuilder $co private function configureConnectionForDoctrineDBALVersion2(ContainerBuilder $container, string $connectionName): void { - $connectionDefinition = $container->getDefinition(sprintf(self::CONNECTION_SERVICE_NAME_FORMAT, $connectionName)); + $connectionDefinition = $container->getDefinition(\sprintf(self::CONNECTION_SERVICE_NAME_FORMAT, $connectionName)); $connectionDefinition->setConfigurator([new Reference(ConnectionConfigurator::class), 'configure']); } diff --git a/src/ErrorTypesParser.php b/src/ErrorTypesParser.php index ce0d7b90..b717c641 100644 --- a/src/ErrorTypesParser.php +++ b/src/ErrorTypesParser.php @@ -75,7 +75,7 @@ private static function convertErrorConstants(string $value): string }, $value); if (null === $output) { - throw new \InvalidArgumentException(sprintf('The "%s" value could not be parsed.', $value)); + throw new \InvalidArgumentException(\sprintf('The "%s" value could not be parsed.', $value)); } return $output; diff --git a/src/EventListener/AbstractTracingRequestListener.php b/src/EventListener/AbstractTracingRequestListener.php index 022f2d1b..95c31543 100644 --- a/src/EventListener/AbstractTracingRequestListener.php +++ b/src/EventListener/AbstractTracingRequestListener.php @@ -67,7 +67,7 @@ protected function getRouteName(Request $request): string $route = $request->attributes->get('_controller'); if (\is_array($route) && \is_callable($route, true)) { - $route = sprintf('%s::%s', \is_object($route[0]) ? get_debug_type($route[0]) : $route[0], $route[1]); + $route = \sprintf('%s::%s', \is_object($route[0]) ? get_debug_type($route[0]) : $route[0], $route[1]); } } diff --git a/src/EventListener/TracingRequestListener.php b/src/EventListener/TracingRequestListener.php index f5667953..10f8a2bf 100644 --- a/src/EventListener/TracingRequestListener.php +++ b/src/EventListener/TracingRequestListener.php @@ -46,10 +46,10 @@ public function handleKernelRequestEvent(RequestEvent $event): void $routeName = $request->attributes->get('_route'); if (null !== $routeName && \is_string($routeName)) { - $context->setName(sprintf('%s %s', $request->getMethod(), $routeName)); + $context->setName(\sprintf('%s %s', $request->getMethod(), $routeName)); $context->setSource(TransactionSource::route()); } else { - $context->setName(sprintf('%s %s%s%s', $request->getMethod(), $request->getSchemeAndHttpHost(), $request->getBaseUrl(), $request->getPathInfo())); + $context->setName(\sprintf('%s %s%s%s', $request->getMethod(), $request->getSchemeAndHttpHost(), $request->getBaseUrl(), $request->getPathInfo())); $context->setSource(TransactionSource::url()); } diff --git a/src/EventListener/TracingSubRequestListener.php b/src/EventListener/TracingSubRequestListener.php index 6791d548..12b0d7b0 100644 --- a/src/EventListener/TracingSubRequestListener.php +++ b/src/EventListener/TracingSubRequestListener.php @@ -36,7 +36,7 @@ public function handleKernelRequestEvent(RequestEvent $event): void $spanContext = new SpanContext(); $spanContext->setOp('http.server'); - $spanContext->setDescription(sprintf('%s %s%s%s', $request->getMethod(), $request->getSchemeAndHttpHost(), $request->getBaseUrl(), $request->getPathInfo())); + $spanContext->setDescription(\sprintf('%s %s%s%s', $request->getMethod(), $request->getSchemeAndHttpHost(), $request->getBaseUrl(), $request->getPathInfo())); $spanContext->setData([ 'http.request.method' => $request->getMethod(), 'http.url' => $request->getUri(), diff --git a/src/Tracing/Cache/TraceableCacheAdapterForV2.php b/src/Tracing/Cache/TraceableCacheAdapterForV2.php index 7a5b57c9..ab8a6e86 100644 --- a/src/Tracing/Cache/TraceableCacheAdapterForV2.php +++ b/src/Tracing/Cache/TraceableCacheAdapterForV2.php @@ -44,7 +44,7 @@ public function get(string $key, callable $callback, float $beta = null, array & { return $this->traceFunction('cache.get_item', function () use ($key, $callback, $beta, &$metadata) { if (!$this->decoratedAdapter instanceof CacheInterface) { - throw new \BadMethodCallException(sprintf('The %s::get() method is not supported because the decorated adapter does not implement the "%s" interface.', self::class, CacheInterface::class)); + throw new \BadMethodCallException(\sprintf('The %s::get() method is not supported because the decorated adapter does not implement the "%s" interface.', self::class, CacheInterface::class)); } return $this->decoratedAdapter->get($key, $callback, $beta, $metadata); diff --git a/src/Tracing/Cache/TraceableCacheAdapterForV3.php b/src/Tracing/Cache/TraceableCacheAdapterForV3.php index 564acff3..cd9e205c 100644 --- a/src/Tracing/Cache/TraceableCacheAdapterForV3.php +++ b/src/Tracing/Cache/TraceableCacheAdapterForV3.php @@ -42,7 +42,7 @@ public function get(string $key, callable $callback, float $beta = null, array & { return $this->traceFunction('cache.get_item', function () use ($key, $callback, $beta, &$metadata) { if (!$this->decoratedAdapter instanceof CacheInterface) { - throw new \BadMethodCallException(sprintf('The %s::get() method is not supported because the decorated adapter does not implement the "%s" interface.', self::class, CacheInterface::class)); + throw new \BadMethodCallException(\sprintf('The %s::get() method is not supported because the decorated adapter does not implement the "%s" interface.', self::class, CacheInterface::class)); } return $this->decoratedAdapter->get($key, $callback, $beta, $metadata); diff --git a/src/Tracing/Cache/TraceableCacheAdapterTrait.php b/src/Tracing/Cache/TraceableCacheAdapterTrait.php index a479c0b9..9bb267a3 100644 --- a/src/Tracing/Cache/TraceableCacheAdapterTrait.php +++ b/src/Tracing/Cache/TraceableCacheAdapterTrait.php @@ -70,7 +70,7 @@ public function delete(string $key): bool { return $this->traceFunction('cache.delete_item', function () use ($key): bool { if (!$this->decoratedAdapter instanceof CacheInterface) { - throw new \BadMethodCallException(sprintf('The %s::delete() method is not supported because the decorated adapter does not implement the "%s" interface.', self::class, CacheInterface::class)); + throw new \BadMethodCallException(\sprintf('The %s::delete() method is not supported because the decorated adapter does not implement the "%s" interface.', self::class, CacheInterface::class)); } return $this->decoratedAdapter->delete($key); diff --git a/src/Tracing/Cache/TraceableTagAwareCacheAdapterForV2.php b/src/Tracing/Cache/TraceableTagAwareCacheAdapterForV2.php index a89d911f..e3a807f8 100644 --- a/src/Tracing/Cache/TraceableTagAwareCacheAdapterForV2.php +++ b/src/Tracing/Cache/TraceableTagAwareCacheAdapterForV2.php @@ -45,7 +45,7 @@ public function get(string $key, callable $callback, float $beta = null, array & { return $this->traceFunction('cache.get_item', function () use ($key, $callback, $beta, &$metadata) { if (!$this->decoratedAdapter instanceof CacheInterface) { - throw new \BadMethodCallException(sprintf('The %s::get() method is not supported because the decorated adapter does not implement the "%s" interface.', self::class, CacheInterface::class)); + throw new \BadMethodCallException(\sprintf('The %s::get() method is not supported because the decorated adapter does not implement the "%s" interface.', self::class, CacheInterface::class)); } return $this->decoratedAdapter->get($key, $callback, $beta, $metadata); diff --git a/src/Tracing/Cache/TraceableTagAwareCacheAdapterForV3.php b/src/Tracing/Cache/TraceableTagAwareCacheAdapterForV3.php index 733b4555..700df5e7 100644 --- a/src/Tracing/Cache/TraceableTagAwareCacheAdapterForV3.php +++ b/src/Tracing/Cache/TraceableTagAwareCacheAdapterForV3.php @@ -43,7 +43,7 @@ public function get(string $key, callable $callback, float $beta = null, array & { return $this->traceFunction('cache.get_item', function () use ($key, $callback, $beta, &$metadata) { if (!$this->decoratedAdapter instanceof CacheInterface) { - throw new \BadMethodCallException(sprintf('The %s::get() method is not supported because the decorated adapter does not implement the "%s" interface.', self::class, CacheInterface::class)); + throw new \BadMethodCallException(\sprintf('The %s::get() method is not supported because the decorated adapter does not implement the "%s" interface.', self::class, CacheInterface::class)); } return $this->decoratedAdapter->get($key, $callback, $beta, $metadata); diff --git a/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3.php b/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3.php index 6e79102e..22c8d6d0 100644 --- a/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3.php +++ b/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3.php @@ -176,7 +176,7 @@ public function rollBack(): bool public function getNativeConnection() { if (!method_exists($this->decoratedConnection, 'getNativeConnection')) { - throw new \BadMethodCallException(sprintf('The connection "%s" does not support accessing the native connection.', \get_class($this->decoratedConnection))); + throw new \BadMethodCallException(\sprintf('The connection "%s" does not support accessing the native connection.', \get_class($this->decoratedConnection))); } return $this->decoratedConnection->getNativeConnection(); @@ -191,7 +191,7 @@ public function errorCode(): ?string return $this->decoratedConnection->errorCode(); } - throw new \BadMethodCallException(sprintf('The %s() method is not supported on Doctrine DBAL 3.0.', __METHOD__)); + throw new \BadMethodCallException(\sprintf('The %s() method is not supported on Doctrine DBAL 3.0.', __METHOD__)); } /** @@ -203,7 +203,7 @@ public function errorInfo(): array return $this->decoratedConnection->errorInfo(); } - throw new \BadMethodCallException(sprintf('The %s() method is not supported on Doctrine DBAL 3.0.', __METHOD__)); + throw new \BadMethodCallException(\sprintf('The %s() method is not supported on Doctrine DBAL 3.0.', __METHOD__)); } public function getWrappedConnection(): DriverConnectionInterface diff --git a/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV4.php b/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV4.php index 88ae34b3..0087fd89 100644 --- a/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV4.php +++ b/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV4.php @@ -184,7 +184,7 @@ public function errorCode(): ?string return $this->decoratedConnection->errorCode(); } - throw new \BadMethodCallException(sprintf('The %s() method is not supported on Doctrine DBAL 3.0.', __METHOD__)); + throw new \BadMethodCallException(\sprintf('The %s() method is not supported on Doctrine DBAL 3.0.', __METHOD__)); } /** @@ -196,7 +196,7 @@ public function errorInfo(): array return $this->decoratedConnection->errorInfo(); } - throw new \BadMethodCallException(sprintf('The %s() method is not supported on Doctrine DBAL 3.0.', __METHOD__)); + throw new \BadMethodCallException(\sprintf('The %s() method is not supported on Doctrine DBAL 3.0.', __METHOD__)); } public function getWrappedConnection(): DriverConnectionInterface diff --git a/src/Tracing/Doctrine/DBAL/TracingDriverMiddleware.php b/src/Tracing/Doctrine/DBAL/TracingDriverMiddleware.php index 0ef93b70..d9129441 100644 --- a/src/Tracing/Doctrine/DBAL/TracingDriverMiddleware.php +++ b/src/Tracing/Doctrine/DBAL/TracingDriverMiddleware.php @@ -31,11 +31,11 @@ public function __construct($hubOrConnectionFactory) if ($hubOrConnectionFactory instanceof TracingDriverConnectionFactoryInterface) { $this->connectionFactory = $hubOrConnectionFactory; } elseif ($hubOrConnectionFactory instanceof HubInterface) { - @trigger_error(sprintf('Not passing an instance of the "%s" interface as argument of the constructor is deprecated since version 4.2 and will not work since version 5.0.', TracingDriverConnectionFactoryInterface::class), \E_USER_DEPRECATED); + @trigger_error(\sprintf('Not passing an instance of the "%s" interface as argument of the constructor is deprecated since version 4.2 and will not work since version 5.0.', TracingDriverConnectionFactoryInterface::class), \E_USER_DEPRECATED); $this->connectionFactory = new TracingDriverConnectionFactory($hubOrConnectionFactory); } else { - throw new \InvalidArgumentException(sprintf('The constructor requires either an instance of the "%s" interface or an instance of the "%s" interface.', HubInterface::class, TracingDriverConnectionFactoryInterface::class)); + throw new \InvalidArgumentException(\sprintf('The constructor requires either an instance of the "%s" interface or an instance of the "%s" interface.', HubInterface::class, TracingDriverConnectionFactoryInterface::class)); } } diff --git a/src/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnection.php b/src/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnection.php index de1270bd..30945e97 100644 --- a/src/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnection.php +++ b/src/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnection.php @@ -109,7 +109,7 @@ public function getServerVersion(): string $wrappedConnection = $this->getWrappedConnection(); if (!$wrappedConnection instanceof ServerInfoAwareConnection) { - throw new \BadMethodCallException(sprintf('The wrapped connection must be an instance of the "%s" interface.', ServerInfoAwareConnection::class)); + throw new \BadMethodCallException(\sprintf('The wrapped connection must be an instance of the "%s" interface.', ServerInfoAwareConnection::class)); } return $wrappedConnection->getServerVersion(); @@ -123,7 +123,7 @@ public function getServerVersion(): string public function getNativeConnection() { if (!method_exists($this->decoratedConnection, 'getNativeConnection')) { - throw new \BadMethodCallException(sprintf('The connection "%s" does not support accessing the native connection.', \get_class($this->decoratedConnection))); + throw new \BadMethodCallException(\sprintf('The connection "%s" does not support accessing the native connection.', \get_class($this->decoratedConnection))); } return $this->decoratedConnection->getNativeConnection(); @@ -137,11 +137,11 @@ public function requiresQueryForServerVersion(): bool $wrappedConnection = $this->getWrappedConnection(); if (!$wrappedConnection instanceof ServerInfoAwareConnection) { - throw new \BadMethodCallException(sprintf('The wrapped connection must be an instance of the "%s" interface.', ServerInfoAwareConnection::class)); + throw new \BadMethodCallException(\sprintf('The wrapped connection must be an instance of the "%s" interface.', ServerInfoAwareConnection::class)); } if (!method_exists($wrappedConnection, 'requiresQueryForServerVersion')) { - throw new \BadMethodCallException(sprintf('The %s() method is not supported on Doctrine DBAL 3.0.', __METHOD__)); + throw new \BadMethodCallException(\sprintf('The %s() method is not supported on Doctrine DBAL 3.0.', __METHOD__)); } return $wrappedConnection->requiresQueryForServerVersion(); @@ -156,7 +156,7 @@ public function errorCode(): ?string return $this->decoratedConnection->errorCode(); } - throw new \BadMethodCallException(sprintf('The %s() method is not supported on Doctrine DBAL 3.0.', __METHOD__)); + throw new \BadMethodCallException(\sprintf('The %s() method is not supported on Doctrine DBAL 3.0.', __METHOD__)); } /** @@ -168,7 +168,7 @@ public function errorInfo(): array return $this->decoratedConnection->errorInfo(); } - throw new \BadMethodCallException(sprintf('The %s() method is not supported on Doctrine DBAL 3.0.', __METHOD__)); + throw new \BadMethodCallException(\sprintf('The %s() method is not supported on Doctrine DBAL 3.0.', __METHOD__)); } public function getWrappedConnection(): Connection diff --git a/src/Tracing/HttpClient/AbstractTraceableHttpClient.php b/src/Tracing/HttpClient/AbstractTraceableHttpClient.php index 1220600f..275774d6 100644 --- a/src/Tracing/HttpClient/AbstractTraceableHttpClient.php +++ b/src/Tracing/HttpClient/AbstractTraceableHttpClient.php @@ -111,7 +111,7 @@ public function stream($responses, float $timeout = null): ResponseStreamInterfa if ($responses instanceof AbstractTraceableResponse) { $responses = [$responses]; } elseif (!is_iterable($responses)) { - throw new \TypeError(sprintf('"%s()" expects parameter 1 to be an iterable of TraceableResponse objects, "%s" given.', __METHOD__, get_debug_type($responses))); + throw new \TypeError(\sprintf('"%s()" expects parameter 1 to be an iterable of TraceableResponse objects, "%s" given.', __METHOD__, get_debug_type($responses))); } return new ResponseStream(AbstractTraceableResponse::stream($this->client, $responses, $timeout)); diff --git a/src/Tracing/HttpClient/AbstractTraceableResponse.php b/src/Tracing/HttpClient/AbstractTraceableResponse.php index f53ecd8d..aba53b8e 100644 --- a/src/Tracing/HttpClient/AbstractTraceableResponse.php +++ b/src/Tracing/HttpClient/AbstractTraceableResponse.php @@ -107,7 +107,7 @@ public static function stream(HttpClientInterface $client, iterable $responses, foreach ($responses as $response) { if (!$response instanceof self) { - throw new \TypeError(sprintf('"%s::stream()" expects parameter 1 to be an iterable of TraceableResponse objects, "%s" given.', TraceableHttpClient::class, get_debug_type($response))); + throw new \TypeError(\sprintf('"%s::stream()" expects parameter 1 to be an iterable of TraceableResponse objects, "%s" given.', TraceableHttpClient::class, get_debug_type($response))); } $traceableMap[$response->response] = $response; diff --git a/src/Tracing/Twig/TwigTracingExtension.php b/src/Tracing/Twig/TwigTracingExtension.php index ec06e58c..94504846 100644 --- a/src/Tracing/Twig/TwigTracingExtension.php +++ b/src/Tracing/Twig/TwigTracingExtension.php @@ -95,7 +95,7 @@ private function getSpanDescription(Profile $profile): string return $profile->getTemplate(); default: - return sprintf('%s::%s(%s)', $profile->getTemplate(), $profile->getType(), $profile->getName()); + return \sprintf('%s::%s(%s)', $profile->getTemplate(), $profile->getType(), $profile->getName()); } } } diff --git a/src/Twig/SentryExtension.php b/src/Twig/SentryExtension.php index 2e4f31ed..d6a93984 100644 --- a/src/Twig/SentryExtension.php +++ b/src/Twig/SentryExtension.php @@ -38,7 +38,7 @@ public function getFunctions(): array */ public function getTraceMeta(): string { - return sprintf('', getTraceparent()); + return \sprintf('', getTraceparent()); } /** @@ -46,7 +46,7 @@ public function getTraceMeta(): string */ public function getW3CTraceMeta(): string { - return sprintf('', getW3CTraceparent()); + return \sprintf('', getW3CTraceparent()); } /** @@ -54,6 +54,6 @@ public function getW3CTraceMeta(): string */ public function getBaggageMeta(): string { - return sprintf('', getBaggage()); + return \sprintf('', getBaggage()); } } diff --git a/tests/Tracing/Cache/AbstractTraceableCacheAdapterTest.php b/tests/Tracing/Cache/AbstractTraceableCacheAdapterTest.php index 75583c8b..4b49194f 100644 --- a/tests/Tracing/Cache/AbstractTraceableCacheAdapterTest.php +++ b/tests/Tracing/Cache/AbstractTraceableCacheAdapterTest.php @@ -159,7 +159,7 @@ public function testGetThrowsExceptionIfDecoratedAdapterDoesNotImplementTheCache $adapter = $this->createCacheAdapter($this->createMock(static::getAdapterClassFqcn())); $this->expectException(\BadMethodCallException::class); - $this->expectExceptionMessage(sprintf('The %s::get() method is not supported because the decorated adapter does not implement the "Symfony\\Contracts\\Cache\\CacheInterface" interface.', \get_class($adapter))); + $this->expectExceptionMessage(\sprintf('The %s::get() method is not supported because the decorated adapter does not implement the "Symfony\\Contracts\\Cache\\CacheInterface" interface.', \get_class($adapter))); $adapter->get('foo', static function () {}); } @@ -197,7 +197,7 @@ public function testDeleteThrowsExceptionIfDecoratedAdapterDoesNotImplementTheCa $adapter = $this->createCacheAdapter($this->createMock(static::getAdapterClassFqcn())); $this->expectException(\BadMethodCallException::class); - $this->expectExceptionMessage(sprintf('The %s::delete() method is not supported because the decorated adapter does not implement the "Symfony\\Contracts\\Cache\\CacheInterface" interface.', \get_class($adapter))); + $this->expectExceptionMessage(\sprintf('The %s::delete() method is not supported because the decorated adapter does not implement the "Symfony\\Contracts\\Cache\\CacheInterface" interface.', \get_class($adapter))); $adapter->delete('foo'); } diff --git a/tests/Tracing/HttpClient/TraceableResponseTest.php b/tests/Tracing/HttpClient/TraceableResponseTest.php index f8851137..5a4bb370 100644 --- a/tests/Tracing/HttpClient/TraceableResponseTest.php +++ b/tests/Tracing/HttpClient/TraceableResponseTest.php @@ -55,7 +55,7 @@ public function testInstanceCannotBeUnserialized(): void $this->expectException(\BadMethodCallException::class); $this->expectExceptionMessage('Unserializing instances of this class is forbidden.'); - unserialize(sprintf('O:%u:"%s":0:{}', \strlen(TraceableResponse::class), TraceableResponse::class)); + unserialize(\sprintf('O:%u:"%s":0:{}', \strlen(TraceableResponse::class), TraceableResponse::class)); } public function testDestructor(): void From 49c0182c9fca9aaeb91ae2db1de7c19c038ca9c6 Mon Sep 17 00:00:00 2001 From: Michi Hoffmann Date: Mon, 29 Jul 2024 13:22:23 +0200 Subject: [PATCH 23/57] Prepare 5.0.1 (#867) --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27d2b5e0..65165e5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## 5.0.1 + +The Sentry SDK team is happy to announce the immediate availability of Sentry Laravel SDK v5.0.1. + +### Bug Fixes + +- Add missing `setCallbackWrapper` method to `TraceableCacheAdapterTrait` [(#841)](https://github.com/getsentry/sentry-symfony/pull/841) +- Fix detection of the `symfony/http-client` being installed [(#858)](https://github.com/getsentry/sentry-symfony/pull/858) + ## 5.0.0 The Sentry SDK team is thrilled to announce the immediate availability of Sentry Symfony SDK v5.0.0. From fe787002b96e70dfa701efe8772dfefff03963c3 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Mon, 29 Jul 2024 11:22:56 +0000 Subject: [PATCH 24/57] release: 5.0.1 --- src/SentryBundle.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SentryBundle.php b/src/SentryBundle.php index 693184e2..58ae744f 100644 --- a/src/SentryBundle.php +++ b/src/SentryBundle.php @@ -16,7 +16,7 @@ final class SentryBundle extends Bundle { public const SDK_IDENTIFIER = 'sentry.php.symfony'; - public const SDK_VERSION = '5.0.0'; + public const SDK_VERSION = '5.0.1'; public function build(ContainerBuilder $container): void { From 571a5e81a6db4089a5d99f24aaa91464abb70e66 Mon Sep 17 00:00:00 2001 From: Michi Hoffmann Date: Mon, 29 Jul 2024 17:37:43 +0200 Subject: [PATCH 25/57] Update CHANGELOG.md (#870) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65165e5f..66526c86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## 5.0.1 -The Sentry SDK team is happy to announce the immediate availability of Sentry Laravel SDK v5.0.1. +The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v5.0.1. ### Bug Fixes From b810c4cd73fc79d82edef200afb06728b0c06b1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Aug 2024 14:02:02 +0200 Subject: [PATCH 26/57] Bump the composer group across 1 directory with 2 updates (#871) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 310fca13..8c546770 100644 --- a/composer.json +++ b/composer.json @@ -33,9 +33,9 @@ "friendsofphp/php-cs-fixer": "^2.19||^3.40", "masterminds/html5": "^2.8", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "1.11.7", + "phpstan/phpstan": "1.11.8", "phpstan/phpstan-phpunit": "1.4.0", - "phpstan/phpstan-symfony": "1.4.5", + "phpstan/phpstan-symfony": "1.4.6", "phpunit/phpunit": "^8.5.14||^9.3.9", "symfony/browser-kit": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/cache": "^4.4.20||^5.0.11||^6.0||^7.0", From 198ce5096a7fc7c8be9364ed3f94ef8c5871fbc5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 09:32:50 +0200 Subject: [PATCH 27/57] Update phpstan/phpstan requirement from 1.11.8 to 1.11.9 in the composer group (#872) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8c546770..d112886f 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ "friendsofphp/php-cs-fixer": "^2.19||^3.40", "masterminds/html5": "^2.8", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "1.11.8", + "phpstan/phpstan": "1.11.9", "phpstan/phpstan-phpunit": "1.4.0", "phpstan/phpstan-symfony": "1.4.6", "phpunit/phpunit": "^8.5.14||^9.3.9", From 707eb33e7cb955e76558a0bdf38fe8f65efe2b04 Mon Sep 17 00:00:00 2001 From: Alex Bouma Date: Wed, 14 Aug 2024 03:37:06 +0200 Subject: [PATCH 28/57] Send span origin (#873) --- composer.json | 2 +- src/EventListener/TracingConsoleListener.php | 24 ++++++++++--------- src/EventListener/TracingRequestListener.php | 2 ++ .../TracingSubRequestListener.php | 23 ++++++++++-------- .../Cache/TraceableCacheAdapterTrait.php | 6 +++-- .../DBAL/TracingDriverConnectionForV2V3.php | 13 +++++----- .../DBAL/TracingDriverConnectionForV4.php | 13 +++++----- .../Doctrine/DBAL/TracingStatementForV2.php | 9 +++---- .../Doctrine/DBAL/TracingStatementForV3.php | 9 +++---- .../Doctrine/DBAL/TracingStatementForV4.php | 9 +++---- .../AbstractTraceableHttpClient.php | 7 +++--- src/Tracing/Twig/TwigTracingExtension.php | 11 +++++---- .../App/Messenger/FooMessageHandler.php | 2 +- tests/EventListener/LoginListenerTest.php | 4 ++-- .../TracingConsoleListenerTest.php | 2 ++ .../TracingRequestListenerTest.php | 15 +++++++++++- .../TracingSubRequestListenerTest.php | 2 +- .../IntegrationConfiguratorTest.php | 2 +- .../TracingDriverConnectionForV2V3Test.php | 2 +- .../DBAL/TracingDriverConnectionForV4Test.php | 2 +- ...ingServerInfoAwareDriverConnectionTest.php | 2 +- .../DBAL/TracingStatementForV3Test.php | 2 +- 22 files changed, 97 insertions(+), 66 deletions(-) diff --git a/composer.json b/composer.json index d112886f..70a3ca65 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "php": "^7.2||^8.0", "guzzlehttp/psr7": "^2.1.1", "jean85/pretty-package-versions": "^1.5||^2.0", - "sentry/sentry": "^4.6.1", + "sentry/sentry": "^4.9.0", "symfony/cache-contracts": "^1.1||^2.4||^3.0", "symfony/config": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/console": "^4.4.20||^5.0.11||^6.0||^7.0", diff --git a/src/EventListener/TracingConsoleListener.php b/src/EventListener/TracingConsoleListener.php index 5efbaf26..26beccf3 100644 --- a/src/EventListener/TracingConsoleListener.php +++ b/src/EventListener/TracingConsoleListener.php @@ -59,18 +59,20 @@ public function handleConsoleCommandEvent(ConsoleCommandEvent $event): void $currentSpan = $this->hub->getSpan(); if (null === $currentSpan) { - $transactionContext = new TransactionContext(); - $transactionContext->setOp('console.command'); - $transactionContext->setName($this->getSpanName($command)); - $transactionContext->setSource(TransactionSource::task()); - - $span = $this->hub->startTransaction($transactionContext); + $span = $this->hub->startTransaction( + TransactionContext::make() + ->setOp('console.command') + ->setOrigin('auto.console') + ->setName($this->getSpanName($command)) + ->setSource(TransactionSource::task()) + ); } else { - $spanContext = new SpanContext(); - $spanContext->setOp('console.command'); - $spanContext->setDescription($this->getSpanName($command)); - - $span = $currentSpan->startChild($spanContext); + $span = $currentSpan->startChild( + SpanContext::make() + ->setOp('console.command') + ->setOrigin('auto.console') + ->setDescription($this->getSpanName($command)) + ); } $this->hub->setSpan($span); diff --git a/src/EventListener/TracingRequestListener.php b/src/EventListener/TracingRequestListener.php index 10f8a2bf..e5797a79 100644 --- a/src/EventListener/TracingRequestListener.php +++ b/src/EventListener/TracingRequestListener.php @@ -42,7 +42,9 @@ public function handleKernelRequestEvent(RequestEvent $event): void $request->headers->get('sentry-trace') ?? $request->headers->get('traceparent', ''), $request->headers->get('baggage', '') ); + $context->setOp('http.server'); + $context->setOrigin('auto.http.server'); $routeName = $request->attributes->get('_route'); if (null !== $routeName && \is_string($routeName)) { diff --git a/src/EventListener/TracingSubRequestListener.php b/src/EventListener/TracingSubRequestListener.php index 12b0d7b0..71198bb1 100644 --- a/src/EventListener/TracingSubRequestListener.php +++ b/src/EventListener/TracingSubRequestListener.php @@ -34,16 +34,19 @@ public function handleKernelRequestEvent(RequestEvent $event): void return; } - $spanContext = new SpanContext(); - $spanContext->setOp('http.server'); - $spanContext->setDescription(\sprintf('%s %s%s%s', $request->getMethod(), $request->getSchemeAndHttpHost(), $request->getBaseUrl(), $request->getPathInfo())); - $spanContext->setData([ - 'http.request.method' => $request->getMethod(), - 'http.url' => $request->getUri(), - 'route' => $this->getRouteName($request), - ]); - - $this->hub->setSpan($span->startChild($spanContext)); + $this->hub->setSpan( + $span->startChild( + SpanContext::make() + ->setOp('http.server') + ->setData([ + 'http.request.method' => $request->getMethod(), + 'http.url' => $request->getUri(), + 'route' => $this->getRouteName($request), + ]) + ->setOrigin('auto.http.server') + ->setDescription(\sprintf('%s %s%s%s', $request->getMethod(), $request->getSchemeAndHttpHost(), $request->getBaseUrl(), $request->getPathInfo())) + ) + ); } /** diff --git a/src/Tracing/Cache/TraceableCacheAdapterTrait.php b/src/Tracing/Cache/TraceableCacheAdapterTrait.php index 9bb267a3..1519f784 100644 --- a/src/Tracing/Cache/TraceableCacheAdapterTrait.php +++ b/src/Tracing/Cache/TraceableCacheAdapterTrait.php @@ -173,8 +173,10 @@ private function traceFunction(string $spanOperation, \Closure $callback, string $span = $this->hub->getSpan(); if (null !== $span) { - $spanContext = new SpanContext(); - $spanContext->setOp($spanOperation); + $spanContext = SpanContext::make() + ->setOp($spanOperation) + ->setOrigin('auto.cache'); + if (null !== $spanDescription) { $spanContext->setDescription(urldecode($spanDescription)); } diff --git a/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3.php b/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3.php index 22c8d6d0..1010fb5b 100644 --- a/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3.php +++ b/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3.php @@ -223,12 +223,13 @@ private function traceFunction(string $spanOperation, string $spanDescription, \ $span = $this->hub->getSpan(); if (null !== $span) { - $spanContext = new SpanContext(); - $spanContext->setOp($spanOperation); - $spanContext->setDescription($spanDescription); - $spanContext->setData($this->spanData); - - $span = $span->startChild($spanContext); + $span = $span->startChild( + SpanContext::make() + ->setOp($spanOperation) + ->setData($this->spanData) + ->setOrigin('auto.db') + ->setDescription($spanDescription) + ); } try { diff --git a/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV4.php b/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV4.php index 0087fd89..2f506b25 100644 --- a/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV4.php +++ b/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV4.php @@ -221,12 +221,13 @@ private function traceFunction(string $spanOperation, string $spanDescription, \ $span = $this->hub->getSpan(); if (null !== $span) { - $spanContext = new SpanContext(); - $spanContext->setOp($spanOperation); - $spanContext->setDescription($spanDescription); - $spanContext->setData($this->spanData); - - $span = $span->startChild($spanContext); + $span = $span->startChild( + SpanContext::make() + ->setOp($spanOperation) + ->setData($this->spanData) + ->setOrigin('auto.db') + ->setDescription($spanDescription) + ); } try { diff --git a/src/Tracing/Doctrine/DBAL/TracingStatementForV2.php b/src/Tracing/Doctrine/DBAL/TracingStatementForV2.php index ca9728ce..a506a17a 100644 --- a/src/Tracing/Doctrine/DBAL/TracingStatementForV2.php +++ b/src/Tracing/Doctrine/DBAL/TracingStatementForV2.php @@ -116,10 +116,11 @@ public function bindParam($param, &$variable, $type = ParameterType::STRING, $le */ public function execute($params = null): bool { - $spanContext = new SpanContext(); - $spanContext->setOp(self::SPAN_OP_STMT_EXECUTE); - $spanContext->setDescription($this->sqlQuery); - $spanContext->setData($this->spanData); + $spanContext = SpanContext::make() + ->setOp(self::SPAN_OP_STMT_EXECUTE) + ->setData($this->spanData) + ->setOrigin('auto.db') + ->setDescription($this->sqlQuery); return $this->traceFunction($spanContext, [$this->decoratedStatement, 'execute'], $params); } diff --git a/src/Tracing/Doctrine/DBAL/TracingStatementForV3.php b/src/Tracing/Doctrine/DBAL/TracingStatementForV3.php index b2e8f1a0..45487a5a 100644 --- a/src/Tracing/Doctrine/DBAL/TracingStatementForV3.php +++ b/src/Tracing/Doctrine/DBAL/TracingStatementForV3.php @@ -35,10 +35,11 @@ public function bindParam($param, &$variable, $type = ParameterType::STRING, $le */ public function execute($params = null): Result { - $spanContext = new SpanContext(); - $spanContext->setOp(self::SPAN_OP_STMT_EXECUTE); - $spanContext->setDescription($this->sqlQuery); - $spanContext->setData($this->spanData); + $spanContext = SpanContext::make() + ->setOp(self::SPAN_OP_STMT_EXECUTE) + ->setData($this->spanData) + ->setOrigin('auto.db') + ->setDescription($this->sqlQuery); return $this->traceFunction($spanContext, [$this->decoratedStatement, 'execute'], $params); } diff --git a/src/Tracing/Doctrine/DBAL/TracingStatementForV4.php b/src/Tracing/Doctrine/DBAL/TracingStatementForV4.php index ba958687..5537549e 100644 --- a/src/Tracing/Doctrine/DBAL/TracingStatementForV4.php +++ b/src/Tracing/Doctrine/DBAL/TracingStatementForV4.php @@ -27,10 +27,11 @@ public function bindValue(int|string $param, mixed $value, ParameterType $type): */ public function execute(): Result { - $spanContext = new SpanContext(); - $spanContext->setOp(self::SPAN_OP_STMT_EXECUTE); - $spanContext->setDescription($this->sqlQuery); - $spanContext->setData($this->spanData); + $spanContext = SpanContext::make() + ->setOp(self::SPAN_OP_STMT_EXECUTE) + ->setData($this->spanData) + ->setOrigin('auto.db') + ->setDescription($this->sqlQuery); return $this->traceFunction($spanContext, [$this->decoratedStatement, 'execute']); } diff --git a/src/Tracing/HttpClient/AbstractTraceableHttpClient.php b/src/Tracing/HttpClient/AbstractTraceableHttpClient.php index 275774d6..0ad2432b 100644 --- a/src/Tracing/HttpClient/AbstractTraceableHttpClient.php +++ b/src/Tracing/HttpClient/AbstractTraceableHttpClient.php @@ -74,9 +74,10 @@ public function request(string $method, string $url, array $options = []): Respo 'path' => $uri->getPath(), ]); - $context = new SpanContext(); - $context->setOp('http.client'); - $context->setDescription($method . ' ' . (string) $partialUri); + $context = SpanContext::make() + ->setOp('http.client') + ->setOrigin('auto.http.client') + ->setDescription($method . ' ' . (string) $partialUri); $contextData = [ 'http.url' => (string) $partialUri, diff --git a/src/Tracing/Twig/TwigTracingExtension.php b/src/Tracing/Twig/TwigTracingExtension.php index 94504846..e03996d4 100644 --- a/src/Tracing/Twig/TwigTracingExtension.php +++ b/src/Tracing/Twig/TwigTracingExtension.php @@ -46,11 +46,12 @@ public function enter(Profile $profile): void return; } - $spanContext = new SpanContext(); - $spanContext->setOp('view.render'); - $spanContext->setDescription($this->getSpanDescription($profile)); - - $this->spans[$profile] = $transaction->startChild($spanContext); + $this->spans[$profile] = $transaction->startChild( + SpanContext::make() + ->setOp('view.render') + ->setOrigin('auto.view') + ->setDescription($this->getSpanDescription($profile)) + ); } /** diff --git a/tests/End2End/App/Messenger/FooMessageHandler.php b/tests/End2End/App/Messenger/FooMessageHandler.php index 5641175d..28518d96 100644 --- a/tests/End2End/App/Messenger/FooMessageHandler.php +++ b/tests/End2End/App/Messenger/FooMessageHandler.php @@ -11,7 +11,7 @@ class FooMessageHandler public function __invoke(FooMessage $message): void { if (!$message->shouldRetry()) { - throw new class() extends \Exception implements UnrecoverableExceptionInterface { }; + throw new class extends \Exception implements UnrecoverableExceptionInterface { }; } throw new \Exception('This is an intentional failure while handling a message of class ' . \get_class($message)); diff --git a/tests/EventListener/LoginListenerTest.php b/tests/EventListener/LoginListenerTest.php index cfaf50aa..34c37e3d 100644 --- a/tests/EventListener/LoginListenerTest.php +++ b/tests/EventListener/LoginListenerTest.php @@ -275,7 +275,7 @@ public function authenticationTokenForSymfonyVersionLowerThan54DataProvider(): \ if (version_compare(Kernel::VERSION, '5.0', '<')) { yield 'If the user is an object implementing the Stringable interface, then the __toString() method is invoked' => [ - new LegacyAuthenticatedTokenStub(new class() implements \Stringable { + new LegacyAuthenticatedTokenStub(new class implements \Stringable { public function __toString(): string { return 'foo_user'; @@ -286,7 +286,7 @@ public function __toString(): string ]; } else { yield 'If the user is an object implementing the Stringable interface, then the __toString() method is invoked' => [ - new AuthenticatedTokenStub(new class() implements \Stringable { + new AuthenticatedTokenStub(new class implements \Stringable { public function __toString(): string { return 'foo_user'; diff --git a/tests/EventListener/TracingConsoleListenerTest.php b/tests/EventListener/TracingConsoleListenerTest.php index 3987ea04..fe87b34e 100644 --- a/tests/EventListener/TracingConsoleListenerTest.php +++ b/tests/EventListener/TracingConsoleListenerTest.php @@ -71,6 +71,7 @@ public function handleConsoleCommandEventStartsTransactionIfNoSpanIsSetOnHubData $transactionContext = new TransactionContext(); $transactionContext->setOp('console.command'); $transactionContext->setName(''); + $transactionContext->setOrigin('auto.console'); $transactionContext->setSource(TransactionSource::task()); yield [ @@ -81,6 +82,7 @@ public function handleConsoleCommandEventStartsTransactionIfNoSpanIsSetOnHubData $transactionContext = new TransactionContext(); $transactionContext->setOp('console.command'); $transactionContext->setName('app:command'); + $transactionContext->setOrigin('auto.console'); $transactionContext->setSource(TransactionSource::task()); yield [ diff --git a/tests/EventListener/TracingRequestListenerTest.php b/tests/EventListener/TracingRequestListenerTest.php index da3a3b58..4430466f 100644 --- a/tests/EventListener/TracingRequestListenerTest.php +++ b/tests/EventListener/TracingRequestListenerTest.php @@ -97,6 +97,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext->setName('GET http://www.example.com/'); $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); + $transactionContext->setOrigin('auto.http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setData([ 'net.host.port' => '80', @@ -134,6 +135,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext->setName('GET http://www.example.com/'); $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); + $transactionContext->setOrigin('auto.http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setData([ 'net.host.port' => '80', @@ -171,6 +173,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext->setName('GET http://www.example.com/'); $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); + $transactionContext->setOrigin('auto.http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setData([ 'net.host.port' => '80', @@ -203,6 +206,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext->setName('GET http://www.example.com/'); $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); + $transactionContext->setOrigin('auto.http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setData([ 'net.host.port' => '80', @@ -226,6 +230,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext->setName('GET http://127.0.0.1/'); $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); + $transactionContext->setOrigin('auto.http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setData([ 'net.host.port' => '80', @@ -257,6 +262,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext->setName('GET app_homepage'); $transactionContext->setSource(TransactionSource::route()); $transactionContext->setOp('http.server'); + $transactionContext->setOrigin('auto.http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setData([ 'net.host.port' => '80', @@ -281,6 +287,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext->setName('GET http://www.example.com/path'); $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); + $transactionContext->setOrigin('auto.http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setData([ 'net.host.port' => '80', @@ -305,6 +312,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext->setName('GET http://www.example.com/'); $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); + $transactionContext->setOrigin('auto.http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setData([ 'net.host.port' => '80', @@ -329,6 +337,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext->setName('GET http://www.example.com/'); $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); + $transactionContext->setOrigin('auto.http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setData([ 'net.host.port' => '80', @@ -347,12 +356,13 @@ public function handleKernelRequestEventDataProvider(): \Generator $request = Request::create('http://www.example.com/'); $request->server->set('REQUEST_TIME_FLOAT', 1613493597.010275); - $request->attributes->set('_controller', [new class() {}, 'indexAction']); + $request->attributes->set('_controller', [new class {}, 'indexAction']); $transactionContext = new TransactionContext(); $transactionContext->setName('GET http://www.example.com/'); $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); + $transactionContext->setOrigin('auto.http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setData([ 'net.host.port' => '80', @@ -377,6 +387,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext->setName('GET http://www.example.com/'); $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); + $transactionContext->setOrigin('auto.http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setData([ 'net.host.port' => '80', @@ -401,6 +412,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext->setName('GET http://www.example.com/'); $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); + $transactionContext->setOrigin('auto.http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setData([ 'net.host.port' => '80', @@ -425,6 +437,7 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext->setName('GET http://:/'); $transactionContext->setSource(TransactionSource::url()); $transactionContext->setOp('http.server'); + $transactionContext->setOrigin('auto.http.server'); $transactionContext->setStartTimestamp(1613493597.010275); $transactionContext->setData([ 'net.host.port' => '', diff --git a/tests/EventListener/TracingSubRequestListenerTest.php b/tests/EventListener/TracingSubRequestListenerTest.php index ae54b342..75effa05 100644 --- a/tests/EventListener/TracingSubRequestListenerTest.php +++ b/tests/EventListener/TracingSubRequestListenerTest.php @@ -104,7 +104,7 @@ public function handleKernelRequestEventDataProvider(): \Generator ]; $request = Request::create('http://www.example.com/'); - $request->attributes->set('_controller', [new class() {}, 'indexAction']); + $request->attributes->set('_controller', [new class {}, 'indexAction']); $span = new Span(); $span->setOp('http.server'); diff --git a/tests/Integration/IntegrationConfiguratorTest.php b/tests/Integration/IntegrationConfiguratorTest.php index 44206b5c..4fd59339 100644 --- a/tests/Integration/IntegrationConfiguratorTest.php +++ b/tests/Integration/IntegrationConfiguratorTest.php @@ -50,7 +50,7 @@ public function integrationsDataProvider(): iterable $environmentIntegration = new EnvironmentIntegration(); $modulesIntegration = new ModulesIntegration(); - $userIntegration1 = new class() implements IntegrationInterface { + $userIntegration1 = new class implements IntegrationInterface { public function setupOnce(): void { } diff --git a/tests/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3Test.php b/tests/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3Test.php index d8ce3581..3ad7ede2 100644 --- a/tests/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3Test.php +++ b/tests/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3Test.php @@ -418,7 +418,7 @@ public function testGetWrappedConnection(): void public function testGetNativeConnection(): void { - $nativeConnection = new class() { + $nativeConnection = new class { }; $decoratedConnection = $this->createMock(NativeDriverConnectionInterfaceStub::class); diff --git a/tests/Tracing/Doctrine/DBAL/TracingDriverConnectionForV4Test.php b/tests/Tracing/Doctrine/DBAL/TracingDriverConnectionForV4Test.php index e1daefb7..77490bb3 100644 --- a/tests/Tracing/Doctrine/DBAL/TracingDriverConnectionForV4Test.php +++ b/tests/Tracing/Doctrine/DBAL/TracingDriverConnectionForV4Test.php @@ -412,7 +412,7 @@ public function testGetWrappedConnection(): void public function testGetNativeConnection(): void { - $nativeConnection = new class() { + $nativeConnection = new class { }; $decoratedConnection = $this->createMock(NativeDriverConnectionInterfaceStub::class); diff --git a/tests/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnectionTest.php b/tests/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnectionTest.php index f8cd4537..13342222 100644 --- a/tests/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnectionTest.php +++ b/tests/Tracing/Doctrine/DBAL/TracingServerInfoAwareDriverConnectionTest.php @@ -264,7 +264,7 @@ public function testGetWrappedConnection(): void public function testGetNativeConnection(): void { - $nativeConnection = new class() { + $nativeConnection = new class { }; $decoratedConnection = $this->createMock(NativeDriverConnectionInterfaceStub::class); diff --git a/tests/Tracing/Doctrine/DBAL/TracingStatementForV3Test.php b/tests/Tracing/Doctrine/DBAL/TracingStatementForV3Test.php index 382fb0aa..722b1c27 100644 --- a/tests/Tracing/Doctrine/DBAL/TracingStatementForV3Test.php +++ b/tests/Tracing/Doctrine/DBAL/TracingStatementForV3Test.php @@ -70,7 +70,7 @@ public function testBindParam(): void public function testBindParamForwardsLengthParamOnlyWhenExplicitlySet(): void { $variable = 'bar'; - $decoratedStatement = new class() implements Statement { + $decoratedStatement = new class implements Statement { /** * @var int */ From aa42014be3fa91febe46eca62e5eff3eada857af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:41:44 +0200 Subject: [PATCH 29/57] Bump the composer group across 1 directory with 2 updates (#875) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 70a3ca65..e7b0b5b1 100644 --- a/composer.json +++ b/composer.json @@ -33,9 +33,9 @@ "friendsofphp/php-cs-fixer": "^2.19||^3.40", "masterminds/html5": "^2.8", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "1.11.9", + "phpstan/phpstan": "1.11.11", "phpstan/phpstan-phpunit": "1.4.0", - "phpstan/phpstan-symfony": "1.4.6", + "phpstan/phpstan-symfony": "1.4.8", "phpunit/phpunit": "^8.5.14||^9.3.9", "symfony/browser-kit": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/cache": "^4.4.20||^5.0.11||^6.0||^7.0", From 21626aeef65b7a1615031ea3b7e91f2b2b82134c Mon Sep 17 00:00:00 2001 From: Alex Bouma Date: Tue, 10 Sep 2024 11:43:10 +0200 Subject: [PATCH 30/57] Slow dependency updates (#881) --- .github/dependabot.yml | 4 ++-- .github/workflows/publish-release.yaml | 4 ++-- .github/workflows/static-analysis.yaml | 18 +++++++++--------- .github/workflows/tests.yaml | 16 ++++++++-------- .php-cs-fixer.dist.php | 4 ++++ 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index bf79cc19..a0982451 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,13 +3,13 @@ updates: - package-ecosystem: "github-actions" directory: "/" schedule: - interval: weekly + interval: monthly - package-ecosystem: "composer" directory: "/" allow: - dependency-name: "*phpstan*" schedule: - interval: weekly + interval: monthly groups: composer: patterns: diff --git a/.github/workflows/publish-release.yaml b/.github/workflows/publish-release.yaml index d378f49d..9e7ab3d2 100644 --- a/.github/workflows/publish-release.yaml +++ b/.github/workflows/publish-release.yaml @@ -19,13 +19,13 @@ jobs: name: Release version steps: - name: Checkout - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@v4 with: token: ${{ secrets.GH_RELEASE_PAT }} fetch-depth: 0 - name: Prepare release - uses: getsentry/action-prepare-release@3cea80dc3938c0baf5ec4ce752ecb311f8780cdc #v1.6.4 + uses: getsentry/action-prepare-release@v1 env: GITHUB_TOKEN: ${{ secrets.GH_RELEASE_PAT }} with: diff --git a/.github/workflows/static-analysis.yaml b/.github/workflows/static-analysis.yaml index eeb88d15..1a1a1e8c 100644 --- a/.github/workflows/static-analysis.yaml +++ b/.github/workflows/static-analysis.yaml @@ -17,15 +17,15 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@v4 - name: Setup PHP - uses: shivammathur/setup-php@fc14643b0a99ee9db10a3c025a33d76544fa3761 # v2.30.5 + uses: shivammathur/setup-php@v2 with: php-version: '8.2' - name: Install dependencies - uses: ramsey/composer-install@57532f8be5bda426838819c5ee9afb8af389d51a # v3.0.0 + uses: ramsey/composer-install@v3 with: composer-options: --prefer-dist @@ -37,15 +37,15 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@v4 - name: Setup PHP - uses: shivammathur/setup-php@fc14643b0a99ee9db10a3c025a33d76544fa3761 # v2.30.5 + uses: shivammathur/setup-php@v2 with: php-version: '8.3' - name: Install dependencies - uses: ramsey/composer-install@57532f8be5bda426838819c5ee9afb8af389d51a # v3.0.0 + uses: ramsey/composer-install@v3 with: composer-options: --prefer-dist @@ -57,15 +57,15 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@v4 - name: Setup PHP - uses: shivammathur/setup-php@fc14643b0a99ee9db10a3c025a33d76544fa3761 # v2.30.5 + uses: shivammathur/setup-php@v2 with: php-version: '8.3' - name: Install dependencies - uses: ramsey/composer-install@57532f8be5bda426838819c5ee9afb8af389d51a # v3.0.0 + uses: ramsey/composer-install@v3 with: composer-options: --prefer-dist diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 4449c344..063c70f6 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -68,12 +68,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@v4 with: fetch-depth: 2 - name: Setup PHP - uses: shivammathur/setup-php@fc14643b0a99ee9db10a3c025a33d76544fa3761 # v2.30.5 + uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} coverage: pcov @@ -87,7 +87,7 @@ jobs: if: matrix.php == '8.0' && matrix.dependencies == 'lowest' - name: Install dependencies - uses: ramsey/composer-install@57532f8be5bda426838819c5ee9afb8af389d51a # v3.0.0 + uses: ramsey/composer-install@v3 with: dependency-versions: ${{ matrix.dependencies }} composer-options: --prefer-dist @@ -96,7 +96,7 @@ jobs: run: vendor/bin/phpunit --coverage-clover=build/coverage-report.xml - name: Upload code coverage - uses: codecov/codecov-action@125fc84a9a348dbcf27191600683ec096ec9021c # v4.4.1 + uses: codecov/codecov-action@v4 with: file: build/coverage-report.xml token: ${{ secrets.CODECOV_TOKEN }} @@ -123,10 +123,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@v4 - name: Setup PHP - uses: shivammathur/setup-php@fc14643b0a99ee9db10a3c025a33d76544fa3761 # v2.30.5 + uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} coverage: pcov @@ -139,7 +139,7 @@ jobs: run: composer remove doctrine/dbal doctrine/doctrine-bundle symfony/messenger symfony/twig-bundle symfony/cache symfony/http-client --dev --no-update - name: Install dependencies - uses: ramsey/composer-install@57532f8be5bda426838819c5ee9afb8af389d51a # v3.0.0 + uses: ramsey/composer-install@v3 with: dependency-versions: ${{ matrix.dependencies }} composer-options: --prefer-dist @@ -148,7 +148,7 @@ jobs: run: vendor/bin/phpunit --coverage-clover=build/coverage-report.xml - name: Upload code coverage - uses: codecov/codecov-action@125fc84a9a348dbcf27191600683ec096ec9021c # v4.4.1 + uses: codecov/codecov-action@v4 with: file: build/coverage-report.xml token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 5906a68d..3f0de29f 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -31,6 +31,10 @@ 'method' => 'multi', 'property' => 'multi', ], + 'trailing_comma_in_multiline' => [ + 'after_heredoc' => false, + 'elements' => ['arrays'], + ], ]) ->setFinder( PhpCsFixer\Finder::create() From 9b82b0a0f41234b56a44a088115a48231df15e81 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 09:44:54 +0000 Subject: [PATCH 31/57] Update PHPStan with 2 updates (#880) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index e7b0b5b1..b039bd66 100644 --- a/composer.json +++ b/composer.json @@ -33,9 +33,9 @@ "friendsofphp/php-cs-fixer": "^2.19||^3.40", "masterminds/html5": "^2.8", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "1.11.11", + "phpstan/phpstan": "1.12.3", "phpstan/phpstan-phpunit": "1.4.0", - "phpstan/phpstan-symfony": "1.4.8", + "phpstan/phpstan-symfony": "1.4.9", "phpunit/phpunit": "^8.5.14||^9.3.9", "symfony/browser-kit": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/cache": "^4.4.20||^5.0.11||^6.0||^7.0", From 1bc2033be5ffaa707a64994f44d9482c7e784f71 Mon Sep 17 00:00:00 2001 From: Alex Bouma Date: Thu, 26 Sep 2024 12:06:07 +0200 Subject: [PATCH 32/57] Keep reference to the request until after the transaction is finished (#879) --- src/EventListener/TracingRequestListener.php | 23 ++++++++++++++++++++ src/Integration/RequestFetcher.php | 13 ++++++++++- src/Resources/config/services.xml | 1 + 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/EventListener/TracingRequestListener.php b/src/EventListener/TracingRequestListener.php index e5797a79..f94f9dda 100644 --- a/src/EventListener/TracingRequestListener.php +++ b/src/EventListener/TracingRequestListener.php @@ -4,6 +4,9 @@ namespace Sentry\SentryBundle\EventListener; +use Sentry\Integration\RequestFetcherInterface; +use Sentry\SentryBundle\Integration\RequestFetcher; +use Sentry\State\HubInterface; use Sentry\Tracing\TransactionSource; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Event\RequestEvent; @@ -20,6 +23,18 @@ */ final class TracingRequestListener extends AbstractTracingRequestListener { + /** + * @var RequestFetcherInterface|null + */ + private $requestFetcher; + + public function __construct(HubInterface $hub, ?RequestFetcherInterface $requestFetcher = null) + { + parent::__construct($hub); + + $this->requestFetcher = $requestFetcher; + } + /** * This method is called for each subrequest handled by the framework and * starts a new {@see Transaction}. @@ -35,6 +50,10 @@ public function handleKernelRequestEvent(RequestEvent $event): void /** @var Request $request */ $request = $event->getRequest(); + if ($this->requestFetcher instanceof RequestFetcher) { + $this->requestFetcher->setRequest($request); + } + /** @var float $requestStartTime */ $requestStartTime = $request->server->get('REQUEST_TIME_FLOAT', microtime(true)); @@ -77,6 +96,10 @@ public function handleKernelTerminateEvent(TerminateEvent $event): void $transaction->finish(); metrics()->flush(); + + if ($this->requestFetcher instanceof RequestFetcher) { + $this->requestFetcher->setRequest(null); + } } /** diff --git a/src/Integration/RequestFetcher.php b/src/Integration/RequestFetcher.php index af371783..2f2d2cd2 100644 --- a/src/Integration/RequestFetcher.php +++ b/src/Integration/RequestFetcher.php @@ -9,6 +9,7 @@ use Sentry\Integration\RequestFetcherInterface; use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory; use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; /** @@ -23,6 +24,11 @@ final class RequestFetcher implements RequestFetcherInterface */ private $requestStack; + /** + * @var Request|null The current request + */ + private $currentRequest; + /** * @var HttpMessageFactoryInterface The factory to convert Symfony requests to PSR-7 requests */ @@ -50,7 +56,7 @@ public function __construct(RequestStack $requestStack, ?HttpMessageFactoryInter */ public function fetchRequest(): ?ServerRequestInterface { - $request = $this->requestStack->getCurrentRequest(); + $request = $this->currentRequest ?? $this->requestStack->getCurrentRequest(); if (null === $request) { return null; @@ -62,4 +68,9 @@ public function fetchRequest(): ?ServerRequestInterface return null; } } + + public function setRequest(?Request $request): void + { + $this->currentRequest = $request; + } } diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index ef3ce7d8..02ad8994 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -48,6 +48,7 @@ + From 5f8da1317ee0636ff276c18a14926d35491ff54b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Oct 2024 08:54:56 +0200 Subject: [PATCH 33/57] Bump the composer group with 2 updates (#884) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index b039bd66..ea971f23 100644 --- a/composer.json +++ b/composer.json @@ -33,9 +33,9 @@ "friendsofphp/php-cs-fixer": "^2.19||^3.40", "masterminds/html5": "^2.8", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "1.12.3", + "phpstan/phpstan": "1.12.5", "phpstan/phpstan-phpunit": "1.4.0", - "phpstan/phpstan-symfony": "1.4.9", + "phpstan/phpstan-symfony": "1.4.10", "phpunit/phpunit": "^8.5.14||^9.3.9", "symfony/browser-kit": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/cache": "^4.4.20||^5.0.11||^6.0||^7.0", From 78205167e1ce7abd79fb317171b21524f49deb7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niko=20Gran=C3=B6?= Date: Thu, 14 Nov 2024 16:14:40 +0200 Subject: [PATCH 34/57] fix: Implicitly marking parameter as nullable is deprecated (#894) --- src/Tracing/Cache/TraceableCacheAdapterForV2.php | 2 +- src/Tracing/Cache/TraceableCacheAdapterForV3.php | 2 +- src/Tracing/Cache/TraceableCacheAdapterTrait.php | 2 +- src/Tracing/Cache/TraceableTagAwareCacheAdapterForV2.php | 2 +- src/Tracing/Cache/TraceableTagAwareCacheAdapterForV3.php | 2 +- src/Tracing/HttpClient/AbstractTraceableHttpClient.php | 2 +- src/Tracing/HttpClient/TraceableResponseForV6.php | 2 +- src/Twig/SentryExtension.php | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Tracing/Cache/TraceableCacheAdapterForV2.php b/src/Tracing/Cache/TraceableCacheAdapterForV2.php index ab8a6e86..e8ed9330 100644 --- a/src/Tracing/Cache/TraceableCacheAdapterForV2.php +++ b/src/Tracing/Cache/TraceableCacheAdapterForV2.php @@ -40,7 +40,7 @@ public function __construct(HubInterface $hub, AdapterInterface $decoratedAdapte * * @return mixed */ - public function get(string $key, callable $callback, float $beta = null, array &$metadata = null) + public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null) { return $this->traceFunction('cache.get_item', function () use ($key, $callback, $beta, &$metadata) { if (!$this->decoratedAdapter instanceof CacheInterface) { diff --git a/src/Tracing/Cache/TraceableCacheAdapterForV3.php b/src/Tracing/Cache/TraceableCacheAdapterForV3.php index cd9e205c..ef276620 100644 --- a/src/Tracing/Cache/TraceableCacheAdapterForV3.php +++ b/src/Tracing/Cache/TraceableCacheAdapterForV3.php @@ -38,7 +38,7 @@ public function __construct(HubInterface $hub, AdapterInterface $decoratedAdapte * * @param mixed[] $metadata */ - public function get(string $key, callable $callback, float $beta = null, array &$metadata = null): mixed + public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed { return $this->traceFunction('cache.get_item', function () use ($key, $callback, $beta, &$metadata) { if (!$this->decoratedAdapter instanceof CacheInterface) { diff --git a/src/Tracing/Cache/TraceableCacheAdapterTrait.php b/src/Tracing/Cache/TraceableCacheAdapterTrait.php index 1519f784..b2af9a59 100644 --- a/src/Tracing/Cache/TraceableCacheAdapterTrait.php +++ b/src/Tracing/Cache/TraceableCacheAdapterTrait.php @@ -168,7 +168,7 @@ public function reset(): void * * @phpstan-return TResult */ - private function traceFunction(string $spanOperation, \Closure $callback, string $spanDescription = null) + private function traceFunction(string $spanOperation, \Closure $callback, ?string $spanDescription = null) { $span = $this->hub->getSpan(); diff --git a/src/Tracing/Cache/TraceableTagAwareCacheAdapterForV2.php b/src/Tracing/Cache/TraceableTagAwareCacheAdapterForV2.php index e3a807f8..62477cc2 100644 --- a/src/Tracing/Cache/TraceableTagAwareCacheAdapterForV2.php +++ b/src/Tracing/Cache/TraceableTagAwareCacheAdapterForV2.php @@ -41,7 +41,7 @@ public function __construct(HubInterface $hub, TagAwareAdapterInterface $decorat * * @return mixed */ - public function get(string $key, callable $callback, float $beta = null, array &$metadata = null) + public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null) { return $this->traceFunction('cache.get_item', function () use ($key, $callback, $beta, &$metadata) { if (!$this->decoratedAdapter instanceof CacheInterface) { diff --git a/src/Tracing/Cache/TraceableTagAwareCacheAdapterForV3.php b/src/Tracing/Cache/TraceableTagAwareCacheAdapterForV3.php index 700df5e7..cc5cc7b4 100644 --- a/src/Tracing/Cache/TraceableTagAwareCacheAdapterForV3.php +++ b/src/Tracing/Cache/TraceableTagAwareCacheAdapterForV3.php @@ -39,7 +39,7 @@ public function __construct(HubInterface $hub, TagAwareAdapterInterface $decorat * * @param mixed[] $metadata */ - public function get(string $key, callable $callback, float $beta = null, array &$metadata = null): mixed + public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed { return $this->traceFunction('cache.get_item', function () use ($key, $callback, $beta, &$metadata) { if (!$this->decoratedAdapter instanceof CacheInterface) { diff --git a/src/Tracing/HttpClient/AbstractTraceableHttpClient.php b/src/Tracing/HttpClient/AbstractTraceableHttpClient.php index 0ad2432b..d1f83b2c 100644 --- a/src/Tracing/HttpClient/AbstractTraceableHttpClient.php +++ b/src/Tracing/HttpClient/AbstractTraceableHttpClient.php @@ -107,7 +107,7 @@ public function request(string $method, string $url, array $options = []): Respo /** * {@inheritdoc} */ - public function stream($responses, float $timeout = null): ResponseStreamInterface + public function stream($responses, ?float $timeout = null): ResponseStreamInterface { if ($responses instanceof AbstractTraceableResponse) { $responses = [$responses]; diff --git a/src/Tracing/HttpClient/TraceableResponseForV6.php b/src/Tracing/HttpClient/TraceableResponseForV6.php index 43dbbbf2..64cc7f28 100644 --- a/src/Tracing/HttpClient/TraceableResponseForV6.php +++ b/src/Tracing/HttpClient/TraceableResponseForV6.php @@ -14,7 +14,7 @@ final class TraceableResponseForV6 extends AbstractTraceableResponse implements /** * {@inheritdoc} */ - public function getInfo(string $type = null): mixed + public function getInfo(?string $type = null): mixed { return $this->response->getInfo($type); } diff --git a/src/Twig/SentryExtension.php b/src/Twig/SentryExtension.php index d6a93984..56fd71b7 100644 --- a/src/Twig/SentryExtension.php +++ b/src/Twig/SentryExtension.php @@ -17,7 +17,7 @@ final class SentryExtension extends AbstractExtension /** * @param HubInterface $hub The current hub */ - public function __construct(HubInterface $hub = null) + public function __construct(?HubInterface $hub = null) { } From a6b680ebec0972e76bc94e297bab5c145df491f4 Mon Sep 17 00:00:00 2001 From: Michi Hoffmann Date: Tue, 19 Nov 2024 21:48:27 +0100 Subject: [PATCH 35/57] Run tests against PHP 8.4 (#893) --- .github/workflows/static-analysis.yaml | 2 +- .github/workflows/tests.yaml | 16 +++++++++------- composer.json | 4 ++-- .../HttpClient/TraceableResponseForV5.php | 2 +- .../Fixtures/php/error_types.php | 3 ++- .../Fixtures/xml/error_types.xml | 2 +- .../Fixtures/yml/error_types.yml | 2 +- .../DependencyInjection/SentryExtensionTest.php | 3 ++- .../End2End/App/Controller/TracingController.php | 2 +- 9 files changed, 20 insertions(+), 16 deletions(-) diff --git a/.github/workflows/static-analysis.yaml b/.github/workflows/static-analysis.yaml index 1a1a1e8c..91c0cee4 100644 --- a/.github/workflows/static-analysis.yaml +++ b/.github/workflows/static-analysis.yaml @@ -22,7 +22,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.2' + php-version: '8.3' - name: Install dependencies uses: ramsey/composer-install@v3 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 063c70f6..d7c302a8 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -1,11 +1,10 @@ -name: Continuous Integration +name: CI on: - pull_request: null + pull_request: push: branches: - master - - develop - release/** permissions: @@ -28,6 +27,7 @@ jobs: - '8.1' - '8.2' - '8.3' + - '8.4' symfony-version: - 4.4.* - 5.* @@ -52,6 +52,8 @@ jobs: symfony-version: 7.* - php: '8.1' symfony-version: 7.* + - php: '8.4' + symfony-version: 4.4.* include: - php: '7.2' symfony-version: 4.4.* @@ -82,9 +84,9 @@ jobs: - name: Setup Problem Matchers for PHPUnit run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" - - name: Update PHPUnit - run: composer require --dev phpunit/phpunit ^9.3.9 --no-update - if: matrix.php == '8.0' && matrix.dependencies == 'lowest' + # These dependencies are not used running the tests but can cause deprecation warnings so we remove them before running the tests + - name: Remove unused dependencies + run: composer remove vimeo/psalm phpstan/phpstan friendsofphp/php-cs-fixer --dev --no-interaction --no-update - name: Install dependencies uses: ramsey/composer-install@v3 @@ -118,7 +120,7 @@ jobs: - php: '8.0' dependencies: lowest symfony-version: 4.4.* - - php: '8.3' + - php: '8.4' dependencies: highest steps: diff --git a/composer.json b/composer.json index ea971f23..b591b465 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "php": "^7.2||^8.0", "guzzlehttp/psr7": "^2.1.1", "jean85/pretty-package-versions": "^1.5||^2.0", - "sentry/sentry": "^4.9.0", + "sentry/sentry": "^4.10.0", "symfony/cache-contracts": "^1.1||^2.4||^3.0", "symfony/config": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/console": "^4.4.20||^5.0.11||^6.0||^7.0", @@ -36,7 +36,7 @@ "phpstan/phpstan": "1.12.5", "phpstan/phpstan-phpunit": "1.4.0", "phpstan/phpstan-symfony": "1.4.10", - "phpunit/phpunit": "^8.5.14||^9.3.9", + "phpunit/phpunit": "^8.5.40||^9.6.21", "symfony/browser-kit": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/cache": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/dom-crawler": "^4.4.20||^5.0.11||^6.0||^7.0", diff --git a/src/Tracing/HttpClient/TraceableResponseForV5.php b/src/Tracing/HttpClient/TraceableResponseForV5.php index 0ca572a2..c079fe4f 100644 --- a/src/Tracing/HttpClient/TraceableResponseForV5.php +++ b/src/Tracing/HttpClient/TraceableResponseForV5.php @@ -16,7 +16,7 @@ final class TraceableResponseForV5 extends AbstractTraceableResponse implements * * @return mixed */ - public function getInfo(string $type = null) + public function getInfo(?string $type = null) { return $this->response->getInfo($type); } diff --git a/tests/DependencyInjection/Fixtures/php/error_types.php b/tests/DependencyInjection/Fixtures/php/error_types.php index 9c8473e5..6d072037 100644 --- a/tests/DependencyInjection/Fixtures/php/error_types.php +++ b/tests/DependencyInjection/Fixtures/php/error_types.php @@ -7,6 +7,7 @@ /** @var ContainerBuilder $container */ $container->loadFromExtension('sentry', [ 'options' => [ - 'error_types' => \E_ALL & ~(\E_NOTICE | \E_STRICT | \E_DEPRECATED), + // 2048 is \E_STRICT which has been deprecated in PHP 8.4 so we should not reference it directly to prevent deprecation notices + 'error_types' => \E_ALL & ~(\E_NOTICE | 2048 | \E_DEPRECATED), ], ]); diff --git a/tests/DependencyInjection/Fixtures/xml/error_types.xml b/tests/DependencyInjection/Fixtures/xml/error_types.xml index c0c46ab9..4be73596 100644 --- a/tests/DependencyInjection/Fixtures/xml/error_types.xml +++ b/tests/DependencyInjection/Fixtures/xml/error_types.xml @@ -7,6 +7,6 @@ https://sentry.io/schema/dic/sentry-symfony https://sentry.io/schema/dic/sentry-symfony/sentry-1.0.xsd"> - + diff --git a/tests/DependencyInjection/Fixtures/yml/error_types.yml b/tests/DependencyInjection/Fixtures/yml/error_types.yml index 95149254..8c976cd2 100644 --- a/tests/DependencyInjection/Fixtures/yml/error_types.yml +++ b/tests/DependencyInjection/Fixtures/yml/error_types.yml @@ -1,3 +1,3 @@ sentry: options: - error_types: E_ALL & ~(E_NOTICE|E_STRICT|E_DEPRECATED) + error_types: E_ALL & ~(E_NOTICE|2048|E_DEPRECATED) diff --git a/tests/DependencyInjection/SentryExtensionTest.php b/tests/DependencyInjection/SentryExtensionTest.php index bf9aeff7..ae8921c8 100644 --- a/tests/DependencyInjection/SentryExtensionTest.php +++ b/tests/DependencyInjection/SentryExtensionTest.php @@ -288,7 +288,8 @@ public function testErrorTypesOptionIsParsedFromStringToIntegerValue(): void $container = $this->createContainerFromFixture('error_types'); $optionsDefinition = $container->getDefinition('sentry.client.options'); - $this->assertSame(\E_ALL & ~(\E_NOTICE | \E_STRICT | \E_DEPRECATED), $optionsDefinition->getArgument(0)['error_types']); + // 2048 is \E_STRICT which has been deprecated in PHP 8.4 so we should not reference it directly to prevent deprecation notices + $this->assertSame(\E_ALL & ~(\E_NOTICE | 2048 | \E_DEPRECATED), $optionsDefinition->getArgument(0)['error_types']); } /** diff --git a/tests/End2End/App/Controller/TracingController.php b/tests/End2End/App/Controller/TracingController.php index 37579ae4..fa86876a 100644 --- a/tests/End2End/App/Controller/TracingController.php +++ b/tests/End2End/App/Controller/TracingController.php @@ -21,7 +21,7 @@ class TracingController */ private $connection; - public function __construct(HubInterface $hub, Connection $connection = null) + public function __construct(HubInterface $hub, ?Connection $connection = null) { $this->hub = $hub; $this->connection = $connection; From 0949fc20321f23daf0a96beaa4bf46bc9d7f1727 Mon Sep 17 00:00:00 2001 From: Rodion Date: Wed, 20 Nov 2024 04:39:04 -0500 Subject: [PATCH 36/57] Set status for console command transactions (#891) Co-authored-by: Jeffrey Hung <17494876+Jeffreyhung@users.noreply.github.com> Co-authored-by: Michi Hoffmann --- src/EventListener/TracingConsoleListener.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/EventListener/TracingConsoleListener.php b/src/EventListener/TracingConsoleListener.php index 26beccf3..57c187a6 100644 --- a/src/EventListener/TracingConsoleListener.php +++ b/src/EventListener/TracingConsoleListener.php @@ -7,6 +7,7 @@ use Sentry\State\HubInterface; use Sentry\Tracing\Span; use Sentry\Tracing\SpanContext; +use Sentry\Tracing\SpanStatus; use Sentry\Tracing\Transaction; use Sentry\Tracing\TransactionContext; use Sentry\Tracing\TransactionSource; @@ -93,6 +94,7 @@ public function handleConsoleTerminateEvent(ConsoleTerminateEvent $event): void $span = $this->hub->getSpan(); if (null !== $span) { + $span->setStatus(0 === $event->getExitCode() ? SpanStatus::ok() : SpanStatus::internalError()); $span->finish(); } } From 5427bd31fc0754174bc67e4c6efbdfdf2d58d9e3 Mon Sep 17 00:00:00 2001 From: Michi Hoffmann Date: Wed, 20 Nov 2024 10:43:12 +0100 Subject: [PATCH 37/57] Prepare 5.1.0 (#895) --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66526c86..6a0fd9c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## 5.1.0 + +The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v5.1.0. + +### Features + +- The SDK was updated to support PHP 8.4 [(#893)](https://github.com/getsentry/sentry-symfony/pull/893) +- Set the status for CLI command transactions based on the exit code [(#891)](https://github.com/getsentry/sentry-symfony/pull/891) + +### Bug Fixes + +- Fix including request data on transactions [(#879)](https://github.com/getsentry/sentry-symfony/pull/879) + ## 5.0.1 The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v5.0.1. From d8eb611b79cde1016470585a96f47f47d5374a49 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Wed, 20 Nov 2024 09:43:49 +0000 Subject: [PATCH 38/57] release: 5.1.0 --- src/SentryBundle.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SentryBundle.php b/src/SentryBundle.php index 58ae744f..18a04292 100644 --- a/src/SentryBundle.php +++ b/src/SentryBundle.php @@ -16,7 +16,7 @@ final class SentryBundle extends Bundle { public const SDK_IDENTIFIER = 'sentry.php.symfony'; - public const SDK_VERSION = '5.0.1'; + public const SDK_VERSION = '5.1.0'; public function build(ContainerBuilder $container): void { From 9897bdb025ff0e855fb259fbb33acd2f24c32686 Mon Sep 17 00:00:00 2001 From: Alex Bouma Date: Wed, 11 Dec 2024 15:19:11 +0100 Subject: [PATCH 39/57] Allow `logger` to be a service reference (#899) --- phpstan-baseline.neon | 22 ++++++++++++++++++- src/DependencyInjection/SentryExtension.php | 4 ++++ .../DependencyInjection/Fixtures/php/full.php | 2 +- .../DependencyInjection/Fixtures/xml/full.xml | 2 +- .../DependencyInjection/Fixtures/yml/full.yml | 2 +- .../SentryExtensionTest.php | 3 ++- .../Fixtures/UserWithIdentifierStub.php | 11 +++++++++- 7 files changed, 40 insertions(+), 6 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index be7174a9..4313a41a 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -70,6 +70,11 @@ parameters: count: 2 path: src/DependencyInjection/SentryExtension.php + - + message: "#^Cannot access offset 'logger' on mixed\\.$#" + count: 1 + path: src/DependencyInjection/SentryExtension.php + - message: "#^Cannot access offset 'traces_sampler' on mixed\\.$#" count: 1 @@ -92,7 +97,7 @@ parameters: - message: "#^Parameter \\#1 \\$id of class Symfony\\\\Component\\\\DependencyInjection\\\\Reference constructor expects string, mixed given\\.$#" - count: 9 + count: 10 path: src/DependencyInjection/SentryExtension.php - @@ -165,6 +170,21 @@ parameters: count: 1 path: src/EventListener/LoginListener.php + - + message: "#^Instanceof between Throwable and Symfony\\\\Component\\\\Messenger\\\\Exception\\\\DelayedMessageHandlingException will always evaluate to false\\.$#" + count: 1 + path: src/EventListener/MessengerListener.php + + - + message: "#^Instanceof between Throwable and Symfony\\\\Component\\\\Messenger\\\\Exception\\\\HandlerFailedException will always evaluate to false\\.$#" + count: 1 + path: src/EventListener/MessengerListener.php + + - + message: "#^Result of && is always false\\.$#" + count: 2 + path: src/EventListener/MessengerListener.php + - message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpKernel\\\\Event\\\\KernelEvent\\:\\:isMasterRequest\\(\\)\\.$#" count: 1 diff --git a/src/DependencyInjection/SentryExtension.php b/src/DependencyInjection/SentryExtension.php index 78f1faa4..52675ded 100644 --- a/src/DependencyInjection/SentryExtension.php +++ b/src/DependencyInjection/SentryExtension.php @@ -94,6 +94,10 @@ private function registerConfiguration(ContainerBuilder $container, array $confi }); } + if (isset($options['logger'])) { + $options['logger'] = new Reference($options['logger']); + } + if (isset($options['traces_sampler'])) { $options['traces_sampler'] = new Reference($options['traces_sampler']); } diff --git a/tests/DependencyInjection/Fixtures/php/full.php b/tests/DependencyInjection/Fixtures/php/full.php index 0f30c967..aa11c22f 100644 --- a/tests/DependencyInjection/Fixtures/php/full.php +++ b/tests/DependencyInjection/Fixtures/php/full.php @@ -21,7 +21,7 @@ 'attach_metric_code_locations' => true, 'context_lines' => 0, 'environment' => 'development', - 'logger' => 'php', + 'logger' => Sentry\Logger\DebugStdOutLogger::class, 'spotlight' => true, 'spotlight_url' => 'http://localhost:8969', 'release' => '4.0.x-dev', diff --git a/tests/DependencyInjection/Fixtures/xml/full.xml b/tests/DependencyInjection/Fixtures/xml/full.xml index 88d01372..df951eb4 100644 --- a/tests/DependencyInjection/Fixtures/xml/full.xml +++ b/tests/DependencyInjection/Fixtures/xml/full.xml @@ -20,7 +20,7 @@ attach-metric-code-locations="true" context-lines="0" environment="development" - logger="php" + logger="Sentry\Logger\DebugStdOutLogger" spotlight="true" spotlight-url="http://localhost:8969" release="4.0.x-dev" diff --git a/tests/DependencyInjection/Fixtures/yml/full.yml b/tests/DependencyInjection/Fixtures/yml/full.yml index 8da66d50..8a42e682 100644 --- a/tests/DependencyInjection/Fixtures/yml/full.yml +++ b/tests/DependencyInjection/Fixtures/yml/full.yml @@ -16,7 +16,7 @@ sentry: attach_metric_code_locations: true context_lines: 0 environment: development - logger: php + logger: Sentry\Logger\DebugStdOutLogger spotlight: true spotlight_url: http://localhost:8969 release: 4.0.x-dev diff --git a/tests/DependencyInjection/SentryExtensionTest.php b/tests/DependencyInjection/SentryExtensionTest.php index ae8921c8..232f0887 100644 --- a/tests/DependencyInjection/SentryExtensionTest.php +++ b/tests/DependencyInjection/SentryExtensionTest.php @@ -9,6 +9,7 @@ use PHPUnit\Framework\TestCase; use Psr\Log\NullLogger; use Sentry\ClientInterface; +use Sentry\Logger\DebugStdOutLogger; use Sentry\Options; use Sentry\SentryBundle\DependencyInjection\SentryExtension; use Sentry\SentryBundle\EventListener\ConsoleListener; @@ -211,7 +212,7 @@ public function testClientIsCreatedFromOptions(): void 'attach_metric_code_locations' => true, 'context_lines' => 0, 'environment' => 'development', - 'logger' => 'php', + 'logger' => new Reference(DebugStdOutLogger::class), 'spotlight' => true, 'spotlight_url' => 'http://localhost:8969', 'release' => '4.0.x-dev', diff --git a/tests/EventListener/Fixtures/UserWithIdentifierStub.php b/tests/EventListener/Fixtures/UserWithIdentifierStub.php index 9b82b8ea..97eccde9 100644 --- a/tests/EventListener/Fixtures/UserWithIdentifierStub.php +++ b/tests/EventListener/Fixtures/UserWithIdentifierStub.php @@ -9,20 +9,29 @@ final class UserWithIdentifierStub implements UserInterface { /** - * @var string + * @var non-empty-string */ private $username; + /** + * @param non-empty-string $username + */ public function __construct(string $username = 'foo_user') { $this->username = $username; } + /** + * @return non-empty-string + */ public function getUserIdentifier(): string { return $this->getUsername(); } + /** + * @return non-empty-string + */ public function getUsername(): string { return $this->username; From 7d668f23dae7fbefff0db6b39b581fd52add6487 Mon Sep 17 00:00:00 2001 From: Stephanie Anderson Date: Wed, 11 Dec 2024 15:20:25 +0100 Subject: [PATCH 40/57] chore(meta): update issue templates to use issue types (#901) Co-authored-by: Michi Hoffmann --- .../{feature.yml => 01-feature.yml} | 4 +-- .github/ISSUE_TEMPLATE/02-improvement.yml | 30 +++++++++++++++++++ .../ISSUE_TEMPLATE/{bug.yml => 03-bug.yml} | 1 + 3 files changed, 33 insertions(+), 2 deletions(-) rename .github/ISSUE_TEMPLATE/{feature.yml => 01-feature.yml} (92%) create mode 100644 .github/ISSUE_TEMPLATE/02-improvement.yml rename .github/ISSUE_TEMPLATE/{bug.yml => 03-bug.yml} (99%) diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/01-feature.yml similarity index 92% rename from .github/ISSUE_TEMPLATE/feature.yml rename to .github/ISSUE_TEMPLATE/01-feature.yml index 9f331d37..164acf1b 100644 --- a/.github/ISSUE_TEMPLATE/feature.yml +++ b/.github/ISSUE_TEMPLATE/01-feature.yml @@ -1,6 +1,6 @@ name: πŸ’‘ Feature Request -description: Create a feature request for this SDK. -labels: 'enhancement' +description: Propose new functionality for the SDK +type: Feature body: - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/02-improvement.yml b/.github/ISSUE_TEMPLATE/02-improvement.yml new file mode 100644 index 00000000..ae828cd7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/02-improvement.yml @@ -0,0 +1,30 @@ +name: πŸ’‘ Improvement +description: Propose an improvement for existing functionality of the SDK +type: Improvement +body: + - type: markdown + attributes: + value: Thanks for taking the time to file a request! Please fill out this form as completely as possible. + - type: textarea + id: problem + attributes: + label: Problem Statement + description: A clear and concise description of what you want and what your use case is. + placeholder: |- + I want to make whirled peas, but Sentry doesn't blend. + validations: + required: true + - type: textarea + id: expected + attributes: + label: Solution Brainstorm + description: We know you have bright ideas to share ... share away, friend. + placeholder: |- + Add a blender to Sentry. + validations: + required: true + - type: markdown + attributes: + value: |- + ## Thanks πŸ™ + Check our [triage docs](https://open.sentry.io/triage/) for what to expect next. diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/03-bug.yml similarity index 99% rename from .github/ISSUE_TEMPLATE/bug.yml rename to .github/ISSUE_TEMPLATE/03-bug.yml index 7d62230e..528f3942 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/03-bug.yml @@ -1,5 +1,6 @@ name: 🐞 Bug Report description: Tell us about something that's not working the way we (probably) intend. +type: Bug body: - type: dropdown id: type From 0f16c5f31c1fd68920ea25c2562656953faa2c53 Mon Sep 17 00:00:00 2001 From: Stephanie Anderson Date: Wed, 11 Dec 2024 15:22:24 +0100 Subject: [PATCH 41/57] chore(meta): add contributor list to README (#902) Co-authored-by: Michi Hoffmann --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3def7600..87b0db9e 100644 --- a/README.md +++ b/README.md @@ -51,12 +51,16 @@ try { } ``` -## Symfony Version Compatibility - ## Contributing to the SDK Please refer to [CONTRIBUTING.md](CONTRIBUTING.md). +### Thanks to all the people who contributed so far! + + + + + ## Getting help/support If you need help setting up or configuring the Symfony SDK (or anything else in the Sentry universe) please head over to the [Sentry Community on Discord](https://discord.com/invite/Ww9hbqr). There is a ton of great people in our Discord community ready to help you! @@ -76,3 +80,4 @@ Licensed under the MIT license, see [`LICENSE`](LICENSE) [Packagist link]: https://packagist.org/packages/sentry/sentry-symfony [Master Code Coverage]: https://codecov.io/gh/getsentry/sentry-symfony/branch/master [Master Code Coverage Image]: https://img.shields.io/codecov/c/github/getsentry/sentry-symfony/master?logo=codecov + From 84c57fbed5c3eec00783638b6150418aacfcf62b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Dec 2024 14:24:13 +0000 Subject: [PATCH 42/57] Bump codecov/codecov-action from 4 to 5 (#898) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/tests.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index d7c302a8..8c3dabe9 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -98,7 +98,7 @@ jobs: run: vendor/bin/phpunit --coverage-clover=build/coverage-report.xml - name: Upload code coverage - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 with: file: build/coverage-report.xml token: ${{ secrets.CODECOV_TOKEN }} @@ -150,7 +150,7 @@ jobs: run: vendor/bin/phpunit --coverage-clover=build/coverage-report.xml - name: Upload code coverage - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 with: file: build/coverage-report.xml token: ${{ secrets.CODECOV_TOKEN }} From a63b6b7c58a94364fd0ef06cd209fe3ca3f83210 Mon Sep 17 00:00:00 2001 From: Jeffrey Hung <17494876+Jeffreyhung@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:21:46 -0800 Subject: [PATCH 43/57] feat(release): Replace release bot with GH app (#903) --- .github/workflows/publish-release.yaml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-release.yaml b/.github/workflows/publish-release.yaml index 9e7ab3d2..b18520b6 100644 --- a/.github/workflows/publish-release.yaml +++ b/.github/workflows/publish-release.yaml @@ -18,16 +18,23 @@ jobs: runs-on: ubuntu-latest name: Release version steps: + - name: Get auth token + id: token + uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + with: + app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }} + private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }} + - name: Checkout uses: actions/checkout@v4 with: - token: ${{ secrets.GH_RELEASE_PAT }} + token: ${{ steps.token.outputs.token }} fetch-depth: 0 - name: Prepare release uses: getsentry/action-prepare-release@v1 env: - GITHUB_TOKEN: ${{ secrets.GH_RELEASE_PAT }} + GITHUB_TOKEN: ${{ steps.token.outputs.token }} with: version: ${{ github.event.inputs.version }} force: ${{ github.event.inputs.force }} From 2f19c19dad002d5aa5025b9265dcf4f505909ec8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Jan 2025 10:21:49 +0100 Subject: [PATCH 44/57] Bump actions/create-github-app-token from 1.11.0 to 1.11.1 (#904) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish-release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-release.yaml b/.github/workflows/publish-release.yaml index b18520b6..ccaaa074 100644 --- a/.github/workflows/publish-release.yaml +++ b/.github/workflows/publish-release.yaml @@ -20,7 +20,7 @@ jobs: steps: - name: Get auth token id: token - uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1 with: app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }} private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }} From a31db71ddda32346e4080dd696392bcf81387e6f Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 2 Feb 2025 18:15:03 -0600 Subject: [PATCH 45/57] =?UTF-8?q?#910=20-=20Don=E2=80=99t=20try=20to=20get?= =?UTF-8?q?=20session=20when=20it=E2=80=99s=20stateless=20(#911)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michi Hoffmann --- src/EventListener/LoginListener.php | 6 +++++- tests/EventListener/LoginListenerTest.php | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/EventListener/LoginListener.php b/src/EventListener/LoginListener.php index 2a766cc7..ef663efb 100644 --- a/src/EventListener/LoginListener.php +++ b/src/EventListener/LoginListener.php @@ -47,7 +47,11 @@ public function __construct(HubInterface $hub, ?TokenStorageInterface $tokenStor */ public function handleKernelRequestEvent(RequestEvent $event): void { - if (null === $this->tokenStorage || !$this->isMainRequest($event)) { + if ( + null === $this->tokenStorage + || !$this->isMainRequest($event) + || $event->getRequest()->attributes->get('_stateless') + ) { return; } diff --git a/tests/EventListener/LoginListenerTest.php b/tests/EventListener/LoginListenerTest.php index 34c37e3d..da037bef 100644 --- a/tests/EventListener/LoginListenerTest.php +++ b/tests/EventListener/LoginListenerTest.php @@ -298,6 +298,18 @@ public function __toString(): string } } + public function testHandleKernelRequestEventDoesNothingIfRequestIsForStatelessRoute(): void + { + $this->tokenStorage->expects($this->never()) + ->method('getToken'); + + $this->listener->handleKernelRequestEvent(new RequestEvent( + $this->createMock(HttpKernelInterface::class), + new Request([], [], ['_stateless' => true]), + HttpKernelInterface::SUB_REQUEST + )); + } + public function testHandleKernelRequestEventDoesNothingIfRequestIsNotMain(): void { $this->tokenStorage->expects($this->never()) From fd43dd9546a82e8605ccaac6ec1eae3ce9cd48f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 01:15:30 +0100 Subject: [PATCH 46/57] Bump actions/create-github-app-token from 1.11.1 to 1.11.2 (#909) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish-release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-release.yaml b/.github/workflows/publish-release.yaml index ccaaa074..8d81ba44 100644 --- a/.github/workflows/publish-release.yaml +++ b/.github/workflows/publish-release.yaml @@ -20,7 +20,7 @@ jobs: steps: - name: Get auth token id: token - uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1 + uses: actions/create-github-app-token@136412a57a7081aa63c935a2cc2918f76c34f514 # v1.11.2 with: app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }} private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }} From 475a95868094d9a443bfcb3b617ba9ba76ab846c Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Thu, 27 Feb 2025 15:00:20 +0100 Subject: [PATCH 47/57] Allow to install the bundle without Symfony security (#912) --- composer.json | 6 +++--- .../Compiler/AddLoginListenerTagPass.php | 10 +++++++++- src/DependencyInjection/SentryExtension.php | 6 ++++++ src/Resources/config/services.xml | 1 - .../Compiler/AddLoginListenerTagPassTest.php | 16 ++++++++++++++++ .../DependencyInjection/SentryExtensionTest.php | 7 +++++++ 6 files changed, 41 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index b591b465..4dbee1b8 100644 --- a/composer.json +++ b/composer.json @@ -23,9 +23,7 @@ "symfony/event-dispatcher": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/http-kernel": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/polyfill-php80": "^1.22", - "symfony/psr-http-message-bridge": "^1.2||^2.0||^6.4||^7.0", - "symfony/security-core": "^4.4.20||^5.0.11||^6.0||^7.0", - "symfony/security-http": "^4.4.20||^5.0.11||^6.0||^7.0" + "symfony/psr-http-message-bridge": "^1.2||^2.0||^6.4||^7.0" }, "require-dev": { "doctrine/dbal": "^2.13||^3.3||^4.0", @@ -46,6 +44,8 @@ "symfony/monolog-bundle": "^3.4", "symfony/phpunit-bridge": "^5.2.6||^6.0||^7.0", "symfony/process": "^4.4.20||^5.0.11||^6.0||^7.0", + "symfony/security-core": "^4.4.20||^5.0.11||^6.0||^7.0", + "symfony/security-http": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/twig-bundle": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/yaml": "^4.4.20||^5.0.11||^6.0||^7.0", "vimeo/psalm": "^4.3||^5.16.0" diff --git a/src/DependencyInjection/Compiler/AddLoginListenerTagPass.php b/src/DependencyInjection/Compiler/AddLoginListenerTagPass.php index 24d3110c..5f935cb6 100644 --- a/src/DependencyInjection/Compiler/AddLoginListenerTagPass.php +++ b/src/DependencyInjection/Compiler/AddLoginListenerTagPass.php @@ -17,9 +17,17 @@ final class AddLoginListenerTagPass implements CompilerPassInterface */ public function process(ContainerBuilder $container): void { + if (!$container->hasDefinition(LoginListener::class)) { + return; + } $listenerDefinition = $container->getDefinition(LoginListener::class); - if (!class_exists(LoginSuccessEvent::class)) { + if (class_exists(LoginSuccessEvent::class)) { + $listenerDefinition->addTag('kernel.event_listener', [ + 'event' => LoginSuccessEvent::class, + 'method' => 'handleLoginSuccessEvent', + ]); + } elseif (class_exists(AuthenticationSuccessEvent::class)) { $listenerDefinition->addTag('kernel.event_listener', [ 'event' => AuthenticationSuccessEvent::class, 'method' => 'handleAuthenticationSuccessEvent', diff --git a/src/DependencyInjection/SentryExtension.php b/src/DependencyInjection/SentryExtension.php index 52675ded..a05a62e8 100644 --- a/src/DependencyInjection/SentryExtension.php +++ b/src/DependencyInjection/SentryExtension.php @@ -15,6 +15,7 @@ use Sentry\Options; use Sentry\SentryBundle\EventListener\ConsoleListener; use Sentry\SentryBundle\EventListener\ErrorListener; +use Sentry\SentryBundle\EventListener\LoginListener; use Sentry\SentryBundle\EventListener\MessengerListener; use Sentry\SentryBundle\EventListener\TracingConsoleListener; use Sentry\SentryBundle\EventListener\TracingRequestListener; @@ -34,6 +35,7 @@ use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; final class SentryExtension extends ConfigurableExtension { @@ -75,6 +77,10 @@ protected function loadInternal(array $mergedConfig, ContainerBuilder $container $this->registerTwigTracingConfiguration($container, $mergedConfig['tracing']); $this->registerCacheTracingConfiguration($container, $mergedConfig['tracing']); $this->registerHttpClientTracingConfiguration($container, $mergedConfig['tracing']); + + if (!interface_exists(TokenStorageInterface::class)) { + $container->removeDefinition(LoginListener::class); + } } /** diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 02ad8994..ff0407e0 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -83,7 +83,6 @@ - diff --git a/tests/DependencyInjection/Compiler/AddLoginListenerTagPassTest.php b/tests/DependencyInjection/Compiler/AddLoginListenerTagPassTest.php index cc91f8f7..6fb3248b 100644 --- a/tests/DependencyInjection/Compiler/AddLoginListenerTagPassTest.php +++ b/tests/DependencyInjection/Compiler/AddLoginListenerTagPassTest.php @@ -28,4 +28,20 @@ public function testProcess(): void $this->assertSame([['event' => AuthenticationSuccessEvent::class, 'method' => 'handleAuthenticationSuccessEvent']], $listenerDefinition->getTag('kernel.event_listener')); } + + public function testProcessLoginSuccess(): void + { + if (!class_exists(LoginSuccessEvent::class)) { + $this->markTestSkipped('Skipping this test because LoginSuccessEvent does not exist.'); + } + + $container = new ContainerBuilder(); + $container->register(LoginListener::class)->setPublic(true); + $container->addCompilerPass(new AddLoginListenerTagPass()); + $container->compile(); + + $listenerDefinition = $container->getDefinition(LoginListener::class); + + $this->assertSame([['event' => LoginSuccessEvent::class, 'method' => 'handleLoginSuccessEvent']], $listenerDefinition->getTag('kernel.event_listener')); + } } diff --git a/tests/DependencyInjection/SentryExtensionTest.php b/tests/DependencyInjection/SentryExtensionTest.php index 232f0887..db949243 100644 --- a/tests/DependencyInjection/SentryExtensionTest.php +++ b/tests/DependencyInjection/SentryExtensionTest.php @@ -14,6 +14,7 @@ use Sentry\SentryBundle\DependencyInjection\SentryExtension; use Sentry\SentryBundle\EventListener\ConsoleListener; use Sentry\SentryBundle\EventListener\ErrorListener; +use Sentry\SentryBundle\EventListener\LoginListener; use Sentry\SentryBundle\EventListener\MessengerListener; use Sentry\SentryBundle\EventListener\RequestListener; use Sentry\SentryBundle\EventListener\SubRequestListener; @@ -418,6 +419,12 @@ public function testLoggerOptionFallbackToNullLoggerIfNotSet(): void $this->assertDefinitionMethodCallAt($methodCalls[3], 'setLogger', [new Reference(NullLogger::class, ContainerBuilder::IGNORE_ON_INVALID_REFERENCE)]); } + public function testLoginListener(): void + { + $container = $this->createContainerFromFixture('full'); + $this->assertTrue($container->hasDefinition(LoginListener::class)); + } + /** * @dataProvider releaseOptionDataProvider */ From 5ad3a656147c398706ad47f7b159feacae2cc7be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 08:19:37 +0100 Subject: [PATCH 48/57] Bump actions/create-github-app-token from 1.11.2 to 1.11.5 (#914) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish-release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-release.yaml b/.github/workflows/publish-release.yaml index 8d81ba44..a1be1e49 100644 --- a/.github/workflows/publish-release.yaml +++ b/.github/workflows/publish-release.yaml @@ -20,7 +20,7 @@ jobs: steps: - name: Get auth token id: token - uses: actions/create-github-app-token@136412a57a7081aa63c935a2cc2918f76c34f514 # v1.11.2 + uses: actions/create-github-app-token@0d564482f06ca65fa9e77e2510873638c82206f2 # v1.11.5 with: app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }} private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }} From e5b42bb7ea420ac122aff91ea03def6225588b5f Mon Sep 17 00:00:00 2001 From: Michi Hoffmann Date: Mon, 3 Mar 2025 08:46:42 +0100 Subject: [PATCH 49/57] Prepare 5.2.0 (#913) Co-authored-by: Mathieu Santostefano --- CHANGELOG.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a0fd9c7..db5b004b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,34 @@ +# CHANGELOG + +## 5.2.0 + +The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v5.2.0. + +### Features + +- Allow to configure the logger via the `sentry.yaml` configuration file [(#899)](https://github.com/getsentry/sentry-symfony/pull/899) + + ```yaml + sentry: + dsn: "%env(SENTRY_DSN)%" + options: + logger: "sentry.logger" + + services: + sentry.logger: + class: 'Sentry\Logger\DebugFileLogger' + arguments: + $filePath: '../../var/log/sentry.log' + ``` + +### Bug Fixes + +- Fixed updating the user context when a route is marked as stateless [(#910)](https://github.com/getsentry/sentry-symfony/pull/910) + +### Misc + +- Remove `symfony/security-core` and `symfony/security-http` as dependencies [(#912)](https://github.com/getsentry/sentry-symfony/pull/912) + ## 5.1.0 The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v5.1.0. From 394576244d8ac03fd2f305b82d23a6fd7a083b45 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Mon, 3 Mar 2025 07:47:12 +0000 Subject: [PATCH 50/57] release: 5.2.0 --- src/SentryBundle.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SentryBundle.php b/src/SentryBundle.php index 18a04292..596b5b94 100644 --- a/src/SentryBundle.php +++ b/src/SentryBundle.php @@ -16,7 +16,7 @@ final class SentryBundle extends Bundle { public const SDK_IDENTIFIER = 'sentry.php.symfony'; - public const SDK_VERSION = '5.1.0'; + public const SDK_VERSION = '5.2.0'; public function build(ContainerBuilder $container): void { From 2891197b39d6ed09ca51e6ca5649534354aac0f2 Mon Sep 17 00:00:00 2001 From: Alex Bouma Date: Mon, 5 May 2025 17:38:56 +0200 Subject: [PATCH 51/57] Fix tests (#920) --- composer.json | 2 +- .../TracingConsoleListenerTest.php | 5 +++++ .../TracingRequestListenerTest.php | 17 +++++++++++++++++ .../HttpClient/TraceableHttpClientTest.php | 12 ++++++------ tests/Twig/SentryExtensionTest.php | 4 ++-- 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index 4dbee1b8..580a952c 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "php": "^7.2||^8.0", "guzzlehttp/psr7": "^2.1.1", "jean85/pretty-package-versions": "^1.5||^2.0", - "sentry/sentry": "^4.10.0", + "sentry/sentry": "^4.11.0", "symfony/cache-contracts": "^1.1||^2.4||^3.0", "symfony/config": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/console": "^4.4.20||^5.0.11||^6.0||^7.0", diff --git a/tests/EventListener/TracingConsoleListenerTest.php b/tests/EventListener/TracingConsoleListenerTest.php index fe87b34e..b619dfe7 100644 --- a/tests/EventListener/TracingConsoleListenerTest.php +++ b/tests/EventListener/TracingConsoleListenerTest.php @@ -44,6 +44,9 @@ public function testHandleConsoleCommandEventStartsTransactionIfNoSpanIsSetOnHub $this->hub->expects($this->once()) ->method('startTransaction') ->with($this->callback(function (TransactionContext $context) use ($expectedTransactionContext): bool { + // This value is random when the metadata is constructed, thus we set it to a fixed expected value since we don't care for the value here + $context->getMetadata()->setSampleRand(0.1337); + $this->assertEquals($expectedTransactionContext, $context); return true; @@ -73,6 +76,7 @@ public function handleConsoleCommandEventStartsTransactionIfNoSpanIsSetOnHubData $transactionContext->setName(''); $transactionContext->setOrigin('auto.console'); $transactionContext->setSource(TransactionSource::task()); + $transactionContext->getMetadata()->setSampleRand(0.1337); yield [ new Command(), @@ -84,6 +88,7 @@ public function handleConsoleCommandEventStartsTransactionIfNoSpanIsSetOnHubData $transactionContext->setName('app:command'); $transactionContext->setOrigin('auto.console'); $transactionContext->setSource(TransactionSource::task()); + $transactionContext->getMetadata()->setSampleRand(0.1337); yield [ new Command('app:command'), diff --git a/tests/EventListener/TracingRequestListenerTest.php b/tests/EventListener/TracingRequestListenerTest.php index 4430466f..1c0c3193 100644 --- a/tests/EventListener/TracingRequestListenerTest.php +++ b/tests/EventListener/TracingRequestListenerTest.php @@ -65,6 +65,9 @@ public function testHandleKernelRequestEvent(Options $options, Request $request, $this->hub->expects($this->once()) ->method('startTransaction') ->with($this->callback(function (TransactionContext $context) use ($expectedTransactionContext): bool { + // This value is random when the metadata is constructed, thus we set it to a fixed expected value since we don't care for the value here + $context->getMetadata()->setSampleRand(0.1337); + $this->assertEquals($expectedTransactionContext, $context); return true; @@ -108,6 +111,7 @@ public function handleKernelRequestEventDataProvider(): \Generator 'net.host.name' => 'www.example.com', ]); $transactionContext->getMetadata()->setDynamicSamplingContext($samplingContext); + $transactionContext->getMetadata()->setSampleRand(0.1337); yield 'request.headers.sentry-trace EXISTS' => [ new Options(), @@ -146,6 +150,7 @@ public function handleKernelRequestEventDataProvider(): \Generator 'net.host.name' => 'www.example.com', ]); $transactionContext->getMetadata()->setDynamicSamplingContext($samplingContext); + $transactionContext->getMetadata()->setSampleRand(0.1337); yield 'request.headers.traceparent EXISTS' => [ new Options(), @@ -184,6 +189,8 @@ public function handleKernelRequestEventDataProvider(): \Generator 'net.host.name' => 'www.example.com', ]); $transactionContext->getMetadata()->setDynamicSamplingContext($samplingContext); + $transactionContext->getMetadata()->setParentSamplingRate(1.0); + $transactionContext->getMetadata()->setSampleRand(0.1337); yield 'request.headers.sentry-trace and headers.baggage EXISTS' => [ new Options(), @@ -216,6 +223,7 @@ public function handleKernelRequestEventDataProvider(): \Generator 'route' => '', 'net.host.name' => 'www.example.com', ]); + $transactionContext->getMetadata()->setSampleRand(0.1337); $request = Request::create('http://www.example.com'); $request->server->remove('REQUEST_TIME_FLOAT'); @@ -240,6 +248,7 @@ public function handleKernelRequestEventDataProvider(): \Generator 'route' => '', 'net.host.ip' => '127.0.0.1', ]); + $transactionContext->getMetadata()->setSampleRand(0.1337); yield 'request.server.HOST IS IPV4' => [ new Options(), @@ -272,6 +281,7 @@ public function handleKernelRequestEventDataProvider(): \Generator 'route' => 'app_homepage', 'net.host.name' => 'www.example.com', ]); + $transactionContext->getMetadata()->setSampleRand(0.1337); yield 'request.attributes.route IS STRING' => [ new Options(), @@ -297,6 +307,7 @@ public function handleKernelRequestEventDataProvider(): \Generator 'route' => '/path', 'net.host.name' => 'www.example.com', ]); + $transactionContext->getMetadata()->setSampleRand(0.1337); yield 'request.attributes.route IS INSTANCEOF Symfony\Component\Routing\Route' => [ new Options(), @@ -322,6 +333,7 @@ public function handleKernelRequestEventDataProvider(): \Generator 'route' => 'App\\Controller::indexAction', 'net.host.name' => 'www.example.com', ]); + $transactionContext->getMetadata()->setSampleRand(0.1337); yield 'request.attributes._controller IS STRING' => [ new Options(), @@ -347,6 +359,7 @@ public function handleKernelRequestEventDataProvider(): \Generator 'route' => 'App\\Controller::indexAction', 'net.host.name' => 'www.example.com', ]); + $transactionContext->getMetadata()->setSampleRand(0.1337); yield 'request.attributes._controller IS CALLABLE (1)' => [ new Options(), @@ -372,6 +385,7 @@ public function handleKernelRequestEventDataProvider(): \Generator 'route' => 'class@anonymous::indexAction', 'net.host.name' => 'www.example.com', ]); + $transactionContext->getMetadata()->setSampleRand(0.1337); yield 'request.attributes._controller IS CALLABLE (2)' => [ new Options(), @@ -397,6 +411,7 @@ public function handleKernelRequestEventDataProvider(): \Generator 'route' => '', 'net.host.name' => 'www.example.com', ]); + $transactionContext->getMetadata()->setSampleRand(0.1337); yield 'request.attributes._controller IS ARRAY and NOT VALID CALLABLE' => [ new Options(), @@ -423,6 +438,7 @@ public function handleKernelRequestEventDataProvider(): \Generator 'net.host.name' => 'www.example.com', 'net.peer.ip' => '127.0.0.1', ]); + $transactionContext->getMetadata()->setSampleRand(0.1337); yield 'request.server.REMOTE_ADDR EXISTS and client.options.send_default_pii = TRUE' => [ new Options(['send_default_pii' => true]), @@ -446,6 +462,7 @@ public function handleKernelRequestEventDataProvider(): \Generator 'route' => '', 'net.host.name' => '', ]); + $transactionContext->getMetadata()->setSampleRand(0.1337); yield 'request.server.SERVER_PROTOCOL NOT EXISTS' => [ new Options(), diff --git a/tests/Tracing/HttpClient/TraceableHttpClientTest.php b/tests/Tracing/HttpClient/TraceableHttpClientTest.php index 31147116..4306378e 100644 --- a/tests/Tracing/HttpClient/TraceableHttpClientTest.php +++ b/tests/Tracing/HttpClient/TraceableHttpClientTest.php @@ -92,9 +92,9 @@ public function testRequest(): void $this->assertSame(200, $response->getStatusCode()); $this->assertSame('GET', $response->getInfo('http_method')); $this->assertSame('https://username:password@www.example.com/test-page?foo=bar#baz', $response->getInfo('url')); - $this->assertSame(['sentry-trace: ' . $spans[1]->toTraceparent()], $mockResponse->getRequestOptions()['normalized_headers']['sentry-trace']); - $this->assertSame(['traceparent: ' . $spans[1]->toW3CTraceparent()], $mockResponse->getRequestOptions()['normalized_headers']['traceparent']); - $this->assertSame(['baggage: ' . $transaction->toBaggage()], $mockResponse->getRequestOptions()['normalized_headers']['baggage']); + $this->assertSame([\sprintf('sentry-trace: %s', $spans[1]->toTraceparent())], $mockResponse->getRequestOptions()['normalized_headers']['sentry-trace']); + $this->assertSame([\sprintf('traceparent: %s', $spans[1]->toW3CTraceparent())], $mockResponse->getRequestOptions()['normalized_headers']['traceparent']); + $this->assertSame([\sprintf('baggage: %s', $transaction->toBaggage())], $mockResponse->getRequestOptions()['normalized_headers']['baggage']); $this->assertNotNull($transaction->getSpanRecorder()); $spans = $transaction->getSpanRecorder()->getSpans(); @@ -199,9 +199,9 @@ public function testRequestDoesContainsTracingHeadersWithoutTransaction(): void $this->assertSame(200, $response->getStatusCode()); $this->assertSame('POST', $response->getInfo('http_method')); $this->assertSame('https://www.example.com/test-page', $response->getInfo('url')); - $this->assertSame(['sentry-trace: 566e3688a61d4bc888951642d6f14a19-566e3688a61d4bc8'], $mockResponse->getRequestOptions()['normalized_headers']['sentry-trace']); - $this->assertSame(['traceparent: 00-566e3688a61d4bc888951642d6f14a19-566e3688a61d4bc8-00'], $mockResponse->getRequestOptions()['normalized_headers']['traceparent']); - $this->assertSame(['baggage: sentry-trace_id=566e3688a61d4bc888951642d6f14a19,sentry-public_key=public,sentry-release=1.0.0,sentry-environment=test'], $mockResponse->getRequestOptions()['normalized_headers']['baggage']); + $this->assertSame([\sprintf('sentry-trace: %s', $propagationContext->toTraceparent())], $mockResponse->getRequestOptions()['normalized_headers']['sentry-trace']); + $this->assertSame([\sprintf('traceparent: %s', $propagationContext->toW3CTraceparent())], $mockResponse->getRequestOptions()['normalized_headers']['traceparent']); + $this->assertSame([\sprintf('baggage: %s', $propagationContext->toBaggage())], $mockResponse->getRequestOptions()['normalized_headers']['baggage']); } public function testRequestSetsUnknownErrorAsSpanStatusIfResponseStatusCodeIsUnavailable(): void diff --git a/tests/Twig/SentryExtensionTest.php b/tests/Twig/SentryExtensionTest.php index 861ca14c..5cbfd25b 100644 --- a/tests/Twig/SentryExtensionTest.php +++ b/tests/Twig/SentryExtensionTest.php @@ -138,7 +138,7 @@ public function testBaggageMetaFunctionWithNoActiveSpan(): void SentrySdk::setCurrentHub($hub); - $this->assertSame('', $environment->render('foo.twig')); + $this->assertSame(\sprintf('', $propagationContext->toBaggage()), $environment->render('foo.twig')); } public function testBaggageMetaFunctionWithActiveSpan(): void @@ -164,7 +164,7 @@ public function testBaggageMetaFunctionWithActiveSpan(): void $hub->setSpan($transaction); - $this->assertSame('', $environment->render('foo.twig')); + $this->assertSame(\sprintf('', $transaction->toBaggage()), $environment->render('foo.twig')); } private static function isTwigBundlePackageInstalled(): bool From 58bbad0c288651789154cf82d3011951a4790a3c Mon Sep 17 00:00:00 2001 From: Stephanie Anderson Date: Mon, 5 May 2025 17:43:15 +0200 Subject: [PATCH 52/57] Update GH issue templates for Linear compatibility (#917) Co-authored-by: Michi Hoffmann --- .github/ISSUE_TEMPLATE/01-feature.yml | 2 +- .github/ISSUE_TEMPLATE/02-improvement.yml | 2 +- .github/ISSUE_TEMPLATE/03-bug.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/01-feature.yml b/.github/ISSUE_TEMPLATE/01-feature.yml index 164acf1b..a7aab2fd 100644 --- a/.github/ISSUE_TEMPLATE/01-feature.yml +++ b/.github/ISSUE_TEMPLATE/01-feature.yml @@ -1,6 +1,6 @@ name: πŸ’‘ Feature Request description: Propose new functionality for the SDK -type: Feature +labels: ["Symfony", "Feature"] body: - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/02-improvement.yml b/.github/ISSUE_TEMPLATE/02-improvement.yml index ae828cd7..ab64fdca 100644 --- a/.github/ISSUE_TEMPLATE/02-improvement.yml +++ b/.github/ISSUE_TEMPLATE/02-improvement.yml @@ -1,6 +1,6 @@ name: πŸ’‘ Improvement description: Propose an improvement for existing functionality of the SDK -type: Improvement +labels: ["Symfony", "Improvement"] body: - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/03-bug.yml b/.github/ISSUE_TEMPLATE/03-bug.yml index 528f3942..a4a1d26b 100644 --- a/.github/ISSUE_TEMPLATE/03-bug.yml +++ b/.github/ISSUE_TEMPLATE/03-bug.yml @@ -1,6 +1,6 @@ name: 🐞 Bug Report description: Tell us about something that's not working the way we (probably) intend. -type: Bug +labels: ["Symfony", "Bug"] body: - type: dropdown id: type From ed34b0c72fbc1bf82095a9c0fe8b2858251104f4 Mon Sep 17 00:00:00 2001 From: Alex Bouma Date: Mon, 7 Jul 2025 12:57:59 +0200 Subject: [PATCH 53/57] Remove support for `traceparent` (#928) --- composer.json | 2 +- .../DBAL/TracingDriverConnectionForV2V3.php | 4 +- .../DBAL/TracingDriverConnectionForV4.php | 4 +- .../AbstractTraceableHttpClient.php | 2 - src/Twig/SentryExtension.php | 5 ++- .../TracingRequestListenerTest.php | 39 ---------------- .../HttpClient/TraceableHttpClientTest.php | 3 +- tests/Twig/SentryExtensionTest.php | 44 ------------------- 8 files changed, 9 insertions(+), 94 deletions(-) diff --git a/composer.json b/composer.json index 580a952c..a68c320a 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "php": "^7.2||^8.0", "guzzlehttp/psr7": "^2.1.1", "jean85/pretty-package-versions": "^1.5||^2.0", - "sentry/sentry": "^4.11.0", + "sentry/sentry": "^4.14.1", "symfony/cache-contracts": "^1.1||^2.4||^3.0", "symfony/config": "^4.4.20||^5.0.11||^6.0||^7.0", "symfony/console": "^4.4.20||^5.0.11||^6.0||^7.0", diff --git a/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3.php b/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3.php index 1010fb5b..9a3a9035 100644 --- a/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3.php +++ b/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV2V3.php @@ -246,10 +246,10 @@ private function traceFunction(string $spanOperation, string $spanDescription, \ * * @param array $params The connection params * - * @return array - * * @phpstan-param ConnectionParams $params * + * @return array + * * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md */ private function getSpanData(string $databasePlatform, array $params): array diff --git a/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV4.php b/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV4.php index 2f506b25..ee0d2bbf 100644 --- a/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV4.php +++ b/src/Tracing/Doctrine/DBAL/TracingDriverConnectionForV4.php @@ -244,10 +244,10 @@ private function traceFunction(string $spanOperation, string $spanDescription, \ * * @param array $params The connection params * - * @return array - * * @phpstan-param ConnectionParams $params * + * @return array + * * @see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md */ private function getSpanData(string $databasePlatform, array $params): array diff --git a/src/Tracing/HttpClient/AbstractTraceableHttpClient.php b/src/Tracing/HttpClient/AbstractTraceableHttpClient.php index d1f83b2c..5a61dfb8 100644 --- a/src/Tracing/HttpClient/AbstractTraceableHttpClient.php +++ b/src/Tracing/HttpClient/AbstractTraceableHttpClient.php @@ -18,7 +18,6 @@ use function Sentry\getBaggage; use function Sentry\getTraceparent; -use function Sentry\getW3CTraceparent; /** * This is an implementation of the {@see HttpClientInterface} that decorates @@ -59,7 +58,6 @@ public function request(string $method, string $url, array $options = []): Respo if (self::shouldAttachTracingHeaders($client, $uri)) { $headers['baggage'] = getBaggage(); $headers['sentry-trace'] = getTraceparent(); - $headers['traceparent'] = getW3CTraceparent(); } $options['headers'] = $headers; diff --git a/src/Twig/SentryExtension.php b/src/Twig/SentryExtension.php index 56fd71b7..3c2ecc77 100644 --- a/src/Twig/SentryExtension.php +++ b/src/Twig/SentryExtension.php @@ -10,7 +10,6 @@ use function Sentry\getBaggage; use function Sentry\getTraceparent; -use function Sentry\getW3CTraceparent; final class SentryExtension extends AbstractExtension { @@ -43,10 +42,12 @@ public function getTraceMeta(): string /** * Returns an HTML meta tag named `traceparent`. + * + * @deprecated since version 5.3. To be removed in version 6.0. */ public function getW3CTraceMeta(): string { - return \sprintf('', getW3CTraceparent()); + return ''; } /** diff --git a/tests/EventListener/TracingRequestListenerTest.php b/tests/EventListener/TracingRequestListenerTest.php index 1c0c3193..6eb17581 100644 --- a/tests/EventListener/TracingRequestListenerTest.php +++ b/tests/EventListener/TracingRequestListenerTest.php @@ -129,45 +129,6 @@ public function handleKernelRequestEventDataProvider(): \Generator $transactionContext, ]; - $samplingContext = DynamicSamplingContext::fromHeader(''); - $samplingContext->freeze(); - - $transactionContext = new TransactionContext(); - $transactionContext->setTraceId(new TraceId('566e3688a61d4bc888951642d6f14a19')); - $transactionContext->setParentSpanId(new SpanId('566e3688a61d4bc8')); - $transactionContext->setParentSampled(true); - $transactionContext->setName('GET http://www.example.com/'); - $transactionContext->setSource(TransactionSource::url()); - $transactionContext->setOp('http.server'); - $transactionContext->setOrigin('auto.http.server'); - $transactionContext->setStartTimestamp(1613493597.010275); - $transactionContext->setData([ - 'net.host.port' => '80', - 'http.request.method' => 'GET', - 'http.url' => 'http://www.example.com/', - 'http.flavor' => '1.1', - 'route' => '', - 'net.host.name' => 'www.example.com', - ]); - $transactionContext->getMetadata()->setDynamicSamplingContext($samplingContext); - $transactionContext->getMetadata()->setSampleRand(0.1337); - - yield 'request.headers.traceparent EXISTS' => [ - new Options(), - Request::create( - 'http://www.example.com', - 'GET', - [], - [], - [], - [ - 'REQUEST_TIME_FLOAT' => 1613493597.010275, - 'HTTP_traceparent' => '00-566e3688a61d4bc888951642d6f14a19-566e3688a61d4bc8-01', - ] - ), - $transactionContext, - ]; - $samplingContext = DynamicSamplingContext::fromHeader('sentry-trace_id=566e3688a61d4bc888951642d6f14a19,sentry-public_key=public,sentry-sample_rate=1'); $samplingContext->freeze(); diff --git a/tests/Tracing/HttpClient/TraceableHttpClientTest.php b/tests/Tracing/HttpClient/TraceableHttpClientTest.php index 4306378e..0b24516b 100644 --- a/tests/Tracing/HttpClient/TraceableHttpClientTest.php +++ b/tests/Tracing/HttpClient/TraceableHttpClientTest.php @@ -176,7 +176,7 @@ public function testRequestDoesContainsTracingHeadersWithoutTransaction(): void 'trace_propagation_targets' => ['www.example.com'], ]); $client = $this->createMock(ClientInterface::class); - $client->expects($this->exactly(5)) + $client->expects($this->exactly(4)) ->method('getOptions') ->willReturn($options); @@ -200,7 +200,6 @@ public function testRequestDoesContainsTracingHeadersWithoutTransaction(): void $this->assertSame('POST', $response->getInfo('http_method')); $this->assertSame('https://www.example.com/test-page', $response->getInfo('url')); $this->assertSame([\sprintf('sentry-trace: %s', $propagationContext->toTraceparent())], $mockResponse->getRequestOptions()['normalized_headers']['sentry-trace']); - $this->assertSame([\sprintf('traceparent: %s', $propagationContext->toW3CTraceparent())], $mockResponse->getRequestOptions()['normalized_headers']['traceparent']); $this->assertSame([\sprintf('baggage: %s', $propagationContext->toBaggage())], $mockResponse->getRequestOptions()['normalized_headers']['baggage']); } diff --git a/tests/Twig/SentryExtensionTest.php b/tests/Twig/SentryExtensionTest.php index 5cbfd25b..d0921ad1 100644 --- a/tests/Twig/SentryExtensionTest.php +++ b/tests/Twig/SentryExtensionTest.php @@ -73,50 +73,6 @@ public function testTraceMetaFunctionWithActiveSpan(): void $this->assertSame('', $environment->render('foo.twig')); } - public function testW3CTraceMetaFunctionWithNoActiveSpan(): void - { - $environment = new Environment(new ArrayLoader(['foo.twig' => '{{ sentry_w3c_trace_meta() }}'])); - $environment->addExtension(new SentryExtension()); - - $propagationContext = PropagationContext::fromDefaults(); - $propagationContext->setTraceId(new TraceId('566e3688a61d4bc888951642d6f14a19')); - $propagationContext->setSpanId(new SpanId('566e3688a61d4bc8')); - - $hub = new Hub(null, new Scope($propagationContext)); - - SentrySdk::setCurrentHub($hub); - - $this->assertSame('', $environment->render('foo.twig')); - } - - public function testW3CTraceMetaFunctionWithActiveSpan(): void - { - $environment = new Environment(new ArrayLoader(['foo.twig' => '{{ sentry_w3c_trace_meta() }}'])); - $environment->addExtension(new SentryExtension()); - - $client = $this->createMock(ClientInterface::class); - $client->expects($this->atLeastOnce()) - ->method('getOptions') - ->willReturn(new Options([ - 'traces_sample_rate' => 1.0, - 'release' => '1.0.0', - 'environment' => 'development', - ])); - - $hub = new Hub($client); - - SentrySdk::setCurrentHub($hub); - - $transaction = new Transaction(new TransactionContext()); - $transaction->setTraceId(new TraceId('a3c01c41d7b94b90aee23edac90f4319')); - $transaction->setSpanId(new SpanId('e69c2aef0ec34f2a')); - $transaction->setSampled(true); - - $hub->setSpan($transaction); - - $this->assertSame('', $environment->render('foo.twig')); - } - public function testBaggageMetaFunctionWithNoActiveSpan(): void { $environment = new Environment(new ArrayLoader(['foo.twig' => '{{ sentry_baggage_meta() }}'])); From 062304f39c43315d04bf63fe0620cb18814033fa Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Mon, 7 Jul 2025 15:09:08 +0200 Subject: [PATCH 54/57] Implement `NamespacedPoolInterface` for `TraceableCacheAdapterForV3` (#927) --- ...raceableCacheAdapterForV3WithNamespace.php | 64 +++++++++++++++++++ src/aliases.php | 8 ++- .../Cache/TraceableCacheAdapterTest.php | 13 ++++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 src/Tracing/Cache/TraceableCacheAdapterForV3WithNamespace.php diff --git a/src/Tracing/Cache/TraceableCacheAdapterForV3WithNamespace.php b/src/Tracing/Cache/TraceableCacheAdapterForV3WithNamespace.php new file mode 100644 index 00000000..7b53c286 --- /dev/null +++ b/src/Tracing/Cache/TraceableCacheAdapterForV3WithNamespace.php @@ -0,0 +1,64 @@ + + */ + use TraceableCacheAdapterTrait; + + /** + * @param HubInterface $hub The current hub + * @param AdapterInterface $decoratedAdapter The decorated cache adapter + */ + public function __construct(HubInterface $hub, AdapterInterface $decoratedAdapter) + { + $this->hub = $hub; + $this->decoratedAdapter = $decoratedAdapter; + } + + /** + * {@inheritdoc} + * + * @param mixed[] $metadata + */ + public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed + { + return $this->traceFunction('cache.get_item', function () use ($key, $callback, $beta, &$metadata) { + if (!$this->decoratedAdapter instanceof CacheInterface) { + throw new \BadMethodCallException(\sprintf('The %s::get() method is not supported because the decorated adapter does not implement the "%s" interface.', self::class, CacheInterface::class)); + } + + return $this->decoratedAdapter->get($key, $callback, $beta, $metadata); + }, $key); + } + + public function withSubNamespace(string $namespace): static + { + if (!$this->decoratedAdapter instanceof NamespacedPoolInterface) { + throw new \BadMethodCallException(\sprintf('The %s::withSubNamespace() method is not supported because the decorated adapter does not implement the "%s" interface.', self::class, NamespacedPoolInterface::class)); + } + + $clone = clone $this; + $clone->decoratedAdapter = $this->decoratedAdapter->withSubNamespace($namespace); + + return $clone; + } +} diff --git a/src/aliases.php b/src/aliases.php index 92272bef..e0433bcb 100644 --- a/src/aliases.php +++ b/src/aliases.php @@ -9,6 +9,7 @@ use Sentry\SentryBundle\Tracing\Cache\TraceableCacheAdapter; use Sentry\SentryBundle\Tracing\Cache\TraceableCacheAdapterForV2; use Sentry\SentryBundle\Tracing\Cache\TraceableCacheAdapterForV3; +use Sentry\SentryBundle\Tracing\Cache\TraceableCacheAdapterForV3WithNamespace; use Sentry\SentryBundle\Tracing\Cache\TraceableTagAwareCacheAdapter; use Sentry\SentryBundle\Tracing\Cache\TraceableTagAwareCacheAdapterForV2; use Sentry\SentryBundle\Tracing\Cache\TraceableTagAwareCacheAdapterForV3; @@ -38,12 +39,17 @@ use Symfony\Component\Cache\DoctrineProvider; use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\HttpClient\Response\StreamableInterface; +use Symfony\Contracts\Cache\NamespacedPoolInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; if (interface_exists(AdapterInterface::class)) { if (!class_exists(DoctrineProvider::class, false) && version_compare(\PHP_VERSION, '8.0.0', '>=')) { if (!class_exists(TraceableCacheAdapter::class, false)) { - class_alias(TraceableCacheAdapterForV3::class, TraceableCacheAdapter::class); + if (interface_exists(NamespacedPoolInterface::class)) { + class_alias(TraceableCacheAdapterForV3WithNamespace::class, TraceableCacheAdapter::class); + } else { + class_alias(TraceableCacheAdapterForV3::class, TraceableCacheAdapter::class); + } } if (!class_exists(TraceableTagAwareCacheAdapter::class, false)) { diff --git a/tests/Tracing/Cache/TraceableCacheAdapterTest.php b/tests/Tracing/Cache/TraceableCacheAdapterTest.php index 1536adfd..5e5b9c29 100644 --- a/tests/Tracing/Cache/TraceableCacheAdapterTest.php +++ b/tests/Tracing/Cache/TraceableCacheAdapterTest.php @@ -6,6 +6,7 @@ use Sentry\SentryBundle\Tracing\Cache\TraceableCacheAdapter; use Symfony\Component\Cache\Adapter\AdapterInterface; +use Symfony\Contracts\Cache\NamespacedPoolInterface; /** * @phpstan-extends AbstractTraceableCacheAdapterTest @@ -27,4 +28,16 @@ protected static function getAdapterClassFqcn(): string { return AdapterInterface::class; } + + public function testNamespacePoolImplementation(): void + { + if (!interface_exists(NamespacedPoolInterface::class)) { + $this->markTestSkipped('NamespacedPoolInterface does not exists.'); + } + + $decoratedAdapter = $this->createMock(static::getAdapterClassFqcn()); + $adapter = $this->createCacheAdapter($decoratedAdapter); + + static::assertInstanceOf(NamespacedPoolInterface::class, $adapter); + } } From 8bec2086298d0d23b4ece4050a4d924bafb853d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Jul 2025 15:09:23 +0200 Subject: [PATCH 55/57] Bump actions/create-github-app-token from 1.11.5 to 2.0.6 (#924) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish-release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-release.yaml b/.github/workflows/publish-release.yaml index a1be1e49..fbf88435 100644 --- a/.github/workflows/publish-release.yaml +++ b/.github/workflows/publish-release.yaml @@ -20,7 +20,7 @@ jobs: steps: - name: Get auth token id: token - uses: actions/create-github-app-token@0d564482f06ca65fa9e77e2510873638c82206f2 # v1.11.5 + uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6 with: app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }} private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }} From 24feecb334c0efb7fdfff159efb360f2338d8140 Mon Sep 17 00:00:00 2001 From: Michi Hoffmann Date: Mon, 7 Jul 2025 16:12:04 +0200 Subject: [PATCH 56/57] Prepare 5.3.0 (#929) --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index db5b004b..d011c1dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # CHANGELOG +## 5.3.0 + +The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v5.3.0. + +### Features + +- Implement `NamespacedPoolInterface` for `TraceableCacheAdapterForV3` [(#927)](https://github.com/getsentry/sentry-symfony/pull/927) + +### Misc + +- Update minimum required version of `sentry/sentry` to `^4.14.1` +- Remove support for `traceparent` header [(#928)](https://github.com/getsentry/sentry-symfony/pull/928) + ## 5.2.0 The Sentry SDK team is happy to announce the immediate availability of Sentry Symfony SDK v5.2.0. From 5081e7d842424ec09a96e3c79c5b48b89d1195b2 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Mon, 7 Jul 2025 14:14:08 +0000 Subject: [PATCH 57/57] release: 5.3.0 --- src/SentryBundle.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SentryBundle.php b/src/SentryBundle.php index 596b5b94..49f7843d 100644 --- a/src/SentryBundle.php +++ b/src/SentryBundle.php @@ -16,7 +16,7 @@ final class SentryBundle extends Bundle { public const SDK_IDENTIFIER = 'sentry.php.symfony'; - public const SDK_VERSION = '5.2.0'; + public const SDK_VERSION = '5.3.0'; public function build(ContainerBuilder $container): void {