package main import ( "fmt" "log/slog" "net/http" "os" "time" "code.tczkiot.com/seqlog" ) func main() { // 创建日志目录 baseDir := "./logs" if err := os.MkdirAll(baseDir, 0755); err != nil { panic(err) } // 创建 LogHub logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ Level: slog.LevelInfo, })) handler := func(topic string, record *seqlog.Record) error { fmt.Printf("[%s] 处理记录: %s\n", topic, string(record.Data)) return nil } hub := seqlog.NewLogHub(baseDir, logger, handler) // 启动 LogHub if err := hub.Start(); err != nil { panic(err) } defer hub.Stop() // 创建自己的 ServeMux mux := http.NewServeMux() // 注册自己的业务端点 mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") fmt.Fprintf(w, `{"status":"ok","service":"my-app"}`) }) mux.HandleFunc("/metrics", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain") fmt.Fprintf(w, "# HELP my_app_requests_total Total requests\n") fmt.Fprintf(w, "my_app_requests_total 12345\n") }) // 在 /logs 路径下集成 seqlog Web UI // 方法 1:使用子路径(需要创建一个包装 ServeMux) logsMux := http.NewServeMux() if err := hub.RegisterWebUIRoutes(logsMux); err != nil { panic(err) } mux.Handle("/logs/", http.StripPrefix("/logs", logsMux)) // 启动模拟写日志 go func() { topics := []string{"app", "system", "access"} count := 0 ticker := time.NewTicker(500 * time.Millisecond) defer ticker.Stop() for range ticker.C { count++ topic := topics[count%len(topics)] message := fmt.Sprintf("日志消息 %d - %s", count, time.Now().Format(time.RFC3339)) if _, err := hub.Write(topic, []byte(message)); err != nil { fmt.Printf("写入失败: %v\n", err) } } }() // 启动服务器 fmt.Println("\n==== Seqlog 集成示例 ====") fmt.Println("业务端点:") fmt.Println(" - http://localhost:8080/health") fmt.Println(" - http://localhost:8080/metrics") fmt.Println("Web UI:") fmt.Println(" - http://localhost:8080/logs/") fmt.Println("按 Ctrl+C 退出") if err := http.ListenAndServe(":8080", mux); err != nil { fmt.Printf("服务器错误: %v\n", err) } }