Skip to content

Instantly share code, notes, and snippets.

@katoba86
Created June 19, 2019 11:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save katoba86/cc4122a7b74b73d982b3b909d59b2a72 to your computer and use it in GitHub Desktop.
Save katoba86/cc4122a7b74b73d982b3b909d59b2a72 to your computer and use it in GitHub Desktop.
Error logging in a database is in Yii2 really not comfortably implemented. (My opinion). The additional row with the server information confused and is not good to read. Here's a small class, which makes sure that the prefix matches the URL name (if not available, the user IP) and adds the additional informations in the message.
<?php
namespace app\lib;
use yii\helpers\VarDumper;
use yii\log\DbTarget;
use yii\log\LogRuntimeException;
class MyDBLogger extends DbTarget
{
public function export()
{
if ($this->db->getTransaction()) {
// create new database connection, if there is an open transaction
// to ensure insert statement is not affected by a rollback
$this->db = clone $this->db;
}
$tableName = $this->db->quoteTableName($this->logTable);
$sql = "INSERT INTO $tableName ([[level]], [[category]], [[log_time]], [[prefix]], [[message]])
VALUES (:level, :category, :log_time, :prefix, :message)";
$command = $this->db->createCommand($sql);
foreach ($this->messages as $message) {
list($text, $level, $category, $timestamp) = $message;
if (!is_string($text)) {
// exceptions may not be serializable if in the call stack somewhere is a Closure
if ($text instanceof \Throwable || $text instanceof \Exception) {
$text = (string) $text;
} else {
$text = VarDumper::export($text);
}
}
//collect additional infos
$additional = [];
if(isset($_SERVER)){ //looks cleaner :)
$additional["SERVER"] = $_SERVER;
}
if(isset($_GET)){ //CLI apps
$additional["GET"] = $_GET;
}
if(isset($_POST)){
$additional["POST"] = $_POST;
}
if(count($additional)!==0){
$text=$text."\n\n\n".VarDumper::export($additional);
}
if ($command->bindValues([
':level' => $level,
':category' => $category,
':log_time' => $timestamp,
':prefix' => $this->getMessagePrefix($message),
':message' => $text,
])->execute() > 0) {
continue;
}
throw new LogRuntimeException('Unable to export log through database!');
}
}
}
return [
//............
/*
* --------------------------------------------------------------------------
* Log Targets
* --------------------------------------------------------------------------
*
* A log target is an instance of the yii\log\Target class or its child class.
* It filters the log messages by their severity levels and categories and then
* exports them to some medium. You can register multiple targets.
*
*/
'targets' => [
[
'class' => 'app\lib\MyDBLogger', //your class
'levels' => ['error'], //or ['warning','error']
'logVars' => [], //we dont need this...
'logTable' => 'log_front', // or another table...
'prefix' => function ($message) {
if(isset($_SERVER) && isset($_SERVER["REQUEST_URI"])){
return $_SERVER["REQUEST_URI"];
}
return $_SERVER["REMOTE_ADDR"];
}
],
//other targets
],
];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment