Sykr's avatar
Level 10

Laravel logging - change mode daily to monthly

Hi. By default in daily mode, logs storing like laravel-2019-02-15.log. I want to change it to laravel-2019-March.log. I know that I need create custom channel driver. How it's possible? Does anybody meet this type of task?

0 likes
8 replies
Sykr's avatar
Level 10

@BOBBYBOUWMANN - Thanks, but I'm confusing where exactly I can override? Is this code ok?

namespace App\Logging;

use Monolog\Logger;
use Monolog\Handler\RotatingFileHandler;

class MonthlyCustomLogger extends RotatingFileHandler
{
    const FILE_PER_DAY = 'Y-m-d';
    const FILE_PER_MONTH = 'Y-m';
    
    public function __construct($filename, $maxFiles = 0, $level = Logger::DEBUG, $bubble = true, $filePermission = null, $useLocking = false)
    {
        $this->filename = $filename;
        $this->maxFiles = (int) $maxFiles;
        $this->nextRotation = new \DateTime('tomorrow');
        $this->filenameFormat = '{filename}-{date}';
        // $this->dateFormat = FILE_PER_DAY; // original was
        $this->dateFormat = FILE_PER_MONTH; // changed to

        parent::__construct($this->getTimedFilename(), $level, $bubble, $filePermission, $useLocking);
    }
}
Sykr's avatar
Sykr
OP
Best Answer
Level 10

@BOBBYBOUWMANN - My friend Pavel Politaev find simple solution:

'driver' => 'daily',
'level' => 'debug',
'path' => storage_path('logs/sms/sms-'.date('Y').'-'.date('m').'.log'),
imrelaur's avatar

Here is my custom monthly logger.

First you add custom channel to config/logging.php . For example:

        'user' => [
            'driver' => 'custom',
            'via' => \App\Logging\MonthlyLogger::class,
            'path' => storage_path('logs/user.log'),
            'months' => 12,
        ],

Secondly create this class in app/Logging folder.

<?php

namespace App\Logging;

use Monolog\Logger;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\RotatingFileHandler;

class MonthlyLogger
{
    public function __invoke(array $config) : Logger
    {
        $name = pathinfo($config['path'], PATHINFO_FILENAME);

        return new Logger($name, [$this->handler($config['path'], $config['months'])]);
    }

    private function handler(string $path, int $months) : RotatingFileHandler
    {
        return tap(new RotatingFileHandler($path, $months), function ($handler) {
            $handler
                ->setFormatter(new LineFormatter(null, 'Y-m-d H:i:s', false, true))
                ->setFilenameFormat('{filename}-{date}', RotatingFileHandler::FILE_PER_MONTH);
        });
    }
}

For using it use Log::channel('user')->info('John Doe');

1 like
Arya_Svitkona's avatar

@imre08 How does the RotatingFileHandler realize that a new log file must be created on the first day of the new month?

Bruno_Goossens's avatar

Here is my solution

        'monthly' => [
            'driver' => 'monolog',
            'handler' => Monolog\Handler\RotatingFileHandler::class,
            'with' => [
                'filename' => storage_path('logs/monthly.log'),
                'maxFiles' => env('LOG_MAX_FILES', 12),
                'level' => env('LOG_LEVEL', 'info'),
                'dateFormat' => Monolog\Handler\RotatingFileHandler::FILE_PER_MONTH,
            ],
        ],

Please or to participate in this conversation.