Comments (8)
This is the same case as we discussed on Symfony discussions. Monolog as well as Symfony doesn't know your web app is a long running script. You have to jump into request-response cycle and reset given service on your own.
from monolog.
This is not the same case.
I was wondering if there is a way of scoping the logger for each request and, doing so, we could have FingersCrossedHandler implemented safely in stateful runtimes such as Swoole, ReactPHP, FrankenPHP, etc.
This is the main point here. As you pointed out in Symfony discussions, the handler is already marked to be reset on terminate. But that doesn't fix the issue of having the same logger for every request.
from monolog.
Look at the following code inside an example controller:
#[Route('/slow', methods: ['GET'], format: 'json')]
public function slow(): Response
{
$this->logger->info('Slow - logger id', ['id' => spl_object_hash($this->logger)]);
$this->logger->debug('Log de debug antes do sleep');
sleep(10);
return $this->json('Ok');
}
#[Route('/fast', methods: ['GET'], format: 'json')]
public function fast(): Response
{
$this->logger->info('Fast - logger id', ['id' => spl_object_hash($this->logger)]);
$this->logger->error('Erro solo que não deve ter mais nada');
return $this->json('Ok');
}
If you access the slow route, it's going to add info and debug logs, but if you have fingers crossed configured to only log errors, nothing should be logged. But if, while the slow endpoint is running, you access the fast one, you'll see the logs from the slow request, because the logger is the same.
Hence the following:
I was wondering if there is a way of scoping the logger for each request and, doing so, we could have FingersCrossedHandler implemented safely in stateful runtimes such as Swoole, ReactPHP, FrankenPHP, etc.
from monolog.
Same goes for the following:
#[Route('/slow', methods: ['GET'], format: 'json')]
public function slow(): Response
{
$this->logger->info('Slow - logger id', ['id' => spl_object_hash($this->logger)]);
$this->logger->debug('Debug log before sleep');
sleep(10);
$this->logger->error('Error log that should come after the debug');
return $this->json('Ok');
}
#[Route('/fast', methods: ['GET'], format: 'json')]
public function fast(): Response
{
$this->logger->info('Fast - logger id', ['id' => spl_object_hash($this->logger)]);
return $this->json('Ok');
}
The 'Fast - logger id'
message should never be sent to the output, but in a stateful runtime it does, because the error log in the slow
endpoint makes everything in the logs to be sent.
from monolog.
Does your stateful runtime allow to handle more than 1 concurrent request per process? Or does it share memory between processes (or threads depending on runtime architecture)? If any of these is true then you indeed have a problem (like it is in Java or C# applications I believe).
Along the stateful runtimes out there I have only been working with RoadRunner and it allows only 1 request per worker and doesn't share memory between workers.
from monolog.
Does your stateful runtime allow to handle more than 1 concurrent request per process?
It's not mine 😅 but yes, Swoole does allow that.
Or does it share memory between processes (or threads depending on runtime architecture)?
That is also possible in Swoole, yes.
If any of these is true that then you indeed have a problem
Yep, that's why I'm bringing up the discussion so we can figure out a way of having our PHP applications running on those runtimes safely. :-D
from monolog.
The only way to avoid issues when running concurrent requests running in a runtime is to have no stateful services being shared between those requests. This would require either having no stateful services at all (but the whole point of a FingersCrossedHandler is to be stateful by buffering log entries until activation happens) or to have separate instances per request being handled (in the case of Symfony, this would end up meaning booting separate kernels for each concurrent request so that they have separate containers).
from monolog.
Yeah IMO if you share a single container between multiple concurrent requests in one process you're gonna have bigger issues than the FingersCrossedHandler. Like what happens when an entity is half-modified in one request while another flushes doctrine changes? Doesn't sound very ACID compliant :D
So yes if you run concurrent requests in a single process I would say you need to have at least a fresh container per request, which would instantiate a new fingers crossed handler as well. You can still reset and reuse the container once done with that request so you'd have a pool of containers each running a single request at a time, if that really saves enough cycles to be worth the risks of state pollution between requests.
from monolog.
Related Issues (20)
- Issue with Logging to stdout in Laravel 10.21 using Monolog v3 EXCEPTION#Cannot log request: fwrite(): Write of 378 bytes failed with errno=32 Broken pipe HOT 37
- The file does not close after writing HOT 5
- How do I use includeStacktraces? HOT 1
- Support more flexible normalizer HOT 2
- cannot access private method HOT 7
- Add support for Elasticsearch with Bulk API and data stream HOT 1
- Could a new release be considered to remove the 0.7MB logo from the package ? HOT 1
- Uncaught Error: Class "Monolog\Logger" not found HOT 7
- User definable duplication for DeduplicationHandler
- Encounter problem in format function HOT 3
- DatetimeImmutable HOT 1
- Extending Processors - private properties HOT 1
- Incorrect logs are written in Monolog files intermittently HOT 1
- Truncated JsonFormatter logs at 8191 characters HOT 5
- Log Message is truncated HOT 1
- Log level not compliant with rfc5424 HOT 2
- DeduplicationHandler in a read only container HOT 4
- IntrospectionProcessorTests: $expect and $actual are the same object by reference.
- Php 8.3 compatibility issue HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from monolog.