Problem/Motivation

The DbLogController::eventDetails() method has the following lines:

        // ...
        [
          ['data' => $this->t('Location'), 'header' => TRUE],
          $this->l($dblog->location, $dblog->location ? Url::fromUri($dblog->location) : Url::fromRoute('<none>')),
        ],
        [
          ['data' => $this->t('Referrer'), 'header' => TRUE],
          $this->l($dblog->referer, $dblog->referer ? Url::fromUri($dblog->referer) : Url::fromRoute('<none>')),
        ],
        // ...

This is forcing to render as links things that may not be valid links. Also, is calling l() method even if there is nothing to render. There are currently two different issues regarding this problem:

Proposed resolution

Remaining tasks

Write a patch.

User interface changes

None.

API changes

New protected method in DbLogController.

Data model changes

None.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dagmar created an issue. See original summary.

cilefen’s picture

dagmar’s picture

I think we should close them as duplicated. But let's wait a few days so they don't get lost on the hidden duplicated queue.

cilefen’s picture

Posting my patch from the other issue.

dawehner’s picture

Issue tags: +Needs tests
xlin’s picture

Status: Active » Needs review
FileSize
3.59 KB

Combined patch from 2755497 and 2858182.

dawehner’s picture

+++ b/core/lib/Drupal/Core/Logger/LoggerChannel.php
@@ -110,7 +110,9 @@ public function log($level, $message, array $context = []) {
-      $context['request_uri'] = $request->getUri();
+      if ($request->getHost()) {
+        $context['request_uri'] = $request->getUri();
+      }

IMHO this should document why we need this if here.

xlin’s picture

Added new method to format the referer URL.

dawehner’s picture

Status: Needs review » Needs work

Needs work for #7

dagmar’s picture

The approach of formatReferer should be abastracted in something that we can use also for location. Also the parameter $row doesn't seem accurate. We should accept a random string and make sure that it can be rendered as a link.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

dagmar’s picture

Issue tags: -Needs tests +Novice

The remaining things to change here are quite simple to implement. See #10

msankhala’s picture

+++ b/core/modules/dblog/src/Controller/DbLogController.php
@@ -420,4 +447,23 @@ public function topLogMessages($type) {
+  protected function cleanReferer(Url $url) {

This method is not being used anymore.

msankhala’s picture

Assigned: Unassigned » msankhala
msankhala’s picture

Assigned: msankhala » Unassigned
Status: Needs work » Needs review
FileSize
5.63 KB

Here is updated patch as per suggestions in #10. Removed unused protected function cleanReferer(Url $url) from patch and updated test cases so that it does not require changes mentioned in #7.

msankhala’s picture

By mistake uploaded the same patch of #7. Here is updated patch.

The last submitted patch, 16: refactor-dblog-link-rendering-2868725-7.patch, failed testing. View results

joachim’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/dblog/src/Controller/DbLogController.php
    @@ -368,6 +372,22 @@ public function formatMessage($row) {
    +   * Formats a uri to link if valid.
    

    Should give context here to explain when the link might not be valid -- because it's an empty string? because the logger passed in just a plain text message? Something else?

  2. +++ b/core/modules/dblog/src/Controller/DbLogController.php
    @@ -368,6 +372,22 @@ public function formatMessage($row) {
    +   * @return string|\Drupal\Core\Link
    +   *   The formatted link.
    

    Needs to say what you get back if it's not valid.

msankhala’s picture

Updated method docblock and return type description as per #19

msankhala’s picture

Status: Needs work » Needs review
dagmar’s picture

Status: Needs review » Needs work

Thanks @msankhala

  1. +++ b/core/modules/dblog/src/Controller/DbLogController.php
    @@ -244,6 +246,8 @@ public function eventDetails($event_id) {
    +      $location = $this->formatLink($dblog->location);
    +      $referer = $this->formatLink($dblog->referer);
    

    You can just add the calls inside the array. No need to create two new variables.

  2. +++ b/core/modules/dblog/src/Controller/DbLogController.php
    @@ -368,6 +372,26 @@ public function formatMessage($row) {
    +   * In watchdog entry sometimes uri string may be empty or invalid url. Like
    +   * empty 'referer 'or invalid 'location'. In this case return string as it is.
    

    This is not watchdog specific. I'm not a native english speaker so I may not be the best to define the docs here, but I expect to see something like: "Some log attributes like Referer or Location can be rendered as links if they are correctly formatted. This function returns a link version of an uri if it can be successfully render as a link. It fallback to the string version of the uri otherwise."

  3. +++ b/core/modules/dblog/src/Controller/DbLogController.php
    @@ -368,6 +372,26 @@ public function formatMessage($row) {
    +   *   Return Link object if uri string is valid url. Otherwise return string as
    

    Return a Link object if the uri can be converted as a link. In case of emtpy uri, or invalid, fallback to plain string.

  4. +++ b/core/tests/Drupal/Tests/Core/Logger/LoggerChannelTest.php
    @@ -127,6 +136,15 @@ function ($context) {
    +    // Request with referer but no hostname. Request with no hostname will have
    

    There are no test coverage at all for location in the DbLogTest class. Could you add a extra assertion in DbLogTest::testLogEventPage ?

msankhala’s picture

Thanks, @dagmar for feedback.

Some log attributes like Referer or Location can be rendered as links if they are correctly formatted. This function returns a link version of an uri if it can be successfully rendered as a link. It fallback to the string version of the uri otherwise.

and

Return a Link object if the uri can be converted as a link. In case of empty uri, or invalid, fallback to the plain string.

I think these are explanatory enough. I'll try to add test for location in DbLogTest::testLogEventPage.

msankhala’s picture

Assigned: Unassigned » msankhala
msankhala’s picture

FileSize
2.93 KB

Here is updated patch as per suggestion in #22

msankhala’s picture

Damn!! missed to hit upload button to upload patch before uploading interdiff. Here we go with both patch and interdiff.

msankhala’s picture

Status: Needs work » Needs review
msankhala’s picture

Assigned: msankhala » Unassigned
dagmar’s picture

Status: Needs review » Needs work

This issue is trying to solve two things:

But is currently including tests for the last one.

Take a look to https://www.drupal.org/project/drupal/issues/2858182#comment-11977909 and https://www.drupal.org/project/drupal/issues/2858182#comment-12033546

We should include in the DbLogTest a new method that create a log with an invalid referer and location and make sure they are returned as plain strings.

msankhala’s picture

Assigned: Unassigned » msankhala
msankhala’s picture

Assigned: msankhala » Unassigned
Status: Needs work » Needs review
FileSize
7.25 KB
4.89 KB

Updated patch as per #29

dagmar’s picture

Status: Needs review » Needs work

Great! almost there. Just a few final comments.

  1. +++ b/core/modules/dblog/src/Controller/DbLogController.php
    @@ -243,7 +245,6 @@ public function eventDetails($event_id) {
    -      $message = $this->formatMessage($dblog);
    

    This change is not necessary.

  2. +++ b/core/modules/dblog/src/Controller/DbLogController.php
    @@ -368,6 +369,28 @@ public function formatMessage($row) {
    +   * uri if it can be successfully render as a link. It fallback to the string
    

    s/render/rendered
    s/fallback/fallbacks

  3. +++ b/core/modules/dblog/src/Controller/DbLogController.php
    @@ -368,6 +369,28 @@ public function formatMessage($row) {
    +   *   empty uri or invalid, fallback to plain string.
    

    s/fallback/fallbacks

  4. +++ b/core/modules/dblog/tests/src/Functional/DbLogTest.php
    @@ -114,10 +114,57 @@ public function testLogEventPage() {
    +      'request_uri' => '/some/incorrect/url',
    ...
    +    $this->assertText( $this->cssSelect('table.dblog-event > tbody > tr:nth-child(4) > td')[0]->getText());
    ...
    +    $this->assertEmpty($this->cssSelect('table.dblog-event > tbody > tr:nth-child(5) > td')[0]->getText());
    

    This assertion should check that the text of nth-child(4) matches with '/some/incorrect/url'

  5. +++ b/core/modules/dblog/tests/src/Functional/DbLogTest.php
    @@ -114,10 +114,57 @@ public function testLogEventPage() {
    +    $this->assertEmpty($this->cssSelect('table.dblog-event > tbody > tr:nth-child(5) > td')[0]->getText());
    

    You could use a valid referer url here and ensure is a link.

msankhala’s picture

+++ b/core/modules/dblog/src/Controller/DbLogController.php
@@ -243,7 +245,6 @@ public function eventDetails($event_id) {
-      $message = $this->formatMessage($dblog);

This change is not necessary.

I think we can keep this change to maintain consistency. $message variable is also being used only once which can be replaced by $this->formatMessage($dblog).

+++ b/core/modules/dblog/src/Controller/DbLogController.php
@@ -368,6 +369,28 @@ public function formatMessage($row) {
+   * uri if it can be successfully render as a link. It fallback to the string

s/render/rendered - This is valid.
s/fallback/fallbacks - IDE gives typo error on this change.

+++ b/core/modules/dblog/src/Controller/DbLogController.php
@@ -368,6 +369,28 @@ public function formatMessage($row) {
+   *   empty uri or invalid, fallback to plain string.

s/fallback/fallbacks - IDE gives typo error on this change.

I'll update test case according to point 4 and 5.

msankhala’s picture

msankhala’s picture

Status: Needs work » Needs review
dagmar’s picture

Status: Needs review » Reviewed & tested by the community

Thanks so much @msankhala. Excellent work.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/dblog/src/Controller/DbLogController.php
    @@ -243,7 +245,6 @@ public function eventDetails($event_id) {
    -      $message = $this->formatMessage($dblog);
    
    @@ -263,15 +264,15 @@ public function eventDetails($event_id) {
    -          $message,
    +          $this->formatMessage($dblog),
    

    This change is not required for the change.

  2. +++ b/core/modules/dblog/src/Controller/DbLogController.php
    @@ -368,6 +369,28 @@ public function formatMessage($row) {
    +   * @param string $uri
    

    This can be a null so the typehint should be a string|null

  3. +++ b/core/modules/dblog/tests/src/Functional/DbLogTest.php
    @@ -114,10 +114,57 @@ public function testLogEventPage() {
    +   * Test individual log event page with missing log attributes.
    ...
    +      'referer' => 'http://example.org?dblog=1',
    

    We should also test a log entry where these are not set at all. The test hints that it is doing a test where there is no request_uri or referer. But it doesn't appear to be.

  4. +++ b/core/tests/Drupal/Tests/Core/Logger/LoggerChannelTest.php
    @@ -106,11 +106,20 @@ public function providerTestLog() {
    -    $request_mock = $this->getMock('Symfony\Component\HttpFoundation\Request', ['getClientIp']);
    +    $request_mock = $this->getMock('Symfony\Component\HttpFoundation\Request', ['getClientIp', 'getHost', 'getUri']);
         $request_mock->expects($this->any())
           ->method('getClientIp')
           ->will($this->returnValue('127.0.0.1'));
    +    $request_mock->expects($this->any())
    +      ->method('getHost')
    +      ->will($this->returnValue(NULL));
    +    $request_mock->expects($this->any())
    +      ->method('getUri')
    +      ->will($this->returnValue('http://:/'));
         $request_mock->headers = $this->getMock('Symfony\Component\HttpFoundation\ParameterBag');
    +    $request_mock->headers->expects($this->any())
    +      ->method('get')
    +      ->will($this->returnValue('Drupal'));
     
         // No request or account.
         $cases[] = [
    @@ -127,6 +136,15 @@ function ($context) {
    
    @@ -127,6 +136,15 @@ function ($context) {
           NULL,
           $account_mock,
         ];
    +    // Request with referer but no hostname. Request with no hostname will have
    +    // request_uri = 'http://:/'.
    +    $cases [] = [
    +      function ($context) {
    +        return $context['referer'] == 'Drupal' && $context['request_uri'] == 'http://:/';
    +      },
    +      $request_mock,
    +      NULL,
    +    ];
    

    This should be in a separate issue it is testing code that is not changed by the fix as far as I can see so it seems confusing.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

dagmar’s picture

Status: Needs review » Needs work

Thanks! @Krzysztof Domański

  1. +++ b/core/modules/dblog/tests/src/Functional/DbLogTest.php
    @@ -113,10 +113,82 @@ public function testLogEventPage() {
    +    $context = [
    +      'request_uri' => 'http://example.com?dblog=1',
    +      'referer' => NULL,
    +      'uid' => 0,
    +      'channel' => 'testing',
    +      'link' => NULL,
    +      'ip' => '0.0.1.0',
    +      'timestamp' => REQUEST_TIME,
    +    ];
    +    \Drupal::service('logger.dblog')->log(RfcLogLevel::ERROR, 'Test error message', $context);
    

    I think this block of code can be replaced with the new generateLogEntries method.

  2. +++ b/core/modules/dblog/tests/src/Functional/DbLogTest.php
    @@ -113,10 +113,82 @@ public function testLogEventPage() {
    +    $context = [
    +      'request_uri' => '/some/incorrect/url',
    +      'referer' => 'http://example.org?dblog=1',
    +      'uid' => 0,
    +      'channel' => 'testing',
    +      'link' => NULL,
    +      'ip' => '0.0.1.0',
    +      'timestamp' => REQUEST_TIME,
    +    ];
    +    \Drupal::service('logger.dblog')->log(RfcLogLevel::ERROR, 'Test error message', $context);
    

    Same here

Krzysztof Domański’s picture

Status: Needs work » Needs review
FileSize
3.79 KB
4.91 KB

I used generateLogEntries method to inject fake log data and Database::getConnection()->query($query)->fetchField() to get the last log.

dagmar’s picture

Status: Needs review » Reviewed & tested by the community

Thanks @Krzysztof Domański

I've created the follow up requested by @alexpott in #37 here. #3039201: Follow up of #2868725. More test coverage in LoggerChannelTest.

Krzysztof Domański’s picture

Re #41

I think this block of code can be replaced with the new generateLogEntries method.

I think we can change this also in the other tests. I've created issue.
#3039207: Use the generateLogEntries method in DBLogTest

alexpott’s picture

Version: 8.8.x-dev » 8.7.x-dev
Category: Task » Bug report
Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/dblog/src/Controller/DbLogController.php
    @@ -369,6 +371,28 @@ public function formatMessage($row) {
    +   * Formats a uri string to link if valid.
    ...
    +  protected function formatLink($uri) {
    

    Let's call this createLink and change the text to Creates a Link object if the provided URI is valid.

  2. +++ b/core/modules/dblog/src/Controller/DbLogController.php
    @@ -369,6 +371,28 @@ public function formatMessage($row) {
    +   * Some log attributes like 'referer' or 'location' can be rendered as links
    +   * if they are correctly formatted. This function returns a link version of an
    +   * uri if it can be successfully rendered as a link. It fallback to the string
    +   * version of the uri otherwise.
    

    This text is a bit verbose and repeats information from the one liner. And doesn't deal with the null situation. I'm not sure it is necessary at all.

  3. +++ b/core/modules/dblog/src/Controller/DbLogController.php
    @@ -369,6 +371,28 @@ public function formatMessage($row) {
    +   * @param string|null $uri
    +   *   The uri string to convert into link if valid.
    ...
    +   *   Return a Link object if the uri can be converted as a link. In case of
    +   *   empty uri or invalid, fallback to plain string.
    

    Can return NULL no? Could say fallback to the provided $uri. also @return \Drupal\Core\Link|string|null

  4. As per the issues marked duplicate of this - this looks like a bug fix.
Krzysztof Domański’s picture

Status: Needs work » Needs review
FileSize
1.77 KB
4.65 KB

Re #45.1 and #45.2. A new description is enough, so I have removed a long text.

   /**
-   * Formats a uri string to link if valid.
-   *
-   * Some log attributes like 'referer' or 'location' can be rendered as links
-   * if they are correctly formatted. This function returns a link version of an
-   * uri if it can be successfully rendered as a link. It fallback to the string
-   * version of the uri otherwise.
+   * Creates a Link object if the provided URI is valid.
    *
dagmar’s picture

Status: Needs review » Reviewed & tested by the community

Thanks @Krzysztof Domański

@alexpott comments from #45 are addressed in #46.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed 511bdacdd2 to 8.8.x and 2b5e56a9cc to 8.7.x. Thanks!

  • alexpott committed 511bdac on 8.8.x
    Issue #2868725 by msankhala, Krzysztof Domański, xlin, cilefen, dagmar,...

  • alexpott committed 2b5e56a on 8.7.x
    Issue #2868725 by msankhala, Krzysztof Domański, xlin, cilefen, dagmar,...

Status: Fixed » Closed (fixed)

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