last 200 lines // POST id=<…> same as GET // POST id=<…> clear=1 truncate the log // // RESPONSE // {"ok":true,"content":"…","ts":} read — ts is 0 when the log does not exist // {"ok":true} clear // {"ok":false,"error":"Invalid job id"} // // DEPENDS ON // include/scheduler.php vv_job_log_path() // ═══════════════════════════════════════════════════════════════════════════════════════════════ header('Content-Type: application/json'); require_once dirname(__DIR__) . '/include/scheduler.php'; $id = trim($_SERVER['REQUEST_METHOD'] === 'POST' ? ($_POST['id'] ?? '') : ($_GET['id'] ?? '')); if (!$id || !preg_match('/^[a-zA-Z0-9_.\/\-]+\.sh$/', $id) || str_contains($id, '..')) { echo json_encode(['ok' => false, 'error' => 'Invalid job id']); exit; } $logFile = vv_job_log_path($id); if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['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), ]);