Problem/Motivation
With Syslog module enabled, syslog quickly gets cluttered with PHP notices and other things I don't care to pay attention to. Additionally, we're using www.splunk.com to monitor a number of servers. And now we're on the brink of being forced to pay a lot more for our subscription because of the amount of data being indexed because syslog is so big.
Proposed resolution
Provide a way to ignore some type of logs written to some specific loggers.
Remaining tasks
- Decide which approach should be used to filter by severity level. See #110
- Write patch (See proposed solution in #46)
- Write tests
User interface changes
None. Ignore logs are defined in settings.php
API changes
None.
| Comment | File | Size | Author |
|---|---|---|---|
| #129 | 1408208-nr-bot.txt | 161 bytes | needs-review-queue-bot |
| #113 | interdiff-107-113.txt | 498 bytes | loparev |
| #113 | 1408208-loglevel_filter-113.patch | 26.91 KB | loparev |
| #107 | interdiff-105-107.txt | 2.22 KB | loparev |
| #107 | 1408208-loglevel_filter-107.patch | 26.95 KB | loparev |
Issue fork drupal-1408208
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #1
bryanhirsch commentedThis patch includes both the proposed changes described above and the corresponding changes proposed to dblog here, http://drupal.org/node/1295182. It really doesn't make sense to do these separately because they're both form_alter()ing the same System form. From a UX perspective, to do one without or differently than the other is really backward.
Comment #2
bryanhirsch commentedFixes minor issues in previous patch. Checkboxes FAPI elements do not have #multiple property. #options were hardcoded for two checkboxes where they shouldn't have been.
Comment #3
bryanhirsch commentedRe-uploading patch that didn't upload correctly in comment #2.
Comment #4
bryanhirsch commentedRe-rolling this patch post review for Drupal Gardens by David Rothstein at Acquia.
Removing unnecessary db update to dblog module. Also making syslog UI able to provide defaults independent of watchdog table (which may not exist if Database Logging is not installed).
Comment #5
bryanhirsch commentedThis version of the patch includes minor bug fixes. With the previous patch, in cases where dblog module was enabled and no message types are available in the database yet, we were getting php notices and an unfriendly user experience. This patch resolves these issues.
Comment #6
bryanhirsch commentedRe-rolling again.
Comment #7
David_Rothstein commentedWe discovered an issue with the patch: It calls watchdog_severity_levels() from a hook_watchdog() implementation, but watchdog is one of Drupal's bootstrap hooks which can get invoked very early in the page load, so in some cases that function won't be loaded yet so you can get a fatal error.
The attached patch fixes it by explicitly loading includes/common.inc. Note that this is rerolled based on #4 above, not #6, since #4 is what I was working off of. But I'm also attaching the interdiff showing the changes I made, so someone can apply that to #6 later.
Also setting this to "needs review" so that the testbot will run on it. (I did verify that there were test failures due to the earlier patches and the attached patch fixes the ones I saw, at least.)
Comment #8
irek02 commentedIf I uncheck some options in 'Allowed message severity ' section, then they don't show up in logs, so it works properly in that way.
However, if I uncheck some options in 'Allowed message types' section, e.g. php (screenshot), then it doesn't prevent php-type messages to show up in logs (screenshot). I also tried to make custom named types of messages in watchdog() ('irek02-patch check '), but after unchecking them they were showing up in the log anyway...
P.S.
To check the patch I included all 8 severity types watchdog() functions in the beginning of the node_view() function in node.module:
Comment #9
irek02 commentedThis piece of code in the patch is responsible for checking if the message type is allowed to go in logs
The reason it doesn't work, because when we uncheck some option in message types, then the value of this type in $allowed_types becomes '0' (e.g. 'php' => '0'). So the proper way to see if any options were unchecked would be something like this:
After I did this correction the unchecked types of messages stopped showing up in the logs.
Comment #10
irek02 commentedHere is the patch with changes I mentioned in my comment #9.
However, sometimes I get warning messages after I save the changes in admin/config/development/logging. I've noticed it before I started modifying the patch:

Comment #11
soyarma commentedBump! This wooden toy needs to become a real boy (AKA get it into core :))
Comment #12
kenorb commentedLooks great.
Comment #13
fgmSomething simple, also with tests: #1268636: Watchdog should ignore reports below the system reporting level.
Note that this is part of the motivation behind #1594956: Merge watchdog and Symfony logger classes too.
Comment #14
SumeetSingh commentedCould not reproduce #10, can anyone else?
Re-rolled patch for 8.x branch
Comment #16
SumeetSingh commented#14: 1408208-14-syslog-dblog-filter-messages.patch queued for re-testing.
Comment #18
SumeetSingh commentedBetter patch should pass tests
Comment #19
irek02 commentedThat looks good for me.
Comment #20
cobadger commentedApplied patch from #18 and added the following to my node_view() function in node.module (with thanks to irek02 for giving me this code):
$message_types = array('php', 'page not found', 'content');
// Remove quote marks
$severities = array(WATCHDOG_DEBUG, WATCHDOG_INFO, WATCHDOG_NOTICE, WATCHDOG_WARNING, WATCHDOG_ERROR, WATCHDOG_CRITICAL, WATCHDOG_ALERT, WATCHDOG_EMERGENCY);
foreach($message_types as $message_type) {
foreach($severities as $severity) {
watchdog($message_type, 'Checking the patch: '.$severity, $variables = array(), $severity = $severity, $link = NULL);
}
}
Results:
Comment #21
star-szrThanks! Some small documentation and style fixes.
These comments should end in a period.
This comment should be wrapped at 80 characters.
Need a space between 'if' and '(', the if statement should use braces, and the return should only be indented 2 spaces within the if statement.
There are two comments with the "curent" typo.
"Get $all_types to provide as default values for types of messages to log." - or remove the first comment, I think the "If dblog is enabled…" comment explains this better.
Comment #22
star-szrForgot to mention, there are a few lines with trailing whitespace as well :)
Comment #23
ramlev commentedThe patch from #18 fails on 8.x rev 6273774d30615b882068ffe20736137b45d1f2a6, since the dblog_install hook doesn't even exists in the install file.
Im working on getting it to work on HEAD and fixing the issues mentioned above.
Comment #24
ramlev commentedThis a bit more advanced, since a lot of variable_get, variable_set is handled, and needed to be converted to the new configuration system.
Comment #25
ramlev commentedRerolled the patch from #18.
Now supporting CMI.
Comment #26
geerlingguy commentedI don't want to bikeshed or anything, but is there any chance we could get in the ability to alter or discard watchdog messages in other modules? I'm basically looking for the ability to have a custom module hook in and make watchdog() not write a given message (regardless of the severity level).
For example, for one site, I may be interested in failed login attempts, but I don't care about login and logout notices. Or, I might be interested in PHP notices from one module, but not for others, so I could alter the watchdog entry and somehow tell watchdog to not log a message if it's from module 'xyz'.
Comment #27
fgmTechnically, nothing would obviously prevent us from adding such an alter hook.
However, watchdog() calls can be very numerous and we want their resolution to be as fast as possible, so I do not think it is a good idea to add it. Better filter and route calls directly from the configuration, which is the direction taken by the Monolog patch #1289536: Switch Watchdog to a PSR-3 logging framework, on which I'll be working again soon.
Comment #27.0
fgmUpdated issue summary.
Comment #28
breathingrock commentedMight I suggest adding an alter hook before the log entry is processed. This would not only be generally useful, but in handling cases where the log entry array is emptied, we can prevent processing of watchdog messages as needed.
Comment #30
breathingrock commented28: bootstrap_watchdog-log-entry-alter_1408208_28.patch queued for re-testing.
Comment #32
breathingrock commentedFixed patch - created in relation to Drupal root.
Comment #33
elijah lynnThe patch above won't apply to a standard Drupal site as most don't have a docroot folder (as Acquia does).
Try cd /docroot and then run git diff --relative inside docroot.
Comment #34
breathingrock commentedThank. you. ElijahLynn.
This one should work now.
Comment #35
elijah lynnComment #38
elijah lynnThis is getting tested against D8 not D7. It will need to be re-rolled for Drupal 8.
Comment #39
Dave Cohen commentedI agree with @breathingrock that using drupal_alter() is a nice approach and deserves to be in D7 and D8. Thanks for that patch.
Comment #40
fgmdrupal_alter() is nice, but as I said on #27, it also has a cost, and this hook can be fired quite often, so we probably want to minimize its cost: simply cutting out messages by reference to a logging level, as proposed on #1268636: Watchdog should ignore reports below the system reporting level, is less expensive.
Comment #41
Dave Cohen commentedAs you know, drupal_alter() has benefits to offset that cost. It's been added to more than a few functions that can be fired quite often. Like url(), menu_get_item(), etc. IMHO it's worth the cost for (a) the added flexibility, and (b) the small patch that could actually make it into D7.
I haven't actually tested the performance impact it would have on watchdog(). But watchdog() already invokes hook_watchdog(), so I'm guessing the change would be from kinda slow to kinda slower, not from fast to slow.
Comment #45
dagmarComment #46
fgmSince we are now firmly in D8 territory and no longer in D7, maybe a cleaner approach would be to use the native features we have in D8 ?
In the logger case, we have the notion of overriding a service, which means code which would run less often. In D7, using drupal_alter means a log event with the patch is handled like:
By contrast, in D8, assume a service override:
logger.channel_filteredservice implementing this modification, and tagged as a service collector for "logger"services
Comment #48
dagmarSince feature requests are only accepted for Drupal 8.5.x+ and there is no patch for D8 here, I'm changing the status to active. The plan proposed by @fgm in #46 seems a reasonable plan to start.
Comment #50
loparev commentedHi. I've faced the same need and found this thread. Pretty informative and provides some good ideas. But, @fgm, seems like your idea with re-assigning parent for logger channels will not work as
LoggerChannelFactory::get()creates only instance ofLoggerChannelclass ($instance = new LoggerChannel($channel);).So, in order to get this work, you need to re-define the whole chain: logger factory -> logger channel. I suggest even easier approach: don't change parents for all the channels but change the class of
logger.channel_baseinstead.I didn't find the better approach than just patch
systemmodule and implement logger channel there. It could be done directly inLoggerChannelbut I found it weird that class fromDrupal\Core(lib) must know something about module's config.Please, take a look at this patch. With this applied you can setup filtering mapping for each channel and even loggers. For example:
In this example,
DbLogwill log records which have levelwarningand higher. Syslog will log every record. All these rules are applied only tomy_channelchannel.Comment #51
loparev commentedComment #53
loparev commentedCorrect one (previous didn't create new files from the patch)
Comment #56
loparev commentedComment #57
loparev commentedComment #58
dagmar@Loparev Thanks for working on this! I have a few comments on the current code, and some additional requests at the end.
In my opinion, I think is better to expose this as a config setting in settings.php. I don't remember a place (besides configuration management UI) where you can specify settings directly as YAML.
This could be refactored to exit the function sooner, instead of having so many nested foreach and ifs.
Here you could check if the settings are defined to alter the logger.
Finally, there is one way to test the syslog functionality. Take a look to #2874069: Make syslog testable to know how initial tests were implemented.
Comment #59
fgmRegarding config/settings, IMO logging configuration is very much a per-environment thing, so it is more something that belongs in settings than in config ; "config settings in settings.php" is a bit ambiguous about that.
Regarding testing, #2874069: Make syslog testable is a start, but a good next step would be to have some SyslogInterface for this wrapping implementation, one level up from LoggerInterface, allowing a simpler spy mechanism than the existing kerneltest which needs to touch the filesystem, probably going one level down to an actual in-memory unit test. This could be done as part of the test for this patch, and possibly taken from there back to the syslog tests.
Comment #60
loparev commentedHi, @dagmar
Oh, ok. Even better to have
$filtering_mappingdefined as php array.Yes, this looks terrible for now. I've started writing unit tests and found out that there are some issue with current implementation. Will work on this.
Got it, thanks.
Yes, I've looked at
syslogtests and took them as a base for my tests.Hi, @fgm
Will think about this, thank you. Probably I will implement tests in
syslog-like styleand then refactor them as you said.Thank you, guys, for the feedback. I'll continue to work on this.
Comment #61
loparev commentedRefactored:
settings.phpinsteadSince we don't use config object here maybe it would be better to patch existing
LoggerChannelinstead of defining the new one and overriding the service definition? I meanLoggerChanneldoesn't depend on core's module config.Comment #62
loparev commentedSeems like it would be better to have this changes directly in core's LoggerChannel.
Comment #63
br0kenMissing the documentation of the property.
Better to change to `string[]`.
Should be `$logFilters` I believe.
Put the condition per line.
Shouldn't we have `break` or even `return` here?
Comment #64
loparev commentedThanks, @BR0kEN
Done.
Comment #65
dagmarI think this tests are a good candidate to use of @dataProvider. Instead of repeat the assertions you could simplify a lot the amount of code provided.
Comment #66
loparev commentedI avoided using data provider intentionally because I think it's not so good. What if you used data provider with a lot of input sets and the test fails? The only info you will be given is just "Test failed on data set N" (or something close to this). It's really bad because you don't really know what that data set means and what it tests. But if you have separate tests then you will see "thatLongTestNameMethodWhichTestsSomething failed". This error message gives some additional context about the error. And moreover, test will remain that big even if you will use data providers just because you will need to describe your inputs and outputs in one big array.
99% I might be wrong with all of this, just wanted to hear from you about this. If using data providers is a common practice then for sure I will rewrite tests.
Comment #67
dagmarI see what do you mean @Loparev. What about this:
Move this code:
Into a protected method, and then call it in one line. As part of the assertion:
I think it will reduce around 600 lines of code by replacing those 4 lines (including the space) into one line of code.
Comment #68
loparev commentedIndeed. Done.
Comment #69
loparev commentedComment #70
dagmarThanks!
Reading this documentation is not 100% clear to me how this could work. I think this needs to include some extra examples of:
Maybe a useful set of @see links to other documentation pages can enrich the explanations provided here.
Also. Is log_filters the right name? If we compare them with views filters for example or array_filter, they are used in the opposite way in the sense what you filter is what you get from results. Maybe logs_exclude or logs_suppress is a better name for this setting.
Finally. There are 50+ coding standard messages that are reported here: https://www.drupal.org/pift-ci-job/1009521
Comment #71
loparev commentedHi @dagmar
I improved the description and fixed linter reported issues. As for the
log_filters, I would like to suggestlogs_suppression. What do you think?Comment #72
dagmarI'm not sure if this makes sense from a performance point of view. You are forcing to iterate through all the settings in the log function.
If you just save the settings as they are defined in settings.php You can skip a few cycles by just checking if there are some keys defined.
I'm not really sure that we want to ignore all the logs higher than this. I rather prefer to specify each log by separate. Or maybe introduce an 'all' options to exclude them all.
system is enabled by default.
Missing descriptions here.
You could replace CHANNEL_NAME_1 and CHANNEL_NAME_2 by CHANNEL_A and CHANNEL_B.
To make them shorter.
This is not just for core.
I've been thinking about the use of suppress, removed, filter here. I think the word we are looking for is 'ignore'. Since we are not deleting logs, just not persist them.
Maybe here we could use the 'page not found' since this one of the the most used cases.
I think this could be deleted if the
>operator is changed to==in the LoggerChannel class.I'm afraid this is incomplete. Most of the channels are dynamic and they are defined when you call \Drupal::logger().
I list of the ones called by core are:
We may want to show small list of the most relevant.
Comment #73
dagmarComment #74
loparev commentedMm..ok, agree, let's change > logic to = logic. By "all options" you mean something like this: "channel->level->*", "channel->*->loggers", "*->level->loggers", "channel->*->*", "*->*->loggers", "*->level->*" and "*->*->*" (probably just "*")? Just want to make sure we discussed all the things before implementing.
Comment #75
dagmarYes @Loparev. I don't see a use case for
* -> * -> *you could just disable the logging module in that case. Maybe we should analyze if the nested option is the best alternative here.I'm thinking that maybe a plain set of configurations is more flexible and allow the use of `*` in a natural way. For example
Comment #76
loparev commentedAgree. Will work on this.
Comment #77
loparev commentedBut @dagmar, if we choose
we need to admit we would need to iterate through all the settings in each
log()call.Comment #78
dagmarYou could create a new structure based on the settings defined in the settings.php. So you analyze the settings once, and create an optimized version to determinate if a log should be ignored or not.
Comment #79
loparev commentedI've rewritten the patch in order to meet all the requirements/suggestions/review issues (I believe :))
ignore_logsLoggerChannel::isIgnoredLog()which returnsTRUEin case we need to ignore current log recordComment #80
loparev commentedComment #81
loparev commentedFixed typo.
Comment #83
loparev commentedHi @dagmar,
What do you think about the latest patch?
Comment #84
dagmar@Loparev I will review it during this week.
Comment #85
loparev commentedThanks!
Comment #86
fgmReferenced the older issue, which someone found in may.
Comment #87
dagmarUse single quotes instead of double.
I'm not really sure if this is the fastest way to check this. Makes sense from a readability point of view, but I wonder if there is another way to organize things to make this less cpu consuming.
I'm not saying this is slow. But clearly it adds some extra checks before each log and with hundred of logs written by minute it could affect performance.
I'm not a algorithms expert. Maybe another person can take a look and give another point of view.
Comment #88
loparev commentedYou're right. I think using
isset()instead ofin_array()will help not to impact performance dramatically. Additionally, not evaluating conditions in advance will help as well.Comment #89
dagmarThere are some error related to coding standards:
This can be organized to fit in a 80 line.
This is not consistent with the use of level above.
Maybe \Psr\Log\LogLevel::DEBUG, instead?
Comment #90
fgmRerolled addressing the points in #89 plus a few more in other files touched by the patch.
Note that, standards-wise, there is still an issue with the fact that LoggerChannelTest.php contains 2 classes instead of just one. Not sure what is the core practice regarding this: it should respect coding standards, but test class files with multiple classes in them are still very frequent (22 classes in ProxyBuilderTest, for example), so I assumed we would keep things that way.
Comment #91
loparev commentedHi, @dagmar and @fgm.
Thanks for the feedback and fixing sniffer issues. What are the next steps regarding this patch? Are there some other stages to be done before getting this into the codebase?
Comment #92
dagmarThis is still not addressed. I think we should use the LogLevel::EMERGENCY, LogLevel::ERROR, etc instead.
I think we could add a check to verify there something defined in $this->ignoreLogs.
Like !empty($this->ignoreLogs)
Because right now it will fail (but check) all the conditions if the array is empty.
Comment #93
loparev commentedI'll handle this today.
Comment #94
fgmRegarding 1. : the code uses the numeric RfcLogLevel::* constants, so we can not really use the strings or the LogLevel::*. Also testLogRecursionProtection() should probably use the RfcLogLevel::* constants instead of hardcoding 0 to 7, I guess.
Regarding 2. : since this is new code for 8.7 which won't be backported to 8.6, AIUI we can require PHP7 syntax, probably taking advantage of the ?? null-coalescing syntax instead of using isset() or empty().
Comment #95
dagmarI was doing a performance review of the code and noticed this. When you hit a not found page the, this is the how LoggerChannels methods are executed:
In another test, for example adding a
notExistentFunction()to the user login form I get this call stack.(You can try this by yourself adding a var_dump at the beginning of each method of the class.)
Since the constructor is called 2 or 3 times in each execution, it could be interesting to move the code that reads the settings from the constructor outside. For example directly into
isIgnoredLog. That the first time checks if the settings are initialized, and if they are not, load them from there.Comment #96
loparev commentedDone.
Done.
Internally code uses numeric
RfcLogLevelconstants but in settings user defines rules withLogLevelstring constants. Not sure why can't we use string constants here.Done.
Done.
Done.
Comment #97
loparev commentedSorry, uploaded the wrong patch. Here is the correct one.
Comment #98
loparev commentedComment #99
dagmarThis is looking really good to me. I did a full review again and just found a few changes that can improve the patch.
This line should be removed to be consistent with the settings defined before this patch.
The wildcard symbol can be used with any parameter in any sequence.
Comment #100
loparev commentedComment #101
dagmarI did a final review of the patch. And since I have no extra comments to add, the code looks good, with good test coverage, and all my concerns has been addressed, I'm marking this as RTBC.
@Loparev great work! You should probably expect an extra requests of changes by other eyes that may see things that I don't see.
Just a minor, minor thing (that i'm not totally sure anyway).
@var array[string]bool|NULL
Comment #102
loparev commentedI didn't find any occurrences of
array[string]boolin the core and I'm not sure if it's a correct way to sayarray containing string keys and bool values.Thank you for the review!
Comment #103
larowlanwe don't actually need this, or the logger - see https://www.previousnext.com.au/blog/making-your-drupal-8-kernel-tests-f... - we can just make the test class the logger class.
Any reasons not to use
\Drupal\KernelTests\KernelTestBase::setSetting?It feels like these methods all follow the same pattern, setSettings, fire logs, assert counts.
I think you could refactor them to use a data provider and remove the duplication
another option would be to subclass LoggerChannel for testing sake (put the class in this file) and flip the method to public in the subclass, then test that instead
chance you could key this array?
case #3 is harder to debug in a fail than
case 'some description'
Comment #104
loparev commentedHi @larowlan
I'll look at this on weekend.
Thanks.
Comment #105
loparev commented1. Got it. Done.
2. Didn't notice this method. Done.
3. Done.
4. Done.
5. Oh, it was my point why I don't use data providers. I didn't even realize we can set meaningful keys for cases array) Now I see all the power of data providers :D Done.
Comment #106
dagmarsyslogandsyslog_testmodule are no longer required as far I can see.There are a few coding standards warnings reported too:
Also, it could be nice to add a Kernel test to dblog module to test that no logs are created when the settings are set to ignore page not found, like the example of default.settings.php
Comment #107
loparev commentedNo, they are required as we test cases with two loggers presented. Take a look at assertions of
full_match, for example. We ignore messages forLoggingTestlogger fordebuglevel and forchannel achannel and that's why there is'debug_messages_count' => 3,assertion (2 messages for channel_b and one for channel_a).Done. Also, it's weird that test bot doesn't fail the build if there are some coding standard issues. Developer sees the green build, how he/she could know if there are some issues?) I didn't even have a thought to open the build console if it's green.
I don't really understand why do we need this additional test. Seems like we've covered all the cases in
Drupal\Tests\system\Kernel\Logging\LoggingTesttest.Comment #108
loparev commentedLet's merge this if there are no objections?
Comment #109
loparev commentedHi, I know you were working on the Drupal 8.6.0, it is great to see the new release!
I just want to draw a few attention to this ticket. I suggest marking this as RTBC in order to gather more reviews/attention here.
Comment #110
dagmarI took another look to the patch and it is looking really good.
However after reading again the issue summary and thinking this feature being used by all sort of drupal (big and small) sites I wonder if we should provide a way to decide wether Severity Level filter should be more customizable. (Greater than certain level
>=or just equal to the defined setting==)The oldest request I found related to this issue is: #77875: Allow administrator to set logging level for Watchdog. The idea of Severity greater or lower than certain values was proposed there too. I was the one that proposed in #72 that this should be changed to
==but now thinking this more carefully I'm not sure if we should support both options. Or if we opt in for one of them, at least think better what is the best option here.Having
==gives enough flexibility to select what to ignore and what not. But using>=allow users to reduce the amount of settings to write in case you want to ignore a group of different severity levels for some particular channel or logger.I understand this adds complexity to the patch and also requires some extra considerations of how to define if the severity check should be greater, equal or lower than the specified. Also brings some collision situations (where you define
< Errorand> Warningin two different options.So please, share your thoughts on this.
Regarding the current code:
This is no longer the case. Since you are changing the visibility scope in LoggerChannelTestable.
Another thing I notice is that there is no use of the Splat operator in core yet. There is a relevant issue here: #2551661: replace call_user_func_array() with splat (variadics) which is quite old and the reasons that blocked the process are no longer valid today.
Comment #111
dagmarComment #112
dagmarComment #113
loparev commentedAs for
==vs>=. Both have pros and cons. Logic==is straightforward but too verbose. On the other hand>=logic is flexible enough (you can ignore a bunch of logs with only one rule defined) but it's too flexible :) (there might be collisions in logic but, to be honest, it's not the issue as we could implement "first/last matching rule wins" logic). So, both options are good enough. It's just the question of taste. Personally, I would prefer==logic as it's simple, straightforward and doesn't require handling collisions and extra considerations for severity levels.Oh, thank you. Fixed.
According to this post since
Drupal 8.7.xit's required to usePHP 7and, thereby, splat operator in the core is no longer the issue. So it should be safe to use it in this patch since it against8.7.x.Comment #114
loparev commentedComment #115
xanoWhen I stumbled into this issue I thought the same @fgm brought up in #27: why don't we use the existing tools to achieve this, without having to introduce new settings or APIs? Like Monolog's FilterHandler, we can decorate any
LoggerInterfacewith our own custom or third-partyLoggerInterfacedecorators that filter log messages by severity, or by whatever other condition you want. The added benefit is that this approach allows the use of existing third-party PSR-3 solutions, and it's very similar to how other logging frameworks handle this, making this easier to grasp for a lot of people.Comment #116
fgmI just did a roundup of the patterns we currently have in core to access logger channels, and it's annoyingly diverse:
{ parent: logger.channel_base, arguments: ["channel_name"] }, which is AFAICS the recommended pattern. However...exception.loggerandplugin.manager.mailboth directly take@logger.factoryand do what they want with it outside general viewlogger.channel_base,logger.channel.contactandlogger.channel.fileare created with something like { factory: "logger.factory:get", arguments: ["channel_name"] }So tackling filtering early on, on the "emitter" side, is not obvious: the filtering will be easier on the "logger" side, because these are gathered by the
@logger.factoryusing the { tags: { name: "service_collector", tag: "logger" } } pattern, meaning all loggers gathered at this point can be handled at once by adding an implementation ofCompilerPassInterfacethat will run before theTaggedHandlersPassand update all services tagger withloggerto wrap them with a filtering decorator before they are collected by theTaggedHandlersPass.Comment #117
loparev commentedJust want to follow up on this. What should be the next steps?
Comment #118
fgm@loparev, maybe evaluating the "compilerpass" option I mentioned ?
Comment #127
alienzed commentedthis feature would be amazing... kinda nuts that it doesn't already exist!
Comment #128
sonam.chaturvedi commentedPatch #113 does not apply successfully on 10.1.x-dev. Need new patch for it.
Comment #129
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #133
andyf commentedThanks for all the work on this. I was about to add an issue to squelch 403/404s from the watchdog log, and thought there might be something more general floating around!
I've taken the patch from #113, made an MR from it, rebased against latest, and nudged the tests back to green again.
Comment #134
andyf commentedI started looking at this, and while I kinda hate to push this back further when what's there is eminently usable, I was thinking it might make sense to add a more general purpose
collected_service_decoratortag to simplify adding decorators to any group of collected services. Don't want to add complexity, was just thinking we'd be pretty much writing it anyway, so it might make sense to do it in a general purpose way.If that makes sense, I'm not sure if it should be a new issue where it can be worked on in isolation, or part of this issue where it can be used when it's introduced.
Thanks!
Comment #135
mstrelan commentedThis is not really system.module, changing component to base system. I think we should move the kernel test to
core/tests/Drupal/KernelTests/Coreas well.