New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Console][ErrorHandler] Add option to disable deprecations in dev console in 4.4 #35575
Comments
This burning our prods and sending it into hell, especially with messenger in conjunction with I did some forensics and found that in there: i.e.: $level = error_reporting();
$silenced = 0 === ($level & $type);
// Strong errors are not authorized to be silenced.
$level |= E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED;
It's a matter of opinion, I don't see a deprecation notice as a strong error. The error handler component refuses explicitly to honour our error reporting configuration, without any kind of valid argument. Deprecations should not get into log into production. |
@pounard, in production environment this problem should not appear. This depends on the bin/console:
In short, the problem appears - in my case, when using console like this:
|
Nope, because: /**
* Bundle.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class FrameworkBundle extends Bundle
{
public function boot()
{
ErrorHandler::register(null, false)->throwAt($this->container->getParameter('debug.error_handler.throw_at'), true); |
Or did we do something wrong ? But if I get that right, when the Framework bundle initializes itself, it registers the |
I'm on 4.4.4 now and my |
I'm using 4.4.1, may be this bug was fixed somehow ? |
@jkobus are you logging everything 'till the Because |
As a matter of fact I stumbled upon this: https://stackoverflow.com/a/35779541 I know it's for 2.7 (rather old version) but it seems to work here. Nevertheless, I think the bug is real in Symfony 4.4.1 (at least) and probably until current latest stable. |
@pounard Could you please create a small example application using the latest 4.4 patch release that allows to reproduce this? |
I did a minimal installation that reproduces the bug, see https://github.com/pounard/symfony-issue-35575
Monolog config is the following: monolog:
handlers:
main:
type: fingers_crossed
action_level: warning
handler: nested
buffer_size: 500
nested:
type: rotating_file
path: "%kernel.logs_dir%/%kernel.environment%.log"
date_format: Y-m-d
max_files: 30
level: info How to test by yourself:
Expected:
Actual behaviour:
Once again, I repeat, this is because the |
That's with 5.0, I'm writing a 4.4 branch. |
Using 4.4.5, use Even worse, I had to remove Behaviour is still reproducible, deprecations goes to log. |
I added Fun thing, if I disable This is what I called a seriously inconsistent, unexpected and awkward behaviour. |
To reproduce the very stupid behaviour from my previous comment, use |
I sincerely think that this line: // Strong errors are not authorized to be silenced.
$level |= E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED; In the |
This line is correct: deprecations are always silenced already, see all the calls, they are like You should be able to route the deprecation channel to wherever you want, see e.g. the default config which routes them to a dedicated file: |
This line is correct: deprecations are always silenced already, see all the calls, they are like @error_reporting(), on purpose. @nicolas-grekas then pull my work and test. It's not about being silenced, it's about going down to the log, there is no way to prevent deprecations to be emitted into the log handler if you accept the EDIT: I think you misunderstood the topic of this issue. |
Those deprecations, i.e. those triggered using |
OK, I admit, the original issue wasn't really about those, but that I may have hijacked it: the original issue author did point his/her finger on the same piece of code that trigger the actual behaviours I'm fighting against, so I guess that's the right place to discuss. |
I'm sorry also to highlight this but the tone is so stressful here that it's hard to get into anything constructive. "burning", "broken", "forensic", "refuses explicitly to honour", "without any kind of valid argument", "Once again, I repeat", "Even worse", "Fun thing", "This is much worse", "seriously inconsistent, unexpected and awkward behaviour.", "do not attempt to be smarter". Please keep a cool head. All those words are needlessly dramatic and emotionally loaded. This is even worse when they claim something that happens to be wrong: the line that is yelled at is likely not related, since the error level is always zero for deprecations. @pounard I did understand that you'd like to handle deprecations separately from other PHP notices, yet you wonder how to do so since right now the @jkobus I'm not sure anymore if @pounard's request would fix your case. Please tell if this is being hijacked or not from your pov :) |
Don't take those words seriously, I honestly do not want any harm: I am very much appreciating all the hard work and all the time contributors give to this project. I took the time to write a complete and concrete example with explanation, because I now that maintaining free (and any other kind of) software is hard and time consuming. I do apologize if it hurt you, please believe me, I don't want any harm and I sincerely appreciate your work. Now, let me explain:
EDIT: "Fun thing" because it's fun :) I am amused when I debug, it's fun, it's what I do for a living and I love this, my job, it's a passion. Fun is fun, in the sens it is fun, not bad ! You, pretty much like me, are confined at home because of the current pandemic, and we all have our nerves on steel because of all of this. I think it might affect our judgement when we read this kind of issues. Most of my comments were before that, at least before drastic government actions. Once again, I'm sorry if you took that wrong, I will try to be much more careful with my language. But I did not, ever, insult or point fingers at anyone, just an odd behaviour. I know that sometime, people do stumble upon edge cases (this time it was me) and that's what I discriminate, not you, never ever I will doubt about contributors themselves. |
@nicolas-grekas I will take a look at it |
@nicolas-grekas @jkobus I honestly think that the line I was pointing at a few comment above should be removed, I don't see any valid reason for the error handler to enforce Was there a reason initially to force those to be verbose ? Maybe for testing environments ? A compromise could be to just remove |
@pounard check
E_RECOVERABLE_ERROR and E_USER_ERROR always stop execution and 2. E_USER_DEPRECATED are always silenced. This means 1. we must replace a silenced execution stop (=BIGWTF) by an exception and 2. we must forward deprecations to the logger (then, it's up to the logger to decide). 1. and 2. are thus both independent of the current error reporting level.
|
So you mean by "silenced" that the PHP handler will not be run for those, took me a while to figure that one out. OK I get that. Now, let's consider my use case, I did explicitly told PHP to ignore I did some step debugging, even thought they are "silenced" meaning PHP won't scream, they still reach that line of code:
So I attempted to decompose the code:
Now, everything in this seems fine. Except that, I did a simple patch here, I just removed the
In here, I don't really understand why and how logging conditions have been chosen, especially this code is very hard to read because of heavy bitflags usage, and, in my opinion, it lacks comments for the reader to understand it fully without having to debug. From my point of view, the Right, then I should have no // Strong errors are not authorized to be silenced.
$level |= E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED; I agree with the original code author "Strong errors are not authorized to be silenced". But where I do not agree, To be honest after debugging almost the whole class (and it is very hard, because there's more than one instance, one that restores another from the error handler and changes its internals, very hard runtime to fully understand) there is absolutely no technical reason I could see for |
in 5.4 i decided to not have this prod/dev discrepancy
having the deprecation in channel in prod, but the php channel in dev feels weird to me. Now it's always the deprecation channel, thus can be excluded. |
To me this is a recipe error btw. |
Since I upgraded a project from 5.3 to 5.4, deprecations are back again in console. I tried many subtile ways of configuring monolog, nothing is working. I hoped I would not need to go into step debug again, but I'll do. |
OK here is where I got so far:
The debug machinery is terribly complicated (and honestly, code is far from being easily read), I'm stopping here. I suspect that when At this very moment, This means that something, during initialization, forces all the deprecations to have a configured logger which ignores channels and sends everything to every handler it has at this point. But at this very moment, handlers in memory are not the one configured by the user configuration, because framework is not bootstrapped yet. I think this is a bug, and the bug lies in But in the end, this is not a critical bug, since it happens only when As a side note, the whole |
I'd add that for people that wanted to shutdown deprecation logging that happens before monolog is fully bootstrapped, I'm sorry, but it seems to be an non-solvable problem considering how is implemented the debug machinery. It'd probably require a full refactor of this component. Switching to PHP 8.1 with Symfony 6 will convert most of those errors into exceptions, forcing you to fix your deprecations anyway, so my advice is to upgrade ^^ |
@pounard that's easier said than done for many of us. |
Yes, I definitely agree, I didn't fix anything myself yet on my projects, it's an insane amount of work, almost impossible because of external dependencies. I was being sarcastic. |
I've tested almost all suggestions here, but none worked with Symfony 6.0 and monolog-bundle 3.7.1. It's sad because the deprecations are in third-party libraries which I'm not the owner of, and I really don't care if they use a deprecated class that is inside a famous project. Also, I can't see any reason for Symfony forcing us to deal with deprecations if we don't ask for that. That being said, my workaround is to redirect the stderr to nowhere: $ ./bin/console MY_COMMAND 2>/dev/null |
Same, which is a shame as like you say, I fixed all deprecations I could find and all deprecations are from third party packages which are already at their latest versions. Was hoping the monolog fix would work but no. |
I'd like to share what we ended up doing, for those out there that might be interested on how to work around your console commands getting polluted with deprecation notices which you have no control over. We created our own custom debug error handler, which is essentially a copy of the original debug handler with an additional flag to opt-in/out of the console deprecations. We then modified our MyApp\DebugErrorHandlerdeclare(strict_types=1);
use Symfony\Component\ErrorHandler\BufferingLogger;
use Symfony\Component\ErrorHandler\DebugClassLoader;
use Symfony\Component\ErrorHandler\ErrorHandler;
/**
* This class is a copy of the original Symfony\Component\ErrorHandler\Debug
* class with the difference that it sets a null logger for deprecations.
* At the time of writing it's still impossible to silence deprecations in the
* symfony console which leads to noisy output when running console commands
* with debug enabled.
*
* For more information see https://github.com/symfony/symfony/issues/35575.
*/
class DebugErrorHandler
{
public static function enable(bool $showDeprecations = true): ErrorHandler
{
// (... original code from `Symfony\Component\ErrorHandler\ErrorHandler\Debug` ...)
$errorHandler = new ErrorHandler(new BufferingLogger(), true);
if (!$showDeprecations) {
// silence deprecations in the console
$errorHandler->setLoggers([
\E_DEPRECATED => null,
\E_USER_DEPRECATED => null,
]);
}
return ErrorHandler::register($errorHandler);
}
} bin/console(...)
if ($_SERVER['APP_DEBUG']) {
umask(0000);
if (class_exists(Debug::class)) {
// use custom debug error handler instead of default one
// https://github.com/symfony/symfony/issues/35575
$showDeprecations = $_ENV['APP_CONSOLE_DEPRECATIONS'] ?? $_SERVER['APP_CONSOLE_DEPRECATIONS'] ?? false;
$showDeprecations = filter_var($showDeprecations, \FILTER_VALIDATE_BOOLEAN);
DebugErrorHandler::enable($showDeprecations);
}
} By default deprecations will not be shown in the console, if one wishes to see them just set the Hopefully someone else in this thread will also find it useful. Cheers! |
A workaround without the need to implement an handler class is to just call... // calls setLoggers on the currently registered handler instance
ErrorHandler::register(null, false)->setLoggers([
\E_DEPRECATED => [null],
\E_USER_DEPRECATED => [null],
]); ...at the appropriate place in your application boot sequence. For example in your AppKernel: namespace App;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
class Kernel extends BaseKernel
{
public function boot()
{
parent::boot();
ErrorHandler::register(null, false)->setLoggers([
\E_DEPRECATED => [null],
\E_USER_DEPRECATED => [null],
]);
}
} |
Set the following env variable (eg. in .env.local):
|
Isn't |
Correct, A revised version of @ju1ius solution but with an opt in/out flag: class Kernel extends BaseKernel
{
use MicroKernelTrait;
public function boot(): void
{
parent::boot();
// https://github.com/symfony/symfony/issues/35575
if ($_SERVER['APP_DEBUG']) {
$showDeprecations = $_ENV['APP_DEPRECATIONS'] ?? $_SERVER['APP_DEPRECATIONS'] ?? false;
$showDeprecations = filter_var($showDeprecations, FILTER_VALIDATE_BOOLEAN);
if (!$showDeprecations) {
ErrorHandler::register(null, false)->setLoggers([
\E_DEPRECATED => [null],
\E_USER_DEPRECATED => [null],
]);
}
}
}
} |
Hello, i have the same message about "deprecation" in my console for 5.4.10 project even with APP_ENV=prod / APP_DEBUG=0 and a "default" monolog.yaml when clearing cache. Only way i found is to change this in framework.yaml
|
We have the same thing, none of the above worked. For now fixed locally with this in
Still shows the deprecations in profiler. But no longer annoying messages on your |
It would be great if this was implemented by default, maybe you could open a PR? I would be more than happy to provide a PR if you don't have the time. This issue is been dragging for well over 2 years now, time for some fixes :) |
@mdeboer I'm happy to provide a PR too, maybe we can collab ;) The problem here seems more that this issue is not getting attention from the symfony core team. Seems a bit pointless to be proposing a PR without any feedback from the team on whether they think this is the way to do it and are receptive to such change. |
@nocive Well given it would only be a small PR, it would get their attention probably. And when it does, all they have to do is review it and hit a button instead of giving the OK and waiting for anyone to propose a PR. I barely have any time this week but if you cook up a PR, add me as a collab or ask me for a review and I'll have a look. Probably 95% of the needed changes have already been written here by people. |
Huge canvases displayed every time the command is called is not the norm, it repels newcomers who start using Symfony. |
I don't see a pull request created by you that would this three year old issue. It says a lot about you. |
@xabbuh whereas I understand why you'd defend the core team (as I would I guess because Symfony is huge and great) I do think all the confusion around logging is due to the fact there's probably no-one fully understanding the whole debug, monolog and error handler code at once. I do think, without any disrespect to core team member, it's open source, that many people did work on this, but never one person on the whole chain, which makes it a very hard to understand piece of historical spaghetti code. In my opinion, all code around early logging should be trashed and rewrote from scratch simpler. That's I guess what one would call "technical debt". |
I completely get the frustration with this issue. Seeing hundreds of lines of deprecation warnings when using the console is obnoxious and doesn't make much sense. Deprecation messages are useful but only in certain contexts. The console definitely isn't one of them (in my view at least). This is worsened significantly by the fact that the bulk of those messages come from third party code that can't be reasonably fixed. Personally, I'd love to fix this issue on my own but I don't know nearly enough about the complete system to feel confident enough to overhaul or fix it to be more flexible. Given that this issue has been around for as long as it has, I'm clearly not alone in that. The workaround in the |
Could you please share boot() workaround? I am completely frustrated with this. It is a bad joke that PHP and Symfony does not give a straightforward way to disable such things. Error handling is a mess in PHP. What a pity. |
|
Description
After running any command in dev (debug=1) I get a lot of messages in stdout like:
Console screen gets a bit messy.
That's very helpful but I don't need it every time I run a console command.
Right now the only workaround is to disable debug, because the error_reporting setting is ignored.
Previously (4.2) I just used an option in framework.yaml:
It was enough to get rid of those deprecations.
The text was updated successfully, but these errors were encountered: