mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-03-17 20:26:57 +00:00
168 lines
4.2 KiB
Go
168 lines
4.2 KiB
Go
package display
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/DeBrosOfficial/network/pkg/cli/monitor"
|
|
)
|
|
|
|
// NodeTable prints detailed per-node information to w.
|
|
func NodeTable(snap *monitor.ClusterSnapshot, w io.Writer) error {
|
|
for i, cs := range snap.Nodes {
|
|
if i > 0 {
|
|
fmt.Fprintln(w)
|
|
}
|
|
|
|
host := cs.Node.Host
|
|
role := cs.Node.Role
|
|
|
|
if cs.Error != nil {
|
|
fmt.Fprintf(w, "%s (%s)\n", styleRed.Render("Node: "+host), role)
|
|
fmt.Fprintf(w, " %s\n", styleRed.Render(fmt.Sprintf("UNREACHABLE: %v", cs.Error)))
|
|
continue
|
|
}
|
|
|
|
r := cs.Report
|
|
if r == nil {
|
|
fmt.Fprintf(w, "%s (%s)\n", styleRed.Render("Node: "+host), role)
|
|
fmt.Fprintf(w, " %s\n", styleRed.Render("No report available"))
|
|
continue
|
|
}
|
|
|
|
fmt.Fprintf(w, "%s\n", styleBold.Render(fmt.Sprintf("Node: %s (%s)", host, role)))
|
|
|
|
// System
|
|
if r.System != nil {
|
|
sys := r.System
|
|
fmt.Fprintf(w, " System: CPU %d | Load %.2f | Mem %d%% (%d/%d MB) | Disk %d%%\n",
|
|
sys.CPUCount, sys.LoadAvg1, sys.MemUsePct, sys.MemUsedMB, sys.MemTotalMB, sys.DiskUsePct)
|
|
} else {
|
|
fmt.Fprintln(w, " System: "+styleMuted.Render("no data"))
|
|
}
|
|
|
|
// RQLite
|
|
if r.RQLite != nil {
|
|
rq := r.RQLite
|
|
readyStr := styleRed.Render("Not Ready")
|
|
if rq.Ready {
|
|
readyStr = styleGreen.Render("Ready")
|
|
}
|
|
if rq.Responsive {
|
|
fmt.Fprintf(w, " RQLite: %s | Term %d | Applied %d | Peers %d | %s\n",
|
|
rq.RaftState, rq.Term, rq.Applied, rq.NumPeers, readyStr)
|
|
} else {
|
|
fmt.Fprintf(w, " RQLite: %s\n", styleRed.Render("NOT RESPONDING"))
|
|
}
|
|
} else {
|
|
fmt.Fprintln(w, " RQLite: "+styleMuted.Render("not configured"))
|
|
}
|
|
|
|
// WireGuard
|
|
if r.WireGuard != nil {
|
|
wg := r.WireGuard
|
|
if wg.InterfaceUp {
|
|
// Check handshakes
|
|
hsOK := true
|
|
for _, p := range wg.Peers {
|
|
if p.LatestHandshake == 0 || p.HandshakeAgeSec > 180 {
|
|
hsOK = false
|
|
break
|
|
}
|
|
}
|
|
hsStr := statusIcon(hsOK)
|
|
fmt.Fprintf(w, " WireGuard: UP | %s | %d peers | handshakes %s\n",
|
|
wg.WgIP, wg.PeerCount, hsStr)
|
|
} else {
|
|
fmt.Fprintf(w, " WireGuard: %s\n", styleRed.Render("DOWN"))
|
|
}
|
|
} else {
|
|
fmt.Fprintln(w, " WireGuard: "+styleMuted.Render("not configured"))
|
|
}
|
|
|
|
// Olric
|
|
if r.Olric != nil {
|
|
ol := r.Olric
|
|
stateStr := styleRed.Render("inactive")
|
|
if ol.ServiceActive {
|
|
stateStr = styleGreen.Render("active")
|
|
}
|
|
fmt.Fprintf(w, " Olric: %s | %d members\n", stateStr, ol.MemberCount)
|
|
} else {
|
|
fmt.Fprintln(w, " Olric: "+styleMuted.Render("not configured"))
|
|
}
|
|
|
|
// IPFS
|
|
if r.IPFS != nil {
|
|
ipfs := r.IPFS
|
|
daemonStr := styleRed.Render("inactive")
|
|
if ipfs.DaemonActive {
|
|
daemonStr = styleGreen.Render("active")
|
|
}
|
|
clusterStr := styleRed.Render("DOWN")
|
|
if ipfs.ClusterActive {
|
|
clusterStr = styleGreen.Render("OK")
|
|
}
|
|
fmt.Fprintf(w, " IPFS: %s | %d swarm peers | cluster %s\n",
|
|
daemonStr, ipfs.SwarmPeerCount, clusterStr)
|
|
} else {
|
|
fmt.Fprintln(w, " IPFS: "+styleMuted.Render("not configured"))
|
|
}
|
|
|
|
// Anyone
|
|
if r.Anyone != nil {
|
|
an := r.Anyone
|
|
mode := an.Mode
|
|
if mode == "" {
|
|
if an.RelayActive {
|
|
mode = "relay"
|
|
} else if an.ClientActive {
|
|
mode = "client"
|
|
} else {
|
|
mode = "inactive"
|
|
}
|
|
}
|
|
bootStr := styleRed.Render("not bootstrapped")
|
|
if an.Bootstrapped {
|
|
bootStr = styleGreen.Render("bootstrapped")
|
|
}
|
|
fmt.Fprintf(w, " Anyone: %s | %s\n", mode, bootStr)
|
|
} else {
|
|
fmt.Fprintln(w, " Anyone: "+styleMuted.Render("not configured"))
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// NodeJSON writes the node details as JSON.
|
|
func NodeJSON(snap *monitor.ClusterSnapshot, w io.Writer) error {
|
|
type nodeDetail struct {
|
|
Host string `json:"host"`
|
|
Role string `json:"role"`
|
|
Status string `json:"status"`
|
|
Error string `json:"error,omitempty"`
|
|
Report interface{} `json:"report,omitempty"`
|
|
}
|
|
|
|
var entries []nodeDetail
|
|
for _, cs := range snap.Nodes {
|
|
e := nodeDetail{
|
|
Host: cs.Node.Host,
|
|
Role: cs.Node.Role,
|
|
}
|
|
if cs.Error != nil {
|
|
e.Status = "unreachable"
|
|
e.Error = cs.Error.Error()
|
|
} else if cs.Report != nil {
|
|
e.Status = "ok"
|
|
e.Report = cs.Report
|
|
} else {
|
|
e.Status = "unknown"
|
|
}
|
|
entries = append(entries, e)
|
|
}
|
|
|
|
return writeJSON(w, entries)
|
|
}
|