Problem/Motivation

-      watchdog('comment', 'Comment type %label has been updated.', array('%label' => $comment_type->label()), WATCHDOG_NOTICE, $edit_link);
+      $this->logger->log(WATCHDOG_NOTICE, 'Comment type %label has been updated.', array('%label' => $comment_type->label(), 'link' => $edit_link));

Meh.

Proposed resolution

Support this too.

Remaining tasks

Do it.

User interface changes

None.

API changes

None.

Comments

gábor hojtsy’s picture

gábor hojtsy’s picture

Tracked down #1289536: Switch Watchdog to a PSR-3 logging framework as the source of the logger stuff. Left this comment there.

I'm very puzzled by this change or more precisely the lack of thought could have went into considering the translation friendliness, if we even continue to care about that?

1. First of all, this new system had no potx issue opened to support text extraction (now I opened at #2285063: Support for Drupal 8 logger API).

2. Second, the change log mentions methods like notice() and error() which are not defined here, OTOH a log() method is defined which takes a level but that is not mentioned in the change notice.

3. This now supports two possible log string formats. Its unclear to me how that affects translations/translators. Will they get the PSR log format exposed to them? The transformed format? Should we do the same transformation on the potx side?

Answers to some of these questions would be required to even start implementing #2285063: Support for Drupal 8 logger API. Thanks!

gábor hojtsy’s picture

Title: Support loggers » Support for Drupal 8 logger API

Retitle to be a better explanation.

tstoeckler’s picture

So to my knowledge the reason why we didn't/couldn't use t() in watchdog() in Drupal 7 was that we wanted to be able to use watchdog() in situations where the translation system has not been set up yet.

With the removal of st() and get_t() - and instead always being able to use t() - pre-translation-system really means pre-container. Because as soon as you have a \Drupal::getContainer(), t() will work just fine in current Drupal 8.

However, since watchdog() depends on the container as well, we do not support calling watchdog() in a pre-container state anyway: It will fatal - regardless of whether you also try to call t() or not.

So unless I am missing something major I think this issue should be moved to the Drupal 8 issue queue and be re-titled as "Translate messages before sending them to watchdog()". If I am not mistaken that would also allow us to get rid of the LogMessageParser-dance we currently have to do to support runtime translation (in a follow-up).

Thoughts?

gábor hojtsy’s picture

Nonononono! No! We don't translate messages in logging because of multilingual sites. You would be totally capable of managing an e-commerce site with Hungarian, Arabic and Chinese interfaces but probably not able to debug errors with messages in Hungarian, Arabic and Chinese. So we store the messages and the placeholder values separately for translation later and then can translate it for the language of your choice, eg. German for you, Arabic for your colleague who's mother tongue is Arabic to help figure out the issue. We are doing this for several major Drupal releases starting from Drupal 6.

See http://cgit.drupalcode.org/potx/tree/potx.inc?h=6.x-3.x#n286 and http://cgit.drupalcode.org/potx/tree/potx.inc?h=6.x-3.x#n905 (both the type and message are translated when displayed so both are extracted).

So we need to reproduce this kind of approach somehow to the current logging, IF it still translates the messages on display in dblog that is. And looking at DbLogController, we do

        // Messages without variables or user specified text.
        if ($dblog->variables === 'N;') {
          $message = $dblog->message;
        }
        // Message to translate with injected variables.
        else {
          $message = $this->t($dblog->message, unserialize($dblog->variables));
        }
        if (isset($dblog->wid)) {
          // Truncate link_text to 56 chars of message.
          $log_text = Unicode::truncate(Xss::filter($message, array()), 56, TRUE, TRUE);
          $message = $this->l($log_text, 'dblog.event',  array('event_id' => $dblog->wid), array('html' => TRUE));
        }

       // .....
       $this->t($dblog->type)

One could say that if there are no variables that does not mean there should be no t(), that is a bug to be opened. But mostly the message and the type are translated on display definitely.

Finally, we need to figure out how this relates to the PSR log message format which uses totally different placeholder conventions.

ParisLiakos’s picture

2. Second, the change log mentions methods like notice() and error() which are not defined here, OTOH a log() method is defined which takes a level but that is not mentioned in the change notice.

notice(), error() and other methods are provided by \Psr\Log\LoggerTrait which the core class uses

3. This now supports two possible log string formats. Its unclear to me how that affects translations/translators. Will they get the PSR log format exposed to them? The transformed format? Should we do the same transformation on the potx side?

Translators should only care for String::format(). Loggers are responsible for translating PSR style placeholders to String::format style, by using LogMessageParser, before storing them

ParisLiakos’s picture

Oh..i might have misunderstood point 3.
PSR style is gonna be used from external libraries. Drupal code should always use the String::format() style.
So if we want to make external libraries' log messages translatable, we could support PSR style as well. Probably worth it?

gábor hojtsy’s picture

Well, we currently do not even venture into the vendor folder(s) for extraction. I guess we may want to do that for the log messages only. Our other "standard APIs" don't really apply anywhere else. Sounds like we assume / tell module developers to keep using the Drupal scheme, so if we don't parse vendor projects then we are fine storing the string as-is found in the source code without transformation?

ParisLiakos’s picture

yes, exactly..agreed

gábor hojtsy’s picture

So looking at how this is defined (at https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logg...) we would need to find strings in methods names the following:

  1. log
  2. debug
  3. info
  4. notice
  5. warning
  6. error
  7. critical
  8. alert
  9. emergency

I think detection of strings based on these methods will definitely run into several false positives like debug() which clashes with our own testing APIs at least. Not sure if we use the other method names at other places for non-logging things, but given the simplicity of them they very well may be.

gábor hojtsy’s picture

Status: Active » Needs review
StatusFileSize
new2.51 KB

Here is a start for what this looks like.

gábor hojtsy’s picture

StatusFileSize
new4.74 KB
new3.35 KB

Add log() support. Please review!

gábor hojtsy’s picture

Status: Needs review » Needs work

Looking at that again, the log() parser may go to an infinite loop if there is no second argument to log(), which may be with false positives.

gábor hojtsy’s picture

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

This should skip false positives. Also added to the format_plural checker with tests for both format_plural and formatPlural uses.

gábor hojtsy’s picture

Yay, works. Reviews please :)

gábor hojtsy’s picture

Version: 6.x-3.x-dev » 7.x-2.x-dev
Status: Needs review » Patch (to be ported)

Oh well, then, we'll fix it in followups if needed.

  • Commit ba359a2 on 6.x-3.x by Gábor Hojtsy:
    Issue #2285063 by Gábor Hojtsy: Support for Drupal 8 logger API.
    

  • Gábor Hojtsy committed ba359a2 on 7.x-2.x
    Issue #2285063 by Gábor Hojtsy: Support for Drupal 8 logger API.
    

  • Gábor Hojtsy committed ba359a2 on 7.x-3.x
    Issue #2285063 by Gábor Hojtsy: Support for Drupal 8 logger API.
    
SebCorbin’s picture

Version: 7.x-2.x-dev » 7.x-3.x-dev
Status: Patch (to be ported) » Closed (fixed)

Ported to 7.x-3.x as it has been branched directly from 6.x-3.x