How to store error Log to database in CodeIgniter

codeigniter, database error handling
codeigniter log user activity
error handling in codeigniter
error log for codeigniter
codeigniter log_message
codeigniter log database
codeigniter query error handling
codeigniter log to syslog

I would like to store system error log to a database by extending the existing CI_Log class. So far this is what i have done

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;
    }
}

and i have the following configured in autoload.php and config.php

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

However when i test it, it does not store the error to database (although, it displays and writes the log properly)

Can any one point out what i missed here?

ps:

Having changed the code so it extends CI_Exceptions does not work as well:

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;
    }
}

I believe I tried this a while back and concluded that one should not reference the CI instance in MY_Log, since it's not yet available (or not always constructed yet).

Error Handling — CodeIgniter 4.0.4 documentation, I believe I tried this a while back and concluded that one should not reference the CI instance in MY_Log, since it's not yet available (or not always constructed� Store php error or exception logs into database. Contribute to appleboy/CodeIgniter-Log-Library development by creating an account on GitHub.

The problem is happening because the log_message() function - which utilizes the Log library - is being used before the CI_Controller singleton is available.

You’ll likely need to add a check to see if the CI_Controller class is available yet, and if it is, then use the get_instance() function. Then, when using $CI, you’ll have to make sure it’s set appropriately first (or just do it inside the first check’s if statement if you aren’t utilizing the constructor to assign $CI).

Chances are you’re trying to log errors that occur in your controllers, which would mean the DB functions would be available by then. You’ll just be without DB logging for those earlier debug messages that occur when some Core files initialize.

PHP Error Log Library (Database), In this case, a more generic message is displayed to keep the best user Disabling error reporting DOES NOT stop logs from being written if there are errors. This exception is thrown for database errors, such as when the database� log_message() function is used to write log messages. This is useful when you want to write custom messages.

I ran into a similar problem with order of loading. My goal was to redirect CI logging to MonoLog and to have any errors emailed to me. I wanted to use the library framework that was already in place to load Monolog and SwiftMail, but that isn't available.

I loaded the config settings from get_config in CI_Log, but this only includes values from config.php (not from any other config files). I used the get_config function as a base to create another function to load other config files. This then allowed me to load my email settings. I then created new loaders for Monolog and Swiftmail. Its a little messy, but it works.

<?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);
    }
}

}

Error Handling — CodeIgniter 3.1.11 documentation, We can store all error message into database. ) ENGINE=InnoDB DEFAULT CHARSET=utf8; You can install via codeigniter spark or step by step from following instruction. Finally excute via command line. Simple Codeigniter application project looks like below in Eclipse editor. Codeigniter Database Configuration. As you know that Php Codeigniter is popular for minimum configuration (almost Zero configuration) framework. To connect to database you need to provide username, password and database name configuration details in database.php file.

@Jeremy In one of your comments, you have mentioned that your logger class is stored inside the libraries folder. Instead, it should be placed under the core folder with the name as MY_Log.php. For more details refer to the following link:

https://codeigniter.com/user_guide/general/core_classes.html#extending-core-class

The only issue was with the file naming convention and placing it in the wrong folder. As for your code, I have tested it at my end and it works properly. I know its an old question but was knowing the solution for the same so shared it.

appleboy/CodeIgniter-Log-Library: Store php error or , In addition, it has an error logging class that permits error and debugging returning the proper code helps server software keep track of your scripts and the � It DOES NOT return a database result set, nor does it set the query timer, or compile bind data, or store your query for debugging. It simply lets you submit a query. Most users will rarely use this function. It returns whatever the database drivers’ “execute” function returns.

Getting Started Quickly With CodeIgniter Logging, Store all php error or exception logs into database. Installation. Create log table on your database. SQL structure is available on sql/mysql.sql --� Like any other framework, we need to interact with the database very often and CodeIgniter makes this job easy for us. It provides rich set of functionalities to interact with database. In this section, we will understand how the CRUD (Create, Read, Update, Delete) functions work with CodeIgniter.

Logging Information — CodeIgniter 4.0.4 documentation, Get some pointers to help you get going with CodeIgniter logging, Hopefully, you agree with me that logging every error at this level is probably inappropriate. This might be that the website is down, the database is unreachable, this is where you store all of the configuration for your logging needs. CodeIgniter 3 has a 2MB download, including the user guide. CodeIgniter 4 is a 1.2MB download, plus 6MB for the user guide. Much of the CodeIgniter configuration is done by convention, for instance putting models in a "models" folder. There are still a number of configuration options available

ADD ERROR LOG FILE IN CODEIGNITER, You must supply the “level” of the error in the first parameter, indicating what info, Interesting events in your application, like a user logging in, logging SQL� CodeIgniter always loads the global config file first (i.e., the one in application/config/), then tries to load the configuration files for the current environment. This means you are not obligated to place all of your configuration files in an environment folder.

Comments
  • any error it throws?\
  • Is your logger in libraries folder? Try renaming it MY_Log (or whatever prefix you have set in config instead of MY_)
  • @LolCoder i tested it by creating a deliberate error of inserting data to a non-existing table.
  • @package yes my logger class is inside application/libraries/logger.php, there is one thing that i am not sure of, is how to load this library. Because normally if i want to load my own library i need to explicitly specify it inside my controller
  • @package both renaming logger.php -> MY_Logger.php and renaming the class Logger -> class MY_Logger does not work either.