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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- Enh #784: Remove unused code in `AbstractSchema::getTableIndexes()` (@vjik)
- Bug #788: Fix casting integer to string in `AbstractCommand::getRawSql()` (@Tigrov)
- Enh #789: Remove unnecessary type casting to array in `AbstractDMLQueryBuilder::getTableUniqueColumnNames()` (@Tigrov)
- Enh #794: Add category to log context (@darkdef)
darkdef marked this conversation as resolved.
Show resolved Hide resolved

## 1.2.0 November 12, 2023

Expand Down
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\LogTypes;

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

// implements other methods of LoggerInterface without changes
}
```
10 changes: 1 addition & 9 deletions src/Driver/Pdo/AbstractPdoCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -255,21 +255,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(LogLevel::INFO, $rawSql, [$logCategory, LogTypes::KEY => LogTypes::TYPE_QUERY]);
Tigrov marked this conversation as resolved.
Show resolved Hide resolved
}

$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, [LogTypes::KEY => LogTypes::TYPE_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, [LogTypes::KEY => LogTypes::TYPE_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__,
[LogTypes::KEY => LogTypes::TYPE_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__, LogTypes::KEY => LogTypes::TYPE_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 @@ -60,7 +60,8 @@
$this->logger?->log(
LogLevel::DEBUG,
'Begin transaction' . ($isolationLevel ? ' with isolation level ' . $isolationLevel : '')
. ' ' . __METHOD__
. ' ' . __METHOD__,
[LogTypes::KEY => LogTypes::TYPE_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__,
[LogTypes::KEY => LogTypes::TYPE_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__,
[LogTypes::KEY => LogTypes::TYPE_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__,
[LogTypes::KEY => LogTypes::TYPE_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__,
[LogTypes::KEY => LogTypes::TYPE_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__,
[LogTypes::KEY => LogTypes::TYPE_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__,
[LogTypes::KEY => LogTypes::TYPE_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__,
[LogTypes::KEY => LogTypes::TYPE_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__,
[LogTypes::KEY => LogTypes::TYPE_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__,
[LogTypes::KEY => LogTypes::TYPE_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
14 changes: 14 additions & 0 deletions src/Driver/Pdo/LogTypes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Db\Driver\Pdo;

class LogTypes
darkdef marked this conversation as resolved.
Show resolved Hide resolved
{
public const KEY = 'log-type';
vjik marked this conversation as resolved.
Show resolved Hide resolved

public const TYPE_CONNECTION = 'connection';
public const TYPE_QUERY = 'query';
public const TYPE_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 + ['log-type' => 'query']
);
return $logger;
}
Expand Down
Loading