Passed
Pull Request — master (#793)
by Alexander
10:27 queued 08:06
created

DbLogger::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 0
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Logger;
6
7
use Psr\Log\LoggerInterface as PsrLoggerInterface;
8
use Psr\Log\LogLevel;
9
use Throwable;
10
use Yiisoft\Db\Logger\Context\ConnectionContext;
11
use Yiisoft\Db\Logger\Context\QueryContext;
12
use Yiisoft\Db\Logger\Context\TransactionContext;
13
14
class DbLogger implements DbLoggerInterface
15
{
16
    private const DEFAULT_LOG_LEVEL = LogLevel::DEBUG;
17
18
    private static array $LOG_LEVELS = [
19
        DbLoggerEvent::CONNECTION_BEGIN => LogLevel::INFO,
20
        DbLoggerEvent::CONNECTION_END => LogLevel::DEBUG,
21
        DbLoggerEvent::CONNECTION_ERROR => LogLevel::ERROR,
22
23
        DbLoggerEvent::TRANSACTION_BEGIN_TRANS => LogLevel::DEBUG,
24
        DbLoggerEvent::TRANSACTION_BEGIN_SAVEPOINT => LogLevel::DEBUG,
25
        DbLoggerEvent::TRANSACTION_BEGIN_NESTED_ERROR => LogLevel::DEBUG,
26
27
        DbLoggerEvent::TRANSACTION_COMMIT => LogLevel::DEBUG,
28
        DbLoggerEvent::TRANSACTION_RELEASE_SAVEPOINT => LogLevel::DEBUG,
29
        DbLoggerEvent::TRANSACTION_COMMIT_NESTED_ERROR => LogLevel::INFO,
30
31
        DbLoggerEvent::TRANSACTION_ROLLBACK => LogLevel::INFO,
32
        DbLoggerEvent::TRANSACTION_ROLLBACK_SAVEPOINT => LogLevel::DEBUG,
33
        DbLoggerEvent::TRANSACTION_ROLLBACK_NESTED_ERROR => LogLevel::INFO,
34
35
        DbLoggerEvent::TRANSACTION_SET_ISOLATION_LEVEL => LogLevel::DEBUG,
36
        DbLoggerEvent::TRANSACTION_ROLLBACK_ON_LEVEL => LogLevel::ERROR,
37
38
        DbLoggerEvent::QUERY => LogLevel::INFO,
39
    ];
40
41
    public function __construct(protected PsrLoggerInterface $logger)
42
    {
43
    }
44
45
    public function log(string $logEvent, ContextInterface $context): void
46
    {
47
        if ($context instanceof ConnectionContext) {
48
            $this->logConnection($logEvent, $context->getMethodName(), $context->getDsn());
49
        }
50
51
        if ($context instanceof TransactionContext) {
52
            $this->logTransaction($logEvent, $context->getIsolationLevel(), $context->getLevel(), $context->getMethodName(), $context->getException());
53
        }
54
55
        if ($context instanceof QueryContext) {
56
            $this->logger->log(self::$LOG_LEVELS[$logEvent] ?? self::DEFAULT_LOG_LEVEL, $context->getRawSql(), [$context->getCategory()]);
57
        }
58
    }
59
60
    public function setLevel(string $logEvent, string $level): void
61
    {
62
        self::$LOG_LEVELS[$logEvent] = $level;
63
    }
64
65
    private function logConnection(string $logEvent, string $methodName, string $dsn): void
66
    {
67
        $logLevel = self::$LOG_LEVELS[$logEvent] ?? self::DEFAULT_LOG_LEVEL;
68
        $message = match ($logEvent) {
69
            DbLoggerEvent::CONNECTION_BEGIN, DbLoggerEvent::CONNECTION_ERROR =>
70
                'Opening DB connection: ' . $dsn,
71
            DbLoggerEvent::CONNECTION_END => 'Closing DB connection: ' . $dsn . ' ' . $methodName,
72
        };
73
        $this->logger->log($logLevel, $message);
74
    }
75
76
    private function logTransaction(string $logType, string|null $isolationLevel, int $level, string $methodName, ?Throwable $exception = null): void
77
    {
78
        $logLevel = self::$LOG_LEVELS[$logType] ?? self::DEFAULT_LOG_LEVEL;
79
80
        if ($logType === DbLoggerEvent::TRANSACTION_ROLLBACK_ON_LEVEL) {
81
            $this->logger->log($logLevel, (string)$exception, [$methodName]);
82
            return;
83
        }
84
85
        $message = match ($logType) {
86
            DbLoggerEvent::TRANSACTION_BEGIN_TRANS => 'Begin transaction' . ($isolationLevel ? ' with isolation level ' . $isolationLevel : '') . ' ' . $methodName,
87
            DbLoggerEvent::TRANSACTION_BEGIN_SAVEPOINT => 'Set savepoint ' . $level . ' ' . $methodName,
88
            DbLoggerEvent::TRANSACTION_BEGIN_NESTED_ERROR => 'Transaction not started: nested transaction not supported ' . $methodName,
89
90
            DbLoggerEvent::TRANSACTION_COMMIT => 'Commit transaction ' . $methodName,
91
            DbLoggerEvent::TRANSACTION_RELEASE_SAVEPOINT => 'Release savepoint ' . $level . ' ' . $methodName,
92
            DbLoggerEvent::TRANSACTION_COMMIT_NESTED_ERROR => 'Transaction not committed: nested transaction not supported ' . $methodName,
93
94
            DbLoggerEvent::TRANSACTION_ROLLBACK => 'Roll back transaction ' . $methodName,
95
            DbLoggerEvent::TRANSACTION_ROLLBACK_SAVEPOINT => 'Roll back to savepoint ' . $level . ' ' . $methodName,
96
            DbLoggerEvent::TRANSACTION_ROLLBACK_NESTED_ERROR => 'Transaction not rolled back: nested transaction not supported ' . $methodName,
97
98
            DbLoggerEvent::TRANSACTION_SET_ISOLATION_LEVEL => 'Setting transaction isolation level to ' . $level . ' ' . $methodName,
99
        };
100
        $this->logger->log($logLevel, $message);
101
    }
102
}
103