Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DbLoggerInterface #793

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 7 additions & 14 deletions src/Driver/Pdo/AbstractPdoCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@
use PDO;
use PDOException;
use PDOStatement;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\LogLevel;
use Throwable;
use Yiisoft\Db\Command\AbstractCommand;
use Yiisoft\Db\Command\Param;
use Yiisoft\Db\Command\ParamInterface;
use Yiisoft\Db\Exception\ConvertException;
use Yiisoft\Db\Exception\Exception;
use Yiisoft\Db\Exception\InvalidParamException;
use Yiisoft\Db\Logger\Context\QueryContext;
use Yiisoft\Db\Logger\DbLoggerAwareInterface;
use Yiisoft\Db\Logger\DbLoggerAwareTrait;
use Yiisoft\Db\Logger\DbLoggerEvent;
use Yiisoft\Db\Profiler\Context\CommandContext;
use Yiisoft\Db\Profiler\ProfilerAwareInterface;
use Yiisoft\Db\Profiler\ProfilerAwareTrait;
Expand All @@ -32,9 +33,9 @@
*
* It also provides methods for binding parameter values and retrieving query results.
*/
abstract class AbstractPdoCommand extends AbstractCommand implements PdoCommandInterface, LoggerAwareInterface, ProfilerAwareInterface
abstract class AbstractPdoCommand extends AbstractCommand implements PdoCommandInterface, DbLoggerAwareInterface, ProfilerAwareInterface
{
use LoggerAwareTrait;
use DbLoggerAwareTrait;
use ProfilerAwareTrait;

/**
Expand Down Expand Up @@ -255,21 +256,13 @@ protected function internalGetQueryResult(int $queryMode): mixed
return $result;
}

/**
* Logs the current database query if query logging is on and returns the profiling token if profiling is on.
*/
protected function logQuery(string $rawSql, string $category): void
{
$this->logger?->log(LogLevel::INFO, $rawSql, [$category]);
}

protected function queryInternal(int $queryMode): mixed
{
$logCategory = self::class . '::' . $this->getQueryMode($queryMode);

if ($this->logger !== null) {
$rawSql = $this->getRawSql();
$this->logQuery($rawSql, $logCategory);
$this->logger->log(DbLoggerEvent::QUERY, new QueryContext(__METHOD__, $rawSql, $logCategory));
}

$queryContext = new CommandContext(__METHOD__, $logCategory, $this->getSql(), $this->getParams());
Expand Down
35 changes: 19 additions & 16 deletions src/Driver/Pdo/AbstractPdoConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@

use PDO;
use PDOException;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\LogLevel;
use Throwable;
use Yiisoft\Db\Cache\SchemaCache;
use Yiisoft\Db\Connection\AbstractConnection;
use Yiisoft\Db\Exception\Exception;
use Yiisoft\Db\Exception\InvalidCallException;
use Yiisoft\Db\Exception\InvalidConfigException;
use Yiisoft\Db\Profiler\Context\ConnectionContext;
use Yiisoft\Db\Logger\Context\ConnectionContext as LoggerContext;
use Yiisoft\Db\Logger\Context\TransactionContext as LoggerTransactionContext;
use Yiisoft\Db\Logger\DbLoggerAwareInterface;
use Yiisoft\Db\Logger\DbLoggerAwareTrait;
use Yiisoft\Db\Logger\DbLoggerEvent;
use Yiisoft\Db\Profiler\Context\ConnectionContext as ProfilerContext;
use Yiisoft\Db\Profiler\ProfilerAwareInterface;
use Yiisoft\Db\Profiler\ProfilerAwareTrait;
use Yiisoft\Db\QueryBuilder\QueryBuilderInterface;
Expand All @@ -36,9 +38,9 @@
*
* It implements the ConnectionInterface, which defines the interface for interacting with a database connection.
*/
abstract class AbstractPdoConnection extends AbstractConnection implements PdoConnectionInterface, LoggerAwareInterface, ProfilerAwareInterface
abstract class AbstractPdoConnection extends AbstractConnection implements PdoConnectionInterface, DbLoggerAwareInterface, ProfilerAwareInterface
{
use LoggerAwareTrait;
use DbLoggerAwareTrait;
use ProfilerAwareTrait;

protected PDO|null $pdo = null;
Expand Down Expand Up @@ -80,7 +82,7 @@ public function __sleep(): array
public function beginTransaction(string $isolationLevel = null): TransactionInterface
{
$transaction = parent::beginTransaction($isolationLevel);
if ($this->logger !== null && $transaction instanceof LoggerAwareInterface) {
if ($this->logger !== null && $transaction instanceof DbLoggerAwareInterface) {
$transaction->setLogger($this->logger);
}

Expand All @@ -98,16 +100,17 @@ public function open(): void
}

$token = 'Opening DB connection: ' . $this->driver->getDsn();
$connectionContext = new ConnectionContext(__METHOD__);
$profilerContext = new ProfilerContext(__METHOD__);
$loggerContext = new LoggerContext(__METHOD__, $this->getDriver()->getDsn());

try {
$this->logger?->log(LogLevel::INFO, $token);
$this->profiler?->begin($token, $connectionContext);
$this->logger?->log(DbLoggerEvent::CONNECTION_BEGIN, $loggerContext);
$this->profiler?->begin($token, $profilerContext);
$this->initConnection();
$this->profiler?->end($token, $connectionContext);
$this->profiler?->end($token, $profilerContext);
} catch (PDOException $e) {
$this->profiler?->end($token, $connectionContext->setException($e));
$this->logger?->log(LogLevel::ERROR, $token);
$this->profiler?->end($token, $profilerContext->setException($e));
$this->logger?->log(DbLoggerEvent::CONNECTION_ERROR, $loggerContext->setException($e));

throw new Exception($e->getMessage(), (array) $e->errorInfo, $e);
}
Expand All @@ -117,8 +120,8 @@ public function close(): void
{
if ($this->pdo !== null) {
$this->logger?->log(
LogLevel::DEBUG,
'Closing DB connection: ' . $this->driver->getDsn() . ' ' . __METHOD__,
DbLoggerEvent::CONNECTION_END,
new LoggerContext(__METHOD__, $this->getDriver()->getDsn()),
);

$this->pdo = null;
Expand Down Expand Up @@ -225,7 +228,7 @@ protected function rollbackTransactionOnLevel(TransactionInterface $transaction,
try {
$transaction->rollBack();
} catch (Throwable $e) {
$this->logger?->log(LogLevel::ERROR, (string) $e, [__METHOD__]);
$this->logger?->log(DbLoggerEvent::TRANSACTION_ROLLBACK_ON_LEVEL, (new LoggerTransactionContext(__METHOD__, $level))->setException($e));
/** hide this exception to be able to continue throwing original exception outside */
}
}
Expand Down
50 changes: 19 additions & 31 deletions src/Driver/Pdo/AbstractPdoTransaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@

namespace Yiisoft\Db\Driver\Pdo;

use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\LogLevel;
use Throwable;
use Yiisoft\Db\Exception\Exception;
use Yiisoft\Db\Exception\InvalidConfigException;
use Yiisoft\Db\Exception\NotSupportedException;
use Yiisoft\Db\Logger\Context\TransactionContext;
use Yiisoft\Db\Logger\DbLoggerAwareInterface;
use Yiisoft\Db\Logger\DbLoggerAwareTrait;
use Yiisoft\Db\Logger\DbLoggerEvent;
use Yiisoft\Db\Transaction\TransactionInterface;

/**
Expand All @@ -35,9 +36,9 @@
* }
* ```
*/
abstract class AbstractPdoTransaction implements TransactionInterface, LoggerAwareInterface
abstract class AbstractPdoTransaction implements TransactionInterface, DbLoggerAwareInterface
{
use LoggerAwareTrait;
use DbLoggerAwareTrait;

/**
* @var int The nesting level of the transaction.
Expand All @@ -52,16 +53,13 @@
{
$this->db->open();

$loggerContext = new TransactionContext(__METHOD__, $this->level, $isolationLevel);
if ($this->level === 0) {
if ($isolationLevel !== null) {
$this->setTransactionIsolationLevel($isolationLevel);
}

$this->logger?->log(
LogLevel::DEBUG,
'Begin transaction' . ($isolationLevel ? ' with isolation level ' . $isolationLevel : '')
. ' ' . __METHOD__
);
$this->logger?->log(DbLoggerEvent::TRANSACTION_BEGIN_TRANS, $loggerContext);

$this->db->getPDO()?->beginTransaction();
$this->level = 1;
Expand All @@ -70,14 +68,11 @@
}

if ($this->db->isSavepointEnabled()) {
$this->logger?->log(LogLevel::DEBUG, 'Set savepoint ' . $this->level . ' ' . __METHOD__);
$this->logger?->log(DbLoggerEvent::TRANSACTION_BEGIN_SAVEPOINT, $loggerContext);

$this->createSavepoint('LEVEL' . $this->level);
} else {
$this->logger?->log(
LogLevel::DEBUG,
'Transaction not started: nested transaction not supported ' . __METHOD__
);
$this->logger?->log(DbLoggerEvent::TRANSACTION_BEGIN_NESTED_ERROR, $loggerContext);

throw new NotSupportedException('Transaction not started: nested transaction not supported.');
}
Expand All @@ -93,21 +88,19 @@

$this->level--;

$loggerContext = new TransactionContext(__METHOD__, $this->level);
if ($this->level === 0) {
$this->logger?->log(LogLevel::DEBUG, 'Commit transaction ' . __METHOD__);
$this->logger?->log(DbLoggerEvent::TRANSACTION_COMMIT, $loggerContext);
$this->db->getPDO()?->commit();

return;
}

if ($this->db->isSavepointEnabled()) {
$this->logger?->log(LogLevel::DEBUG, 'Release savepoint ' . $this->level . ' ' . __METHOD__);
$this->logger?->log(DbLoggerEvent::TRANSACTION_RELEASE_SAVEPOINT, $loggerContext);
$this->releaseSavepoint('LEVEL' . $this->level);
} else {
$this->logger?->log(
LogLevel::INFO,
'Transaction not committed: nested transaction not supported ' . __METHOD__
);
$this->logger?->log(DbLoggerEvent::TRANSACTION_COMMIT_NESTED_ERROR, $loggerContext);
}
}

Expand All @@ -134,21 +127,19 @@

$this->level--;

$loggerContext = new TransactionContext(__METHOD__, $this->level);
if ($this->level === 0) {
$this->logger?->log(LogLevel::INFO, 'Roll back transaction ' . __METHOD__);
$this->logger?->log(DbLoggerEvent::TRANSACTION_ROLLBACK, $loggerContext);
$this->db->getPDO()?->rollBack();

return;
}

if ($this->db->isSavepointEnabled()) {
$this->logger?->log(LogLevel::DEBUG, 'Roll back to savepoint ' . $this->level . ' ' . __METHOD__);
$this->logger?->log(DbLoggerEvent::TRANSACTION_ROLLBACK_SAVEPOINT, $loggerContext);
$this->rollBackSavepoint('LEVEL' . $this->level);
} else {
$this->logger?->log(
LogLevel::INFO,
'Transaction not rolled back: nested transaction not supported ' . __METHOD__
);
$this->logger?->log(DbLoggerEvent::TRANSACTION_ROLLBACK_NESTED_ERROR, $loggerContext);
}
}

Expand All @@ -158,10 +149,7 @@
throw new Exception('Failed to set isolation level: transaction was inactive.');
}

$this->logger?->log(
LogLevel::DEBUG,
'Setting transaction isolation level to ' . $this->level . ' ' . __METHOD__
);
$this->logger?->log(DbLoggerEvent::TRANSACTION_SET_ISOLATION_LEVEL, new TransactionContext(__METHOD__, $this->level, $level));

Check warning on line 152 in src/Driver/Pdo/AbstractPdoTransaction.php

View check run for this annotation

Codecov / codecov/patch

src/Driver/Pdo/AbstractPdoTransaction.php#L152

Added line #L152 was not covered by tests
$this->setTransactionIsolationLevel($level);
}

Expand Down
33 changes: 33 additions & 0 deletions src/Logger/Context/AbstractContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Db\Logger\Context;

use Throwable;
use Yiisoft\Db\Logger\ContextInterface;

abstract class AbstractContext implements ContextInterface
{
private Throwable|null $exception = null;

public function __construct(private string $methodName)
{
}

public function getMethodName(): string
{
return $this->methodName;
}

public function setException(Throwable $e): static
{
$this->exception = $e;
return $this;
}

public function getException(): Throwable|null
{
return $this->exception;
}
}
18 changes: 18 additions & 0 deletions src/Logger/Context/ConnectionContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Db\Logger\Context;

final class ConnectionContext extends AbstractContext
{
public function __construct(string $methodName, private string $dsn)
{
parent::__construct($methodName);
}

public function getDsn(): string
{
return $this->dsn;
}
}
23 changes: 23 additions & 0 deletions src/Logger/Context/QueryContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Db\Logger\Context;

final class QueryContext extends AbstractContext
{
public function __construct(string $methodName, private string $rawSql, private string $category)
{
parent::__construct($methodName);
}

public function getRawSql(): string
{
return $this->rawSql;
}

public function getCategory(): string
{
return $this->category;
}
}
23 changes: 23 additions & 0 deletions src/Logger/Context/TransactionContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Db\Logger\Context;

final class TransactionContext extends AbstractContext
{
public function __construct(string $methodName, private int $level, private string|null $isolationLevel = null)
{
parent::__construct($methodName);
}

public function getLevel(): int
{
return $this->level;
}

public function getIsolationLevel(): string|null
{
return $this->isolationLevel;
}
}
19 changes: 19 additions & 0 deletions src/Logger/ContextInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Db\Logger;

use Throwable;

/**
* Logger context.
*/
interface ContextInterface
{
public function getMethodName(): string;

public function getException(): Throwable|null;

public function setException(Throwable $e): static;
}
Loading
Loading