symfony: [Console][ErrorHandler] Add option to disable deprecations in dev console in 4.4
Description
After running any command in dev (debug=1) I get a lot of messages in stdout like:
2020-02-03T16:37:57+01:00 [info] User Deprecated: The "Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand" class is deprecated since Symfony 4.2, use "Symfony\Component\Console\Command\Command" with dependency injection instead.
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:
framework:
php_errors:
log: 4096
It was enough to get rid of those deprecations.
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 17
- Comments: 71 (51 by maintainers)
Correct,
SYMFONY_DEPRECATIONS_HELPER
will only have any effect when running via the symfony phpunit helper.A revised version of @ju1ius solution but with an opt in/out flag:
Hi,
Is there any config to make the
[info] User Deprecated:
disappear when running a console command in debug ?Running Symfony 5.4
Thanks in advance for your help, Julien
This burning our prods and sending it into hell, especially with messenger in conjunction with
fingers_crossed
handler which is broken (but that’s another topic, rather difficult to solve topic, and I get that).I did some forensics and found that in there:
https://github.com/symfony/symfony/blob/master/src/Symfony/Component/ErrorHandler/ErrorHandler.php#L411
i.e.:
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.
A workaround without the need to implement an handler class is to just call…
…at the appropriate place in your application boot sequence.
For example in your AppKernel:
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
bin/console
file to use our custom debug error handler instead of the default one.MyApp\DebugErrorHandler
bin/console
By default deprecations will not be shown in the console, if one wishes to see them just set the
APP_CONSOLE_DEPRECATIONS
environment variable to a truthy value.Hopefully someone else in this thread will also find it useful. Cheers!
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 😃
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
php
channel mixes both at theinfo
level. It looks like a feature request, nice one.@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 😃
I have the same question – I can’t see the output of my console commands, frequently $logger->info(“something I want to see”), and I feel like I’ve tried everything in this long thread. Also running Symfony 5.4.
Most of these errors are related to not having a return type, and they’re from bundles I have no control over.
I don’t see a pull request created by you that would this three year old issue. It says a lot about you.
Set the following env variable (eg. in .env.local):
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:
@pounard that’s easier said than done for many of us. I for one have a project where most of the deprecations do not come from our code directly but rather from upstream dependencies which have yet to adapt their code to be deprecation free. So sadly, unless one is willing to create a bunch of forks with custom patches, there’s really not much else that can be done.
OK here is where I got so far:
BufferingLogger
is set as default logger, inDebug::enable()
, before the kernel is created by callingErrorHandler::setDefaultLogger()
.ErrorHandler::register()
is called right after that (OK, it wants to capture errors before monolog is initialized, I guess, seems legit).FrameworkBundle::boot()
the error handler is set once again (seems legit at this point).ConsoleEvents::COMMAND
event,DebugHandlersListener::configure()
method is called which calls itselfDebugHandlersListener::setDefaultLoggers()
, which sets a deprecation logger by callingErrorHandler::setDefaultLogger()
once again.ErrorHandler::setDefaultLogger()
callssetLoggers()
which itself will call$this->bootstrappingLogger->cleanLogs()
, which will fetch all errors that were buffered in theBufferingLogger
.Symfony\Bridge\Monolog\Logger::addRecord()
for each log entry.$record
array has the right channel and level set, which is good.handle()
method, most handlers will only check for the error level, not the channel, which makes all of them log the error.DebugHandlersListener::setDefaultLoggers()
which was not ended yet, it callsErrorHandler::setDefaultLogger()
a second time, at the end of the method.ErrorHandler::setLogger()
a second time, which then decide to$flush
because loggers have changed, but this time$this->bootstrappingLogger->cleanLogs()
yields no logs.DebugHandlersListener::configure()
, please note I still do not have anything in console displaying yet (either it’s not flushed yet, either logs have not been sent yet).The debug machinery is terribly complicated (and honestly, code is far from being easily read), I’m stopping here. I suspect that when
cleanLogs()
is called for the first time, loggers are not fully setup yet (at this very moment, it seems that theErrorHandler
yield only oneLogger
instance), and this is why all messages end up being flushed in console instead of being rightfully dispatched in the right channel handlers.At this very moment,
$type
value is16384
, and only8192
(E_DEPRECATED
) and16384
(E_USER_DEPRECATED
) have a configured logger, all other types have the defaultBufferingLogger
.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
DebugHandlersListener::configure()
, it should not callsetDefaultLoggers()
which forces to flush deprecation errors that happened during initialization (before monolog was correctly setup) because at this moment, monolog is not completely initialized yet. There’s something wrong happening in there.But in the end, this is not a critical bug, since it happens only when
APP_DEBUG
istrue
.As a side note, the whole
DebugHandlersListener
is very confusing, and very hard to understand, I wouldn’t be surprised if there is some confusion in logic inside.@nicolas-grekas, @pounard, I tested this again with symfony 4.4.8.
The issue is with this setting:
By default, it’s now
true
(in documentation it states, that it defaults tokernel.debug
, and thats not true, as it’strue
😄 ). This makes the app to fill production log with deprecations.To change that behavior, one can try to set mentioned value like this:
packages/framework.yaml
Now,
prod.log
is safe, but logs will now appear in console (dev, debug=true). The reason is that this setting will also prevent writing deprecations todev.log
and - I guess, any logs left in buffer are just written to stdout, which is reasonable as logs are not lost in buffer.So the workaround here is to have two
framework.yaml
files:packages/framework.yaml
This will write deprecations to log, leaving the console clean.
packages/prod/framework.yaml
This will keep prod.log clean from deprecations. This actually solves my issue.
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
Isn’t
SYMFONY_DEPRECATIONS_HELPER
just phpunit-specific?In Symfony 5.x this worked - mutes the deprecations totally:
I sincerely think that this line:
In the
ErrrorHandler::handleError()
should just be removed. Please let developers and sysadmin configure their own environments, do not attempt to be smarter than them with this.Huge canvases displayed every time the command is called is not the norm, it repels newcomers who start using Symfony. I have Symfony 6 & PHP 8.1 versions and the same thing happens. The problem is almost 3 years old and not solved, it says a lot about the core team.
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 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
boot()
kernel function has mostly eliminated the problem for me. Specifically, the modified version @nocive posted in June. There are still situations when using the console where it just spits out hundreds of deprecation warnings, and that’s not particularly fun. But it’s mostly been eliminated.I believe if you register a
deprecations
channel in your monolog configuration, all deprecations will be logged there. Then you can exclude them from the console, just like other channels. But that is with 6.2, not sure if this is related- or backported to 4.4.Not sure if this was already the case back then or if it works though but I’ll give it a go. If that works, this issue could be marked as resolved I think, unless the documentation needs to be updated?
https://github.com/symfony/symfony/issues/35575#issuecomment-1164178596
@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”.
We have the same thing, none of the above worked. For now fixed locally with this in
php.ini
:Still shows the deprecations in profiler. But no longer annoying messages on your
bin/console
.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.
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.
I’ll add my two cents here because I am experimenting the same kind of issue under 4.x.
On dev env running under Docker, I have hundreds of deprecation line each time I refresh a page:
As for any PHP application, I start by using
error_reporting
to remove the deprecation report on thepublic/index.php
, before kernel loading.I also tried configuring php-fpm directly with the
log_level = warning
directive.And finally, the
php_errors
configuration option proposed by @jkobusNothing worked, and indeed, removing the
E_DEPRECATED | E_USER_DEPRECATED
part of theErrorHandler
“resolves” the issue, as reported by @pounard. There is also the debug disabling possibility, but that is not an acceptable solution as it will not only disable the error reporting.I also agree that deprecation warnings are great, especially on the profiler report. However, having hundreds of deprecation warnings per request on our local dev output give nothing else expect an unusable log.
I read there is a possible configuration with Symfony 5. However I do not understand: Why can’t the “Strong errors” part be configurable? As you override the possibility to directly manage
error_reporting
, it would be great at least to give a control back door for the end developer.Or am I also missing something?
Best regards
./config/packages/monolog.yaml
Also Symfony 5 has this
./config/packages/prod/deprecations.yaml
So this is probably why it works
The problem still exists in symfony 4.4.30.
@pounard, in production environment this problem should not appear.
This depends on the
APP_DEBUG
env variable, which should be0
on production bu default.bin/console:
In short, the problem appears - in my case, when using console like this: