2013-05-07 84 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); 
    } 
} 

}