diff --git a/composer.json b/composer.json index 844a6c182..2830ef33b 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,8 @@ }, "require-dev": { "nette/di": "^2.4 || ^3.0", - "nette/tester": "^2.0" + "nette/tester": "^2.0", + "psr/log": "^1.0" }, "suggest": { "https://nette.org/donate": "Please support Tracy via a donation" diff --git a/src/Bridges/Psr/PsrToTracyLoggerAdapter.php b/src/Bridges/Psr/PsrToTracyLoggerAdapter.php new file mode 100644 index 000000000..9f20389b1 --- /dev/null +++ b/src/Bridges/Psr/PsrToTracyLoggerAdapter.php @@ -0,0 +1,62 @@ + Psr\Log\LogLevel::DEBUG, + Tracy\ILogger::INFO => Psr\Log\LogLevel::INFO, + Tracy\ILogger::WARNING => Psr\Log\LogLevel::WARNING, + Tracy\ILogger::ERROR => Psr\Log\LogLevel::ERROR, + Tracy\ILogger::EXCEPTION => Psr\Log\LogLevel::ERROR, + Tracy\ILogger::CRITICAL => Psr\Log\LogLevel::CRITICAL, + ]; + + /** @var Psr\Log\LoggerInterface */ + private $psrLogger; + + + public function __construct(Psr\Log\LoggerInterface $psrLogger) + { + $this->psrLogger = $psrLogger; + } + + + public function log($value, string $priority = self::INFO) + { + if ($value instanceof \Throwable) { + $message = $value->getMessage(); + $context = ['exception' => $value]; + + } elseif (!is_string($value)) { + $message = trim(Tracy\Dumper::toText($value)); + $context = []; + + } else { + $message = $value; + $context = []; + } + + $this->psrLogger->log( + self::PRIORITY_MAP[$priority] ?? Psr\Log\LogLevel::ERROR, + $message, + $context + ); + } +} diff --git a/src/Bridges/Psr/TracyToPsrLoggerAdapter.php b/src/Bridges/Psr/TracyToPsrLoggerAdapter.php new file mode 100644 index 000000000..155290bf8 --- /dev/null +++ b/src/Bridges/Psr/TracyToPsrLoggerAdapter.php @@ -0,0 +1,61 @@ + Tracy\ILogger::CRITICAL, + Psr\Log\LogLevel::ALERT => Tracy\ILogger::CRITICAL, + Psr\Log\LogLevel::CRITICAL => Tracy\ILogger::CRITICAL, + Psr\Log\LogLevel::ERROR => Tracy\ILogger::ERROR, + Psr\Log\LogLevel::WARNING => Tracy\ILogger::WARNING, + Psr\Log\LogLevel::NOTICE => Tracy\ILogger::WARNING, + Psr\Log\LogLevel::INFO => Tracy\ILogger::INFO, + Psr\Log\LogLevel::DEBUG => Tracy\ILogger::DEBUG, + ]; + + /** @var Tracy\ILogger */ + private $tracyLogger; + + + public function __construct(Tracy\ILogger $tracyLogger) + { + $this->tracyLogger = $tracyLogger; + } + + + public function log($level, $message, array $context = []) + { + $priority = self::PRIORITY_MAP[$level] ?? Tracy\ILogger::ERROR; + + if (isset($context['exception']) && $context['exception'] instanceof \Throwable) { + $this->tracyLogger->log($context['exception'], $priority); + unset($context['exception']); + } + + if ($context) { + $message = [ + 'message' => $message, + 'context' => $context, + ]; + } + + $this->tracyLogger->log($message, $priority); + } +} diff --git a/tests/Tracy.Bridges/PsrToTracyLoggerAdapter.phpt b/tests/Tracy.Bridges/PsrToTracyLoggerAdapter.phpt new file mode 100644 index 000000000..c419c1601 --- /dev/null +++ b/tests/Tracy.Bridges/PsrToTracyLoggerAdapter.phpt @@ -0,0 +1,45 @@ +entries[] = [$level, $message, $context]; + } +} + + +$psrLogger = new DummyPsrLogger; +$tracyLogger = new PsrToTracyLoggerAdapter($psrLogger); +$exception = new \Exception('Something went wrong'); + +$tracyLogger->log('info'); +$tracyLogger->log('warning', ILogger::WARNING); +$tracyLogger->log(123); +$tracyLogger->log(['x' => 'y']); +$tracyLogger->log($exception); + +Assert::same([ + [Psr\Log\LogLevel::INFO, 'info', []], + [Psr\Log\LogLevel::WARNING, 'warning', []], + [Psr\Log\LogLevel::INFO, '123', []], + [Psr\Log\LogLevel::INFO, "array (1)\n x => \"y\"", []], + [Psr\Log\LogLevel::INFO, 'Something went wrong', ['exception' => $exception]], +], $psrLogger->entries); diff --git a/tests/Tracy.Bridges/TracyToPsrLoggerAdapter.phpt b/tests/Tracy.Bridges/TracyToPsrLoggerAdapter.phpt new file mode 100644 index 000000000..115de84ff --- /dev/null +++ b/tests/Tracy.Bridges/TracyToPsrLoggerAdapter.phpt @@ -0,0 +1,47 @@ +entries[] = [$priority, $value]; + } +} + + +$tracyLogger = new DummyTracyLogger; +$psrLogger = new TracyToPsrLoggerAdapter($tracyLogger); +$exception = new \Exception('Something went wrong'); + +$psrLogger->info('info'); +$psrLogger->warning('warning'); +$psrLogger->error('order failed with exception', ['exception' => $exception]); +$psrLogger->error('order failed with context', ['orderId' => 123]); +$psrLogger->error('order failed with context and exception', ['orderId' => 123, 'exception' => $exception]); + +Assert::same([ + [ILogger::INFO, 'info'], + [ILogger::WARNING, 'warning'], + [ILogger::ERROR, $exception], + [ILogger::ERROR, 'order failed with exception'], + [ILogger::ERROR, ['message' => 'order failed with context', 'context' => ['orderId' => 123]]], + [ILogger::ERROR, $exception], + [ILogger::ERROR, ['message' => 'order failed with context and exception', 'context' => ['orderId' => 123]]], +], $tracyLogger->entries);