diff --git a/Plugin/usr/local/emhttp/plugins/varaverk/api/log.php b/Plugin/usr/local/emhttp/plugins/varaverk/api/log.php new file mode 100644 index 0000000..a1a62c3 --- /dev/null +++ b/Plugin/usr/local/emhttp/plugins/varaverk/api/log.php @@ -0,0 +1,30 @@ + false, 'error' => 'Invalid job id']); + exit; +} + +$logFile = vv_job_log_path($id); + +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_GET['clear'])) { + if (file_exists($logFile)) file_put_contents($logFile, ''); + echo json_encode(['ok' => true]); + exit; +} + +if (!file_exists($logFile)) { + echo json_encode(['ok' => true, 'content' => '', 'ts' => 0]); + exit; +} + +$lines = array_slice(file($logFile) ?: [], -200); +echo json_encode([ + 'ok' => true, + 'content' => implode('', $lines), + 'ts' => filemtime($logFile), +]); diff --git a/Plugin/usr/local/emhttp/plugins/varaverk/css/varaverk.css b/Plugin/usr/local/emhttp/plugins/varaverk/css/varaverk.css index 4dc005d..ef38636 100644 --- a/Plugin/usr/local/emhttp/plugins/varaverk/css/varaverk.css +++ b/Plugin/usr/local/emhttp/plugins/varaverk/css/varaverk.css @@ -33,21 +33,33 @@ .vv-status-down { color: #f44336; } /* Scheduler */ -#vv-scheduler { max-width: 900px; } .vv-hint { color: #888; font-size: 13px; margin-bottom: 16px; } -.vv-job { margin-bottom: 4px; } -.vv-orch { background: #1e1e1e; border: 1px solid #444; border-radius: 6px; - padding: 10px 12px; margin-bottom: 8px; } +.vv-sched-card { margin-bottom: 10px; } .vv-script { background: #161616; border: 1px solid #333; border-radius: 4px; padding: 6px 10px; margin: 4px 0; margin-left: 20px; } -.vv-job-row { display: flex; align-items: center; gap: 10px; } -.vv-job-label { flex: 1; font-size: 14px; } -.vv-cron { width: 160px; background: #111; border: 1px solid #444; color: #ddd; +.vv-job-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; } +.vv-job-label { flex: 1; font-size: 14px; min-width: 160px; } +.vv-cron { width: 150px; background: #111; border: 1px solid #444; color: #ddd; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 13px; } -.vv-children { padding-top: 6px; } +.vv-children { padding-top: 8px; border-top: 1px solid #333; margin-top: 8px; } .vv-advanced-toggle { background: none; border: 1px solid #555; color: #aaa; padding: 2px 8px; border-radius: 4px; cursor: pointer; font-size: 12px; } .vv-advanced-toggle:hover { border-color: #888; color: #fff; } +.vv-job-status { font-size: 12px; min-width: 20px; } +.vv-btn-sm { padding: 3px 10px; background: #2a2a2a; border: 1px solid #555; color: #ccc; + border-radius: 4px; cursor: pointer; font-size: 12px; white-space: nowrap; } +.vv-btn-sm:hover { border-color: #888; color: #fff; } +.vv-btn-sm.active { border-color: #4caf50; color: #4caf50; } + +/* Log panel */ +.vv-log-panel { margin-top: 10px; border-top: 1px solid #333; padding-top: 8px; } +.vv-log-toolbar { display: flex; justify-content: space-between; align-items: center; + margin-bottom: 4px; } +.vv-log-ts { font-size: 11px; color: #666; } +.vv-log-pre { background: #0d0d0d; border: 1px solid #333; border-radius: 4px; + padding: 10px 12px; margin: 0; font-family: monospace; font-size: 12px; + color: #ccc; white-space: pre-wrap; word-break: break-all; + max-height: 340px; overflow-y: auto; line-height: 1.5; } /* Toggle switch */ .vv-toggle { position: relative; display: inline-block; width: 36px; height: 20px; flex-shrink: 0; } diff --git a/Plugin/usr/local/emhttp/plugins/varaverk/include/scheduler.php b/Plugin/usr/local/emhttp/plugins/varaverk/include/scheduler.php index 18605ce..7f1c3d5 100644 --- a/Plugin/usr/local/emhttp/plugins/varaverk/include/scheduler.php +++ b/Plugin/usr/local/emhttp/plugins/varaverk/include/scheduler.php @@ -34,6 +34,10 @@ function vv_schedule_update(string $id, bool $enabled, string $cron): bool { define('LOG_DIR', '/var/log/varaverk'); +function vv_job_log_path(string $id): string { + return LOG_DIR . '/' . preg_replace('/\.sh$/', '.log', $id); +} + function vv_cron_rebuild(array $schedule): bool { if (!is_dir(LOG_DIR)) mkdir(LOG_DIR, 0755, true); @@ -44,9 +48,11 @@ function vv_cron_rebuild(array $schedule): bool { $scriptsDir = SCRIPTS_DIR; foreach ($schedule as $entry) { if (empty($entry['enabled']) || empty($entry['cron']) || empty($entry['id'])) continue; - $script = "$scriptsDir/{$entry['id']}"; - $cron = $entry['cron']; - $lines[] = "$cron " . CRON_USER . " bash \"$script\" >> " . LOG_DIR . "/jobs.log 2>&1"; + $script = "$scriptsDir/{$entry['id']}"; + $logFile = vv_job_log_path($entry['id']); + $logDir = dirname($logFile); + if (!is_dir($logDir)) mkdir($logDir, 0755, true); + $lines[] = "{$entry['cron']} " . CRON_USER . " bash \"$script\" >> \"$logFile\" 2>&1"; } $lines[] = ""; diff --git a/Plugin/usr/local/emhttp/plugins/varaverk/pages/scheduler.php b/Plugin/usr/local/emhttp/plugins/varaverk/pages/scheduler.php index 5fca296..94ec3bd 100644 --- a/Plugin/usr/local/emhttp/plugins/varaverk/pages/scheduler.php +++ b/Plugin/usr/local/emhttp/plugins/varaverk/pages/scheduler.php @@ -4,15 +4,16 @@ $tree = vv_job_tree(); ?>
-

Orchestrators run their child scripts in the correct order. Disable an orchestrator and enable individual scripts below it to run them in isolation for debugging or testing.

- -
+ +
+ +
-
+ + + + -