feat: switch monitor client to Docker-first runtime

- remove install.sh-based deployment path
- add multi-stage Dockerfile for HarborForge.Monitor
- support HF_MONITER_* env vars and keep HF_MONITOR_* compatibility
- add rootfs-aware host metric collection for Docker deployment
This commit is contained in:
zhi
2026-03-20 11:00:42 +00:00
parent 8cc3781454
commit 739b8fcd74
7 changed files with 139 additions and 71 deletions

View File

@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"os"
"path/filepath"
)
type Config struct {
@@ -12,15 +13,17 @@ type Config struct {
APIKey string `json:"apiKey"`
ReportIntervalSec int `json:"reportIntervalSec"`
LogLevel string `json:"logLevel"`
RootFS string `json:"rootFs"`
}
func Load(path string) (Config, error) {
cfg := Config{
BackendURL: getenv("HF_MONITOR_BACKEND_URL", "https://monitor.hangman-lab.top"),
Identifier: getenv("HF_MONITOR_IDENTIFIER", hostnameOr("unknown-host")),
APIKey: os.Getenv("HF_MONITOR_API_KEY"),
ReportIntervalSec: getenvInt("HF_MONITOR_REPORT_INTERVAL", 30),
LogLevel: getenv("HF_MONITOR_LOG_LEVEL", "info"),
BackendURL: getenvAny([]string{"HF_MONITER_BACKEND_URL", "HF_MONITOR_BACKEND_URL"}, "https://monitor.hangman-lab.top"),
Identifier: getenvAny([]string{"HF_MONITER_IDENTIFIER", "HF_MONITOR_IDENTIFIER"}, hostnameOr("unknown-host")),
APIKey: getenvAny([]string{"HF_MONITER_API_KEY", "HF_MONITOR_API_KEY"}, ""),
ReportIntervalSec: getenvIntAny([]string{"HF_MONITER_REPORT_INTERVAL", "HF_MONITOR_REPORT_INTERVAL"}, 30),
LogLevel: getenvAny([]string{"HF_MONITER_LOG_LEVEL", "HF_MONITOR_LOG_LEVEL"}, "info"),
RootFS: getenvAny([]string{"HF_MONITER_ROOTFS", "HF_MONITOR_ROOTFS"}, ""),
}
if path != "" {
@@ -32,13 +35,14 @@ func Load(path string) (Config, error) {
}
// env always wins over file
cfg.BackendURL = getenv("HF_MONITOR_BACKEND_URL", cfg.BackendURL)
cfg.Identifier = getenv("HF_MONITOR_IDENTIFIER", cfg.Identifier)
if v := os.Getenv("HF_MONITOR_API_KEY"); v != "" {
cfg.BackendURL = getenvAny([]string{"HF_MONITER_BACKEND_URL", "HF_MONITOR_BACKEND_URL"}, cfg.BackendURL)
cfg.Identifier = getenvAny([]string{"HF_MONITER_IDENTIFIER", "HF_MONITOR_IDENTIFIER"}, cfg.Identifier)
if v := getenvAny([]string{"HF_MONITER_API_KEY", "HF_MONITOR_API_KEY"}, ""); v != "" {
cfg.APIKey = v
}
cfg.ReportIntervalSec = getenvInt("HF_MONITOR_REPORT_INTERVAL", cfg.ReportIntervalSec)
cfg.LogLevel = getenv("HF_MONITOR_LOG_LEVEL", cfg.LogLevel)
cfg.ReportIntervalSec = getenvIntAny([]string{"HF_MONITER_REPORT_INTERVAL", "HF_MONITOR_REPORT_INTERVAL"}, cfg.ReportIntervalSec)
cfg.LogLevel = getenvAny([]string{"HF_MONITER_LOG_LEVEL", "HF_MONITOR_LOG_LEVEL"}, cfg.LogLevel)
cfg.RootFS = getenvAny([]string{"HF_MONITER_ROOTFS", "HF_MONITOR_ROOTFS"}, cfg.RootFS)
if cfg.BackendURL == "" {
return cfg, fmt.Errorf("backendUrl is required")
@@ -49,6 +53,7 @@ func Load(path string) (Config, error) {
if cfg.ReportIntervalSec <= 0 {
cfg.ReportIntervalSec = 30
}
applyHostFSEnv(cfg.RootFS)
return cfg, nil
}
@@ -80,20 +85,27 @@ func merge(dst *Config, src Config) {
if src.LogLevel != "" {
dst.LogLevel = src.LogLevel
}
if src.RootFS != "" {
dst.RootFS = src.RootFS
}
}
func getenv(key, fallback string) string {
if v := os.Getenv(key); v != "" {
return v
func getenvAny(keys []string, fallback string) string {
for _, key := range keys {
if v := os.Getenv(key); v != "" {
return v
}
}
return fallback
}
func getenvInt(key string, fallback int) int {
if v := os.Getenv(key); v != "" {
var out int
if _, err := fmt.Sscanf(v, "%d", &out); err == nil && out > 0 {
return out
func getenvIntAny(keys []string, fallback int) int {
for _, key := range keys {
if v := os.Getenv(key); v != "" {
var out int
if _, err := fmt.Sscanf(v, "%d", &out); err == nil && out > 0 {
return out
}
}
}
return fallback
@@ -106,3 +118,20 @@ func hostnameOr(fallback string) string {
}
return name
}
func applyHostFSEnv(rootFS string) {
if rootFS == "" {
return
}
setIfEmpty("HOST_PROC", filepath.Join(rootFS, "proc"))
setIfEmpty("HOST_SYS", filepath.Join(rootFS, "sys"))
setIfEmpty("HOST_ETC", filepath.Join(rootFS, "etc"))
setIfEmpty("HOST_VAR", filepath.Join(rootFS, "var"))
setIfEmpty("HOST_RUN", filepath.Join(rootFS, "run"))
}
func setIfEmpty(key, value string) {
if os.Getenv(key) == "" {
_ = os.Setenv(key, value)
}
}