diff --git a/Server/application/command/TaskSchedulerCommand.php b/Server/application/command/TaskSchedulerCommand.php index 4f8f09f42..a975985f6 100644 --- a/Server/application/command/TaskSchedulerCommand.php +++ b/Server/application/command/TaskSchedulerCommand.php @@ -430,12 +430,7 @@ class TaskSchedulerCommand extends Command $logMessage = "\n" . str_repeat('=', 60) . "\n"; $logMessage .= "任务开始执行: {$taskName} ({$taskId})\n"; $logMessage .= "执行时间: " . date('Y-m-d H:i:s') . "\n"; - $logMessage .= "执行目录: {$executionPath}\n"; $logMessage .= "命令: {$command}\n"; - $logMessage .= "[DEBUG] 任务配置: " . json_encode($task, JSON_UNESCAPED_UNICODE) . "\n"; - $logMessage .= "[DEBUG] 当前工作目录: " . getcwd() . "\n"; - $logMessage .= "[DEBUG] PHP版本: " . PHP_VERSION . "\n"; - $logMessage .= "[DEBUG] 操作系统: " . PHP_OS . "\n"; $logMessage .= str_repeat('=', 60) . "\n"; file_put_contents($logFile, $logMessage, FILE_APPEND); @@ -449,30 +444,20 @@ class TaskSchedulerCommand extends Command 2 => ['pipe', 'w'], // stderr ]; - // [DEBUG] 记录进程启动前信息 - $debugLog = "[DEBUG] 准备启动进程\n"; - $debugLog .= "[DEBUG] PHP路径: {$phpPath}\n"; - $debugLog .= "[DEBUG] Think路径: {$thinkPath}\n"; - $debugLog .= "[DEBUG] 执行目录: {$executionPath}\n"; - $debugLog .= "[DEBUG] 完整命令: {$command}\n"; - $debugLog .= "[DEBUG] 超时设置: {$timeout}秒\n"; - file_put_contents($logFile, $debugLog, FILE_APPEND); - $process = @proc_open($command, $descriptorspec, $pipes, $executionPath); if (!is_resource($process)) { $errorMsg = "任务执行失败: 无法启动进程"; - $errorMsg .= "\n[DEBUG] proc_open 返回: " . var_export($process, true); - $errorMsg .= "\n[DEBUG] 错误信息: " . error_get_last()['message'] ?? '无错误信息'; + $lastError = error_get_last(); + if ($lastError) { + $errorMsg .= "\n错误信息: " . $lastError['message']; + } Log::error($errorMsg, ['task' => $taskId]); file_put_contents($logFile, $errorMsg . "\n", FILE_APPEND); $this->removeLock($taskId); // 删除锁文件 return; } - // [DEBUG] 记录进程启动成功 - file_put_contents($logFile, "[DEBUG] 进程启动成功,进程资源类型: " . get_resource_type($process) . "\n", FILE_APPEND); - // 设置非阻塞模式 stream_set_blocking($pipes[1], false); stream_set_blocking($pipes[2], false); @@ -480,82 +465,39 @@ class TaskSchedulerCommand extends Command $startWaitTime = time(); $output = ''; $error = ''; - $loopCount = 0; - $lastStatusCheck = 0; $finalExitCode = null; // 保存进程结束时的退出码 // 等待进程完成或超时 while (true) { - $loopCount++; $status = proc_get_status($process); - // [DEBUG] 每10次循环记录一次状态(减少日志量) - if ($loopCount % 10 == 0 || time() - $lastStatusCheck > 5) { - $elapsed = time() - $startWaitTime; - $debugStatus = "[DEBUG] 循环 #{$loopCount}, 已运行 {$elapsed}秒\n"; - $debugStatus .= "[DEBUG] 进程状态: running=" . ($status['running'] ? 'true' : 'false'); - if (isset($status['exitcode'])) { - $debugStatus .= ", exitcode=" . $status['exitcode']; - } - if (isset($status['signaled'])) { - $debugStatus .= ", signaled=" . ($status['signaled'] ? 'true' : 'false'); - } - if (isset($status['termsig'])) { - $debugStatus .= ", termsig=" . $status['termsig']; - } - $debugStatus .= "\n"; - file_put_contents($logFile, $debugStatus, FILE_APPEND); - $lastStatusCheck = time(); - } - // 读取输出 - $outputChunk = stream_get_contents($pipes[1]); - $errorChunk = stream_get_contents($pipes[2]); - - if (!empty($outputChunk)) { - $output .= $outputChunk; - file_put_contents($logFile, "[DEBUG] 标准输出片段: " . substr($outputChunk, 0, 200) . "\n", FILE_APPEND); - } - - if (!empty($errorChunk)) { - $error .= $errorChunk; - file_put_contents($logFile, "[DEBUG] 错误输出片段: " . substr($errorChunk, 0, 200) . "\n", FILE_APPEND); - } + $output .= stream_get_contents($pipes[1]); + $error .= stream_get_contents($pipes[2]); // 检查是否完成 if (!$status['running']) { - // [DEBUG] 记录进程结束时的详细状态 - $debugEnd = "[DEBUG] 进程已结束\n"; - $debugEnd .= "[DEBUG] 最终状态: " . json_encode($status, JSON_UNESCAPED_UNICODE) . "\n"; + // 保存退出码(在进程刚结束时获取,此时最准确) if (isset($status['exitcode'])) { - $finalExitCode = $status['exitcode']; // 立即保存退出码 - $debugEnd .= "[DEBUG] proc_get_status 返回的退出码: " . $status['exitcode'] . " (已保存)\n"; + $finalExitCode = $status['exitcode']; } - file_put_contents($logFile, $debugEnd, FILE_APPEND); break; } // 检查超时 if ((time() - $startWaitTime) > $timeout) { - $timeoutMsg = "任务执行超时({$timeout}秒),终止进程\n"; - $timeoutMsg .= "[DEBUG] 当前循环次数: {$loopCount}\n"; - $timeoutMsg .= "[DEBUG] 已运行时间: " . (time() - $startWaitTime) . "秒\n"; Log::warning("任务执行超时({$timeout}秒),终止进程", ['task' => $taskId]); - file_put_contents($logFile, $timeoutMsg, FILE_APPEND); + file_put_contents($logFile, "任务执行超时({$timeout}秒),终止进程\n", FILE_APPEND); if (function_exists('proc_terminate')) { - $terminateResult = proc_terminate($process); - file_put_contents($logFile, "[DEBUG] proc_terminate 返回: " . var_export($terminateResult, true) . "\n", FILE_APPEND); - } else { - file_put_contents($logFile, "[DEBUG] proc_terminate 函数不可用\n", FILE_APPEND); + proc_terminate($process); } // 关闭管道 @fclose($pipes[0]); @fclose($pipes[1]); @fclose($pipes[2]); - $closeResult = proc_close($process); - file_put_contents($logFile, "[DEBUG] 超时后 proc_close 返回: {$closeResult}\n", FILE_APPEND); + proc_close($process); $this->removeLock($taskId); // 删除锁文件 return; @@ -566,58 +508,23 @@ class TaskSchedulerCommand extends Command } // 读取剩余输出 - $remainingOutput = stream_get_contents($pipes[1]); - $remainingError = stream_get_contents($pipes[2]); - - if (!empty($remainingOutput)) { - $output .= $remainingOutput; - file_put_contents($logFile, "[DEBUG] 剩余标准输出: " . substr($remainingOutput, 0, 500) . "\n", FILE_APPEND); - } - - if (!empty($remainingError)) { - $error .= $remainingError; - file_put_contents($logFile, "[DEBUG] 剩余错误输出: " . substr($remainingError, 0, 500) . "\n", FILE_APPEND); - } - - // [DEBUG] 记录关闭管道前的状态 - file_put_contents($logFile, "[DEBUG] 准备关闭管道,输出长度: " . strlen($output) . ", 错误长度: " . strlen($error) . "\n", FILE_APPEND); - file_put_contents($logFile, "[DEBUG] 已保存的退出码: " . ($finalExitCode !== null ? $finalExitCode : 'null') . "\n", FILE_APPEND); + $output .= stream_get_contents($pipes[1]); + $error .= stream_get_contents($pipes[2]); // 关闭管道 - $closeResults = []; - $closeResults['stdin'] = @fclose($pipes[0]); - $closeResults['stdout'] = @fclose($pipes[1]); - $closeResults['stderr'] = @fclose($pipes[2]); - file_put_contents($logFile, "[DEBUG] 管道关闭结果: " . json_encode($closeResults, JSON_UNESCAPED_UNICODE) . "\n", FILE_APPEND); + @fclose($pipes[0]); + @fclose($pipes[1]); + @fclose($pipes[2]); // 获取退出码 $exitCodeFromClose = proc_close($process); - // [DEBUG] 记录退出码获取结果 - file_put_contents($logFile, "[DEBUG] proc_close 返回的退出码: {$exitCodeFromClose}\n", FILE_APPEND); - file_put_contents($logFile, "[DEBUG] 退出码类型: " . gettype($exitCodeFromClose) . "\n", FILE_APPEND); - // 优先使用进程刚结束时保存的退出码(proc_get_status 在进程刚结束时的返回值) // 因为关闭管道后,proc_get_status 可能会返回 -1,这是 PHP 的已知行为 if ($finalExitCode !== null) { $exitCode = $finalExitCode; - file_put_contents($logFile, "[DEBUG] ✅ 使用进程结束时保存的退出码: {$exitCode}\n", FILE_APPEND); - if ($exitCodeFromClose === -1 && $exitCode === 0) { - file_put_contents($logFile, "[DEBUG] ℹ️ 注意: proc_close 返回 -1,但进程结束时的退出码为 0,这是 PHP 的已知行为,任务实际执行成功\n", FILE_APPEND); - } elseif ($exitCodeFromClose !== -1 && $exitCodeFromClose !== $exitCode) { - file_put_contents($logFile, "[DEBUG] ⚠️ 警告: proc_close 返回 {$exitCodeFromClose},但进程结束时的退出码为 {$exitCode},使用进程结束时的退出码\n", FILE_APPEND); - } } else { - // 如果没有保存的退出码,使用 proc_close 的返回值 $exitCode = $exitCodeFromClose; - file_put_contents($logFile, "[DEBUG] 使用 proc_close 的退出码: {$exitCode}\n", FILE_APPEND); - if ($exitCode === -1) { - file_put_contents($logFile, "[DEBUG] ⚠️ 退出码为 -1,可能原因:\n", FILE_APPEND); - file_put_contents($logFile, "[DEBUG] 1. 进程被信号终止\n", FILE_APPEND); - file_put_contents($logFile, "[DEBUG] 2. 进程异常终止\n", FILE_APPEND); - file_put_contents($logFile, "[DEBUG] 3. 无法获取进程退出状态\n", FILE_APPEND); - file_put_contents($logFile, "[DEBUG] 4. Windows系统上的特殊返回值\n", FILE_APPEND); - } } // 记录输出 @@ -645,20 +552,6 @@ class TaskSchedulerCommand extends Command $logMessage .= "完成时间: " . date('Y-m-d H:i:s') . "\n"; $logMessage .= "执行时长: {$duration} 秒\n"; $logMessage .= "退出码: {$exitCode} ({$exitCodeMeaning})\n"; - $logMessage .= "[DEBUG] 输出总长度: " . strlen($output) . " 字节\n"; - $logMessage .= "[DEBUG] 错误总长度: " . strlen($error) . " 字节\n"; - if ($exitCode === -1) { - $logMessage .= "[DEBUG] ⚠️ 退出码 -1 详细分析:\n"; - $logMessage .= "[DEBUG] - 是否有错误输出: " . (!empty($error) ? '是' : '否') . "\n"; - $logMessage .= "[DEBUG] - 是否有标准输出: " . (!empty($output) ? '是' : '否') . "\n"; - $logMessage .= "[DEBUG] - 执行时长: {$duration} 秒\n"; - if ($duration < 1) { - $logMessage .= "[DEBUG] - ⚠️ 执行时长过短,可能是进程启动失败\n"; - } - if ($duration > $timeout * 0.9) { - $logMessage .= "[DEBUG] - ⚠️ 执行时长接近超时时间\n"; - } - } $logMessage .= str_repeat('=', 60) . "\n"; file_put_contents($logFile, $logMessage, FILE_APPEND);