The method logFileCanBeCreated avoids the rotate method

Created on 3 January 2025, 4 months ago

Problem/Motivation

Using monolog_extra, the older logs never gets removed.
It happens because the method logFileCanBeCreated, creates an empty file to check if the file is writable.
On the object RotatingFileHandler, on the method write, on of the conditions to sets the property mustRotate is that the file is new (does not exists previously). Because the file was created empty, the mustRotate will never meet the condition.

Method logFileCanBeCreated:

  public function logFileCanBeCreated() {
    $url = $this->getUrl();
    @fopen($url, 'a');
    set_error_handler([$this, 'customErrorHandler']);
    $stream = fopen($url, 'a');
    restore_error_handler();
    if (is_resource($stream)) {
      $can_be_created = TRUE;
    }
    else {
      $can_be_created = FALSE;
      $this->loggerChannel->critical($this->t('The stream or file :file could not be opened: :message', [
        ':file' => $url,
        ':message' => self::$errorMessage,
      ]));
    }
    return $can_be_created;
  }

Method write:

    protected function write(LogRecord $record): void
    {

        // on the first record written, if the log is new, we rotate (once per day) after the log has been written so that the new file exists
        if (null === $this->mustRotate) {
            $this->mustRotate = null === $this->url || !file_exists($this->url);
        }
...

Steps to reproduce

Install monolog_extra module and configure the rotate file handler.

Create the mymodule.services.yml

services:
  monolog.handler.mymodule.safe_rotating_handler:
    class: Drupal\monolog_extra\Logger\Handler\SafeRotatingFileHandler
    arguments: ['@file_system', '@logger.channel.mymodule', 'private://mymodule/logs/mymodule.log', 3]

  logger.channel.mymodule:
    class: Drupal\Core\Logger\LoggerChannel
    factory: logger.factory:get
    arguments: ['mymodule_file_handler']

  logger.channel.mymodule_file_log:
    class: Drupal\Core\Logger\LoggerChannel
    factory: logger.factory:get
    arguments: ['mymodule_file_log']

Create on sites/default/monolog.services.yml

parameters:
  monolog.channel_handlers:
    default:
      handlers:
        - name: 'drupal.dblog'
    mymodule_file_log:
      handlers:
        - name: 'mymodule.safe_rotating_handler'

Add an entry log:

$logger = \Drupal::service('logger.channel.mymodule_file_log');
$logger->notice('hello world');

Proposed resolution

Unlink the file after creating it.

🐛 Bug report
Status

Active

Version

1.0

Component

Code

Created by

🇪🇸Spain eduardo morales alberti Spain, 🇪🇺

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Production build 0.71.5 2024