summaryrefslogtreecommitdiff
path: root/internal/collector
diff options
context:
space:
mode:
Diffstat (limited to 'internal/collector')
-rw-r--r--internal/collector/parse_test.go34
-rw-r--r--internal/collector/script_embed.go9
-rw-r--r--internal/collector/scriptdata/loadbars-remote.sh35
-rw-r--r--internal/collector/types.go2
4 files changed, 63 insertions, 17 deletions
diff --git a/internal/collector/parse_test.go b/internal/collector/parse_test.go
index ec77067..fe7a73c 100644
--- a/internal/collector/parse_test.go
+++ b/internal/collector/parse_test.go
@@ -44,29 +44,31 @@ func TestParseCPULine(t *testing.T) {
func TestParseMemLine(t *testing.T) {
tests := []struct {
+ name string
line string
wantKey string
wantValue int64
wantOK bool
}{
- {"MemTotal: 123456 kB", "MemTotal", 123456, true},
- {"MemFree: 99999 kB", "MemFree", 99999, true},
- {"Buffers: 0 kB", "Buffers", 0, true},
- {"not a mem line", "", 0, false},
- {"", "", 0, false},
+ {"MemTotal", "MemTotal: 123456 kB", "MemTotal", 123456, true},
+ {"MemFree", "MemFree: 99999 kB", "MemFree", 99999, true},
+ {"Buffers_zero", "Buffers: 0 kB", "Buffers", 0, true},
+ {"not_a_mem_line", "not a mem line", "", 0, false},
+ {"empty_string", "", "", 0, false},
}
for _, tt := range tests {
- got, ok := ParseMemLine(tt.line)
- if ok != tt.wantOK {
- t.Errorf("ParseMemLine(%q) ok = %v, want %v", tt.line, ok, tt.wantOK)
- continue
- }
- if !tt.wantOK {
- continue
- }
- if got.Key != tt.wantKey || got.Value != tt.wantValue {
- t.Errorf("ParseMemLine(%q) = %+v, want key=%q value=%d", tt.line, got, tt.wantKey, tt.wantValue)
- }
+ t.Run(tt.name, func(t *testing.T) {
+ got, ok := ParseMemLine(tt.line)
+ if ok != tt.wantOK {
+ t.Fatalf("ParseMemLine(%q) ok = %v, want %v", tt.line, ok, tt.wantOK)
+ }
+ if !tt.wantOK {
+ return
+ }
+ if got.Key != tt.wantKey || got.Value != tt.wantValue {
+ t.Errorf("ParseMemLine(%q) = %+v, want key=%q value=%d", tt.line, got, tt.wantKey, tt.wantValue)
+ }
+ })
}
}
diff --git a/internal/collector/script_embed.go b/internal/collector/script_embed.go
new file mode 100644
index 0000000..168ca37
--- /dev/null
+++ b/internal/collector/script_embed.go
@@ -0,0 +1,9 @@
+package collector
+
+import _ "embed"
+
+// RemoteScript is the loadbars-remote.sh script embedded for local and SSH execution.
+// Path is relative to this file's directory (internal/collector).
+//
+//go:embed scriptdata/loadbars-remote.sh
+var RemoteScript []byte
diff --git a/internal/collector/scriptdata/loadbars-remote.sh b/internal/collector/scriptdata/loadbars-remote.sh
new file mode 100644
index 0000000..9037ad8
--- /dev/null
+++ b/internal/collector/scriptdata/loadbars-remote.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# loadbars-remote.sh - Emits loadbars protocol (M LOADAVG, M MEMSTATS, M NETSTATS, M CPUSTATS)
+# for local or remote execution. No Perl required.
+# Usage: bash loadbars-remote.sh
+# Interval for CPU sampling (seconds)
+INTERVAL=0.14
+
+while true; do
+ # Load average: first 3 fields of /proc/loadavg joined by ;
+ echo "M LOADAVG"
+ read -r l1 l5 l15 _ < /proc/loadavg 2>/dev/null || true
+ echo "${l1:-0};${l5:-0};${l15:-0}"
+
+ # Memory: full /proc/meminfo
+ echo "M MEMSTATS"
+ cat /proc/meminfo 2>/dev/null || true
+
+ # Network: /proc/net/dev, skip 2 header lines, then "iface: rx... tx..."
+ echo "M NETSTATS"
+ while IFS= read -r line; do
+ line="${line/:/ }"
+ set -- $line
+ # $1=iface, $2=rx_bytes $3=rx_packets $4=rx_errs $5=rx_drop ... $10=tx_bytes $11=tx_packets $12=tx_errs $13=tx_drop
+ if [ -n "$2" ] || [ -n "${10:-}" ]; then
+ echo "$1:b=${2:-0};tb=${10:-0};p=${3:-0};tp=${11:-0} e=${4:-0};te=${12:-0};d=${5:-0};td=${13:-0}"
+ fi
+ done < <(tail -n +3 /proc/net/dev 2>/dev/null)
+
+ # CPU: /proc/stat, 20 times with INTERVAL sleep
+ echo "M CPUSTATS"
+ for _ in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
+ cat /proc/stat 2>/dev/null || true
+ sleep "$INTERVAL" 2>/dev/null || true
+ done
+done
diff --git a/internal/collector/types.go b/internal/collector/types.go
index b0db600..13bcb1f 100644
--- a/internal/collector/types.go
+++ b/internal/collector/types.go
@@ -7,7 +7,7 @@ type CPULine struct {
}
// Total returns sum of all CPU counters.
-func (c *CPULine) Total() int64 {
+func (c CPULine) Total() int64 {
return c.User + c.Nice + c.System + c.Idle + c.Iowait + c.IRQ + c.SoftIRQ + c.Steal + c.Guest + c.GuestNice
}