74 lines
2.0 KiB
Go
74 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type MetricProbe interface {
|
|
Probe(services []Service) Metrics
|
|
}
|
|
|
|
type SystemMetricProbe struct{}
|
|
|
|
func NewMetricProbe() MetricProbe {
|
|
return SystemMetricProbe{}
|
|
}
|
|
|
|
func (p SystemMetricProbe) Probe(services []Service) Metrics {
|
|
return Metrics{
|
|
ActiveSessions: countProcesses("codex", "openclaw", "opencode", "gemini", "hermes"),
|
|
ConnectedAgents: countConnectedAgents(services),
|
|
ActiveModels: countLiteLLMModels(),
|
|
SkillsAvailable: countSkillDirs(),
|
|
Workers: countProcesses("codex", "openclaw", "opencode", "gemini", "hermes", "xworkmate-go-core"),
|
|
}
|
|
}
|
|
|
|
func countConnectedAgents(services []Service) int {
|
|
count := 0
|
|
for _, service := range services {
|
|
name := strings.ToLower(service.Name)
|
|
if service.State == "active" && (strings.Contains(name, "bridge") || strings.Contains(name, "openclaw")) {
|
|
count++
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
func countProcesses(names ...string) int {
|
|
out := commandOutput("pgrep", "-af", strings.Join(names, "|"))
|
|
if out == "" {
|
|
return 0
|
|
}
|
|
count := 0
|
|
for _, line := range strings.Split(out, "\n") {
|
|
if strings.TrimSpace(line) != "" && !strings.Contains(line, "pgrep -af") {
|
|
count++
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
func countLiteLLMModels() int {
|
|
out := commandOutput("sh", "-lc", "curl -fsS --max-time 1 http://127.0.0.1:4000/v1/models 2>/dev/null | python3 -c 'import json,sys; print(len(json.load(sys.stdin).get(\"data\", [])))' 2>/dev/null")
|
|
if count := parseIntOrZero(out); count > 0 {
|
|
return count
|
|
}
|
|
out = commandOutput("sh", "-lc", "grep -R \"^[[:space:]]*- model_name:\" \"$HOME/.local/share/xworkspace/litellm-config.yaml\" /etc/litellm*.yaml 2>/dev/null | wc -l")
|
|
return parseIntOrZero(out)
|
|
}
|
|
|
|
func countSkillDirs() int {
|
|
out := commandOutput("sh", "-lc", "find \"$HOME/.openclaw/workspace/skills\" \"$HOME/.codex/skills\" \"$HOME/.agents/skills\" -name SKILL.md 2>/dev/null | wc -l")
|
|
return parseIntOrZero(out)
|
|
}
|
|
|
|
func parseIntOrZero(value string) int {
|
|
n, err := strconv.Atoi(strings.TrimSpace(value))
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
return n
|
|
}
|