Mik
Mik

Reputation: 385

yii2: how to exclude DbTarget info from log?

I made my own log target like DbTarget to record some specific info in DB while logging but every execute query is logged by other target. How to disable it?

targets config:

$except = [
    'yii\db\*',
    'yii\filters\RateLimiter::beforeAction',
    'yii\web\Session::open',
    'yii\swiftmailer\Mailer::sendMessage',
    'accessLog',
];

return [
    [
        'class'          => 'common\cms\log\AdvDbTarget',
        'levels'         => ['error', 'warning'],
        'exportInterval' => 1,
        'except'         => [
            'yii\db\*',
            'yii\filters\RateLimiter::beforeAction',
            'yii\web\Session::open',
            'yii\swiftmailer\Mailer::sendMessage',
        ],
        'logVars'        => ['_GET', '_POST', '_SERVER', '_COOKIE', '_SESSION'],
        'disableTargets' => ['query'],
    ],
    [
        'class'          => 'yii\log\FileTarget',
        'categories'     => ['yii\swiftmailer\Logger::add'],
        'exportInterval' => 1,
    ],
    [
        'class'          => 'yii\log\FileTarget',
        'except'         => $except,
        'logFile'        => '@logs/application.' . date('Y-m-d') . '.log',
        'exportInterval' => 1,
        'logVars'        => [],
        'levels'         => ['info']
    ],
    [
        'class'          => 'yii\log\FileTarget',
        'except'         => $except,
        'levels'         => ['error', 'warning'],
        'logFile'        => '@logs/application.error.' . date('Y-m-d') . '.log',
        'logVars'        => ['_GET', '_POST', '_SERVER'],
    ],
    [
        'class'          => 'yii\log\FileTarget',
        'except'         => $except,
        'logFile'        => '@logs/application.trace.' . date('Y-m-d') . '.log',
        'exportInterval' => 1,
        'logVars'        => [],
        'levels'         => ['trace'],
        'enabled'        => YII_DEBUG
    ],
    'query' => [
        'class'          => 'yii\log\FileTarget',
        'categories'     => ['yii\db\Command*'],
        'logFile'        => '@logs/query.' . date('Y-m-d') . '.log',
        'exportInterval' => 1,
        'logVars'        => [],
        'levels'         => ['info'],
        'enabled'        => YII_DEBUG
    ],
    [
        'class'          => 'yii\log\FileTarget',
        'categories'     => ['billing'],
        'logFile'        => '@logs/billing.' . date('Y-m-d') . '.log',
        'exportInterval' => 1,
    ],
    [
        'class'          => 'yii\log\FileTarget',
        'categories'     => ['billing'],
        'logFile'        => '@logs/billing.error.' . date('Y-m-d') . '.log',
        'levels'         => ['error'],
    ],
    [
        'class'          => 'yii\log\FileTarget',
        'categories'     => ['mailer'],
        'logFile'        => '@logs/mailer.' . date('Y-m-d') . '.log',
        'logVars'        => [],
        'exportInterval' => 1,
    ],
    [
        'class'          => 'yii\log\FileTarget',
        'levels'         => ['info'],
        'categories'     => ['pipeline'],
        'logFile'        => '@logs/pipeline/pipeline.info.' . date('Y-m-d') . '.log',
        'exportInterval' => 1,
    ],
    [
        'class'          => 'yii\log\FileTarget',
        'levels'         => ['error', 'warning'],
        'categories'     => ['pipeline'],
        'logFile'        => '@logs/pipeline/pipeline.error.' . date('Y-m-d') . '.log',
        'exportInterval' => 1,
    ],
    [
        'class'          => 'yii\log\FileTarget',
        'levels'         => ['info'],
        'categories'     => ['trello'],
        'logFile'        => '@logs/trello/trello.info.' . date('Y-m-d') . '.log',
        'exportInterval' => 1,
    ],
    [
        'class'          => 'yii\log\FileTarget',
        'levels'         => ['error', 'warning'],
        'categories'     => ['trello'],
        'logFile'        => '@logs/trello/trello.error.' . date('Y-m-d') . '.log',
        'exportInterval' => 1,
    ],
    [
        'class'          => 'yii\log\FileTarget',
        'levels'         => ['info'],
        'categories'     => ['push'],
        'logFile'        => '@logs/push/push.info.' . date('Y-m-d') . '.log',
        'exportInterval' => 1,
    ],
    [
        'class'          => 'yii\log\FileTarget',
        'levels'         => ['error', 'warning'],
        'categories'     => ['push'],
        'logFile'        => '@logs/push/push.error.' . date('Y-m-d') . '.log',
        'exportInterval' => 1,
    ],
    [
        'class'          => 'yii\log\FileTarget',
        'categories'     => ['push_server'],
        'logFile'        => '@logs/push/push_server.' . date('Y-m-d') . '.log',
        'exportInterval' => 1,
        'logVars'        => [],
    ],
];

