2013-05-07 57 views
1

我想通過擴展現有的CI_Log類來將系統錯誤日誌存儲到數據庫。到目前爲止,這是我做了什麼如何存儲錯誤在CodeIgniter中登錄數據庫

class MY_Logger extends CI_Log{ 
    public function __construct(){ 
     parent::__construct(); 
    } 

    function write_log($level='error', $msg, $php_error = FALSE){ 

     $result = parent::write_log($level, $msg, $php_error); 
     $ci =& get_instance(); 
     $ci->load->library('user_agent'); 
     if ($result == TRUE && strtoupper($level) == 'ERROR') { 

      $gmtoffset = 60*60*5; 
      $post = array(
       'log_type' => $level, 
       'log_message' => $msg, 
       'log_php_message' => $php_error, 
       'log_ip_origin' => $this->input->ip_address(), 
       'log_user_agent' => $this->agent->agent_string(), 
       'log_date' => date("Y-m-d H:i:s",time() + $gmtoffset) 
      ); 

      $ci->db->insert('system_log', $post); 
     } 

     return $result; 
    } 
} 

和我有以下的autoload.php和config.php文件

$autoload['libraries'] = array('database', 'session', 'xmlrpc', 'user_agent'); 
$config['log_threshold'] = 1; 

配置然而,當我測試了一下,不存儲錯誤數據庫(雖然它顯示並正確寫入日誌)

任何人都可以指出我在這裏錯過了什麼嗎?

PS:

已經改變了代碼,以便它延伸CI_Exceptions不起作用以及:

class MY_Exceptions extends CI_Exceptions{ 
    function __construct(){ 
     parent::__construct(); 
    } 

    function log_exception($severity, $message, $filepath, $line){ 

     //$result = parent::write_log($level, $msg, $php_error); 
     $ci =& get_instance(); 
     //if ($result == TRUE && strtoupper($level) == 'ERROR') { 

      $gmtoffset = 60*60*5; 
      $post = array(
       'log_type' => $severity, 
       'log_message' => $message, 
       'log_php_message' => $line, 
       'log_ip_origin' => $ci->input->ip_address(), 
       'log_user_agent' => $ci->agent->agent_string(), 
       'log_date' => date("Y-m-d H:i:s",time() + $gmtoffset) 
      ); 

      $ci->db->insert('system_log', $post); 
     //} 
     parent::log_exception($severity, $message, $filepath, $line); 
     //return $result; 
    } 
} 
+0

它拋出?\ – 2013-05-07 07:45:13

+0

是您在庫文件夾中記錄任何錯誤?嘗試將其重命名爲MY_Log(或者你在配置中設置的任何前綴而不是MY_) – package 2013-05-07 07:49:38

+0

@LolCoder我通過創建將數據插入到不存在的表的故意錯誤來測試它。 – Jeremy 2013-05-07 07:56:35

回答

0

我相信我嘗試這樣做了一段時間後,並得出結論認爲,不應該引用CI實例中MY_Log,因爲它還沒有可用(或者並不總是被構造)。

0

由於在CI_Controller單例可用之前正在使用log_message()函數(使用日誌庫)正在使用log_message()函數,因此發生了問題。

您可能需要添加一個檢查來查看CI_Controller類是否可用,如果是,則使用get_instance()函數。然後,在使用$ CI時,您必須先確定它是否適當設置(或者,如果您沒有使用構造函數來分配$ CI,則在第一個檢查的if語句內執行)。

很可能您正在嘗試記錄控制器中發生的錯誤,這意味着當時可以使用數據庫功能。對於那些在某些Core文件初始化時發生的早期調試消息,您將只是沒有數據庫日誌記錄。

0

我遇到了類似的加載順序問題。我的目標是將CI日誌記錄重定向到MonoLog,並通過電子郵件向我發送任何錯誤。我想使用已經存在的庫框架來加載Monolog和SwiftMail,但這是不可用的。

我從CI_Log中的get_config加載配置設置,但這隻包含來自config.php的值(不是來自任何其他配置文件)。我使用get_config函數作爲基礎來創建另一個函數來加載其他配置文件。這然後允許我加載我的電子郵件設置。然後我爲Monolog和Swiftmail創建了新的裝載器。它有點混亂,但它有效。

<?php if (! defined('BASEPATH')) exit('No direct script access allowed'); 

include_once APPPATH . 'libraries/Swift_Mail/swift_required.php'; 
require_once APPPATH . 'libraries/common/ClassLoader.php'; 

