//Manda una mail agli sviluppatori di indi e scrive un log function indi_dev_email($oggetto, $messaggio=null, $log=true){ $agg = ''; if($GLOBALS['CONF']['dove_sono'] == 'loc') $agg .= "[DEMO] "; if(function_exists("is_tnx_raw") && is_tnx_raw()) $agg .= "[NOI] "; $oggetto = $agg."[INDI] ".$oggetto; if($log and function_exists('indi_log_globale')) indi_log_globale($oggetto,$messaggio); $raggruppaMail = false; // if ($_SERVER["SERVER_NAME"] == "demo.tnx.it") $raggruppaMail = true; if ($raggruppaMail) { //cecca $fname = "../../errori/"; if (!is_dir($fname)) mkdir($fname); $fname .= "err-" . floor(microtime(true) * 1000) . "-" . mt_rand(1000,9999) . ".json"; $from = "http".($_SERVER['HTTPS']=='on'?'s':'')."://$_SERVER[SERVER_NAME]$_SERVER[REQUEST_URI]"; file_put_contents($fname, json_encode(array("from"=>$from, "to"=>$GLOBALS['_dev_email'], "subject"=>$oggetto, "body"=>$messaggio), JSON_PRETTY_PRINT)); //$GLOBALS['_dev_email'] = "mceccarelli@demo.tnx.it"; $to = $GLOBALS['_dev_email']; $lastMailTs = @file_get_contents("../../errori_lastMailTs_".$to.".txt"); $diff = time() - $lastMailTs; if ($lastMailTs == 0 || $diff > 60) { $body = get_body_error_raggr($lastMailTs,$to); @file_put_contents("../../errori_lastMailTs_".$to.".txt", time()); return mailtnx($to,$oggetto,$body, 'MIME-Version: 1.0' . "\r\n" . 'Content-type: text/html; charset=UTF-8' . "\r\n"); } else { @file_put_contents("../../errori_lastMailToSend_".$to.".txt", time()); @file_put_contents("../../errori_lastMailToSend_".$to.".json", json_encode(array("from"=>$from, "to"=>$to, "subject"=>$oggetto), JSON_PRETTY_PRINT)); } } else{ if($GLOBALS['_dev_email']) //non uso indi_email_wrapper altrimenti con email_debug_cliente li riceve il cliente, _dev_email viene comunque avvalorata con l'email dello sviluppatore tramite ip in locale return mailtnx($GLOBALS['_dev_email'],$oggetto,$messaggio, 'MIME-Version: 1.0' . "\r\n" . 'Content-type: text/html; charset=UTF-8' . "\r\n"); } } function get_body_error_raggr($lastMailTs,$to) { $files = glob("../../errori/*"); usort($files, function($a, $b) { return filemtime($b) - filemtime($a); }); foreach($files as $k=>$v) { $err = json_decode(file_get_contents($v), true); if ($err["to"] == $to) { $err["file"] = substr($v,13); $err["ts"] = filemtime($v); if ($err["ts"] > $lastMailTs) { $rows[] = $err; } } } //https://jsfiddle.net/gSPqX/1/ $b = "
"; foreach($rows as $k=>$v) { $b .= date("d/m/y H:i:s", $v["ts"]) . " - ".$v["subject"]."".print_r_pulito($_SESSION, true);
// die;
// }
$inviaEmail = !@$GLOBALS["CONF"]['indi_error']/*durante il boot*/
|| @$GLOBALS["CONF"]['indi_error'] == "NO"
|| @$_GET['testErrori']
|| @$CONF['inviaErroriViaMailInLocale']
|| @$_GET['t'] == 'webservice';
if(@$_GET['testErrori'] && @$_GET['testErrori'] != 1) $GLOBALS['_dev_email'] = $_GET['testErrori'];
//in caso di Allowed memory size se uso molta memoria la funzione non termina
$RISPARMIA_MEMORIA = strpos($msg, "Allowed memory size") === 0;//può essere serializzata ed esserci la parola "memory" in mezzo
// $RISPARMIA_MEMORIA = stripos($msg, "memory") !== false;
$url = "http".($_SERVER['HTTPS']=='on'?'s':'')."://$_SERVER[SERVER_NAME]$_SERVER[REQUEST_URI]";
if($RISPARMIA_MEMORIA && $inviaEmail){
//esempio di inutile backtrace:
// /home/httpd/html/pagine/indi/INDI_ver1.1/boot00100_gestione_errori.php debugTnx()
// /home/httpd/html/pagine/indi/INDI_ver1.1/boot00100_gestione_errori.php indi_error_handler()
// indi_shutdown_function()
// indi_error_handler_email("Fatal memory", $url);//non ce la ad inviare la mail
// mailtnx("carlo@tnx.it", "Fatal memory", $url);
if(!$GLOBALS['CONF']['disattivaSegnalazioniEmailTnx'])
indi_dev_email("[FATALE] Allowed memory size exhausted", $url, false);
}
if(!error_reporting()) return;//(error_reporting()==0 vuol dire che è stato soppresso l'errore con @)
if($CONF && @$CONF['indi_ignora_tutti_gli_errori']) return;
//in caso di errore riduco il max_execution_time
/* $email = "errori@tnx.it,sysadmin@tnx.it";
if(in_array($CONF['sito'], array("premioceleste"))){
$email = "a.toce@tnx.it,damiano@tnx.it,sysadmin@tnx.it";
}*/
// $email = "carlo@localhost";
//errore warning:
//online: mando mail, non faccio vedere nulla all'utente e continuo lo script
//locale: gestisco come normale warning con stampa a video
if($msg == "Illegal string offset '".@$GLOBALS['lang']."'") return;
if(PHP_MAJOR_VERSION >= 7 && strpos($msg, 'Declaration of') === 0) return;//php7
if(PHP_MAJOR_VERSION >= 8 && strpos($msg, 'Undefined array key') === 0) return;//php8
if(PHP_MAJOR_VERSION >= 8 && strpos($msg, 'Trying to access array offset on value of type null') === 0) return;//php8
if(PHP_MAJOR_VERSION >= 8 && strpos($msg, 'Undefined global variable') === 0) return;//php8
if(PHP_MAJOR_VERSION >= 8 && strpos($msg, 'Undefined array key') === 0) return;//php8
//if(function_exists("is_spider") && is_spider()) return;//carlo 22/7/2013: prendo anche quelli degli spider perchè nel caso dell'ultimo "Allowed memory size of 268435456 bytes exhausted" era proprio uno spider (forse)
if(@$CONF['dove_sono'] == 'loc'){//online non blocco il funzionamento del sito (ad esempio in caso di trigger_error manuale dopo un post che ha il redirict)
$GLOBALS['CONF']['force_no_redirect'] = "SI";//se dopo l'errore c'è un indi_redirect lo perdo!
}
//unisco gli errori del php con quelli di indi, in qualche modo
if(!$RISPARMIA_MEMORIA) $msg_unserialized = unserialize($msg);
if(!is_array($msg_unserialized)) {
$tipierrore_php_indi = array(
E_ERROR => "FATALE",
E_PARSE => "FATALE",
E_COMPILE_ERROR => "FATALE",
E_WARNING => "WARNING",
E_USER_NOTICE => "NOTICE",//attenzione a questi errori, non vengono mostrati online, non andrebbero usati (è il default su trigger error)
E_USER_WARNING => "WARNING",
E_RECOVERABLE_ERROR => "WARNING",
E_DEPRECATED => "WARNING",
E_CORE_WARNING => "WARNING",
E_USER_DEPRECATED => "WARNING",
E_USER_ERROR => "WARNING"
);
$msg = array(
"errore" => $msg,
"nome" => $tipierrore_php_indi[$code], //forse meglio lasciarlo come quello del PHP
"gruppo" => "PHP",
);
}
else{
$msg = $msg_unserialized;
}
$htmlEntitiesFunc = function_exists("indi_htmlentities") ? "indi_htmlentities" : "htmlentities";//lcune volte scatta prima che sia definita la funzione indi
if(!$RISPARMIA_MEMORIA){
$debug_print_backtrace = debug_backtrace();
//while(list($k,$v) = each($debug_print_backtrace)) {
foreach($debug_print_backtrace as $k => $v) {
//scrivo su file
// if($k == 3) {
//$log_file = $debug_print_backtrace[2][0]);
// }
if(($k > 1 and $msg['gruppo'] != "PHP") or ($msg['gruppo'] == "PHP" and $k > 0) && $k < 20) {
// $debug_print_backtrace_out = "".$v['function'].$v['class']."(".nl2br(@$htmlEntitiesFunc(indi_var_dump($v['args'][0]))).") in [".$v['file']."] (linea: ".$v['line'].")";
if (!isset($v["class"])) $v["class"] = "";
@$errore .= "backtrace: $v[file], linea: $v[line] $v[function].$v[class]\n";
@$debug_print_backtrace_out .= "\n".
"".$v['file'].":".$v['line']."
".($v['class']?$v['class']."->":"").$v['function']."()".
(!in_array($v['function'], array("mysql_connect", "mssql_connect", "mssqli_connect")) ? nl2br($htmlEntitiesFunc(indi_var_dump($v['args'], "print_r_pulito"))) : "--- PARAMETRI NASCOSTI PER SICUREZZA ---").
"
";
}
}
}
$linkLinea = "".$file.":".$line."";
if($inviaEmail) {
//invio mail
$durata = time()-$_SERVER['REQUEST_TIME'];
$in = is_file($GLOBALS["CONF"]['path_base']."indi.inc.php")?"indi.inc.php":"indi.php";
$body = "";
$body .= "$msg[errore]";
$body .= "
\n";
$body .= $linkLinea;
$body .= "
\n";
$body .= "$url";
$body .= "
\n";
$body .= "alle ".strftime("%H:%M:%S".substr(microtime(true), -3)." del %d/%m/%Y")." request_time_float ".$_SERVER['REQUEST_TIME_FLOAT']." load ".implode(" / ", sys_getloadavg())."";
$body .= "
\n";
if($durata) $body .= "durata richiesta $durata second".($durata==1?'o':'i')."
\n";
if(!$RISPARMIA_MEMORIA) $body .= $debug_print_backtrace_out;
$body .= "";
$body .= "$in\n";
$body .= "
";
$body .= "";
$body .= $htmlEntitiesFunc(print_r_pulito(array('$_GET'=>$_GET, '$_POST'=>$_POST, '$_SERVER'=>$_SERVER, '$_SESSION'=>@$_SESSION, '$_COOKIE'=>$_COOKIE), true));
$body .= "";
//mando email, il controllo su troppe email è dentro la funzione indi_error_handler_email
indi_error_handler_email($msg,$body);
}
else{
//stampa a video indi
$backtrace_html = "\n
".$htmlEntitiesFunc("$msg[gruppo] $msg[nome]").":
".$htmlEntitiesFunc(indi_var_dump($msg['errore']))." $linkLinea
---> mostra backtrace
";
if($_GET['testaDbOffline']){
$plainText = $msg;
$debugBacktrace = debug_backtrace(); array_unshift($debugBacktrace, array('file'=>__FILE__, 'line'=>__LINE__, 'function'=>'debugTnx')); foreach($debugBacktrace as $debugLine) $plainText[] = $debugLine['file'].":".$debugLine['line']." ".$debugLine['function']."()";
echo "
".implode("
", $plainText);
}
//variabile globale che viene poi stampata nell' output del sito
$GLOBALS['indi_error_messages'][$GLOBALS['indi_error_messages_k']++] = $backtrace_html;
// $GLOBALS['indi_error_messages'][$GLOBALS['indi_error_messages_k']++] = $msg['errore'];
}
if (function_exists("indi_log")) {
indi_log("[GESTORE_ERRORI] $msg[gruppo] $msg[nome] - $msg[errore] - file:$file - linea:$line",$errore);
} else {
echo "";
echo "Non esiste indi_log() per questo errore:" . "$msg[gruppo] $msg[nome] - $msg[errore] - file:$file - linea:$line\n";
print_r($errore);
echo "
";
}
}
function indi_exception_handler($exc){//wrapper per far gestire le eccezioni al gestore d'errori
//$code = $exc->getCode();
//if(!$code) $code = E_USER_WARNING;//se non c'è un codice lo faccio passare (e arrivare come email) come un warning
//CAMBIATO: li faccio arrivare tutti come fatal (perchè poi blocca l'esecuzione!)
$code = E_ERROR;
$msg = $exc->getMessage();
if(!$msg) $msg = "Eccezione senza descrizione";
$file = $exc->getFile();
$line = $exc->getLine();
indi_error_handler($code, $msg, $file, $line, array());
}
function indi_shutdown_function(){//wrapper per far gestire i fatal al gestore d'errori
$error = error_get_last();
// $error:
// Array
// (
// [type] => 1
// [message] => Allowed memory size of 262144 bytes exhausted (tried to allocate 24 bytes)
// [file] => /tnx/www/html/www/carlo/test.php
// [line] => 15
// )
//segnalo l'errore solo se è dei tipi previsti dal livello tnx
if($error['type'] && ($error['type']&ERROR_LEVEL_HANDLER_TNX)) indi_error_handler($error['type'], $error['message'], $error['file'], $error['line'], array());
}
//if(@$_GET['debugBootTnx'] || $NO_INDI_RENDER) {
if(@$_GET['debugBootTnx']) {
//cecca, facilito debug problemi (soprattutto quando si spsotano siti su nuovi server)
//error_reporting(ERROR_LEVEL_HANDLER_TNX);
error_reporting(E_ERROR | E_PARSE);
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
} else {
set_error_handler('indi_error_handler', ERROR_LEVEL_HANDLER_TNX);
// set_exception_handler('indi_exception_handler');
//il try catch va comunque sempre messo
//altrimenti le "Uncaught exception" (che sono dei fatal) passano per la shutdown_function, ma error_get_last non rileva il giusto errore ma il precedente
register_shutdown_function('indi_shutdown_function');
}
?>