Skip to content

Commit

Permalink
create PsrLogRoute
Browse files Browse the repository at this point in the history
  • Loading branch information
klimov-paul committed Jul 18, 2023
1 parent e6f13d7 commit 0285d3d
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/HasPsrLogger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace yii1tech\psr\log;

use Psr\Log\LoggerInterface;
use Yii;

/**
* HasPsrLogger adds ability to configure related PSR compatible logger.
*
* @mixin \CComponent
*
* @property \Psr\Log\LoggerInterface|string|array|null $psrLogger related PSR logger.
*/
trait HasPsrLogger
{

}
86 changes: 86 additions & 0 deletions src/PsrLogRoute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

namespace yii1tech\psr\log;

use CLogRoute;
use LogicException;
use Psr\Log\LoggerInterface;
use Yii;

/**
* PsrLogRoute passes Yii log messages to PSR logger.
*
* This class can be used in case you with to utilize 3rd party PSR logger library like "Monolog" in your Yii application.
*
* > Note: even if you use {@see \yii1tech\psr\log\Logger} as Yii logger, this log route will be unable to handle
* passed log context correctly.
*
* @property \Psr\Log\LoggerInterface|string|array $psrLogger related PSR logger.
*
* @author Paul Klimov <[email protected]>
* @since 1.0
*/
class PsrLogRoute extends CLogRoute
{
/**
* @var \Psr\Log\LoggerInterface related PSR logger.
*/
private $_psrLogger;

/**
* @return \Psr\Log\LoggerInterface related PSR logger instance.
*/
public function getPsrLogger(): LoggerInterface
{
if ($this->_psrLogger === null) {
throw new LogicException('"' . get_class($this) . '::$psrLogger" must be explicitly set.');
}

if (!is_object($this->_psrLogger)) {
$this->_psrLogger = Yii::createComponent($this->_psrLogger);
}

return $this->_psrLogger;
}

/**
* @param \Psr\Log\LoggerInterface|array|string $psrLogger
* @return static self reference.
*/
public function setPsrLogger($psrLogger): self
{
$this->_psrLogger = $psrLogger;

return $this;
}

/**
* {@inheritdoc}
*/
protected function processLogs($logs): void
{
$psrLogger = $this->getPsrLogger();

foreach ($logs as $log) {
$psrLogger->log(
LogLevelConverter::toPsr($log[1]),
$log[0],
$this->createLogContext($log)
);
}
}

/**
* Creates PSR log context from Yii log entry.
*
* @param array $logRow raw log row obtained from Yii logger.
* @return array PSR compatible log context.
*/
protected function createLogContext(array $logRow): array
{
return [
'category' => $logRow[2],
'timestamp' => $logRow[3],
];
}
}
48 changes: 48 additions & 0 deletions tests/PsrLogRouteTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace yii1tech\psr\log\test;

use CLogger;
use Psr\Log\LogLevel;
use yii1tech\psr\log\PsrLogRoute;
use yii1tech\psr\log\test\support\ArrayLogger;

class PsrLogRouteTest extends TestCase
{
public function testSetupPsrLogger(): void
{
$logRoute = new PsrLogRoute();

$psrLogger = new ArrayLogger();

$logRoute->setPsrLogger($psrLogger);

$this->assertSame($psrLogger, $logRoute->getPsrLogger());

$logRoute->setPsrLogger([
'class' => ArrayLogger::class,
]);

$this->assertTrue($logRoute->getPsrLogger() instanceof ArrayLogger);
}

public function testWriteLog(): void
{
$yiiLogger = new CLogger();
$psrLogger = new ArrayLogger();

$logRoute = (new PsrLogRoute())
->setPsrLogger($psrLogger);

$yiiLogger->log('test message', CLogger::LEVEL_INFO, 'test-category');

$logRoute->collectLogs($yiiLogger, true);

$logs = $psrLogger->flush();
$this->assertFalse(empty($logs[0]));
$this->assertSame(LogLevel::INFO, $logs[0]['level']);
$this->assertSame('test message', $logs[0]['message']);
$this->assertSame('test-category', $logs[0]['context']['category']);
$this->assertFalse(empty($logs[0]['context']['timestamp']));
}
}

0 comments on commit 0285d3d

Please sign in to comment.