Problem/Motivation

Currently a number of user activities log messages at a "notice" level that are more correctly categorized as "info" messages, per RFC 5424, namely:

* User Registration notices
* User Login notices
* User Role additions / updates
* User Password Recovery Requests
* User using "one time" login link
* User sessions start / end
* User accounts blocked / deleted
* User Flood control notices

In all of the above instances, when these messages are logged the system is actually functioning as designed, and logging these events is truly "informational" in nature.

Proposed resolution

Let's lower the log message Severity level to one more appropriate, and log these as info events, not notices.

User interface changes

The user login and related messages are now styles as "info" messages rather than "notice" messages.

Before

After

Release notes snippet

Log level changes

Some routine user events which were previously logged as notices are now logged at the lower-severity "info" level. A change record lists which user events are now logged at the "info" level.

Issue fork drupal-3193759

Command icon 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

lhridley created an issue. See original summary.

lisa.rae’s picture

StatusFileSize
new9.98 KB
lisa.rae’s picture

Status: Active » Needs review
zviryatko’s picture

anmolgoyal74’s picture

Status: Needs review » Needs work

There are two more cases which I think should also be changed to info.

In core/modules/user/src/Form/UserPasswordForm.php, submitForm()

    if ($account) {
      // Mail one time login URL and instructions using current language.
      $mail = _user_mail_notify('password_reset', $account);
      if (!empty($mail)) {
        $this->logger('user')
          ->notice('Password reset instructions mailed to %name at %email.', [
            '%name' => $account->getAccountName(),
            '%email' => $account->getEmail(),
          ]);
      }
    }
    else {
      $this->logger('user')
        ->notice('Password reset form was submitted with an unknown or inactive account: %name.', [
          '%name' => $form_state->getValue('name'),
        ]);
    }
baliram.patil’s picture

Status: Needs work » Needs review
StatusFileSize
new11.11 KB

Updated patch according to #5

longwave’s picture

