[9.x] Log facade to accept any number of arguments of any type #45604
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Log facade is one of the crucial elements of Laravel development – this is how you get feedback when things go wrong, as well as when things go well or when you just want to get some extra visibility over your app.
Laravel framework binds LogManager class under the 'log' key in its container and currently it implements a PSR LoggerInterface:
Where we can pass a message as well as a context - any supplemental data that we need. If we refer to the PSR documentation:
Imagine a scenario like this:
A very usual situation indeed – somewhere in our code we have a failing third-party integration and we want to log the output from that API, perhaps there is something useful in there that's going to help us troubleshoot this later.
The problem here is that the second parameter of Log::emergency() call HAS to be an array and if json_decode() doesn't return an array for whatever reason, our Laravel application is going to crash!
Illuminate\Log\LogManager::emergency(): Argument #2 ($context) must be of type array, bool given, called in vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php on line 338 in vendor/psy/psysh/src/Exception/TypeErrorException.php on line 53.
Oh, that's not nice! Remember JavaScript's console.log() command? You can pass anything to it and it's never going to kill your application:
The idea is simple - because we use the logging capability to troubleshoot things, the last thing we want is for the application to crash BECAUSE of the logging. I believe I should be able to pass just about anything to Log facade and it should just work in one capacity or another.
This pull-request is one of the possible implementations where I removed the "array" type from the method signatures in LogManager class. This doesn't violate the LoggerInterface contract that the class implements. Moreover, it's been done before if we look closer in the Logger class:
Compare it with the actual LoggerInterface signature:
As we can see the string|\Stringable type was removed from the signature so that Laravel can use the formatMessage() method later to display Stringable and Jsonable objects nicely.
I propose we do the same with the $context with the same goal - make it a bit more flexible and convenient.
With the updates proposed, I can do stuff like this:
And it just all goes to the log driver, to the logs. I don't have to worry about the number of arguments I pass or the types of arguments I pass (which are hard to predict sometimes). I never have to worry about Log throwing an error again.
Any feedback, opinions, and alternative implementations are welcome! :)