Rotating PHP error log in /home/ directory

GoWilkes

Well-Known Member
Sep 26, 2006
692
33
178
cPanel Access Level
Root Administrator
I have PHP error logs in the account directories:

/home/account/logs/account_com.php.error.log

I see it's getting pretty lofty in size; 5.3G! Mostly full of warnings that are helpful, but not critical.

Is there a way to get these to rotate out like all of the other log files?
 

cPRex

Jurassic Moderator
Staff member
Oct 19, 2014
14,425
2,259
363
cPanel Access Level
Root Administrator
Hey hey! While this is older, and you'd need to change things to be in the context of the MultiPHP Manager, you can disable them globally so they don't get generated in the first place and then have each user enable them as necessary:


but there isn't an automated way to rotate these like there is with the system logs.
 
  • Like
Reactions: GoWilkes

LBJ

Well-Known Member
Nov 1, 2003
117
24
168
cPanel Access Level
DataCenter Provider
G'day GoWilkes,

Is there a way to get these to rotate out like all of the other log files?
You could just run something like this once a month...

Code:
#!/bin/bash

shopt -s nullglob
for f in /home/*/logs/*.php.error.log
do
  for ext_target in {3..1}
  do
    ext_source=$((ext_target-1))
    ext_target=".$ext_target"
    ext_source=".$ext_source"

    if [[ $ext_source == ".0" ]]
    then
      ext_source=""
    fi

    if [[ -f "$f$ext_source" ]]
    then
      mv "$f$ext_source" "$f$ext_target"
    fi
  done
done
I pulled that out of the custom code we wrote for our production servers, but had to modify it to make it stand alone. Double-check it for yourself, and you can temporarily put an echo in front of that single mv if you'd like to run it in a test mode to see what it's about to do. It will mv and overwrite existing files as per...

domain.php.error.log2 -> domain.php.error.log.3
domain.php.error.log1 -> domain.php.error.log.2
domain.php.error.log -> domain.php.error.log.1

Respective rotation will only occur when a base domain.php.error.log file exists. That will only happen after the client's application next causes a warning/error to be logged.

You could optionally expand the code to check for file size, and only rotate when a threshold has been hit. Then you'd probably want to run it daily instead of monthly.

However, I suspect simply retaining 3 previous logs (or whatever you want to modify it to in the code above) would do the trick for you as a monthly routine. That's all we do. Most developers won't want to go back further than 3 months.

Best regards,

LBJ
 
  • Like
Reactions: cPRex

GoWilkes

Well-Known Member
Sep 26, 2006
692
33
178
cPanel Access Level
Root Administrator
For future readers, I'm working towards an alternative. It's not quite the same, but it solves my immediate issue.

I have one higher traffic site, which is the one that creates the huge error log; mostly related to warnings from after my update to PHP 7.x. I noticed that most of those errors were duplicates, so literally thousands of the same warning, over and over!

So instead, I started porting it to MySQL with a UNIQUE index to prevent duplicates.

I include a script on every page of the site, anyway, so it was a simple addition of this to that file:

Code:
// credit to Pekka, at
// https://stackoverflow.com/questions/2911094/outputting-all-php-errors-to-database-not-error-log
function myErrorHandler($errno, $errstr, $errfile, $errline) {
    // table index is UNIQUE on errstr, errfile, and errline
    $error_str = sprintf("INSERT IGNORE INTO error_log VALUES('%s', '%s', '%s', '%s')",
        mysqli_real_escape_string($dbh, $errno),
        mysqli_real_escape_string($dbh, $errstr),
        mysqli_real_escape_string($dbh, $errfile),
        mysqli_real_escape_string($dbh, $errline));

    mysqli_query($dbh, $error_str);

    // Don't execute PHP internal error handler
    return true;
}

// set to the user defined error handler
$old_error_handler = set_error_handler("myErrorHandler");
Is there a way to set this per user in the Apache configuration (eg, at /etc/apache2/conf.d/userdata/ssl/2_4/example)? I wouldn't mind doing it server wide, but only if it would automagically create a MySQL database and table for each account (I obviously don't want everyone's error in my table).
 

GoWilkes

Well-Known Member
Sep 26, 2006
692
33
178
cPanel Access Level
Root Administrator
I'm working on it, but it's going to take some time and the log was growing unnecessarily. It looks like most of the warnings are on "undefined index" or "undefined variable", where I was doing something like this:

Code:
if ($_GET['foo'] == 'bar')
instead of

Code:
if (isset($_GET['foo']) && $_GET['foo'] == 'bar')
 
  • Like
Reactions: cPRex