diff --git a/Makefile b/Makefile index 4609aa5..2a2f0d4 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ phpstan: vendor ## Check PHP code style .PHONY: phpunit phpunit: vendor ## Run PhpUnit tests - vendor/bin/phpunit -v --testdox + vendor/bin/phpunit -v .PHONY: php-cs-fixer-check cs-check: vendor ## Check php code style diff --git a/README.md b/README.md index 11c1b82..56eea4d 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,8 @@ It is a [Monolog](https://github.com/Seldaek/monolog) handler for Sentry PHP SDK - Send each log record to a [Sentry](https://sentry.io) server - Send log records as breadcrumbs when they are handled in batch; the main reported log record is the one with the highest log level -- Send log along with exception when one is set in the main log record context +- Send log along with exception when one is set in the main log record context +- Customize data sent to Sentry to fit your needs - Compatible with Monolog 1 and 2 - ~~Workaround for [an issue](https://github.com/getsentry/sentry-php/issues/811) that prevents sending logs in long running process~~ @@ -56,53 +57,10 @@ Check out the [handler constructor](src/SentryHandler.php) to know how to contro > >Check out the symfony guide for a complete example that addresses all these points -## Customizations / Extension points - -It is required to inherit from `SentryHandler` class and override these methods: - -```php - $value) { - $scope->setExtra((string) $key, $value); - } - } - - if (isset($record['context']['tags']) && \is_array($record['context']['tags'])) { - foreach ($record['context']['tags'] as $key => $value) { - $scope->setTag($key, $value); - } - } - } - - /** {@inheritdoc} */ - protected function afterWrite(): void - { - // Your custom code before events are flushed - // ... - - // Call parent method to keep default behavior or don't call it if you don't need it - parent::afterWrite(); - } -} -``` - -Please look at these methods within [the code](src/SentryHandler.php) if you want more details. - ## Documentation - [Symfony guide](doc/guide-symfony.md): it gives a way to integrate this handler to your app +- [Extension points](doc/extension-points.md): Customize data sent to Sentry and more ## FAQ diff --git a/doc/extension-points.md b/doc/extension-points.md new file mode 100644 index 0000000..48e00ca --- /dev/null +++ b/doc/extension-points.md @@ -0,0 +1,43 @@ +# Extension points + +It is required to inherit from `SentryHandler` class and override these methods: + +```php + $value) { + $scope->setExtra((string) $key, $value); + } + } + + if (isset($record['context']['tags']) && \is_array($record['context']['tags'])) { + foreach ($record['context']['tags'] as $key => $value) { + $scope->setTag($key, $value); + } + } + } + + /** {@inheritdoc} */ + protected function afterWrite(): void + { + // Your custom code before events are flushed + // ... + + // Call parent method to keep default behavior or don't call it if you don't need it + parent::afterWrite(); + } +} +``` + +Please look at these methods within [the code](../src/SentryHandler.php) if you want more details. diff --git a/doc/guide-symfony.md b/doc/guide-symfony.md index 36f0ea8..5d0c0c7 100644 --- a/doc/guide-symfony.md +++ b/doc/guide-symfony.md @@ -2,7 +2,7 @@ >:information_source: > ->- It was written for Symfony 4. +>- It was written for Symfony 4.4. >- Its main purpose is to give ideas of how to integrate this handler in a Symfony project This guide proposed an opinionated solution to integrate Sentry in a Symfony project. @@ -42,10 +42,10 @@ It provides the following benefits: ## Step 1: Configure Sentry Hub -Symfony http client is required: +Symfony http client is suggested because of its native async capabilities: ``` -composer require symfony/http-client +composer require symfony/http-client nyholm/psr7 guzzlehttp/promises ``` Let's configure the Sentry Hub with a factory. It gives full flexibility in terms of configuration. @@ -54,22 +54,13 @@ Let's configure the Sentry Hub with a factory. It gives full flexibility in term setHttpClient(new SentryHttpClient()); + $client = HttpClient::create(['timeout' => 2]); + $clientBuilder->setHttpClient(new HttplugClient($client)); // Enable Sentry RequestIntegration $options = $clientBuilder->getOptions(); @@ -110,43 +102,6 @@ class SentryFactory return SentrySdk::setCurrentHub(new Hub($client)); } } - -/** - * @see https://github.com/symfony/symfony/blob/4.4/src/Symfony/Component/HttpClient/HttplugClient.php - * - * Beware of the following issue with the default HTTP that comes with the Sentry SDK - * @see https://github.com/getsentry/sentry-php/issues/878 - */ -class SentryHttpClient implements HttpAsyncClient -{ - private $client; - - public function __construct() - { - $factory = new Psr17Factory(); - - // DO NOT use the http client from Symfony or you could turn into an infinite loop depending on your monolog config and the if logging of HTTP request is enabled or not - $client = HttpClient::create(['timeout' => 2]); - - $this->client = new Psr18Client($client, $factory, $factory); - } - - /** - * {@inheritdoc} - */ - public function sendAsyncRequest(RequestInterface $request) - { - try { - $response = $this->client->sendRequest($request); - } catch (RequestExceptionInterface $e) { - return new HttpRejectedPromise(new RequestException($e->getMessage(), $request, $e)); - } catch (NetworkExceptionInterface $e) { - return new HttpRejectedPromise(new NetworkException($e->getMessage(), $request, $e)); - } - - return new HttpFulfilledPromise($response); - } -} ``` Then the factory is registered in the Symfony container: diff --git a/src/SentryHandler.php b/src/SentryHandler.php index e97a6d4..5a87afa 100644 --- a/src/SentryHandler.php +++ b/src/SentryHandler.php @@ -112,7 +112,7 @@ protected function write(array $record): void * Extension point. * * This method is called when Sentry event is captured by the handler. - * Override it if you want to add custom logic to the $scope + * Override it if you want to add custom data to Sentry $scope. * * @param Scope $scope Sentry scope where you can add custom data * @param array $record Current monolog record