use MyApp\Common\ClassLoader, 
Monolog\Logger, 
Monolog\Handler\RotatingFileHandler, 
Monolog\Handler\SwiftMailerHandler, 
Psr\Log\LoggerInterface; 

class MY_Log extends CI_Log { 

/** @var \Swift_Mailer */ 
private $mailer; 

/** @var $logger LoggerInterface */ 
protected $logger; 

private $cfg; 

public function __construct() 
{ 
    parent::__construct(); 
    $masterConfig = &get_config(); //This is a config array, not the CI Config object 
    $emailConfig = $this->GetConfig('email'); 
    $this->cfg = array_merge($masterConfig, $emailConfig); 

    $this->InitMailer(); 
    $this->InitLogger(); 
} 

/** 
* There is no exposed CI way to load the email config file, so this allows us to load it. 
* The logic is based on the get_config function in CI. 
* @param $configName 
* @return null 
*/ 
function GetConfig($configName) 
{ 
    $config = null; 

    // Is the config file in the environment folder? 
    if (! defined('ENVIRONMENT') OR ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/'.$configName.'.php')) 
    { 
     $file_path = APPPATH.'config/config.php'; 
    } 

    // Fetch the config file 
    if (! file_exists($file_path)) 
    { 
     exit('The configuration file does not exist.'); 
    } 

    require($file_path); 

    // Does the $config array exist in the file? 
    if (! isset($config) OR ! is_array($config)) 
    { 
     exit('Your config file does not appear to be formatted correctly.'); 
    } 

    return $config; 
} 

/** 
* This mirrors the init in the SwiftMail Loader. This is required b/c 
* libraries are not loaded at this point. 
*/ 
protected function InitMailer() 
{ 
    $transport = Swift_SmtpTransport::newInstance 
     ($this->cfg['smtp_host'], 
      $this->cfg['smtp_port']); 

    $transport->setTimeout(20); //Amazon Internal Timeout of 5s, just giving a buffer 

    if(array_key_exists('smtp_user',$this->cfg)) 
    { 
     $transport->setUsername($this->cfg['smtp_user']); 
    } 

    if(array_key_exists('smtp_pass',$this->cfg)) 
    { 
     $transport->setPassword($this->cfg['smtp_pass']); 
    } 

    if(array_key_exists('smtp_crypto',$this->cfg)) 
    { 
     $transport->setEncryption($this->cfg['smtp_crypto']); 
    } 

    /** @var $mailer Swift_Mailer*/ 
    $this->mailer = Swift_Mailer::newInstance($transport); 
} 

/** 
* Setup monolog. 
*/ 
protected function InitLogger() 
{ 
    $loader = new ClassLoader("Psr", APPPATH . 'libraries'); 
    $loader->register(); 

    $loader = new ClassLoader("Monolog", APPPATH . 'libraries'); 
    $loader->register(); 

    $logLevel = Logger::ERROR; 

    /* CI Error levels 
    * | 0 = Disables logging, Error logging TURNED OFF 
     | 1 = Error Messages (including PHP errors) 
     | 2 = Debug Messages 
     | 3 = Informational Messages 
     | 4 = All Messages 
    */ 

    switch($this->cfg['log_threshold']) 
    { 
     case 0: 
      $logLevel = Logger::ERROR; //We still want errors. 
      break; 
     case 1: 
      $logLevel = Logger::INFO; 
      break; 
     case 2: 
      $logLevel = Logger::DEBUG; 
      break; 
     case 3: 
      $logLevel = Logger::INFO; 
      break; 
     case 4: 
      $logLevel = Logger::DEBUG; 
      break; 
    } 

    /** @var $message Swift_Message*/ 
    $message = Swift_Message::newInstance('MyApp Error - '.ENVIRONMENT) 
     ->setFrom($this->cfg['FROM_ADDR']) 
     ->setTo($this->cfg['ERROR_ADDR']); 

    $swiftMailHandler = new SwiftMailerHandler($this->mailer, $message, Logger::ERROR); 


    $this->logger = new Logger('myapp'); 
    $this->logger->pushHandler(new RotatingFileHandler(APPPATH.'logs/myapp.log', 0, $logLevel, true, 0666)); 
    $this->logger->pushHandler($swiftMailHandler); 
} 


public function write_log($level = 'error', $msg, $php_error = FALSE) 
{ 
    parent::write_log($level, $msg, $php_error); 

    if($level === 'error') 
    { 
     $this->logger->error($msg); 
    } 
    elseif($level === 'debug') 
    { 
     $this->logger->debug($msg); 
    } 
    else 
    { 
     $this->logger->info($msg); 
    } 
} 

}