Some AdvDbTarget methods:

/**
 * Stores log messages to DB.
 */
public function export()
{
    $this->enableLogging(false); //Here I try to avoid logging of execute info
    $tableName = $this->db->quoteTableName($this->logTable);
    $sql = "INSERT INTO $tableName ([[level]], [[category]], [[log_time]], [[prefix]], [[message]], [[info]], [[url]], [[application]], [[application_id]], [[user_id]], [[device_id]])
            VALUES (:level, :category, :log_time, :prefix, :message, :info, :url, :application, :application_id, :user_id, :device_id)";
    $command = $this->db->createCommand($sql);
    foreach ($this->messages as $message) {
        list($text, $level, $category, $timestamp) = $message;
        if (!is_string($text)) {
            if ($text instanceof \Throwable || $text instanceof \Exception) {
                $text = (string) $text;
            } else {
                $text = VarDumper::export($text);
            }
        }
        $url = isset($_SERVER['REQUEST_URI'])?$_SERVER['REQUEST_URI']:'';
        $application    = Yii::$app->id;
        $application_id = $this->getApplicationId();
        $user_id        = $this->getUserId();
        $device_id      = $this->getDeviceId();
        $info           = $this->getContextMessage();
        $prefix         = $this->getMessagePrefix($message);
        $command->bindValues([
            ':level'          => $level,
            ':category'       => $category,
            ':log_time'       => $timestamp,
            ':prefix'         => $prefix,
            ':message'        => $text,
            ':info'           => $info,
            ':url'            => $url,
            ':application'    => $application,
            ':application_id' => $application_id,
            ':user_id'        => $user_id,
            ':device_id'      => $device_id,
        ])->execute();
    }
    $this->enableLogging(true);
}

/**
 * The method makes commands just like 
 * Yii::$app->log->targets['query']->enabled = false/true
 *
 * @param boolean $enable
 */
protected function enableLogging($enable)
{
    if (!empty($this->disableTargets)) {
        foreach ($this->disableTargets as $target) {
            if (isset(Yii::$app->log->targets[$target])) {
                $targetObject = Yii::$app->log->targets[$target];
                if (!$enable) {
                    $this->_diasbledTargets[$target] = $targetObject->enabled;
                    $targetObject->enabled = $enable;
                } else {
                    $targetObject->enabled = $this->_diasbledTargets[$target];
                }
            }
        }
    }
}

AdvDbTarget extends DbTarget. A target named 'query' is the target which logs yii\db\Command messages from AdvDbTarget. My code with enableLogging method not works properly.

Upvotes: 0

Views: 1337

Answers (1)

Mik
Mik

Reputation: 385

The solution is to extend yii\db\Command by custom command class, overload the execute method without tracing & profiling and configure connection like this: $this->db->commandClass = Command::className();

Upvotes: 0

Related Questions