feat: 脚本/定时任务真实执行+输出捕获+执行历史 — 替换pending空壳为本地执行,采集stdout/stderr,更新统计;修复CronJobManager/Automation字段名不匹配(status→enabled,cron→cron_expr,command→content,language→type)
This commit is contained in:
1 parent
85bc2a8e05
commit
a4fd5fc178
19 files changed
+2715
-114
No files matched your search
+58
-1
@@ -18,6 +18,7 @@ import (
|
||||
"ezops/agent/collector"
|
||||
"ezops/agent/model"
|
||||
"ezops/agent/reporter"
|
||||
"ezops/agent/task"
|
||||
)
|
||||
|
||||
// 编译时可注入的版本信息
|
||||
@@ -65,6 +66,10 @@ func main() {
|
||||
portCollector := collector.NewPortCollector()
|
||||
rep := reporter.New(*server, *token, logger)
|
||||
|
||||
// 初始化任务执行器与任务客户端(与 reporter 复用相同的 server/token/hostname)
|
||||
taskExecutor := task.New(logger)
|
||||
taskClient := task.NewClient(*server, *token, hostname, logger)
|
||||
|
||||
// 监听 SIGINT / SIGTERM,支持优雅退出
|
||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||
defer stop()
|
||||
@@ -111,7 +116,59 @@ func main() {
|
||||
report.CPU.UsagePercent, report.Memory.UsagePercent, len(report.Disks), len(report.Ports))
|
||||
}
|
||||
|
||||
// 启动后立即执行一次,再按 ticker 周期执行
|
||||
// pollAndExecute 执行单次任务轮询:拉取待执行任务 → 逐个执行 → 回传结果。
|
||||
// 网络错误只记录日志,不 panic,下一个周期继续重试。
|
||||
pollAndExecute := func() {
|
||||
tasks, err := taskClient.Poll(ctx)
|
||||
if err != nil {
|
||||
// 上下文已取消(Agent 退出中)属于正常情况,不输出告警
|
||||
if ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
logger.Printf("任务轮询失败: %v", err)
|
||||
return
|
||||
}
|
||||
if len(tasks) == 0 {
|
||||
return // 暂无任务,静默返回
|
||||
}
|
||||
logger.Printf("拉取到 %d 个待执行任务", len(tasks))
|
||||
|
||||
for _, t := range tasks {
|
||||
// Agent 退出时跳过后续任务,避免退出延迟
|
||||
if ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
result := taskExecutor.ExecuteTask(ctx, t)
|
||||
if err := taskClient.Submit(ctx, result); err != nil {
|
||||
if ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
logger.Printf("任务 %s 结果回传失败: %v", t.TaskID, err)
|
||||
} else {
|
||||
logger.Printf("任务 %s 结果回传成功 status=%s", t.TaskID, result.Status)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 启动任务轮询协程:每 5 秒轮询一次,与指标采集并行运行。
|
||||
// 使用独立的 5 秒固定间隔,不受 -interval 影响。
|
||||
const taskPollInterval = 5 * time.Second
|
||||
go func() {
|
||||
// 启动后立即轮询一次,再按固定周期执行
|
||||
pollAndExecute()
|
||||
ticker := time.NewTicker(taskPollInterval)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
pollAndExecute()
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// 主协程:启动后立即执行一次指标采集,再按 ticker 周期执行
|
||||
collectAndReport()
|
||||
for {
|
||||
select {
|
||||
|
||||
Reference in new issue
Block a user