Skip to content

Commit

Permalink
Merge pull request #36 from kronostechnologies/dev/add-logger-decorator
Browse files Browse the repository at this point in the history
Ajouter de LoggerDecorator pour filtrer les messages au niveau du Logger
  • Loading branch information
etremblay authored Apr 16, 2021
2 parents 39785a9 + 1723363 commit dc3d30a
Show file tree
Hide file tree
Showing 5 changed files with 262 additions and 27 deletions.
67 changes: 40 additions & 27 deletions src/AbstractWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,23 @@

use Kronos\Log\Exception\InvalidLogLevel;
use Kronos\Log\Traits\Interpolate;
use \Psr\Log\LogLevel;
use Psr\Log\LogLevel;

abstract class AbstractWriter implements WriterInterface
{

use Interpolate;

/**
* Psr\Log\LogLevel priorities, please consider this a const until php 5.6 is officialy used.
* @var array
*/
protected $level_priorities = [
LogLevel::EMERGENCY => 7,
LogLevel::ALERT => 6,
LogLevel::CRITICAL => 5,
LogLevel::ERROR => 4,
LogLevel::WARNING => 3,
LogLevel::NOTICE => 2,
LogLevel::INFO => 1,
LogLevel::DEBUG => 0
];

protected $min_level = LogLevel::DEBUG;
protected $max_level = LogLevel::EMERGENCY;
protected $can_log = true;

public function canLogLevel($level)
/**
* @param string $level
* @return bool
* @throws InvalidLogLevel
*/
public function canLogLevel($level): bool
{
$this->validateLogLevel($level);

Expand All @@ -43,44 +33,67 @@ public function canLogLevel($level)
return true;
}

/**
* @param string $level
* @throws InvalidLogLevel
*/
protected function validateLogLevel($level)
{
if (!isset($this->level_priorities[$level])) {
throw new InvalidLogLevel($level);
}
LogLevelHelper::validateLogLevel((string)$level);
}

/**
* @param string $level
* @throws InvalidLogLevel
*/
public function setMinLevel($level)
{
$this->validateLogLevel($level);

$this->min_level = $level;
}

protected function isLevelLower($base_level, $compared_level)
/**
* @param string $base_level
* @param string $compared_level
* @return bool
*/
protected function isLevelLower($base_level, $compared_level): bool
{
return $this->level_priorities[$compared_level] < $this->level_priorities[$base_level];
return LogLevelHelper::isLower((string)$base_level, (string)$compared_level);
}

/**
* @param string $level
* @throws InvalidLogLevel
*/
public function setMaxLevel($level)
{
$this->validateLogLevel($level);

$this->max_level = $level;
$this->max_level = (string)$level;
}

public function canLog()
public function canLog(): bool
{
return $this->can_log;
}

/**
* @param bool $can_log
*/
public function setCanLog($can_log = true)
{
$this->can_log = $can_log;
$this->can_log = (bool)$can_log;
}

protected function isLevelHigher($base_level, $compared_level)
/**
* @param string $base_level
* @param string $compared_level
* @return bool
*/
protected function isLevelHigher($base_level, $compared_level): bool
{
return $this->level_priorities[$compared_level] > $this->level_priorities[$base_level];
return LogLevelHelper::isHigher($base_level, $compared_level);
}
}
41 changes: 41 additions & 0 deletions src/LogLevelHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Kronos\Log;

use Kronos\Log\Exception\InvalidLogLevel;
use Psr\Log\LogLevel;

class LogLevelHelper
{
public const levelPriorities = [
LogLevel::EMERGENCY => 7,
LogLevel::ALERT => 6,
LogLevel::CRITICAL => 5,
LogLevel::ERROR => 4,
LogLevel::WARNING => 3,
LogLevel::NOTICE => 2,
LogLevel::INFO => 1,
LogLevel::DEBUG => 0
];

public static function isLower(string $baseLevel, string $toCompare): bool
{
return self::levelPriorities[$toCompare] < self::levelPriorities[$baseLevel];
}

public static function isHigher(string $baseLevel, string $toCompare): bool
{
return self::levelPriorities[$toCompare] > self::levelPriorities[$baseLevel];
}

/**
* @param string $level
* @throws InvalidLogLevel
*/
public static function validateLogLevel(string $level): void
{
if (!isset(self::levelPriorities[$level])) {
throw new InvalidLogLevel($level);
}
}
}
76 changes: 76 additions & 0 deletions src/LoggerDecorator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

namespace Kronos\Log;

use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;

