|
| 1 | +package main |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "log" |
| 6 | + "net/http" |
| 7 | + "strings" |
| 8 | + "time" |
| 9 | + |
| 10 | + "github.com/pubgo/funk/metaflags" |
| 11 | +) |
| 12 | + |
| 13 | +var startTime = time.Now() |
| 14 | + |
| 15 | +func main() { |
| 16 | + status := metaflags.String("app_status", "ok", "Current app status") |
| 17 | + replicas := metaflags.Int("replicas", 1, "Number of replicas") |
| 18 | + timeout := metaflags.Duration("timeout", 5*time.Second, "Request timeout") |
| 19 | + features := metaflags.StringSlice("features", []string{"auth"}, "Enabled features") |
| 20 | + labels := metaflags.StringMap("labels", map[string]string{"env": "dev"}, "Node labels") |
| 21 | + |
| 22 | + // 模拟更新 |
| 23 | + go func() { |
| 24 | + time.Sleep(2 * time.Second) |
| 25 | + status.Set("degraded") |
| 26 | + |
| 27 | + time.Sleep(2 * time.Second) |
| 28 | + replicas.Set(3) |
| 29 | + |
| 30 | + time.Sleep(2 * time.Second) |
| 31 | + timeout.Set(10 * time.Second) |
| 32 | + |
| 33 | + time.Sleep(2 * time.Second) |
| 34 | + features.Set([]string{"auth", "metrics", "tracing"}) |
| 35 | + |
| 36 | + time.Sleep(2 * time.Second) |
| 37 | + lbls := labels.Get().(map[string]string) |
| 38 | + lbls["updated"] = time.Now().Format("15:04") |
| 39 | + labels.Set(lbls) |
| 40 | + }() |
| 41 | + |
| 42 | + // HTTP 输出所有元数据 |
| 43 | + http.HandleFunc("/metadata", func(w http.ResponseWriter, r *http.Request) { |
| 44 | + w.Header().Set("Content-Type", "application/json") |
| 45 | + fmt.Fprintln(w, "{") |
| 46 | + first := true |
| 47 | + metaflags.VisitAll(func(e *metaflags.Entry) { |
| 48 | + if !first { |
| 49 | + fmt.Fprint(w, ",") |
| 50 | + } |
| 51 | + first = false |
| 52 | + fmt.Fprintf(w, "\n %q: %v", e.Name, mustJSON(e.Value.Get())) |
| 53 | + }) |
| 54 | + fmt.Fprintln(w, "\n}") |
| 55 | + }) |
| 56 | + |
| 57 | + log.Println("Server starting on :8080") |
| 58 | + log.Fatal(http.ListenAndServe(":8080", nil)) |
| 59 | +} |
| 60 | + |
| 61 | +// 简单 JSON 转换(生产环境用 json.Marshal) |
| 62 | +func mustJSON(v interface{}) string { |
| 63 | + switch val := v.(type) { |
| 64 | + case string: |
| 65 | + return fmt.Sprintf("%q", val) |
| 66 | + case []string: |
| 67 | + return fmt.Sprintf("%q", val) |
| 68 | + case map[string]string: |
| 69 | + var parts []string |
| 70 | + for k, v := range val { |
| 71 | + parts = append(parts, fmt.Sprintf("%q:%q", k, v)) |
| 72 | + } |
| 73 | + return fmt.Sprintf("{%s}", strings.Join(parts, ",")) |
| 74 | + default: |
| 75 | + return fmt.Sprintf("%v", val) |
| 76 | + } |
| 77 | +} |
0 commit comments