feat: client config from yaml with interval/reconnect settings
This commit is contained in:
+13
@@ -0,0 +1,13 @@
|
||||
# Hardware Monitor Client 配置
|
||||
#
|
||||
# machine_name : 设备名称 (默认使用主机名)
|
||||
# server : 服务端地址 (ip:port)
|
||||
# interval : 采集间隔 (秒, 默认 3)
|
||||
# reconnect_delay : 断线重连间隔 (秒, 默认 3)
|
||||
#
|
||||
# 删除此文件可重新配置
|
||||
|
||||
machine_name: my-pc
|
||||
server: 192.168.1.100:8080
|
||||
interval: 3
|
||||
reconnect_delay: 3
|
||||
+65
-23
@@ -33,34 +33,56 @@ var (
|
||||
// ═══════════════════════════════════════════════
|
||||
|
||||
type ClientConfig struct {
|
||||
MachineName string `yaml:"machine_name"`
|
||||
Server string `yaml:"server"`
|
||||
MachineName string `yaml:"machine_name"`
|
||||
Server string `yaml:"server"`
|
||||
Interval int `yaml:"interval"`
|
||||
ReconnectDelay int `yaml:"reconnect_delay"`
|
||||
}
|
||||
|
||||
func defaultConfig() ClientConfig {
|
||||
return ClientConfig{
|
||||
Interval: 3,
|
||||
ReconnectDelay: 3,
|
||||
}
|
||||
}
|
||||
|
||||
func configPath() string {
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
return "client.yaml"
|
||||
// 优先: 当前工作目录
|
||||
if wd, err := os.Getwd(); err == nil {
|
||||
p := filepath.Join(wd, "client.yaml")
|
||||
if _, err := os.Stat(p); err == nil {
|
||||
return p
|
||||
}
|
||||
}
|
||||
return filepath.Join(filepath.Dir(exe), "client.yaml")
|
||||
// 其次: 可执行文件目录
|
||||
if exe, err := os.Executable(); err == nil {
|
||||
return filepath.Join(filepath.Dir(exe), "client.yaml")
|
||||
}
|
||||
return "client.yaml"
|
||||
}
|
||||
|
||||
func loadConfig() (ClientConfig, bool) {
|
||||
p := configPath()
|
||||
raw, err := os.ReadFile(p)
|
||||
if err != nil {
|
||||
return ClientConfig{}, false
|
||||
return defaultConfig(), false
|
||||
}
|
||||
var c ClientConfig
|
||||
if yaml.Unmarshal(raw, &c) != nil {
|
||||
return ClientConfig{}, false
|
||||
cfg := defaultConfig()
|
||||
if yaml.Unmarshal(raw, &cfg) != nil {
|
||||
return defaultConfig(), false
|
||||
}
|
||||
c.MachineName = strings.TrimSpace(c.MachineName)
|
||||
c.Server = strings.TrimSpace(c.Server)
|
||||
if c.MachineName == "" || c.Server == "" {
|
||||
return ClientConfig{}, false
|
||||
cfg.MachineName = strings.TrimSpace(cfg.MachineName)
|
||||
cfg.Server = strings.TrimSpace(cfg.Server)
|
||||
if cfg.MachineName == "" || cfg.Server == "" {
|
||||
return defaultConfig(), false
|
||||
}
|
||||
return c, true
|
||||
if cfg.Interval <= 0 {
|
||||
cfg.Interval = 3
|
||||
}
|
||||
if cfg.ReconnectDelay <= 0 {
|
||||
cfg.ReconnectDelay = 3
|
||||
}
|
||||
return cfg, true
|
||||
}
|
||||
|
||||
func saveConfig(c ClientConfig) error {
|
||||
@@ -68,7 +90,14 @@ func saveConfig(c ClientConfig) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hdr := "# Monitor Client 配置\n# 删除此文件可重新输入设备信息\n\n"
|
||||
hdr := "# Hardware Monitor Client 配置\n"
|
||||
hdr += "#\n"
|
||||
hdr += "# machine_name : 设备名称 (默认使用主机名)\n"
|
||||
hdr += "# server : 服务端地址 (ip:port)\n"
|
||||
hdr += "# interval : 采集间隔 (秒, 默认 3)\n"
|
||||
hdr += "# reconnect_delay : 断线重连间隔 (秒, 默认 3)\n"
|
||||
hdr += "#\n"
|
||||
hdr += "# 删除此文件可重新配置\n\n"
|
||||
p := configPath()
|
||||
os.MkdirAll(filepath.Dir(p), 0755)
|
||||
return os.WriteFile(p, append([]byte(hdr), out...), 0644)
|
||||
@@ -414,7 +443,10 @@ func (m model) handleEnter() (tea.Model, tea.Cmd) {
|
||||
addr += ":8080"
|
||||
}
|
||||
|
||||
m.cfg = ClientConfig{MachineName: name, Server: addr}
|
||||
cfg := defaultConfig()
|
||||
cfg.MachineName = name
|
||||
cfg.Server = addr
|
||||
m.cfg = cfg
|
||||
saveConfig(m.cfg)
|
||||
|
||||
// 切换到监控阶段
|
||||
@@ -869,6 +901,15 @@ func runCollector(done <-chan struct{}, cfg ClientConfig, dataCh chan<- MachineD
|
||||
// 预热
|
||||
cpu.Percent(500*time.Millisecond, true)
|
||||
|
||||
interval := time.Duration(cfg.Interval) * time.Second
|
||||
if interval < time.Second {
|
||||
interval = 3 * time.Second
|
||||
}
|
||||
reconnect := time.Duration(cfg.ReconnectDelay) * time.Second
|
||||
if reconnect < time.Second {
|
||||
reconnect = 3 * time.Second
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-done:
|
||||
@@ -877,7 +918,7 @@ func runCollector(done <-chan struct{}, cfg ClientConfig, dataCh chan<- MachineD
|
||||
}
|
||||
|
||||
wsURL := "ws://" + cfg.Server + "/ws/agent"
|
||||
err := collectLoop(done, wsURL, cfg.MachineName, dataCh, statCh)
|
||||
err := collectLoop(done, wsURL, cfg.MachineName, interval, dataCh, statCh)
|
||||
if err != nil {
|
||||
select {
|
||||
case statCh <- false:
|
||||
@@ -889,12 +930,12 @@ func runCollector(done <-chan struct{}, cfg ClientConfig, dataCh chan<- MachineD
|
||||
select {
|
||||
case <-done:
|
||||
return
|
||||
case <-time.After(3 * time.Second):
|
||||
case <-time.After(reconnect):
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func collectLoop(done <-chan struct{}, wsURL, name string, dataCh chan<- MachineData, statCh chan<- bool) error {
|
||||
func collectLoop(done <-chan struct{}, wsURL, name string, interval time.Duration, dataCh chan<- MachineData, statCh chan<- bool) error {
|
||||
conn, _, err := websocket.DefaultDialer.Dial(wsURL, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -913,8 +954,8 @@ func collectLoop(done <-chan struct{}, wsURL, name string, dataCh chan<- Machine
|
||||
default:
|
||||
}
|
||||
|
||||
// 采集 CPU 使用率 (阻塞 ~3s)
|
||||
perCore, _ := cpu.Percent(3*time.Second, true)
|
||||
// 采集 CPU 使用率
|
||||
perCore, _ := cpu.Percent(interval, true)
|
||||
|
||||
data := collectAll(name, perCore)
|
||||
|
||||
@@ -1130,9 +1171,10 @@ func main() {
|
||||
cfg, loaded := loadConfig()
|
||||
|
||||
if loaded {
|
||||
fmt.Printf(" [✓] 加载配置: %s\n", configPath())
|
||||
fmt.Printf(" [✓] 配置文件: %s\n", configPath())
|
||||
fmt.Printf(" [✓] 设备名称: %s\n", cfg.MachineName)
|
||||
fmt.Printf(" [✓] 服务端 : %s\n", cfg.Server)
|
||||
fmt.Printf(" [✓] 采集间隔: %ds\n", cfg.Interval)
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user