In my CI config file I have this logging treshold set:
$config['log_threshold'] = 1;
In index.php, I have set the following error reporting:
error_reporting(E_ERROR);
My expectation is that this will log any CI errors that I log (using log_message('error','my error message')
), as well as any PHP errors. However, I would expect that it will not log PHP notices, only errors. However, when I look at the log files, it seems to log PHP notices too:
ERROR - 2009-12-18 13:21:50—> Severity: Notice —> Undefined variable: pageindex /var/www/apps/OS4W/system/application/views/user/view.php 12
ERROR - 2009-12-18 13:21:50—> Severity: Notice —> Undefined variable: friendsmode /var/www/apps/OS4W/system/application/views/user/activitytable.php 207
Although the log lines start with “ERROR”, in reality this seems to be a PHP notice, kind of like a warning, that I do not want to log. How can I make sure only CI and PHP errors are logged, yet not PHP notices? I thought error_reporting(E_ERROR)
would do just that?
According to the PHP error reporting docs at http://us2.php.net/manual/en/errorfunc.configuration.php#ini.error-reporting
In PHP 4 and PHP 5 the default value is E_ALL & ~E_NOTICE. This setting does not show E_NOTICE level errors. You may want to show them during development.
I'd try changing your error_reporting() to "E_ALL & ~E_NOTICE" and see if that works.
Dana
Edit: Well, I spoke too soon. I tried this and it stopped the notice from showing up on screen, but still logged it to the log file.
Solution:
OK I think I figured this out. In the common.php file there's a function called "_exception_handler" that handles the logging process. It does some bitwise comparisons of the current severity level and the error_reporting level to see if it should log to the screen, but it does not do so for logging to the log file. IT just passes everything through except for E_STRICT messages which it tosses regardless.
What you can do is wrap the very last line in this function with the same IF statement they use for logging to the screen. So the entire function becomes:
function _exception_handler($severity, $message, $filepath, $line)
{
// We don't bother with "strict" notices since they will fill up
// the log file with information that isn't normally very
// helpful. For example, if you are running PHP 5 and you
// use version 4 style class functions (without prefixes
// like "public", "private", etc.) you'll get notices telling
// you that these have been deprecated.
if ($severity == E_STRICT)
{
return;
}
$error =& load_class('Exceptions');
// Should we display the error?
// We'll get the current error_reporting level and add its bits
// with the severity bits to find out.
if (($severity & error_reporting()) == $severity)
{
$error->show_php_error($severity, $message, $filepath, $line);
}
// Should we log the error? No? We're done...
$config =& get_config();
if ($config['log_threshold'] == 0)
{
return;
}
if (($severity & error_reporting()) == $severity)
{
$error->log_exception($severity, $message, $filepath, $line);
}
}
and I think that will take care of it. Then you can use
error_reporting(E_ALL & ~E_NOTICE);
in your index.php. Of course we're editing the core here. Maybe there's a way to override instead?
Dana
First of all, thank you all for thinking along. After considering your advise, I decided to patch the core of CI. Unfortunately, the core classes can be extended, but not the core itself. Therefore if you apply the same patch, be sure to document it.
Here goes. In system\application\config\config.php I added the following custom config setting right below the log_treshold setting:
/*
|--------------------------------------------------------------------------
| Error Logging Exclusions (custom config addition by Ferdy Christant)
|--------------------------------------------------------------------------
|
| By default, CI will log all PHP errors, whether it is a notice, warning
| or error. Or, by setting the above treshold to 0, it will log nothing
| In most cases, however, you will want to log PHP errors but not the notices
| In the array below, simply place the PHP error constant that you do NOT
| want to see logged.
|
| For a live site you'll usually use the config as follow:
|
| $config['exclude_logging'] = array(E_STRICT,E_NOTICE);
|
*/
$config['exclude_logging'] = array(E_STRICT,E_NOTICE);
As the documentation explains, in this config array you put the PHP error types that you do NOT want to log.
Next, I have patched the core file (system/codeigniter/Common.php) and edited the function _exception_handler
There are two changes. First, I moved the config loading line to the top of the method, since I need it earlier. Find the line below and you will see $config =& get_config(); under it. Delete that.
I removed the // Should we log the error? No? We're done...
Second, the check for severity is modified to check for the array that we declared. Go to the top of the method and replace the if statement that checks $severity == E_STRICT with below:
$config =& get_config();
if (in_array($severity,$config['exclude_logging']))
{
return;
}
These patches allow for fine-grained control over PHP error logging. Normal CI logging will of course still work. As mentioned, the only downside is that this patches the core.
I hope this helps anyone. Thank you for thinking along!
For anyone else that might come across this with CodeIgniter 2.0. The problem is still the same, but the solution is "easier".
You still have to modify a core file: /system/codeigniter/Common.php
Find the _exception_handler()
function (should be at the bottom), and change this line:
if ($severity == E_STRICT)
to this: if ($severity == E_STRICT OR $severity == E_NOTICE)
Funny how they think E_STRICT
notices will fill up the log; but E_NOTICE
won't. Or maybe it's good to punish people for not coding strictly and declaring all their variables before using them? :)
try this, no need to patch CI core:
$hook['pre_controller'] = array(
'class' => 'MY_Commonfunction_hook',
'function' => 'hook',
'filename' => 'MY_Commonfunction_hook.php',
'filepath' => 'hooks');
class MY_Commonfunction_hook {
public function hook() {
set_error_handler('_my_exception_handler');
}
}
function _my_exception_handler($severity, $message, $filepath, $line) {
if ($severity == E_STRICT) {
return;
}
$_error = & load_class('Exceptions', 'core');
if (($severity & error_reporting()) == $severity) {
for ($i = ob_get_level(); $i > 0; $i--) {
@ob_end_clean();
}
$_error->show_php_error($severity, $message, $filepath, $line);
}
if (config_item('log_threshold') == 0) {
return;
}
if (($severity & error_reporting()) == $severity) {
$_error->log_exception($severity, $message, $filepath, $line);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With