class LoggerDecorator implements LoggerInterface
{
/**
* @var string
*/
private $level = LogLevel::DEBUG;
/**
* @var LoggerInterface
*/
private $delegate;

public function __construct(
LoggerInterface $delegate
) {
$this->delegate = $delegate;
}

public function setLevel(string $level)
{
$this->level = $level;
}

public function emergency($message, array $context = array())
{
$this->log(LogLevel::EMERGENCY, $message, $context);
}

public function alert($message, array $context = array())
{
$this->log(LogLevel::ALERT, $message, $context);
}

public function critical($message, array $context = array())
{
$this->log(LogLevel::CRITICAL, $message, $context);
}

public function error($message, array $context = array())
{
$this->log(LogLevel::ERROR, $message, $context);
}

public function warning($message, array $context = array())
{
$this->log(LogLevel::WARNING, $message, $context);
}

public function notice($message, array $context = array())
{
$this->log(LogLevel::NOTICE, $message, $context);
}

public function info($message, array $context = array())
{
$this->log(LogLevel::INFO, $message, $context);
}

public function debug($message, array $context = array())
{
$this->log(LogLevel::DEBUG, $message, $context);
}

public function log($level, $message, array $context = array())
{
if (!LogLevelHelper::isLower($this->level, (string)$level)) {
$this->delegate->log($level, $message, $context);
}
}
}
46 changes: 46 additions & 0 deletions tests/LogLevelHelperTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

use Kronos\Log\Exception\InvalidLogLevel;
use Kronos\Log\LogLevelHelper;
use PHPUnit\Framework\TestCase;
use Psr\Log\LogLevel;

class LogLevelHelperTest extends TestCase
{
public function test_isLower_shouldReturnFalseWhenLevelIsEqual(): void
{
$isLower = LogLevelHelper::isLower(LogLevel::DEBUG, LogLevel::DEBUG);

self::assertFalse($isLower);
}

/**
* @dataProvider provideLevels
*/
public function test_isLower_shouldReturnFalseWhenLevelIsHigher($baseLevel, $toCompare): void
{
$isLower = LogLevelHelper::isLower($baseLevel, $toCompare);

self::assertFalse($isLower);
}

public function test_validateLogLevel_shouldThrowInvalidLogLevelWhenLevelIsUnknown(): void
{
self::expectException(InvalidLogLevel::class);

LogLevelHelper::validateLogLevel('unknown level');
}

public function provideLevels(): array
{
return [
[LogLevel::ALERT, LogLevel::EMERGENCY],
[LogLevel::CRITICAL, LogLevel::ALERT],
[LogLevel::ERROR, LogLevel::CRITICAL],
[LogLevel::WARNING, LogLevel::ERROR],
[LogLevel::NOTICE, LogLevel::WARNING],
[LogLevel::INFO, LogLevel::NOTICE],
[LogLevel::DEBUG, LogLevel::INFO],
];
}
}
59 changes: 59 additions & 0 deletions tests/LoggerDecoratorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

use Kronos\Log\LoggerDecorator;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;

class LoggerDecoratorTest extends TestCase
{
/**
* @var LoggerInterface & MockObject
*/
private $delegate;
/**
* @var LoggerDecorator
*/
private $loggerDecorator;

protected function setUp(): void
{
$this->delegate = $this->createMock(LoggerInterface::class);
$this->loggerDecorator = new LoggerDecorator($this->delegate);
}

public function test_shouldLogWhenMessageLevelIsHigherThanLogger(): void
{
$this->loggerDecorator->setLevel(LogLevel::INFO);
$this->delegate
->expects($this->once())
->method('log')
->with(LogLevel::WARNING, 'a message');

$this->loggerDecorator->log(LogLevel::WARNING, 'a message');
}

/**
* @dataProvider provideLowerLogLevels
*/
public function test_shouldNotLogWhenLoggerLevelIsHigherThanMessage($loggerLevel, $levelOfMessage): void
{
$this->loggerDecorator->setLevel($loggerLevel);
$this->delegate->expects($this->never())->method('log');

$this->loggerDecorator->log($levelOfMessage, 'a message');
}

public function provideLowerLogLevels(): array
{
return [
[LogLevel::INFO, LogLevel::DEBUG],
[LogLevel::NOTICE, LogLevel::INFO],
[LogLevel::WARNING, LogLevel::NOTICE],
[LogLevel::ERROR, LogLevel::WARNING],
[LogLevel::CRITICAL, LogLevel::ERROR],
[LogLevel::EMERGENCY, LogLevel::CRITICAL]
];
}
}

0 comments on commit dc3d30a

Please sign in to comment.