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

Logger context #794

Merged
merged 15 commits into from
Jan 21, 2024
27 changes: 27 additions & 0 deletions docs/en/connection/logger.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,30 @@ return [
```

For other DBMS refer to ["Create connecton"](/docs/en/README.md#create-connection) section.

## Advanced usage of Logger

If you need to redefine logger messages or increase/decrease logging level:

1. Create a custom logger class
2. Use the context to detect type of the message in the "log" method

```php
<?php

declare(strict_types=1);

use Yiisoft\Db\Driver\Pdo\LogType;

class MyLogger extends ParentLoggerClass implements LoggerInterface
{
public function log($level, string|\Stringable $message, array $context = []): void
{
if ($context['type'] === LogType::QUERY) {
... your logic here
}
}

// implements other methods of LoggerInterface without changes
}
```
13 changes: 1 addition & 12 deletions src/Driver/Pdo/AbstractPdoCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@
}
break;
} catch (PDOException $e) {
$rawSql = $rawSql ?: $this->getRawSql();

Check failure on line 214 in src/Driver/Pdo/AbstractPdoCommand.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

RiskyTruthyFalsyComparison

src/Driver/Pdo/AbstractPdoCommand.php:214:27: RiskyTruthyFalsyComparison: Operand of type null|string contains type string, which can be falsy and truthy. This can cause possibly unexpected behavior. Use strict comparison instead. (see https://psalm.dev/356)

Check failure on line 214 in src/Driver/Pdo/AbstractPdoCommand.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.2-ubuntu-latest

RiskyTruthyFalsyComparison

src/Driver/Pdo/AbstractPdoCommand.php:214:27: RiskyTruthyFalsyComparison: Operand of type null|string contains type string, which can be falsy and truthy. This can cause possibly unexpected behavior. Use strict comparison instead. (see https://psalm.dev/356)

Check failure on line 214 in src/Driver/Pdo/AbstractPdoCommand.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

RiskyTruthyFalsyComparison

src/Driver/Pdo/AbstractPdoCommand.php:214:27: RiskyTruthyFalsyComparison: Operand of type null|string contains type string, which can be falsy and truthy. This can cause possibly unexpected behavior. Use strict comparison instead. (see https://psalm.dev/356)

Check failure on line 214 in src/Driver/Pdo/AbstractPdoCommand.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.2-ubuntu-latest

RiskyTruthyFalsyComparison

src/Driver/Pdo/AbstractPdoCommand.php:214:27: RiskyTruthyFalsyComparison: Operand of type null|string contains type string, which can be falsy and truthy. This can cause possibly unexpected behavior. Use strict comparison instead. (see https://psalm.dev/356)
$e = (new ConvertException($e, $rawSql))->run();

if ($this->retryHandler === null || !($this->retryHandler)($e, $attempt)) {
Expand Down Expand Up @@ -255,22 +255,11 @@
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(LogLevel::INFO, $rawSql = $this->getRawSql(), [$logCategory, 'type' => LogType::QUERY]);

$queryContext = new CommandContext(__METHOD__, $logCategory, $this->getSql(), $this->getParams());

Expand Down
7 changes: 4 additions & 3 deletions src/Driver/Pdo/AbstractPdoConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,13 @@ public function open(): void
$connectionContext = new ConnectionContext(__METHOD__);

try {
$this->logger?->log(LogLevel::INFO, $token);
$this->logger?->log(LogLevel::INFO, $token, ['type' => LogType::CONNECTION]);
$this->profiler?->begin($token, $connectionContext);
$this->initConnection();
$this->profiler?->end($token, $connectionContext);
} catch (PDOException $e) {
$this->profiler?->end($token, $connectionContext->setException($e));
$this->logger?->log(LogLevel::ERROR, $token);
$this->logger?->log(LogLevel::ERROR, $token, ['type' => LogType::CONNECTION]);

throw new Exception($e->getMessage(), (array) $e->errorInfo, $e);
}
Expand All @@ -119,6 +119,7 @@ public function close(): void
$this->logger?->log(
LogLevel::DEBUG,
'Closing DB connection: ' . $this->driver->getDsn() . ' ' . __METHOD__,
['type' => LogType::CONNECTION],
);

$this->pdo = null;
Expand Down Expand Up @@ -225,7 +226,7 @@ protected function rollbackTransactionOnLevel(TransactionInterface $transaction,
try {
$transaction->rollBack();
} catch (Throwable $e) {
$this->logger?->log(LogLevel::ERROR, (string) $e, [__METHOD__]);
$this->logger?->log(LogLevel::ERROR, (string) $e, [__METHOD__, 'type' => LogType::TRANSACTION]);
/** hide this exception to be able to continue throwing original exception outside */
}
}
Expand Down
45 changes: 35 additions & 10 deletions src/Driver/Pdo/AbstractPdoTransaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@

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

Check failure on line 62 in src/Driver/Pdo/AbstractPdoTransaction.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

RiskyTruthyFalsyComparison

src/Driver/Pdo/AbstractPdoTransaction.php:62:40: RiskyTruthyFalsyComparison: Operand of type null|string contains type string, which can be falsy and truthy. This can cause possibly unexpected behavior. Use strict comparison instead. (see https://psalm.dev/356)

Check failure on line 62 in src/Driver/Pdo/AbstractPdoTransaction.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.2-ubuntu-latest

RiskyTruthyFalsyComparison

src/Driver/Pdo/AbstractPdoTransaction.php:62:40: RiskyTruthyFalsyComparison: Operand of type null|string contains type string, which can be falsy and truthy. This can cause possibly unexpected behavior. Use strict comparison instead. (see https://psalm.dev/356)

Check failure on line 62 in src/Driver/Pdo/AbstractPdoTransaction.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.1-ubuntu-latest

RiskyTruthyFalsyComparison

src/Driver/Pdo/AbstractPdoTransaction.php:62:40: RiskyTruthyFalsyComparison: Operand of type null|string contains type string, which can be falsy and truthy. This can cause possibly unexpected behavior. Use strict comparison instead. (see https://psalm.dev/356)

Check failure on line 62 in src/Driver/Pdo/AbstractPdoTransaction.php

View workflow job for this annotation

GitHub Actions / psalm / PHP 8.2-ubuntu-latest

RiskyTruthyFalsyComparison

src/Driver/Pdo/AbstractPdoTransaction.php:62:40: RiskyTruthyFalsyComparison: Operand of type null|string contains type string, which can be falsy and truthy. This can cause possibly unexpected behavior. Use strict comparison instead. (see https://psalm.dev/356)
. ' ' . __METHOD__
. ' ' . __METHOD__,
['type' => LogType::TRANSACTION]
);

$this->db->getPDO()?->beginTransaction();
Expand All @@ -70,13 +71,18 @@
}

if ($this->db->isSavepointEnabled()) {
$this->logger?->log(LogLevel::DEBUG, 'Set savepoint ' . $this->level . ' ' . __METHOD__);
$this->logger?->log(
LogLevel::DEBUG,
'Set savepoint ' . $this->level . ' ' . __METHOD__,
['type' => LogType::TRANSACTION]
);

$this->createSavepoint('LEVEL' . $this->level);
} else {
$this->logger?->log(
LogLevel::DEBUG,
'Transaction not started: nested transaction not supported ' . __METHOD__
'Transaction not started: nested transaction not supported ' . __METHOD__,
['type' => LogType::TRANSACTION]
);

throw new NotSupportedException('Transaction not started: nested transaction not supported.');
Expand All @@ -94,19 +100,28 @@
$this->level--;

if ($this->level === 0) {
$this->logger?->log(LogLevel::DEBUG, 'Commit transaction ' . __METHOD__);
$this->logger?->log(
LogLevel::DEBUG,
'Commit transaction ' . __METHOD__,
['type' => LogType::TRANSACTION]
);
$this->db->getPDO()?->commit();

return;
}

if ($this->db->isSavepointEnabled()) {
$this->logger?->log(LogLevel::DEBUG, 'Release savepoint ' . $this->level . ' ' . __METHOD__);
$this->logger?->log(
LogLevel::DEBUG,
'Release savepoint ' . $this->level . ' ' . __METHOD__,
['type' => LogType::TRANSACTION]
);
$this->releaseSavepoint('LEVEL' . $this->level);
} else {
$this->logger?->log(
LogLevel::INFO,
'Transaction not committed: nested transaction not supported ' . __METHOD__
'Transaction not committed: nested transaction not supported ' . __METHOD__,
['type' => LogType::TRANSACTION]
);
}
}
Expand Down Expand Up @@ -135,19 +150,28 @@
$this->level--;

if ($this->level === 0) {
$this->logger?->log(LogLevel::INFO, 'Roll back transaction ' . __METHOD__);
$this->logger?->log(
LogLevel::INFO,
'Roll back transaction ' . __METHOD__,
['type' => LogType::TRANSACTION]
);
$this->db->getPDO()?->rollBack();

return;
}

if ($this->db->isSavepointEnabled()) {
$this->logger?->log(LogLevel::DEBUG, 'Roll back to savepoint ' . $this->level . ' ' . __METHOD__);
$this->logger?->log(
LogLevel::DEBUG,
'Roll back to savepoint ' . $this->level . ' ' . __METHOD__,
['type' => LogType::TRANSACTION]
);
$this->rollBackSavepoint('LEVEL' . $this->level);
} else {
$this->logger?->log(
LogLevel::INFO,
'Transaction not rolled back: nested transaction not supported ' . __METHOD__
'Transaction not rolled back: nested transaction not supported ' . __METHOD__,
['type' => LogType::TRANSACTION]
);
}
}
Expand All @@ -160,7 +184,8 @@

$this->logger?->log(
LogLevel::DEBUG,
'Setting transaction isolation level to ' . $this->level . ' ' . __METHOD__
'Setting transaction isolation level to ' . $this->level . ' ' . __METHOD__,
['type' => LogType::TRANSACTION]

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

View check run for this annotation

Codecov / codecov/patch

src/Driver/Pdo/AbstractPdoTransaction.php#L187-L188

Added lines #L187 - L188 were not covered by tests
);
$this->setTransactionIsolationLevel($level);
}
Expand Down
12 changes: 12 additions & 0 deletions src/Driver/Pdo/LogType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Db\Driver\Pdo;

final class LogType
{
public const CONNECTION = 'connection';
public const QUERY = 'query';
public const TRANSACTION = 'transaction';
}
2 changes: 1 addition & 1 deletion tests/Common/CommonPdoCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ protected function createQueryLogger(string $sql, array $params = []): LoggerInt
->with(
LogLevel::INFO,
$sql,
$params
$params + ['type' => 'query']
);
return $logger;
}
Expand Down
Loading