Skip to content

Commit 42e184c

Browse files
committed
chore: quick update fix/version at 2025-09-18 14:28:25
1 parent 7c14e8e commit 42e184c

File tree

3 files changed

+479
-0
lines changed

3 files changed

+479
-0
lines changed

monitor/example/main.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// main.go
2+
package main
3+
4+
import (
5+
"encoding/json"
6+
"log"
7+
"net/http"
8+
"time"
9+
10+
"github.com/pubgo/funk/monitor"
11+
)
12+
13+
func main() {
14+
// 创建带 Tags 的元数据
15+
status := monitor.String("app_status", "ok", "Current application status",
16+
map[string]any{
17+
"group": "health",
18+
"mutable": true,
19+
})
20+
21+
replicas := monitor.Int("replicas", 1, "Number of replicas",
22+
map[string]any{
23+
"group": "scaling",
24+
"min": 1,
25+
"max": 10,
26+
})
27+
28+
_ = monitor.Duration("http_timeout", 5*time.Second, "HTTP request timeout",
29+
map[string]any{
30+
"unit": "seconds",
31+
"group": "network",
32+
})
33+
34+
labels := monitor.StringMap("labels", map[string]string{"env": "dev"}, "Node labels",
35+
map[string]any{
36+
"group": "metadata",
37+
})
38+
39+
_ = monitor.String("api_key", "sk-xxxx", "API authentication key",
40+
map[string]any{
41+
"sensitive": true,
42+
"group": "security",
43+
})
44+
45+
// 模拟更新
46+
go func() {
47+
time.Sleep(2 * time.Second)
48+
status.Set("degraded")
49+
50+
time.Sleep(2 * time.Second)
51+
replicas.Set(replicas.Get() + 2)
52+
53+
time.Sleep(2 * time.Second)
54+
current := labels.Get()
55+
current["updated"] = time.Now().Format("15:04")
56+
labels.Set(current)
57+
}()
58+
59+
// HTTP handler:只输出非敏感字段
60+
http.HandleFunc("/metadata", func(w http.ResponseWriter, r *http.Request) {
61+
data := extractPublicMetadata()
62+
w.Header().Set("Content-Type", "application/json")
63+
json.NewEncoder(w).Encode(data)
64+
})
65+
66+
log.Println("Monitor server listening on :8080")
67+
log.Fatal(http.ListenAndServe(":8080", nil))
68+
}
69+
70+
// extractPublicMetadata 导出所有非敏感元数据
71+
func extractPublicMetadata() map[string]any {
72+
m := make(map[string]any)
73+
monitor.VisitAll(func(e *monitor.Entry) {
74+
// 跳过敏感字段
75+
if sensitive, ok := e.Tags["sensitive"].(bool); ok && sensitive {
76+
m[e.Name] = "******"
77+
return
78+
}
79+
m[e.Name] = e.Getter()
80+
})
81+
return m
82+
}

monitor/monitor.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// monitor/monitor.go
2+
package monitor
3+
4+
import "sync"
5+
6+
// Getter returns the current value as any
7+
type Getter func() any
8+
9+
// Setter updates the value from any
10+
type Setter func(any) error
11+
12+
// Entry holds metadata about a registered value
13+
type Entry struct {
14+
Name string
15+
Getter Getter
16+
Setter Setter
17+
Usage string
18+
Tags map[string]any // 自定义元数据标签
19+
}
20+
21+
// Monitor manages all registered values
22+
type Monitor struct {
23+
m map[string]*Entry
24+
mu sync.RWMutex
25+
}
26+
27+
var defaultMonitor = NewMonitor("default")
28+
29+
// NewMonitor creates a new Monitor instance
30+
func NewMonitor(name string) *Monitor {
31+
return &Monitor{
32+
m: make(map[string]*Entry),
33+
}
34+
}
35+
36+
// AddFunc registers a new value with getter, setter, usage, and optional tags
37+
func (m *Monitor) AddFunc(name string, get Getter, set Setter, usage string, tags ...map[string]any) {
38+
m.mu.Lock()
39+
defer m.mu.Unlock()
40+
41+
tagMap := make(map[string]any)
42+
if len(tags) > 0 && tags[0] != nil {
43+
for k, v := range tags[0] {
44+
tagMap[k] = v
45+
}
46+
}
47+
48+
m.m[name] = &Entry{
49+
Name: name,
50+
Getter: get,
51+
Setter: set,
52+
Usage: usage,
53+
Tags: tagMap,
54+
}
55+
}
56+
57+
// Lookup returns the entry by name
58+
func (m *Monitor) Lookup(name string) *Entry {
59+
m.mu.RLock()
60+
defer m.mu.RUnlock()
61+
return m.m[name]
62+
}
63+
64+
// VisitAll calls fn for each entry
65+
func (m *Monitor) VisitAll(fn func(*Entry)) {
66+
m.mu.RLock()
67+
defer m.mu.RUnlock()
68+
for _, e := range m.m {
69+
fn(e)
70+
}
71+
}
72+
73+
// Global functions (use defaultMonitor)
74+
75+
func AddFunc(name string, get Getter, set Setter, usage string, tags ...map[string]any) {
76+
defaultMonitor.AddFunc(name, get, set, usage, tags...)
77+
}
78+
79+
func Lookup(name string) *Entry {
80+
return defaultMonitor.Lookup(name)
81+
}
82+
83+
func VisitAll(fn func(*Entry)) {
84+
defaultMonitor.VisitAll(fn)
85+
}

0 commit comments

Comments
 (0)