* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. */ /** * \file bankimport/admin/cronmonitor.php * \ingroup bankimport * \brief Cron job monitoring and log viewer */ // Load Dolibarr environment $res = 0; if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) { $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"; } $tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1; while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { $i--; $j--; } if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) { $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php"; } if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) { $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php"; } if (!$res && file_exists("../../main.inc.php")) { $res = @include "../../main.inc.php"; } if (!$res && file_exists("../../../main.inc.php")) { $res = @include "../../../main.inc.php"; } if (!$res) { die("Include of main fails"); } // Libraries require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"; require_once '../lib/bankimport.lib.php'; dol_include_once('/bankimport/class/bankimportcron.class.php'); /** * @var Conf $conf * @var DoliDB $db * @var Translate $langs * @var User $user */ // Translations $langs->loadLangs(array("admin", "bankimport@bankimport", "cron")); // Parameters $action = GETPOST('action', 'aZ09'); $lines = GETPOSTINT('lines') ?: 100; // Access control if (!$user->admin) { accessforbidden(); } /* * Actions */ if ($action == 'unpause') { $cron = new BankImportCron($db); $cron->unpauseCron(); setEventMessages("Cron-Pause aufgehoben", null, 'mesgs'); header("Location: ".$_SERVER["PHP_SELF"]); exit; } if ($action == 'clearfailcount') { dolibarr_del_const($db, 'BANKIMPORT_CRON_FAIL_COUNT', $conf->entity); setEventMessages("Fehlerzähler zurückgesetzt", null, 'mesgs'); header("Location: ".$_SERVER["PHP_SELF"]); exit; } if ($action == 'resetcronjob') { // Reset the cron job in llx_cronjob table $sql = "UPDATE ".MAIN_DB_PREFIX."cronjob SET processing = 0, datenextrun = NOW() WHERE label = 'BankImportAutoFetch' AND processing = 1"; $resql = $db->query($sql); if ($resql && $db->affected_rows($resql) > 0) { setEventMessages("Hängenden Cron-Job zurückgesetzt", null, 'mesgs'); } else { setEventMessages("Kein hängender Job gefunden oder Fehler", null, 'warnings'); } header("Location: ".$_SERVER["PHP_SELF"]); exit; } /* * View */ $page_name = "Cron Monitor - BankImport"; llxHeader('', $page_name, '', '', 0, 0, '', '', '', 'mod-bankimport page-admin-cronmonitor'); // Admin Tabs $head = bankimportAdminPrepareHead(); print dol_get_fiche_head($head, 'cronmonitor', 'BankImport', -1, 'bank'); // Get cron status $cronStatus = BankImportCron::getCronStatus(); // Get Dolibarr cron job info $sql = "SELECT rowid, label, datenextrun, datelastrun, datelastresult, processing, lastoutput, lastresult, status FROM ".MAIN_DB_PREFIX."cronjob WHERE label = 'BankImportAutoFetch'"; $resql = $db->query($sql); $cronJob = $resql ? $db->fetch_object($resql) : null; print '
| Cron Status Übersicht | |
|---|---|
| Auto-Import aktiviert | '; if ($cronStatus['enabled']) { print 'Aktiviert'; } else { print 'Deaktiviert'; } print ' |
| Pause-Status | ';
if ($cronStatus['paused']) {
print 'PAUSIERT ';
print 'bis '.dol_print_date($cronStatus['paused_until'], 'dayhour');
print ' Grund: '.dol_escape_htmltag($cronStatus['pause_reason']); print ' Pause aufheben'; } else { print 'Aktiv'; } print ' |
| Fehlversuche in Folge | '; $failCount = $cronStatus['fail_count']; if ($failCount >= 3) { print ''.$failCount.' '; print '(bei 3+ wird automatisch pausiert) '; print 'Zurücksetzen'; } elseif ($failCount > 0) { print ''.$failCount.''; } else { print '0'; } print ' |
| Letzter Lauf | ';
if (!empty($cronStatus['last_run'])) {
$lastRun = $cronStatus['last_run'];
$statusClass = 'badge-status4';
if ($lastRun['status'] == 'error') $statusClass = 'badge-status8';
elseif ($lastRun['status'] == 'paused') $statusClass = 'badge-status1';
elseif ($lastRun['status'] == 'running') $statusClass = 'badge-status6';
print ''.strtoupper($lastRun['status']).' ';
print dol_print_date($lastRun['timestamp'], 'dayhour');
if (!empty($lastRun['duration'])) {
print ' (Dauer: '.$lastRun['duration'].'s)';
}
if (!empty($lastRun['message'])) {
print ' '.dol_escape_htmltag($lastRun['message']).''; } } else { print 'Keine Daten'; } print ' |
| Aktuelle Benachrichtigung | '; if (!empty($cronStatus['notification'])) { $notif = $cronStatus['notification']; $notifLabels = array( 'tan_required' => 'TAN erforderlich', 'login_error' => 'Login-Fehler', 'fetch_error' => 'Abruf-Fehler', 'config_error' => 'Konfigurationsfehler', 'session_expired' => 'Session abgelaufen', 'error' => 'Allgemeiner Fehler', 'paused' => 'Pausiert' ); $label = $notifLabels[$notif['type']] ?? $notif['type']; print ''.$label.''; if (!empty($notif['date'])) { print ' seit '.dol_print_date($notif['date'], 'dayhour'); } } else { print 'Keine'; } print ' |
| Dolibarr Cron-Job Status | |
|---|---|
| Job Status | '; if ($cronJob->processing) { print 'LÄUFT / HÄNGT '; print 'Job zurücksetzen'; } elseif ($cronJob->status == 1) { print 'Bereit'; } else { print 'Deaktiviert'; } print ' |
| Nächster geplanter Lauf | '.dol_print_date($db->jdate($cronJob->datenextrun), 'dayhour').' |
| Letzter Lauf (Start) | '.dol_print_date($db->jdate($cronJob->datelastrun), 'dayhour').' |
| Letzter Lauf (Ende) | '.dol_print_date($db->jdate($cronJob->datelastresult), 'dayhour').' |
| Letztes Ergebnis | '; if ($cronJob->lastresult === '0' || $cronJob->lastresult === 0) { print 'OK'; } elseif (!empty($cronJob->lastresult)) { print 'Fehler: '.$cronJob->lastresult.''; } else { print '-'; } print ' |
| Letzte Ausgabe | '.dol_escape_htmltag($cronJob->lastoutput ?: '-').' |
| Cron-Job nicht gefunden | |
| Cron Log-Datei | '; print ''; print ''; print ' | '; print '
|---|---|
';
if (file_exists($logFile)) {
$fileSize = filesize($logFile);
print 'Datei: '.$logFile.' ('.dol_print_size($fileSize, 1).')';
print '';
// Read last N lines efficiently
$logContent = '';
$fp = fopen($logFile, 'r');
if ($fp) {
$buffer = array();
while (!feof($fp)) {
$line = fgets($fp);
if ($line !== false) {
$buffer[] = $line;
if (count($buffer) > $lines) {
array_shift($buffer);
}
}
}
fclose($fp);
$logContent = implode('', $buffer);
}
// Syntax highlighting for log
$logContent = htmlspecialchars($logContent);
$logContent = preg_replace('/\[ERROR\]/', '[ERROR]', $logContent);
$logContent = preg_replace('/\[WARNING\]/', '[WARNING]', $logContent);
$logContent = preg_replace('/\[INFO\]/', '[INFO]', $logContent);
$logContent = preg_replace('/\[DEBUG\]/', '[DEBUG]', $logContent);
$logContent = preg_replace('/========== CRON (START|END.*) ==========/', '========== CRON $1 ==========', $logContent);
print $logContent;
print '';
} else {
print 'Log-Datei existiert noch nicht: '.$logFile.'';
}
print ' | |
| Alle Modul Cron-Jobs | '; print 'Status | '; print 'Nächster Lauf | '; print 'Letzter Lauf | '; print 'Processing | '; print '
|---|---|---|---|---|
| '.$obj->label.' | '; print ''; if ($obj->status == 1) { print 'Aktiv'; } else { print 'Inaktiv'; } print ' | '; print ''.dol_print_date($db->jdate($obj->datenextrun), 'dayhour').' | '; print ''.dol_print_date($db->jdate($obj->datelastrun), 'dayhour').' | '; print ''; if ($obj->processing) { print 'HÄNGT'; } else { print 'OK'; } print ' | '; print '