summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUrban Müller2023-05-04 17:16:47 +0200
committerUrban Müller2023-05-04 17:16:47 +0200
commitc6c7581505fa31fc6ddb97a0839b9020411b46e0 (patch)
tree8e8097a8223912686374d5d9e0537d61d42f354d
parent0b98aaa35fc4320d61eab2ec8d668d010625051f (diff)
downloaditools-c6c7581505fa31fc6ddb97a0839b9020411b46e0.tar.gz
itools-c6c7581505fa31fc6ddb97a0839b9020411b46e0.tar.bz2
itools-c6c7581505fa31fc6ddb97a0839b9020411b46e0.zip
add medium length stackdumps, clean up stack trace generation params, make easier to debug
-rw-r--r--it.class51
1 files changed, 27 insertions, 24 deletions
diff --git a/it.class b/it.class
index e24ddf5..935ec98 100644
--- a/it.class
+++ b/it.class
@@ -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";