Closed (fixed)
Project:
Drupal core
Version:
10.1.x-dev
Component:
base system
Priority:
Normal
Category:
Task
Assigned:
Reporter:
Created:
22 Dec 2017 at 02:37 UTC
Updated:
12 May 2023 at 08:04 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
kim.pepperComment #3
kim.pepperHere's what I am thinking...
Comment #4
jibranComment #5
kim.pepperAdded draft change record https://www.drupal.org/node/2932520
Comment #6
kim.pepperIf we don't want this on
\Drupalwe could add it as a static method on\Drupal\Core\Utility\ErrorThoughts?
Comment #7
jibranI think \Drupal makes sense.
I think we have to mention change notice link here as well.
Comment #8
kim.pepperThanks @jibran!
Comment #9
jibranI can't find anything to nitpick so RTBC.
Comment #10
larowlanLet's do this when we've removed all usages in the follow-up.
I'm not 100% sure that putting this on \Drupal is the best place for it. Really, this function does two things,
In OO code, I'd expect you'd inject a logger, so you really only need the first bit, but then we already have Error::decodeException for this.
I'd be interested to see how many OO calls to watchdog_exception passed the optional variables.
If not many, then those calls should be changed to just log after calling Error::decodeException and this can live on \Drupal for non OO code sake. I.e I suspect we shouldn't need this from OO code, but would like to see the stats first. If there are a few calls to it from OO code that do pass the additional variables, then there might be merit in splitting this into two separate functions as per the two things it does.
OO code would only need the first half
Comment #11
dawehnerWhen I looked at the code I have locally (some contrib modules + core) there was just the search API module using this functionality:
, but even then, those usecases still fundamentally set the same error message. I think its fair to assume that all these parameters got inherited from watchdog() in Drupal 7.
For me there are a two possiblities:
Error::decodeException()is not that bad actually. Code which cares about logging exceptions probably have some other logger injected already as well. All other customizations could be applied on top of thatExceptionLoggerInterfacewhich has something likelogExceptionas its own method. Internally it could wrap the exception as wanted and maybe provide$exception, $message = NULLas possible parameters. For using it could be constructed from an existing logger, so maybe:ExceptionLogger::create($this->logger)->logException($exception)\Drupal. It could happily live somewhere in\Drupal\Core\Loggerfor example.Comment #12
kim.pepperWhile I like the OOP approach to 2) it seems a bit unnecessary to have to inject 2 services, one if you are just logging info, and another if you are logging an exception.
I'm more in favour of 1).
Comment #13
dawehnerNote: At least in my head 2) Wouldn't really have any additional service.
watchdog_exceptionwas not swappable, nor doesExceptionLogger::create() | ExceptionLogger::logException($logger, $exception). Does that make a little bit more sense?Comment #15
borisson_While it is true that this is "more OO", I don't feel that's a solid justification for this change. It doesn't increase testability, it doesn't make code less coupled.
I don't have a solid answer to #13 either.
Comment #16
dawehner@kim.pepper Do you have a question about #13?
Comment #18
xanoYay! OOP! I agree with @dawehner that we can probably come up with a better place to put this than on
\Drupal. That's really just a bunch of helpers for code that's procedural or has trouble with DI. The assessments that this primarily prepares values forLoggerInterfaceis a good one. What about we put this on a tiny helper class somewhere (I wish we did function autoloading too) as a autoloadable, non-injectable helper? The function can return a tuple-style array so calling code can callLoggerInterfaceitself, or the helper function also takes a severity (defaults toerror?) andLoggerInterfaceand logs the parsed exception for you? This would save us the trouble of using another container service, unless anyone sees a need for swapping exception log message formatting application-wide.Comment #19
xanoThis illustrates one of the approaches I suggested (the decorator, as PHP/Drupal folks may not be too familiar with tuples). I opted to mimic
\Psr\Log\LoggerInterface, which explains the change in parameters from the previous patch, which was more closely based onwatchdog_exception(), but that is more for convenience and not essentially required. This patch also includes two conversions, with one procedural (beingwatchdog_exception()itself) and another OOP insideModuleInstaller.Comment #20
xanoI almost wonder if it's worth seeing if we can revise the logging PSR to accept not just strings, but anything that can be cast to a string. Then we can just decorate exceptions in objects that implement
::__toString()and pass them on to any oldLoggerInterfacedirectly.Comment #22
xanoThis patch brings back the concept of a convenience method on
\Drupalthat @kim.pepper originally introduced to provide a much cleaner procedural alternative towatchdog_exception()than what #19 allowed us to do. If we want, we can keep track of exception loggers per log channel inside\Drupalto limit the number objects.Comment #23
dawehnerUpdating the issue summary. I do like the patch right now.
May I ask whether it would be possible to use
ExceptionLogger::create()instead and skip the method on\Drupalaltogether.Comment #24
xanoThanks for the review! :) The reason this is on
\Drupalis that there's where most of the 'procedural-to-OOP' shortcuts live. It would also allow us to statically cache exception loggers if we want to (maybe not....yet?). It also makes it as similar to regular loggers as possible, although I'm fine with making this whole thing more minimal and look less likeLoggerInterface. What would be the benefit ofExceptionLoger::create()over::__construct()?Comment #25
dawehnerYeah I guess it seems totally fine.
I think optimizing for the exception path seems like a bad optimization strategy :)
I think the first is more readable, but also enables future changes of the constructor, your caching if needed.
Comment #26
gappleSmall cleanup to issue summary
Comment #27
gappleFrom #2351099: watchdog_exception() hides the exception from logger implementations, the exception should be passed as a value in the context array of the log call.
Comment #28
kim.pepperComment #29
kim.pepperRe-roll, usage in \Drupal\Core\Extension\ModuleInstaller and code style fix ups.
Comment #30
kim.pepperI'm considering #27 out of scope especially since it's still being debated and looks like #2949419: Pass the raw exception to logger implementations might be an alternative.
Comment #33
kim.pepperRe-roll. Also updates deprecation message and adds a deprecation test.
Comment #35
dawehnerMay I ask a question about the API? Is there ever a usecase for doing
ExceptionLogger::info()for example? IfExceptionLoggerdoesn't actually implement the logger interface anyway, wouldn't it be enough to have ExceptionLogger::logException and not have any of the additional methods?Comment #36
kim.pepperI agree.
It's been a while since I looked at this issue, and I think there could be some re-evaluation of the design.
Rather than static methods, I'd prefer defining an interface: ExceptionLoggerInterface with one method logException($e) which we can then inject as a service where ever we currently need it, and where we can't inject it, we can use the existing \Drupal::service() method approach.
However, we'd also need to take into account how the log factory currently works. This might mean we also need a ExceptionLoggerFactory that wraps the LoggerFactory.
I might put together a POC patch just to demonstrate what I mean.
Comment #37
kim.pepperHere's a patch with the ideas I proposed in #36. I've used the 'cron' service as an example of how this would be injected.
Thoughts?
Comment #39
kim.pepperReplaced a few more usages of \Drupal::exceptionLogger() with the injected service.
Comment #41
gappleI don't think it makes sense to introduce a new service only for logging exceptions, when the existing logging service can be improved (as in #2949419: Pass the raw exception to logger implementations), and doing so would conform to the expectation of other PSR loggers.
Comment #42
kim.pepper@gapple yeah I think you are right. Sometimes I need to write code before I know whether it's the right thing to do or not.
I'd be in favour of just calling the existing logger interface and passing the exception in the 'exception' context key.
Comment #44
andypostComment #45
kim.pepperI'm inclined to mark this closed (wont fix) and focus on #2949419: Pass the raw exception to logger implementations instead. Thoughts?
Comment #46
markhalliwellUnless I'm missing something, that's just a minor feature addition to the existing procedural code.
This issue is about replacing the procedural function with a service.
How is that issue relevant to this one?
Comment #47
kim.pepperThere has mostly been discussion about the approach. I think the patches there are quite old.
Basically, we are using PSR LoggerInterface and already have a mechanism for passing the exception to the logs via the $context param.
e.g.
Comment #48
markhalliwellThen shouldn't this issue be repurposed to still deprecate watchdog_exception() and then pass the exception once #2949419: Pass the raw exception to logger implementations lands?
In any case, either in that issue or this one, watchdog_exception() needs to be deprecated and its implementations removed, yes?
Comment #49
kim.pepperTrue. We can mark this one as duplicate or the other.
Comment #50
markhalliwellWell, that issue is kind of separate from this one. This one specifically deals with the deprecation of watchdog_exception(). I don't think we should muddy that issue with this now that I think about it.
I'd say the current service approach just needs to be removed from the latest patch. The deprecation and replacement of the watchdog_exception() usages is still valid.
Although, this all being said, I don't think we can do this in 8.9.x... so moving to 8.8.x if it can get in. Otherwise, I suppose it'll have to be bumped to 9.0.x?
Comment #51
kim.pepperYeah, I'd say this is unlikely to get into 8.8.x given the alpha is this week.
On thing we should do is look at how
\Drupal\dblog\Logger\DbLog::log()handles exceptions. At the moment it doesn't look at that context key and unsets the 'backtrace' context .We may need to move
\Drupal\Core\Utility\Error::decodeException()insideDbLog::log()and possibly_drupal_log_error()to keep backwards compatibility.Comment #52
gappleCurrently, DbLog stores everything passed to
$context(except the removedbacktrace) to thevariablescolumn of the log table.The patch for #2949419: Pass the raw exception to logger implementations updates DbLog to also remove the exception object from being stored in the database.
Comment #53
gapple#2949419: Pass the raw exception to logger implementations also updates
Error::decodeException()to include the passed exception in the variables array it returns, so the only thing really missing thatwatchdog_exceptionprovides is a default message.Comment #54
kim.pepperNice.
'%type: @message in %function (line %line of %file).'Maybe we can make this a constant?
Comment #56
gappleI used a regex to find/replace instances in the last patch, so missed a couple that didn't match the same format.
Comment #57
kim.pepperLets make it a constant :-)
Comment #58
gappleSome missing imports for the
Errorutility class where it's now used, and make use of a service's injected logger instance where available instead of using the staticDrupal::logger()Comment #59
gappleComment #61
kim.pepperThis is a deprecation, and 8.8.0-alpha1 is out now, so unfortunately, this needs to be against 9.1.x now. 😭
Comment #62
kim.pepperHere's what I was talking about with the constant.
Comment #63
cliddell commentedwatchdog_exception()over to\Drupal::logger().Also, should we really be preemptively
unseting the 'exception' offset, which does not exist, in update.inc for the sake of an issue which has yet to be accepted into core? (i.e. #2949419: Pass the raw exception to logger implementations)Comment #64
gappleThe replacement recommendation should be updated to use
Error::DEFAULT_ERROR_MESSAGEandError::decodeException, as is done in the rest of the patch.#2949419: Pass the raw exception to logger implementations already includes the changes with unset to remove the exception variable, so those could be removed from this patch.
Comment #65
cliddell commentedOkay, the replacement I recommended in the previous patch already makes use of
Error::DEFAULT_ERROR_MESSAGEandError::decodeException().I removed
unseting of the aforementioned exception offset, since the change is already included in #2949419: Pass the raw exception to logger implementations.Comment #66
neclimdulI assume this should be updated to 8.9 now? Probably 9 -> 10 too? I don't remember off the top of my head but I would wager we can't remove this in 9 at this point.
Comment #67
neclimdulactually, no there's a 8.9 beta out so without special consideration this is 9.x and 10.x.
Comment #68
cliddell commentedUpdated patch and change record to target 9.1.x and 10.0.x due to there being both a 8.9 and 9.0 beta out as of this comment.
It is a bit frustrating that this will have to be postponed until 9.1.x due to the lifetime of this ticket and it not being disruptive to my knowledge 😞. Though I do understand the necessity of not introducing new patches late in the release cycle.
Comment #69
neclimdulI'm with you. I mostly keep coming back here like "oh, you still can't do that? this never got committed? How could that be?"
The first bot failure was github being down but all the requeues I've tried failed to apply. I tried every possible method I know of applying patches and they all worked so I feel like this is a testbot failure but I'm feeling a bit out of the loop and/or noobish because everything I've been posting the last couple days seems to have weird mysterious failures I can't figure out.
Comment #70
cliddell commentedThat was my bad, I was still targeting 8.9.x for the test even though I had updated the ticket and patch to target 9.1.x 😅. I just added a test to target 9.1.x.
Comment #71
neslee canil pintoComment #72
cliddell commentedTransitioning back into "Needs review" since it passed the 9.1.x test.
Comment #73
hardik_patel_12 commentedRe-roll for 9.1.x.
Comment #74
kim.pepperI think this is ready.
Comment #75
xjmThanks for working on cleaning up our legacy code! A few points of review:
Can we call this
DEFAULT_ERROR_MESSAGE_TEMPLATEor something? I got really confused when we were passing a constant toFormattableMarkup.I'm also wondering if a
defaultError(array $error_variables)method would be a better way to handle a default message format, rather than a constant?t()can't translate a constant, which is another reason against using a constant. We could havetranslatedDefaultError()anduntranslatedDefaultError(), or something. There might be better names.This seems to not have the constant (that I think should be a method).
Comment #76
kim.pepperError::formatMessage($error)Comment #77
shaktikComment #78
neclimdulI don't think it is being used for "errors." Like we normally would. It looks like this is trying to pass something to the update UI. I can't find any direct usage of ['#abort'] other than to check its existence though so maybe previous reviews couldn't figure it out and left it alone instead of converting to FormatMarkup? Or maybe the message is completely dead? update.inc is really hard to follow :( :(
dawehner wrote this for 8.0 in #2538108: Add hook_post_update_NAME() for data value updates to reliably run after data format updates. Maybe he remembers something...
Comment #79
abhijeet.kumar2107 commentedComment #80
cliddell commented@neclimdul You're right, it's not being used as a watchdog error message; though the message is still in use. See lines 457-460 of DbUpdateController.php for reference.
$querycontains the value of$ret['#abort']. When an update fails, a translated version of the message being logged is displayed to the user stating where the update failed at.I agree with @kim.pepper that this seems a bit unnecessary since error messages being logged to watchdog currently aren't being translated.
Hope this helps!
Comment #81
cliddell commented@abhijeet.kumar2107 Thank you for expressing interest in this ticket! I'm unassigning this ticket in accordance with this entry from the Drupal.org community wiki:
Comment #82
cliddell commented@xjm @kim.pepper in response to #75 and #76, could we potentially leverage the already existing
Error::renderExceptionSafe()method which is being used to accomplish a very similar task and just make inclusion of a backtrace optional using a second argument as a flag? Something like:By making the second argument optional and default to
TRUE, we can maintain backwards compatibility with existing calls toError::renderExceptionSafe()and consolidate the implementations, rather than creating another method to accomplish the same task only without a backtrace.Comment #83
kim.pepperLooking back, I don't think passing the $error argument to format a message is going to work. We need to let the logger do that.
Let's just convert the constant to a static function then, as @xjm suggested.
Comment #84
cliddell commentedOkay, just a question for clarity then: If we create a
translatedDefaultError()method should we callt()a second time at the call site or pass the substitutions directly to the new static method.Using the first example from update.inc:
Comment #85
neclimdulI believe the suggestion is to just use the return from the method without another call. The problem wouldn't be that
tthe function can't translate the input, At runtime the constant will go into it as a string like any other which is why tests pass. The problem would have to be in how we generate translations and that static analysis I guess doesn't handle constants.I think that's kind of a weird arbitrary limitation but that might be beside the point. Something feels kinda off about that sort of method specifically for the installer. At the very least translating errors is something we never do with this one weird exception. Why does this exception exist? If I remember correctly we don't translate errors so you can google them consistently regardless of your language. I don't know why the installer would be an exception to this rule and maybe it shouldn't be.
Comment #87
nwom commented#73 no longer applies to D9.1.x. Here is a re-roll.
Comment #88
daffie commentedComment #89
neclimdulDoesn't look like that re-roll worked. Here's another attempt. Most of the conflicts where from #2807743: Switch from deprecation notice to warning for non-standard placeholders in FormattableMarkup::placeholderFormat() and #2949419: Pass the raw exception to logger implementations which where also testing error/watchdog stuff. Additionally I think a small use conflict somewhere.
Also bumped the version in the deprecation to 9.2.x since that's where this is at.
Comment #90
neclimdulLooking back, xjm's feedback in #75 hasn't been addressed.
I did some quick digging into the "do we translate errors elsewhere" open question. Seems yes but its complicated.
https://localize.drupal.org/translate/languages/hu/translate?project=dru...
From what I can tell, anything going through the logger also gets translated? Does this also not support constants/variables? That would be pretty frustrating and easy to mess up. How do we answer that? I don't know how translatable strings are parsed out of core anymore.
Comment #91
eelkeblokJust to clarify on that last question, the issue is exactly what you were saying in #85; the guideline to only enter the "raw" English text in translation function is because of the way these originals are extracted from source. I am not intimate with the code responsible (e.g. in the PotX project) but I think "static analysis" is giving it more credit than it deserves :) I think it is basically just doing a regex match on a handful of patterns. One of those is log entries, because DB log (?) will translate error messages. I'm not actually positive it is DB log where that happens, but it would seem a logical place and I do know for a fact my Dutch sites all have translated log entries in the recent logs :)
Comment #95
volegerRerolled #89 against 9.3.x
Updated deprecation message
Added more replacements
Comment #96
andypostLooks like new loggers (services) could use separate issue
Comment #97
neclimdul@andypost which services? Been a while since I've looked at this but I don't see any new services, this is just replacing existing calls really.
Comment #98
andypostSorry, probably I did read wrong patch
btw How to restart test? the failure looks unrelated
Comment #99
volegerPlease, review the MR. The test based on the MR was passed.
Comment #101
daffie commentedTo "needs work" for the unresolved thread on the MR.
Comment #102
volegerComment #103
volegerAddressed #101
Comment #104
daffie commentedAll code changes look good to me.
The only thing I am now missing is a deprecation message test for the deprecated function. Sorry, I did not check for it earlier.
After that it is RTBC for me.
Comment #105
kim.pepperAdds a deprecation test.
Comment #106
daffie commentedAll code changes look good to me.
The Is and the CR are in order.
For me it is RTBC.
Comment #107
alexpottThe
is not correct. I've chatted with the release managers and confirmed that we can deprecate in Drupal 9.4 and remove in Drupal 10.
Let's do that here - it means we have one whole release less carrying around deprecated code. We should only deprecate for Drupal 11 now if something is super-disruptive. This change is not. You can remove the usages already in 9.3.x in contrib and custom code because everything you need already exists.
Can we get one patch deprecating in 9.4.x and one patch removing everything for 10.0.x. Thanks!
Comment #108
berdirHm. It might not be complicated to replace, but it's a function that is used a lot. Not just in contrib (38 pages of results on http://grep.xnddx.ru/search?text=watchdog_exception&filename=), it's also going to be used a lot in custom code as it's the default thing to do in a try/catch.
And all it costs us to keep is a 15loc function in a file that we won't be able to remove in D10 anyway.
And last, it's going to cause more logger channels to be injected in a way that's bad for performance (factory services or calling getLogger(), which is bad for performance. FWIW, the current patch doesn't actually use DI for logger/logger factory in any place that still used this.
So IMHO, we should not push this.
Comment #109
kim.pepperwatchdog_exception()is already calling \Drupal::logger($type)->log($severity, $message, $variables);but are you saying we'd be moving away from lazy-loading the logging service and that would be bad for performance?Comment #110
berdirYou don't have to, you can just inject the logger factory and get the channel only when needed. But it's a pretty common pattern to do that already in the constructor as it looks cleaner. Or define a service with a factory which is pretty common in core and copied a lot. Most of those logs are triggered very rarely, so anything we do already upfront is a tiny to a little bit more expensive, yes.
I'm not saying that means we shouldn't do it, just that there is IMHO not a good reason to force this for a D10 removal, there's very little benefit (and even a tiny bit of extra cost depending on how it's done) to force everyone to remove it in the next few months.
Also, it's actually not really backwards compatible to do now, not if you want to use that new constant?
Comment #111
mfbYes it'd be nice to wait until the new constant is available to ask module developers to update their exception logging code (the replacement code is fairly verbose even w/ the new constant :)
Comment #112
alexpottI think we need make it easier to do the correct thing with injecting loggers. It should be possible to inject
'@logger.channel.php'and it not be unnecessarily costly if it is not used.Comment #113
kim.pepperSo to move forward on this issue, are we going to deprecate in 9.4.x and remove in 11.0.x?
Comment #114
alexpott@kim.pepper - I'm not sure - I think we might need to re-evaluate the logging system architecture. It feels as if the architecture is wrong if injecting a logger is viewed as something that is expensive.
Comment #115
kim.pepperIs that from performance analysis or just a hunch?
Comment #116
mfbIn my testing, there is some minor memory and time savings if you can complete a request without any loggers/logger channels being initialized. But I'd assume there is lower hanging fruit as far as performance fixes go. :)
With database logging as the only enabled logger, injecting the first logger channel takes 8376 bytes memory and ~178 microseconds. These numbers increase with each logger module that is enabled.
Injecting an additional logger channel was another 616 bytes of memory and ~9 microseconds, so these are very low impact.
Comment #117
mfbAs far as when to commit this, I was thinking it would be excellent if the new constant could go in ASAP - like, a 9.3.x point release, if that's allowed? That way developers have the option to start fixing their error logging code now, even before the function is deprecated.
Comment #118
kim.pepperI created an issue #3260044: Add a constant for watchdog_exception message if that helps to get this in.
Comment #119
kim.pepperComment #120
daffie commented#3260044: Add a constant for watchdog_exception message has landed.
The MR needs a reroll.
Comment #121
joachim commentedRemoving procedural code is good, but watchdog_exception() was nice DX. We're replacing a single call with a fair amount of boilerplate.
Couldn't we have something like:
Comment #122
kim.pepperre: #121
Were are using the PSR-3 Logger interface, so we can just add new methods to it.
We need an issue summary update for the pros and cons of the different approaches, as we've been through this discussion already.
Comment #123
anybodyRe #121, #122 @joachim and @kim.pepper: Just had EXACTLY the same idea! That would be really a great DX solution! +++1 :)
The proposed solution from https://www.drupal.org/node/2932520 is a drawback.
My hope was that
\Drupal::logger('update')->logException($exception);was already existing...Comment #124
joachim commented> Were are using the PSR-3 Logger interface, so we can just add new methods to it.
I can't tell whether that is a typo or not -- should it say "we CAN'T add new methods" or that we can?
If we can't, then we can still make the DX better, by using the splat operator to unpack the arguments to error(), like this:
That makes it a 1-liner and no need for the constant for the message string.
Comment #125
mfbSeems like changing the decodeException return array that way would be an unpleasant BC break (although it is of course allowed in a major version); a new method seems less prone to cause problems (code that is compatible across versions can check if method exists just as it would check if the constant exists).
Comment #126
joachim commentedI couldn't remember if decodeException() was new in this issue or already existed. Another method, in the latter case. The use of the splat with a helper method which provides all the parameters to error() is the main thing :)
Comment #127
kim.pepperI'm +1 to a method that can be passed to a logger with a splat. I think it would need to be a new method though.
Comment #129
andregp commentedI did a reroll on the MR to make it mergeable again, then created a new method (#127) to pass the error using the splat operator (as suggested in #124 and #126)
Comment #130
joachim commentedI've rebased this but not looked at the test failure.
Comment #133
bradjones1We're against 10.1.x at this point; new MR squashing the prior changes and updating the dangling unreconciled diff.
Comment #134
bradjones1Comment #135
bradjones1I'm not quite familiar enough with the testing environment to know how to fix the phpstan error:
Instantiated class Psr\Log\Test\TestLogger not found.Comment #136
joachim commented> We're against 10.1.x at this point; new MR squashing the prior changes and updating the dangling unreconciled diff.
Please don't do squashes of commits. It loses history, and it makes it harder to do future rebases.
I'll clean up the rebase conflict as soon as I have time.
Comment #138
joachim commentedI've fixed the stray merge conflict and pushed to branch 2932518-deprecate-watchdogexception. That's still on 10.0.x, for the benefit of anyone wanting to patch their site.
I've then made a new branch rebased onto 10.1.x. The correct way to do this without using squash is:
> git rebase --onto 10.1.x 10.0.x
The new branch is 2932518-deprecate-watchdogexception-10.1. I've made a new MR for that.
Could the MR with the squashed code be closed?
Setting to needs work based on review comments.
Please make new commits on 2932518-deprecate-watchdogexception-10.1 (and optionally cherry-pick to 2932518-deprecate-watchdogexception).
Comment #140
joachim commentedARGH I am *sure* I'd cleaned up those merge conflict markers that got left in!!!
Just cleaned up and pushed.
I looked at the test failures. One was the conflict markers.
The other is this, which I don't understand:
------ ----------------------------------------------------------------------
Line core/tests/Drupal/KernelTests/Core/Bootstrap/LegacyBootstrapTest.php
------ ----------------------------------------------------------------------
27 Instantiated class Psr\Log\Test\TestLogger not found.
I can see the class Psr\Log\Test\TestLogger in the codebase!
Comment #143
rpayanmI rerolled the last patch.
Comment #144
bradjones1Doing a "re-roll" on to a new MR is not helpful. Addressing the issues raised in #140 would be a positive contribution.
Comment #145
rpayanm@joachim I asked @xjm and told me that class was removed from the psr/log version that Drupal is using (PSR-4), so that's why the error.
Comment #146
rpayanmCould we use this ?
https://nerdpress.org/2022/03/04/class-psrlogtesttestlogger-not-found/
Comment #147
joachim commentedSee #3321905: Add colinodell/psr-test-logger to core's dev dependencies. Do we need to postpone on that issue?
Comment #148
bradjones1Current MR diff for 9.5.x, if you're like me and not yet on D10 and can't use the MR diff for your project yet.
Comment #149
bradjones1Sigh... that's not right at all.
Comment #150
bradjones1This is for 9.5.x users.
Comment #153
xjmWe don't deprecate new things in 9.5.x anymore, so hiding the patch files. Also closed the redundant MRs for clarity. Thanks!
We don't need to add a test dependency, I don't think; we can construct our own test logger. Edit: although the related issue for auto updates seems to express a different opinion.
Comment #154
bradjones1Updated for latest 9.5.x, not for review but reference.
Comment #155
kim.pepper#3321905: Add colinodell/psr-test-logger to core's dev dependencies was committed so I think this unblocks the test logger issues.
Comment #156
kim.pepperRevisiting this issue after a long while and found it difficult to work out what MRs to use etc. Added a bit more dependency injection of the logger, and switched to the new test logger.
Comment #157
kim.pepperCode style fixes.
Comment #158
smustgrave commented#122 you tagged for issue summary update that still needed?
Patch #157 appears to have some failures.
The service "drupal.proxy_original_service.module_installer" has a dependen
20:35:49 cy on a non-existent service "logger.channel.system". Did you mean one of t
20:35:49 hese: "logger.channel.default", "logger.channel.php", "logger.channel.image
20:35:49 ", "logger.channel.cron", "logger.channel.file", "logger.channel.form", "lo
20:35:49 gger.channel.security"?
Comment #159
kim.pepperLooks like the module installer has undeclared dependency on the 'system' logger channel. I've changed this to 'default' as this causes issues with the proxy.
Also reworked
\Drupal\Tests\update\Unit\UpdateFetcherTestto use the new test logger which greatly simplifies this test.Comment #161
kim.pepperFixes `workspaces.association` service definition.
Comment #162
smustgrave commentedAssuming this no longer needs a reroll.
Only think I saw was that there are 2 instances of
is deprecated in drupal:10.0.0
But the others are deprecation in 10.1
Shouldn't they be the same?
Comment #163
andypostPatch cleaning up DI and fix #162
I think logger needs injection here
may need DI too
already using system logger
no DI found
Comment #164
smustgrave commented@andypost not sure if you meant to leave in Review for the points you mentioned.
Comment #165
andypostI set NR for my changes, also fixed #163-3
Comment #166
kim.pepperFixes for #163 1,2 & 3.
4. This is a value object, and doesn't need DI IMO.
Comment #168
kim.pepperFixed the RouteProviderTest which needed to pass the logger to the constructor.
I have changed the order of arguments in
\Drupal\Core\Routing\MatcherDumper::__construct()so the$table = 'router'param is last. This is because we want the logger to be required in 10.0.x but a required param can't come after an optional one. This$tableparam is only for tests as far as I can tell. Is there a better way to handle this?Comment #169
smustgrave commentedCan we remove the IS update tag?
Also applied patch #168 and there were 2 instances of watchdog_exception I found that may need replacing.
In SecurityAdvisoriesFetcherTest
Then in CronSuspendQueueDelayTest
// Capture logs to watchdog_exception().Everything else looked good to me.
Comment #170
kim.pepper#169 Replaced comment instances of watchdog_exception and removed IS update tag.
Comment #171
smustgrave commentedThanks @kim.pepper!
Comment #172
dagmarThe patch looks good, but in my opinion the change record needs to be a bit more verbose on other ways the
watchdog_exceptionneeds to be replaced:Only the 2 first parameters of this function are covered:
function watchdog_exception($type, Exception $exception, $message = NULL, $variables = [], $severity = RfcLogLevel::ERROR, $link = NULL)There is no example of how to use $link and other errors than
RfcLogLevel::ERROR.Comment #173
alexpottThere's no cases of ever passing a $message in core so it seems this is unnecessary. Everywhere it could be used we see:
$this->logger->error('Invalid security advisory format: ' . Json::encode($advisory_data), Error::decodeException($unexpected_value_exception));So perhaps this method that returns a tuple is unnecessary.
Did we consider adding
Error::logException($logger, \Exception|\Throwable $exception, string $message = Error::DEFAULT_ERROR_MESSAGE, array $additional_variables = []) :voidThe implementation could then be:
Comment #174
berdirThis is reverting back to a !placeholder, that doesn't exist and is wrong. Not sure why that's not failing, not tested?
this was not introduced here, but this usage is wrong. the message must never by dynamic. The messsage is passed to t(), every unique combination will result in a separate, translatable string and fill up the locale tables. the advisory data needs to be put in the variables and passed together with the decoded exception.
Comment #175
kim.pepperI'll look at implementing #173
Comment #176
kim.pepperThanks for the reviews.
Implemented
Error::logException()as suggested in #173 and made a few conversions that simplify the code. I removed thedecodeExceptionWithMessage()function. Great improvement!Fixed issues with #174 1 & 2.
Comment #177
kim.pepperI updated the CR to address feedback in #172 and realised we had hard-coded the log level to ERROR where previously this was an option. I've added an extra param to Error::logException() to take a LogLevel defaulting to LogLevel::ERROR.
Comment #179
kim.pepperMissed a couple of things which are now fixed:
Comment #180
kim.pepper#3340712: Add Single Directory Components as a new experimental module Added a new call to watchdog_exception. Fixing that.
Comment #181
kim.pepperComment #184
smustgrave commentedWow quick turnaround on the new sdc module.
These ones are sometimes above my head but from what I can tell all the points 173 + 174 have been addressed. So don't mind remarking.
Comment #185
alexpottThis is a breaking change - we should not be setting $variables to an empty array here.
Let's change this to use the new
Error::logException()too.This module will be added to the core library and will not be a module. I think we should take this opportunity to chose an existing logger channel. I think this message should end up in the default logger channel. Ie.
logger.channel.default.Comment #186
kim.pepperRe: #185 Thanks for the review.
Comment #187
alexpottI was thinking about asking for a test about passing variables into the watchdog_exception() function because we broke it... and this has lead me to wondering why are we changing the deprecated code? I think in general we should only do this when we have to and I can't see a reason why we have to here.
Comment #188
kim.pepperre: #187 rolled back changes to
watchdog_exception().Comment #189
smustgrave commentedFrom what I can tell #185 + #187 have been addressed. Don't mind moving this forward.
Comment #190
larowlanThis won't work how we're expecting here.
If someone is extending it, their third param will be a string (The table name) and they will get a fatal here rather than a deprecation error.
I think we need to remove the type hint and use an instanceof check too.
There are four scenarios here:
* two params
* three params, where third is a string
* three params, where third is a logger
* four params
We're missing handling for the second case
Exception extends Throwable, any reason we needed the union here instead of just using Throwable?
Unrelated, but I'm not too keen on the use of colinodell/psr-test-logger when we already had
\Symfony\Component\Debug\BufferingLogger- I commented in #3321905: Add colinodell/psr-test-logger to core's dev dependencies to clarify why we need both.Comment #191
kim.pepperThanks for the feedback in #190
Had a quick look at
\Symfony\Component\Debug\BufferingLoggerand doesn't provide the ability to read back the logs AFAIK. It does log toerror_logon__destruct()so maybe that's useful?Comment #192
kim.pepperOops. Forgot to actually set the logger.
Comment #193
kim.pepperReplaced typehint on
decodeException()instead oflogException()Comment #196
mstrelan commentedCouple nits and questions but NW on the comment about
$table. Otherwise LGTM.Doesn't bother me but re-ordering this is technically out of scope.
$tableis not nullable so this condition is unreachableDo we need
\Exceptionhere since it extends\Throwable?Is it worth mentioning that this should be one of the levels defined in \Psr\Log\LogLevel?
Comment #197
kim.pepperThanks for the review @mstrelan! RE: #196:
Rolled back the import re-ordering.
Also fixed incorrect namespace for
\Drupal\KernelTests\Core\Routing\LegacyMatcherDumperTestafter moving it.Comment #198
larowlanFWIW
\Symfony\Component\Debug\BufferingLogger::cleanLogsis how you read them back. But regardless, out of scope here - the horse has bolted - the discussion can happen elsewhereComment #199
mstrelan commentedAll feedback since #190 has been addressed, marking RTBC.
Comment #200
larowlanSaving issue credits.
Comment #202
larowlanCommitted to 10.1.x and published the change record.
Comment #203
kim.pepperCreated a follow-up for somewhat related #3357018: Fix typehints in \Drupal\Core\Utility\Error::decodeException()
Comment #204
larowlanAdded #3357046: Replace usages of colinodell/testlogger with BufferingLogger from symfony/error-handler, then remove dev dependency on testlogger to discuss use of TestLogger