sentry-php: Events are sent only on shutdown: does not work in combination with async or long running processes like queue workers
(…but Rollbar does.)
The way Sentry PHP currently works is that during a request, whenever an error would be sent by Sentry, then rather than sending it off to the Sentry servers right away, it collects all the errors that it would send all in a big batch at the end of the request here.
…which is nice, but there’s a problem: it doesn’t actually do these batches at the end of the request, but rather on shutdown.
Unfortunately that is a problem when using a Swoole or ReactPHP style project, because the server never shuts down until the user force-terminates the process; thus the errors never get sent out to Sentry.
Also, you would think that since there’s a destructor as well also for sending all the batches to Sentry. But unfortunately it doesn’t work, because HttpTransport is never destroyed, because Hub has a static property called currentHub which holds an instance of itself which holds an instance of \Sentry\Client which holds an instance to \Sentry\Transport\HttpTransport.
I suppose a workaround could be that after every request, \Sentry\State\Hub::setCurrent(new \Sentry\State\Hub::setCurrent()); could be called which would result in HttpTransport getting destroyed. But it would be great if there weren’t a static reference to HttpTransport in the first place so that its destructor would end up getting called.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 1
- Comments: 28 (7 by maintainers)
For Laravel, the approach I’m currently testing is to apply within ExceptionHandler:
I implemented a workaround which might be interesting: I created a HttpClient plugin which waits for each promise and swaps it with a
FulfilledPromise. I am not 100% satisfied because, in a long running process, I am still bloating the memory with useless data, but I found it easier than trying to use my own client or my own transport (every class is final otherwise it would have been way easier). The code is, more or less:And, instead of initializig sentry with the usual Sentry::init():
I hope it’s useful for somebody!
Thanks for the report, we are aware that this is a big problem due to us incorrectly implementing the asynchronous sending of the events and I’m working on a fix which has a high priority on my to-do list. Since this is going to require a lot of changes in the API I didn’t find the time yet to open the PR, but on my forked repository there is a branch with the WIP changes that should solve the issue and allow the correct integration of the SDK with ReactPHP and similar libraries. I really hope to be able to submit a PR soon for review
@B-Galati this is the issue, I’ll change the title to make it more clear. As for the proposed solutions, these are the pending PRs: #799 & #813
Closing this issue as it has been solved in the referenced PR. I’m sorry this has been a so long outstanding issue, we will release the new version asap
Issue is still top-priority for
2.2and in the next days I’m gonna hopefully update my PR with the changes that will fix the issue on time for all, but due to the vacation period I don’t know when it will be merged. The release plan in my head is to merge all pending PRs for that version along with this fix and then release the new version@palicao that’s actually way better than my current work around 👍
I’m having a déjà vu on this discussion 😄 Breaking BC is a no-go, we are striving to follow semver and we will continue doing it.
I’m not sure I get what you mean here. The proposals about how to solve this specific issue are two public PRs
The transport and the client have to be hold on to, or otherwise they would have to be constructed each time.
We’re aware of this since it lead to a similar issue in Laravel queue workers, see getsentry/sentry-laravel#228. We’re trying an approach in #799, and in general a simple
flush()should suffice as a way to send events when needed.