I think most of the changes such as password resets, sessions and one time logins are OK, except for:

  1. +++ b/core/modules/user/src/EventSubscriber/UserFloodSubscriber.php
    @@ -50,10 +50,10 @@ public function blockedUser(UserFloodEvent $floodEvent) {
    -        $this->logger->notice('Flood control blocked login attempt for uid %uid from %ip', ['%uid' => $uid, '%ip' => $ip]);
    ...
    -      $this->logger->notice('Flood control blocked login attempt for uid %uid', ['%uid' => $uid]);
    
    @@ -65,7 +65,7 @@ public function blockedUser(UserFloodEvent $floodEvent) {
    -      $this->logger->notice('Flood control blocked login attempt from %ip', ['%ip' => $floodEvent->getIp()]);
    

    I would suggest that flood controls are "normal but significant" and should remain as notices. These do not occur very often in normal operation.

  2. +++ b/core/modules/user/src/Form/UserLoginForm.php
    @@ -249,12 +249,12 @@ public function validateFinal(array &$form, FormStateInterface $form_state) {
    -          $this->logger('user')->notice('Login attempt failed for %user.', ['%user' => $form_state->getValue('name')]);
    ...
    -          $this->logger('user')->notice('Login attempt failed from %ip.', ['%ip' => $this->getRequest()->getClientIp()]);
    

    Perhaps also login failures are "normal but significant"?

  3. +++ b/core/modules/user/user.module
    @@ -673,7 +673,7 @@ function _user_cancel($edit, $account, $method) {
    -      $logger->notice('Blocked user: %name %email.', ['%name' => $account->getAccountName(), '%email' => '<' . $account->getEmail() . '>']);
    
    @@ -684,7 +684,7 @@ function _user_cancel($edit, $account, $method) {
    -      $logger->notice('Deleted user: %name %email.', ['%name' => $account->getAccountName(), '%email' => '<' . $account->getEmail() . '>']);
    

    Deleting a user is certainly a "significant" event. Should blocking be considered the same?

lisa.rae’s picture

It's a philosophical discussion on whether certain event messages qualify as "notices" or "informational" messages. I could argue that "Flood control" and "Blocked user" could be considered "notices", I think a failed login is definitely an "informational" message. My thought on categorizing these messages in the User module as informational is as follows:

In looking through message logs, "notice" is the level that is also applied to PHP messages that, in and of themselves do not halt code processing, but usually indicate that the code is badly written (missing variable, missing array key /value, etc). Notices related to proper code processing, such as Flood Control events or Failed Logins, are not indicative of coding issues but are instead system events where the system is operating as expected, but the log message indicates an event worth noting.

As such, I would argue that PHP notices are more significant events that require developer attention, and should be prioritized higher than a failed login or a flood control event.

The real issue here is that we are using message level logging for different events, not all that require developer attention.

IMO, messages that are indicative of properly executing code, but indicate events that are worth noting should be logged as informational. This would include Flood Control, Failed Logins, and Blocked users.

vikashsoni’s picture

By this patch #6 we can Demote user log entries from "notice" to "info".

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

mrconnerton’s picture

StatusFileSize
new11.14 KB

Rerolled for 9.3.x / 9.4.x. Resolved conflicts.

mfb’s picture

PSR-3 says notice is "Normal but significant events" and info is "Interesting events. Example: User logs in, SQL logs."

So it seems clear that user login should be logged as "info" :) Meanwhile the events that longwave flagged in #7 do seem more like "normal but significant".

The concept of "notice" is definitely tricky, partly because RFC 5424 and PHP errors use completely different sets of levels, and software has to figure out how to map between the two.. I think of PHP notices as being more error-like than RFC 5424 notices..

zviryatko’s picture

@mfb I guess the main reason for such clean up (at least in my case) is that code (php) issues are not equal to application logic issues, so maybe users should see code issues as separate dashboard? Or at least we should provide documentation for that. I.e., for external log systems, it should send only php issues. I think both types of issues are important, but for different roles. Application logic issues for creating content, blocked users, or possibly some failed orders are critical. For example, if order failed, it is a critical issue for business, but not the same as "undefined is not a function"-like one. Worst scenario if there is connection to external api, and if api respond with 500 issue, because of something failed, i.e. your transaction failed in a middle, or if it returns 5xx response but with validation error - user's credit card doesn't have enough funds. Main question for me – should we collect both errors together? If yes, then ->notice("flood: User blocked") and ->notice("php: Undefined index") are the same level. But in other case better to split them.

mfb’s picture

Issue tags: +Needs change record

@zviryatko Yes it's a good idea to assign errors to the right team and alert them, whether through configuring Monolog or configuring an external log system.. Probably lots more community documentation on this is needed :)

This is a good reminder that a change record will be needed, as folks may already have setup custom logging logic, so adding a tag for that.

mfb’s picture

Issue tags: -Needs change record

Created a draft change record: https://www.drupal.org/node/3259469

It's currently out of sync with the most recent patch on this issue. In light of @longwave's review at #7 I'd suggest rolling a new patch with slightly fewer changes, so that there can be consensus to get something committed :)

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

mfb’s picture

Status: Needs review » Needs work

This needs another reroll and also needs some of the demotions removed as per #7

_pratik_’s picture

Assigned: Unassigned » _pratik_
_pratik_’s picture

StatusFileSize
new8.12 KB

Rerolled patch for 10.1.x with #7 demotions.
Please check
thanks

_pratik_’s picture

Assigned: _pratik_ » Unassigned
Status: Needs work » Needs review
_pratik_’s picture

Assigned: Unassigned » _pratik_
_pratik_’s picture

Assigned: _pratik_ » Unassigned
StatusFileSize
new7.4 KB
new517 bytes

Fixed CCF indentation.

longwave’s picture

Status: Needs review » Reviewed & tested by the community

#24 works for me, all the messages that have been demoted are informational only.

xjm’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs release note

This seems sensible. The CR is succinct but sufficient as well. I made a small edit to the CR to make the before/after clearer.

I think we should consider this for the release notes also. My reasoning is that folks could have automated tooling that audits these logs, including security-incident-related stuff, and such tooling might just silently stop reporting rather than triggering an error condition that a site owner would investigate and follow to the CR. So marking NW for the release note. Thanks!

xjm’s picture

Saving issue credits for the original issue report, necessary rerolls, and helpful reviews and discussions that make it clear this fix is the right choice.

mfb’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: -Needs release note

Added release notes; fixed typo in change record

xjm’s picture

Status: Needs review » Needs work

Thansk @mfb.

The patch no longer applies, so will need a reroll.

nitin shrivastava’s picture

Status: Needs work » Needs review
StatusFileSize
new6.91 KB

reroll for 10.1.x

xjm’s picture

Status: Needs review » Needs work

@Nitin shrivastava Thank you for your attempts to reroll this patch.

Unfortunately, the reroll is incorrect. If you compare the diffstats using either Dreditor or git on the command line, you can see that the two patches have a different number of lines changed. The first has:
7 files changed, 10 insertions, 10 deletions.

The second has:
7 files changed, 9 insertions, 9 deletions.

If you look at RoleForm with your rerolled patch applied, you can see where there is still another instance that needs to be changed:

    if ($status == SAVED_UPDATED) {
      $this->messenger()->addStatus($this->t('Role %label has been updated.', ['%label' => $entity->label()]));
      $this->logger('user')->info('Role %label has been updated.', ['%label' => $entity->label(), 'link' => $edit_link]);
    }
    else {
      $this->messenger()->addStatus($this->t('Role %label has been added.', ['%label' => $entity->label()]));
      $this->logger('user')->notice('Role %label has been added.', ['%label' => $entity->label(), 'link' => $edit_link]);
    }

When you reroll patches, please ensure all of the changes from the previous patch are included. You can use the git diff --stat command for an overview of the changes, and you should read both the original patch and your reroll.

Review the instructions on rerolling patches for a full list of steps to take for the reroll and things to check. If you need assistance with a reroll, you can also get assistance in Drupal Slack.

Thanks!

xjm’s picture

Issue tags: +Needs reroll

Tagging for reroll again and hiding the incorrect patch.

Bhanu951 made their first commit to this issue’s fork.

bhanu951’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll

Re Rolled for 10.1.x Based on patch from #24.

bhanu951’s picture

StatusFileSize
new8.13 KB

Re Rolled to patch as GITLAB is having hiccups with MR.

ameymudras’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new232.51 KB
new254.32 KB

Tested #36 on Drupal 10.1.x

- The issue summary makes sense and provides the necessary details
- The patch applies cleanly
- The severity changes from notice to info
- Release notes have been provided
- Did a code review and there are no noticeable issues

Marking this issue as RTBC

xjm’s picture

Issue summary: View changes

Thanks @Bhanu951 for your reroll and @ameymudras for your review. I did not think to look at the change in markup as a result of the patch, so that's helpful. In the future, you can embed your screenshot images in the issue summary "User interface changes" section to make the issue easier to review. I've done that now.

I also edited the release note so that the link text will be unique and meaningful out of context. (This is an accessibility requirement.)

  • xjm committed 40664e71 on 10.1.x
    Issue #3193759 by Bhanu951, _pratik_, lhridley, baliram.patil,...
xjm’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: +10.1.0 release notes

With the patch applied, I reviewed which User module events are still notices:

[ayrton:maintainer | Tue 09:23:58] $ grep -r "notice" core/modules/user/*
core/modules/user/src/Form/UserLoginForm.php:          $this->logger('user')->notice('Login attempt failed for %user.', ['%user' => $form_state->getValue('name')]);
core/modules/user/src/Form/UserLoginForm.php:          $this->logger('user')->notice('Login attempt failed from %ip.', ['%ip' => $this->getRequest()->getClientIp()]);
core/modules/user/src/Form/UserMultipleCancelConfirm.php:    // Output a notice that user 1 cannot be canceled.
core/modules/user/src/EventSubscriber/UserFloodSubscriber.php:        $this->logger->notice('Flood control blocked login attempt for uid %uid from %ip', ['%uid' => $uid, '%ip' => $ip]);
core/modules/user/src/EventSubscriber/UserFloodSubscriber.php:      $this->logger->notice('Flood control blocked login attempt for uid %uid', ['%uid' => $uid]);
core/modules/user/src/EventSubscriber/UserFloodSubscriber.php:      $this->logger->notice('Flood control blocked login attempt from %ip', ['%ip' => $floodEvent->getIp()]);
core/modules/user/user.install:      \Drupal::logger('update')->notice(
core/modules/user/user.module:      $logger->notice('Blocked user: %name %email.', ['%name' => $account->getAccountName(), '%email' => '<' . $account->getEmail() . '>']);
core/modules/user/user.module:      $logger->notice('Deleted user: %name %email.', ['%name' => $account->getAccountName(), '%email' => '<' . $account->getEmail() . '>']);

For these:

  • First and second results, failed logins: Notice-worthy; useful fo to audit e.g. if someone is attempting to brute-force user accounts, or if there are site-wide authentication issues.
  • Third result: Unrelated use of the word in a comment.
  • Fourth through sixth results, users blocked for flooding: Notice-worthy, e.g. for auditing if the site is under attack, or if a user account has been compromised and is being used for spam.
  • Seventh result: I checked in core/modules/user/user.install and the next line is:
            'The role %role has had the following non-existent permission(s) removed: %permissions.',
    

    That's important information, because it affects the user's access to the site and may indicate a data integrity issue.

  • Eighth result, blocked user. Useful to log because it disrupts user access and could be indicative of a problem.
  • Ninth result, deleted user. Ditto.

Finally, I reviewed the change with git diff --color-words and confirmed that the only changes are the method "notice" being changed to "info" in the 10 relevant places.

Committed to 10.1.x, and published the change record. Also tagging for the release notes in case we decide to include it there. Thanks everyone!

mfb’s picture

Looks like we've made a little rabbit hole of log level demotion issues; maybe we can look at #3255699: Demote routine content entity log entries from "notice" to "info" next.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

xjm’s picture

This was already added to the 10.1.0 release notes draft. We should ensure that related issues update the same CR.