SignManifest : capture les erreurs dans un log accessible via SFTP
Sur OVH mutualisé les logs Apache (error_log Apache) ne sont accessibles que via le manager web — pas grep-able en SFTP, donc difficile de diagnostiquer un 500 quand ça se reproduit. Fix : redirige log_errors vers manifest/.signmanifest-error.log dès l'entrée de run(). Trois canaux capturés : 1. ini_set error_log → tout ce que PHP loggue habituellement va aussi dans notre fichier (warnings inclus). 2. register_shutdown_function → attrape les E_ERROR / E_PARSE / fatal errors qui court-circuitent l'exécution avant tout catch normal. 3. try/catch autour de getOrComputeSha256() par version, avec un START/DONE log de chaque étape. Si le process meurt, on saura pile lequel des ZIPs du manifest était en cours au moment du crash. L'opérateur peut maintenant SFTP le fichier après un 500 et coller le contenu ici pour identifier la cause réelle (l'hypothèse timeout du commit précédent était probablement fausse — l'opérateur a rapporté que plein de hashs de la même taille avaient marché avant). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -154,6 +154,32 @@ final class SignManifest
|
|||||||
@set_time_limit(0);
|
@set_time_limit(0);
|
||||||
@ignore_user_abort(true);
|
@ignore_user_abort(true);
|
||||||
|
|
||||||
|
// Capture toutes les erreurs PHP (warnings + fatals + exceptions non-catchées)
|
||||||
|
// dans un fichier accessible via SFTP, à côté du manifest. Sur OVH mutualisé
|
||||||
|
// les logs Apache ne sont accessibles que via le manager web — pas pratique
|
||||||
|
// pour un diagnostic rapide de 500. Ce fichier permet à l'opérateur de le
|
||||||
|
// grep post-clic sans passer par le manager.
|
||||||
|
$errorLogPath = dirname($this->manifestPath) . '/.signmanifest-error.log';
|
||||||
|
@ini_set('log_errors', '1');
|
||||||
|
@ini_set('error_log', $errorLogPath);
|
||||||
|
@error_reporting(E_ALL);
|
||||||
|
$ts = date('Y-m-d H:i:s');
|
||||||
|
@file_put_contents($errorLogPath,
|
||||||
|
"[{$ts}] --- SignManifest::run(scope={$scope}, force=" . ($force?'1':'0')
|
||||||
|
. ", onlyVersion=" . ($onlyVersion ?? 'null') . ") ---\n",
|
||||||
|
FILE_APPEND);
|
||||||
|
// Fatal errors → capturés par un shutdown handler. Sinon Apache renvoie
|
||||||
|
// juste 500 sans qu'on sache ce qui a claqué.
|
||||||
|
register_shutdown_function(function () use ($errorLogPath) {
|
||||||
|
$err = error_get_last();
|
||||||
|
if ($err && in_array($err['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR], true)) {
|
||||||
|
@file_put_contents($errorLogPath,
|
||||||
|
"[" . date('Y-m-d H:i:s') . "] FATAL " . $err['type']
|
||||||
|
. " : {$err['message']} @ {$err['file']}:{$err['line']}\n",
|
||||||
|
FILE_APPEND);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (!is_file($this->manifestPath)) {
|
if (!is_file($this->manifestPath)) {
|
||||||
$this->out("Manifest introuvable : {$this->manifestPath}");
|
$this->out("Manifest introuvable : {$this->manifestPath}");
|
||||||
return ['ok' => false, 'log' => $this->log];
|
return ['ok' => false, 'log' => $this->log];
|
||||||
@@ -242,7 +268,26 @@ final class SignManifest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log préalable au hash — utile pour identifier QUEL ZIP a fait
|
||||||
|
// planter le process si on retombe sur le 500. Sans ça, l'error log
|
||||||
|
// dit juste "PHP Fatal…" sans savoir si c'est le 1er ou le Nième ZIP.
|
||||||
|
@file_put_contents($errorLogPath,
|
||||||
|
"[" . date('Y-m-d H:i:s') . "] START hash $version → $zip ($size octets)\n",
|
||||||
|
FILE_APPEND);
|
||||||
|
try {
|
||||||
$r = $this->getOrComputeSha256($zip, $cache, $force);
|
$r = $this->getOrComputeSha256($zip, $cache, $force);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
@file_put_contents($errorLogPath,
|
||||||
|
"[" . date('Y-m-d H:i:s') . "] EXCEPTION during hash of $version : "
|
||||||
|
. get_class($e) . " : {$e->getMessage()} @ {$e->getFile()}:{$e->getLine()}\n"
|
||||||
|
. $e->getTraceAsString() . "\n",
|
||||||
|
FILE_APPEND);
|
||||||
|
$this->out(" [ERROR] $version : hash failed — " . $e->getMessage());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
@file_put_contents($errorLogPath,
|
||||||
|
"[" . date('Y-m-d H:i:s') . "] DONE hash $version → sha256={$r['sha256']} ({$r['durationMs']} ms, fromCache=" . ($r['fromCache']?'1':'0') . ")\n",
|
||||||
|
FILE_APPEND);
|
||||||
$cacheChanged = true;
|
$cacheChanged = true;
|
||||||
$note = $r['fromCache'] ? '(cache)' : "(calculé en {$r['durationMs']} ms)";
|
$note = $r['fromCache'] ? '(cache)' : "(calculé en {$r['durationMs']} ms)";
|
||||||
$this->out(" [hash] $version : " . basename($zip) . " ($size octets) sha256={$r['sha256']} $note");
|
$this->out(" [hash] $version : " . basename($zip) . " ($size octets) sha256={$r['sha256']} $note");
|
||||||
|
|||||||
Reference in New Issue
Block a user