package app import ( "strings" ) func (transportSystemdBackend) Health(client TransportClient) transportBackendHealthResult { units, errCode, errMsg := transportSystemdHealthUnits(client) if len(units) == 0 { return transportBackendHealthResult{ OK: false, Code: errCode, Message: errMsg, Status: TransportClientDown, } } active := 0 starting := 0 inactive := 0 failed := 0 unknown := 0 issues := make([]string, 0, len(units)) for _, unit := range units { stdout, stderr, _, _ := transportRunCommand(transportBackendHealthTimeout, "systemctl", "is-active", unit) state := strings.ToLower(strings.TrimSpace(stdout)) switch state { case "active": active++ case "activating", "reloading": starting++ case "inactive", "deactivating": inactive++ case "failed": failed++ msg := strings.TrimSpace(stderr) if msg == "" { msg = "systemd unit failed" } issues = append(issues, unit+": "+msg) default: unknown++ msg := strings.TrimSpace(stderr) if msg == "" { msg = strings.TrimSpace(stdout) } if msg == "" { msg = "status unknown" } issues = append(issues, unit+": "+msg) } } total := len(units) if active == total { res := transportBackendHealthResult{OK: true, Status: TransportClientUp} if latency, _ := transportProbeClientLatency(client); latency > 0 { res.LatencyMS = latency } return res } if active+starting == total { return transportBackendHealthResult{OK: true, Status: TransportClientStarting} } if inactive == total { return transportBackendHealthResult{OK: true, Status: TransportClientDown} } msg := strings.TrimSpace(strings.Join(issues, "; ")) if msg == "" { msg = "backend units are not synchronized" } status := TransportClientDegraded if active == 0 && failed == 0 && unknown == 0 { status = TransportClientDown } return transportBackendHealthResult{ OK: false, Code: "TRANSPORT_BACKEND_HEALTH_FAILED", Message: msg, Status: status, Retryable: true, } }