fix(agent): systemctl 模式 Status 补充失败原因(LastError)
enable=false 时走 NewSystemCtlController,其 Status() 在服务未运行时 只返回 Running:false 无原因。现通过 systemctl show 获取 ActiveState/SubState/Result/ExecMainStatus/NRestarts, 给出可读提示: '启动失败(退出码 X, 已重启 N 次)' 或 '未运行(systemctl: x/y)'
This commit is contained in:
parent
6a995db6e2
commit
aae5bc36de
@ -29,24 +29,24 @@ func (s *SystemCtlController) Status() (Status, error) {
|
||||
// 检查服务是否运行
|
||||
cmd := exec.Command("systemctl", "is-active", "--quiet", s.serviceName)
|
||||
err := cmd.Run()
|
||||
|
||||
|
||||
if err != nil {
|
||||
// 服务未运行
|
||||
return Status{Running: false}, nil
|
||||
// 服务未运行:附带失败原因(退出码/重启次数),供 UI 展示
|
||||
return Status{Running: false, LastError: s.failureHint()}, nil
|
||||
}
|
||||
|
||||
|
||||
// 获取 PID
|
||||
pidCmd := exec.Command("systemctl", "show", "--property=MainPID", "--value", s.serviceName)
|
||||
out, err := pidCmd.Output()
|
||||
if err != nil {
|
||||
return Status{Running: true}, nil // 运行但无法获取 PID
|
||||
}
|
||||
|
||||
|
||||
pid, _ := strconv.Atoi(strings.TrimSpace(string(out)))
|
||||
if pid <= 0 {
|
||||
return Status{Running: true}, nil
|
||||
}
|
||||
|
||||
|
||||
return Status{
|
||||
Running: true,
|
||||
Pid: pid,
|
||||
@ -54,6 +54,36 @@ func (s *SystemCtlController) Status() (Status, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// failureHint 查询 systemctl 状态,给出服务未运行的可用原因(如启动失败/退出码)
|
||||
func (s *SystemCtlController) failureHint() string {
|
||||
out, err := exec.Command("systemctl", "show", "--property=ActiveState,SubState,Result,ExecMainStatus,NRestarts", s.serviceName).Output()
|
||||
if err != nil {
|
||||
return fmt.Sprintf("媒体服务未运行 (%s)", s.serviceName)
|
||||
}
|
||||
props := map[string]string{}
|
||||
for _, line := range strings.Split(strings.TrimSpace(string(out)), "\n") {
|
||||
if idx := strings.IndexByte(line, '='); idx > 0 {
|
||||
props[strings.TrimSpace(line[:idx])] = strings.TrimSpace(line[idx+1:])
|
||||
}
|
||||
}
|
||||
switch {
|
||||
case props["SubState"] == "failed" || props["Result"] == "exit-code":
|
||||
code := props["ExecMainStatus"]
|
||||
if code == "" {
|
||||
code = "?"
|
||||
}
|
||||
restarts := props["NRestarts"]
|
||||
if restarts == "" {
|
||||
restarts = "0"
|
||||
}
|
||||
return fmt.Sprintf("媒体服务启动失败(退出码 %s,已重启 %s 次)", code, restarts)
|
||||
case props["ActiveState"] != "" || props["SubState"] != "":
|
||||
return fmt.Sprintf("媒体服务未运行(systemctl: %s/%s)", props["ActiveState"], props["SubState"])
|
||||
default:
|
||||
return fmt.Sprintf("媒体服务未运行 (%s)", s.serviceName)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SystemCtlController) Version() (string, error) {
|
||||
// 从 systemctl 获取 ExecStart 路径,再调用 --version
|
||||
// Output format: { path=/path/to/binary ; argv[]=... }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user