-5

Sure if exception happend then does't matter speed of response from the sentry server, but if it is a log to the sentry? Api client will not receive response before log request sent?

As I see under the hood, it uses Guzzle with promises to send request, but Im not sure a response will be sent before the promise is resolved/rejected.


Changed DSN to my local url and added route for sentry request:

Route::post('/api//envelope',function () {
    info('sleep');
    sleep(10);
    info('end sleep');
    return 'sentry';
})->withoutMiddleware(VerifyCsrfToken::class);

Then added route for debug:

Route::get('/debug-sentry', function () {
    try {
        throw new \Exception('This is a test exception');
    } catch (\Exception $e) {
        app('sentry')->captureException($e);
    }

    return 'Response sent to the client';
});

When opening /debug/sentry it takes ~5s because:

SDK: Failed to send the event to Sentry. Reason: "Idle timeout reached for......

This proves that response will NOT send before promise fulfilled and sentry affect app performance

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
rst630
  • 59
  • 2
  • 14
  • 1
    Test it: Verify With Code You can verify that Sentry is capturing errors in your Laravel application by creating a route that will throw an exception: routes/web.php Copied Route::get('/debug-sentry', function () { throw new Exception('My first Sentry error!'); }); https://docs.sentry.io/platforms/php/guides/laravel/ Also you can dispatch a job for that exception so you are sure it is handled async. – marius-ciclistu May 07 '23 at 18:51
  • But if you dispatch a job then you must handle infinite loops in case that job fails: https://docs.sentry.io/platforms/php/guides/laravel/usage/ see queue jobs. – marius-ciclistu May 07 '23 at 19:01
  • If it uses curl_multi_init then yes the request will take as long as the slowest request. Either way it is synk, blocking the response untill all paralel requests are sent and each received an answer(promise response). – marius-ciclistu May 07 '23 at 19:07
  • https://laravel.com/docs/8.x/middleware#terminable-middleware How to pass the exception to this middleware which executes after the response is being sent? – marius-ciclistu May 10 '23 at 07:10
  • @marius-ciclistu maybe store it in singletone as property and in middleware retrieve the same instance of sigletone and if property set then send this exception – rst630 May 10 '23 at 09:09
  • Please change the question to is sentry-laravel sending data sync/blocking? – marius-ciclistu May 11 '23 at 15:09

2 Answers2

0

UPDATE

Yes acc. to this it is sync

https://github.com/getsentry/sentry-laravel/discussions/691#discussioncomment-5858747

Workaround:

What if: in the exception handler you send response with message 'unexpected error', you cache the exception under 'sentry_exception_' . getmypid(). then in the laravel.com/docs/8.x/middleware#terminable-middleware you retrieve from cache the exception (if set) and you send it to sentry after the response has been sent. All in a try catch. if it throws only log the exception. In any case remove the exception from the cache.

Note: If the process dies due to memory or timeout the exception is not sent with this middleware. So, maybe the job solution from bellow is better.

Old answer:

Note: also the queue might not work but it is a decent tradeoff. You can log the error and then try to send ti to sentry.

Not if you use jobs for reporting the unhandled exception and for reporting the handled ones.

If you dispatch a job then you must handle infinite loops in case that job fails: https://docs.sentry.io/platforms/php/guides/laravel/usage see queue jobs.

If it uses curl_multi_init then yes the request will take as long as the slowest request. Either way it is synk, blocking the response until all paralel requests are sent and each received an answer(promise response).

EDIT:

There are 2 parts for sentry: laravel specific package: https://docs.sentry.io/platforms/php/guides/laravel/

```bash
composer require sentry/sentry-laravel
```

Enable capturing unhandled exception to report to Sentry by making the following change to your `App/Exceptions/Handler.php`:

```php {filename:App/Exceptions/Handler.php}
public function register()
{
    $this->reportable(function (Throwable $e) {
        if (app()->bound('sentry')) {
            app('sentry')->captureException($e);
        }
    });
}

Sdk (used by the above) https://docs.sentry.io/platforms/php/

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/).

This is our "core" SDK, meaning that all the important code regarding error handling lives here.
If you are happy with using the HTTP client we recommend install the SDK like: [`sentry/sdk`](https://github.com/getsentry/sentry-php-sdk)

```bash
composer require sentry/sdk
```

This package (`sentry/sentry`) is not tied to any specific library that sends HTTP messages. Instead,
it uses [Httplug](https://github.com/php-http/httplug) to let users choose whichever
PSR-7 implementation and HTTP client they want to use.

If you just want to get started quickly you should run the following command:

```bash
composer require sentry/sentry php-http/curl-client
```

This is basically what our metapackage (`sentry/sdk`) provides.

This will install the library itself along with an HTTP client adapter that uses
cURL as transport method (provided by Httplug). You do not have to use those
packages if you do not want to. The SDK does not care about which transport method
you want to use because it's an implementation detail of your application. You may
use any package that provides [`php-http/async-client-implementation`](https://packagist.org/providers/php-http/async-client-implementation)
and [`http-message-implementation`](https://packagist.org/providers/psr/http-message-implementation).

### Configuration

```php
\Sentry\init(['dsn' => '___PUBLIC_DSN___' ]);
```

### Usage

```php
try {
    thisFunctionThrows(); // -> throw new \Exception('foo bar');
} catch (\Exception $exception) {
    \Sentry\captureException($exception);
}

https://develop.sentry.dev/sdk/overview/:

The following items are expected of production-ready SDKs:

DSN configuration
**Graceful failures (e.g. Sentry server is unreachable)**
Setting attributes (e.g. tags and extra data)
Support for Linux, Windows and OS X (where applicable)

Feature based support is required for the following:

If cookie data is available, it’s not sent by default
If POST data is available, it’s not sent by default

Additionally, the following features are highly encouraged:

Automated error capturing (e.g. uncaught exception handlers)
Logging framework integration
**Non-blocking event submission**
marius-ciclistu
  • 448
  • 4
  • 14
-1

The short answer is YES but NOOO. Let me explain

Why YES?
Sentry uses Guzzle with asynchronous requests, as you mentioned, to send data to the servers. As usual, it has Life Cycle and runs on server memory in the background.

Why NO, then?
Sentry uses Guzzle with promises to send the error data to its server without waiting for a response, allowing the application to continue running without waiting for the process to complete. The main plus point is Sentry can help you identify performance bottlenecks and improve your application's performance by providing insights into errors and exceptions..

Compared to server performance, this is like nothing to the server. (Because you're already running a Laravel server)


Tips to optimize

  1. use 'traces_sample_rate' => 0.5 # Send 50% of the errors
  2. use 'before_send' to skip/filter unwanted error

Go through the configuration and play with it.


Example

use Illuminate\Support\Facades\Route;

Route::get('/log', function () {
    try {
        throw new Exception('This is a test exception');
    } catch (Exception $e) {
        app('sentry')->captureException($e);
    }

    return 'Response sent to the client';
});

This code will not wait for the response from Sentry. The Laravel Sentry SDK is designed to capture and send exceptions without blocking the application's response. The response 'Response sent to the client' will be sent to the client immediately, regardless of whether Sentry has finished processing the exception.

Abdulla Nilam
  • 36,589
  • 17
  • 64
  • 85
  • 1
    Can you confirm 100% that it returns the response before the promises are fulfilled? If yes I will update my answer. – marius-ciclistu May 08 '23 at 17:25
  • As I expirimented - NO, it will wait promise and only then response, In my case it about 0.4s on official sentry servers (not standalone) – rst630 May 09 '23 at 03:57
  • @marius-ciclistu Yes, I can confirm that when using the Laravel Sentry SDK, the application returns the response to the client before the promises are fulfilled. As mentioned, ***Sentry is designed to be non-blocking and have minimal impact on your application's performance.*** – Abdulla Nilam May 09 '23 at 04:18
  • @AbdullaNilam so it waits for the responce of the sdk then returns. Sync. Then the sdk sends the error to sentry. It sounds like a queue/job. As far as I know, async requests with promises are not like throwing rocks without waiting too see if you hit the target or not. – marius-ciclistu May 09 '23 at 05:42
  • @marius-ciclistu yes you'r right and I prove at answer on my question – rst630 May 09 '23 at 05:48
  • @rst630 so you can avoid it like I said with a queue job. But it will be the same case if sqs from aws or db does not respond on that dispatch. – marius-ciclistu May 09 '23 at 07:06
  • @rst630 I had a problem with elastic search logging in the past. The elastic search did not respond and the app stuck. A solution was to log to stdout. – marius-ciclistu May 09 '23 at 07:14