v0.5.0: Backup bugfixes + monitoring page with metrics store
- Fix "Helyi mentés" showing "–" after controller restart by synthesizing
LastBackup from snapshot history and LastDBDump from dump files on disk
- New monitoring page (/monitoring) with system info, metrics charts, and
container resource overview
- SQLite metrics store (modernc.org/sqlite, pure Go, no CGO) with 60s
collection interval and 30-day auto-prune
- REST API endpoints: /api/metrics/system, /api/metrics/containers/summary,
/api/metrics/containers/{name}, /api/metrics/sysinfo
- Chart.js 4.4.7 embedded locally for offline environments
- System info provider reads hostname, OS, kernel, CPU, uptime from /proc
- Docker compose updated with /etc/os-release host mount
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
//go:build linux
|
||||
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GetStaticInfo reads host-level static system information.
|
||||
// Reads from /proc and /etc (which reflect the host in Docker containers).
|
||||
func GetStaticInfo() StaticSystemInfo {
|
||||
info := StaticSystemInfo{}
|
||||
|
||||
// Hostname
|
||||
info.Hostname, _ = os.Hostname()
|
||||
|
||||
// OS — try host mount first, fall back to container's
|
||||
info.OS = readOSRelease("/host/etc/os-release")
|
||||
if info.OS == "" {
|
||||
info.OS = readOSRelease("/etc/os-release")
|
||||
}
|
||||
|
||||
// Kernel version
|
||||
if data, err := os.ReadFile("/proc/sys/kernel/osrelease"); err == nil {
|
||||
info.Kernel = strings.TrimSpace(string(data))
|
||||
}
|
||||
|
||||
// Architecture
|
||||
if data, err := os.ReadFile("/proc/sys/kernel/arch"); err == nil {
|
||||
info.Architecture = strings.TrimSpace(string(data))
|
||||
}
|
||||
if info.Architecture == "" {
|
||||
// Fallback: use uname -m equivalent from /proc/cpuinfo or runtime
|
||||
info.Architecture = runtime.GOARCH
|
||||
// Try to get the actual host arch
|
||||
if data, err := os.ReadFile("/proc/version"); err == nil {
|
||||
v := string(data)
|
||||
if strings.Contains(v, "x86_64") {
|
||||
info.Architecture = "x86_64"
|
||||
} else if strings.Contains(v, "aarch64") {
|
||||
info.Architecture = "aarch64"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CPU model and cores
|
||||
info.CPUModel, info.CPUCores = readCPUInfo()
|
||||
if info.CPUCores == 0 {
|
||||
info.CPUCores = runtime.NumCPU()
|
||||
}
|
||||
|
||||
// Uptime
|
||||
if data, err := os.ReadFile("/proc/uptime"); err == nil {
|
||||
var uptimeSec float64
|
||||
if _, err := fmt.Sscanf(string(data), "%f", &uptimeSec); err == nil {
|
||||
info.UptimeSeconds = int64(uptimeSec)
|
||||
info.BootTime = time.Now().Add(-time.Duration(info.UptimeSeconds) * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
return info
|
||||
}
|
||||
|
||||
// readOSRelease reads PRETTY_NAME from an os-release file.
|
||||
func readOSRelease(path string) string {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if strings.HasPrefix(line, "PRETTY_NAME=") {
|
||||
val := strings.TrimPrefix(line, "PRETTY_NAME=")
|
||||
val = strings.Trim(val, `"`)
|
||||
return val
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// readCPUInfo reads the CPU model name and number of cores from /proc/cpuinfo.
|
||||
func readCPUInfo() (model string, cores int) {
|
||||
f, err := os.Open("/proc/cpuinfo")
|
||||
if err != nil {
|
||||
return "", 0
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if strings.HasPrefix(line, "model name") {
|
||||
if idx := strings.Index(line, ":"); idx >= 0 {
|
||||
model = strings.TrimSpace(line[idx+1:])
|
||||
}
|
||||
}
|
||||
if strings.HasPrefix(line, "processor") {
|
||||
cores++
|
||||
}
|
||||
}
|
||||
return model, cores
|
||||
}
|
||||
Reference in New Issue
Block a user