diff options
-rw-r--r-- | it.class | 51 |
1 files changed, 27 insertions, 24 deletions
@@ -21,7 +21,7 @@ class it { -static $error_context; # Callback, can provide $result['head'] and $result['toscreen'] +static $error_context; # Callback, can provide $p params like 'head' and 'toscreen' /** * Create config class with static members initialized (e.g. $home). @@ -169,6 +169,8 @@ static function error($p = array(), $extra = null) $p['title'] = $p[0] ?: $p['title']; # handle 'it_error' => "oops" that was cast to array on the way $p['title'] = grapheme_substr($p['title'], 0, 2000) ?: substr($p['title'], 0, 2000); + $p += is_callable(self::$error_context) ? (self::$error_context)() : []; + $home = $GLOBALS['ULTRAHOME']; # support for errlike() in tests @@ -196,12 +198,12 @@ static function error($p = array(), $extra = null) 'to' => $authors ? $authors : (get_current_user() ? get_current_user() : $_SERVER['SERVER_ADMIN']), 'graceperiod' => 60, 'timewindow' => 25*3600, - 'backtraceskip' => 1, 'blockmail' => $p['okstate'] ? 60 : 3600, 'omitdebuginfo' => false, 'failcount' => 2, 'id' => $p['timewindow'] ? "it_error_id_" . it_debug::backtrace(['skipfiles' => "it.class", 'levels' => 1]) : 0, ); + if (it::match('-', $p['timewindow']) && ($parts = explode("-", $p['timewindow']))) list($p['graceperiod'], $p['timewindow']) = [$parts[0], $parts[1] - $parts[0]]; $p += array('blockmailid' => $GLOBALS['ULTRASITE'] . "." . md5($p['to'])); @@ -219,9 +221,7 @@ static function error($p = array(), $extra = null) return $p['fatal'] && !$okstatus ? self::_exit($p) : null; # nothing to report } - $context = is_callable(self::$error_context) ? (self::$error_context)() : []; - - $toscreen = getenv('NOERRORMAILS') || ini_get('display_errors') || (defined("STDOUT") && posix_isatty(STDERR)) || EDC('astwin') || EDC('asdevel') || $context['toscreen']; + $toscreen = getenv('NOERRORMAILS') || ini_get('display_errors') || (defined("STDOUT") && posix_isatty(STDERR)) || EDC('astwin') || EDC('asdevel') || $p['toscreen']; if ($toscreen && !it::is_live()) $GLOBALS['debug_noredir'] = 1; @@ -277,25 +277,24 @@ static function error($p = array(), $extra = null) ($p['omitdebuginfo'] >= 2 ? "" : ($url && !$toscreen? "Title: {$p['title']}\nUrl: $url\n" : "") . ($trace ? ($sendmail ? "" : " ") . "Trace: $trace\n" : "")) . (!$sendmail || $p['omitdebuginfo'] >= 2 ? "" : "Host: " . getenv('HOSTNAME') . " at " . date("Y-m-d H:i:s") . (($t = time() - $_SERVER['REQUEST_TIME']) ? " (invoked {$t}s before)" : "") . "\n") . # no it::date() due to time- debug param - ($sendmail ? $context['head'] : "") . + ($sendmail ? $p['head'] : "") . ($p['id'] && !$toscreen ? "Filter: timewindow=" . $p['graceperiod'] . "-" . ($p['graceperiod'] + $p['timewindow']) . " (previous err: " . it::date('', $errstamp) . ")\n" : "") . (!$origp['blockmail'] || $p['omitdebuginfo'] || $toscreen ? "" : "Block-resend: " . $origp['blockmail'] . " seconds\n") . ($p['body'] ? ($p['omitdebuginfo'] ? "" : "Body:\n") . trim($p['body'])."\n\n" : ""); - if ($sendmail) # we're mailing: send maximum info + if ($sendmail || EDC('verboseerrors')) # we're mailing: send maximum info { $p['title'] = it::replace(['alert:|server:|^: "' => "", '(pw|passw|password\d*|secret)(=)[^&\s]*' => '$1$2*****'], it::match('[^.]*', $GLOBALS['ULTRASITE']) . ": " . $p['title']) . " (via " . getenv('HOSTNAME') . ")"; if (!$p['omitdebuginfo']) { - foreach (($trace ? ($p['trace'] ?: debug_backtrace()) : []) as $level => $stackframe) - if ($level >= $p['backtraceskip'] && $tracesize < 100000 && ($tracesize += strlen(print_r($stackframe, true))) < 100000) # save mem - $stackframes[] = $stackframe; - + $backtrace = $p['trace'] ?: array_slice(debug_backtrace(0), $p['backtraceskip']); + $mediumstack = it_debug::backtrace(['trace' => $backtrace, 'format' => "medium"]); + $longstack = it_debug::backtrace(['trace' => $backtrace, 'format' => "long"]); $reqbody = it::file_get_contents("php://input"); - $body .= ($trace and $t = it::exec('grep -h {0} `ls {1}/alertlog-*|tail -3` /dev/null 2>/dev/null | grep ^2 | cut -d : -f 1-2 | sort | uniq -c | tail -10', $trace, $home)) ? "Histogram: (last 10 affected minutes in 3 days)\n$t" : ""; - $body .= "\n"; + $body .= ($trace and $t = it::exec('grep -h {0} `ls {1}/log/alertlog-*|tail -3` /dev/null 2>/dev/null | grep ^2 | cut -d : -f 1-2 | sort | uniq -c | tail -10', $trace, $home)) ? "Histogram: (last 10 affected minutes in 3 days)\n$t\n" : ""; + $body .= $mediumstack ? "Stack:\n " . it::replace("\n" => "\n ", $mediumstack) . "\n" : ""; $body .= $_GET ? "\$_GET: " . var_export($_GET, true) . "\n\n" : ""; $body .= $_POST ? "\$_POST: " . var_export($_POST, true) . "\n\n" : ""; $body .= $reqbody ? "\$reqbody: " . var_export($reqbody, true) . "\n\n" : ""; @@ -304,7 +303,7 @@ static function error($p = array(), $extra = null) $body .= $_SERVER ? "\$_SERVER: " . var_export($_SERVER, true) . "\n\n" : ""; $body .= $_FILES ? "\$_FILES: " . var_export($_FILES, true) . "\n\n" : ""; $body .= "Processes:\n" . it::exec('ps auxf | egrep -v "rotatelogs|getbanner|logaction|httpd|systemd|sd-pam"|egrep "^www|^cron"') . "\n"; - $body .= $stackframes ? "Stack: " . print_r($stackframes, true) . "\n\n" : ""; + $body .= $longstack ? "Full stack: " . "$longstack\n" : ""; $body = it::replace(array('(pw|passw|password\d*|secret)(\' => |\] => |=)[^&\s]*' => '$1$2********'), $body, array('utf8' => false)); } @@ -315,16 +314,20 @@ static function error($p = array(), $extra = null) $user = posix_getpwuid(posix_geteuid())['name']; - it::mail([ - 'From' => "\"$user@" . gethostname() . "\" <$user>", - 'To' => $p['to'], - 'Reply-To' => $p['to'], - 'Cc' => $GLOBALS['it_defaultconfig']['error_cc'], - 'Subject' => $type . substr($p['title'], 0, 160), - 'Body' => it::replace(['\x00' => "[NULLBYTE]"], $body, ['utf8' => false]), - 'forcemail' => !it::is_devel(), - ]); - $p['title'] = "Mail: " . $p['title']; + if ($sendmail) + it::mail([ + 'From' => "\"$user@" . gethostname() . "\" <$user>", + 'To' => $p['to'], + 'Reply-To' => $p['to'], + 'Cc' => $GLOBALS['it_defaultconfig']['error_cc'], + 'Subject' => $type . substr($p['title'], 0, 160), + 'Body' => it::replace(['\x00' => "[NULLBYTE]"], $body, ['utf8' => false]), + 'forcemail' => !it::is_devel(), + ]); + else + echo $body; + + $p['title'] = "Mail: " . $p['title']; } else if ($_SERVER['REMOTE_ADDR'] && EDC('edplain')) # toscreen mode: web echo $p['title'] . "\n"; |