| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- package main
- import (
- "encoding/json"
- "flag"
- "fmt"
- "log"
- "net/http"
- "time"
- "github.com/prometheus/client_golang/prometheus/promhttp"
- "github.com/seaweedfs/seaweedfs/telemetry/server/api"
- "github.com/seaweedfs/seaweedfs/telemetry/server/dashboard"
- "github.com/seaweedfs/seaweedfs/telemetry/server/storage"
- )
- var (
- port = flag.Int("port", 8080, "HTTP server port")
- enableCORS = flag.Bool("cors", true, "Enable CORS for dashboard")
- logRequests = flag.Bool("log", true, "Log incoming requests")
- enableDashboard = flag.Bool("dashboard", true, "Enable built-in dashboard (optional when using Grafana)")
- cleanupInterval = flag.Duration("cleanup", 24*time.Hour, "Cleanup interval for old instances")
- maxInstanceAge = flag.Duration("max-age", 30*24*time.Hour, "Maximum age for instances before cleanup")
- )
- func main() {
- flag.Parse()
- // Create Prometheus storage instance
- store := storage.NewPrometheusStorage()
- // Start cleanup routine
- go func() {
- ticker := time.NewTicker(*cleanupInterval)
- defer ticker.Stop()
- for range ticker.C {
- store.CleanupOldInstances(*maxInstanceAge)
- }
- }()
- // Setup HTTP handlers
- mux := http.NewServeMux()
- // Prometheus metrics endpoint
- mux.Handle("/metrics", promhttp.Handler())
- // API endpoints
- apiHandler := api.NewHandler(store)
- mux.HandleFunc("/api/collect", corsMiddleware(logMiddleware(apiHandler.CollectTelemetry)))
- mux.HandleFunc("/api/stats", corsMiddleware(logMiddleware(apiHandler.GetStats)))
- mux.HandleFunc("/api/instances", corsMiddleware(logMiddleware(apiHandler.GetInstances)))
- mux.HandleFunc("/api/metrics", corsMiddleware(logMiddleware(apiHandler.GetMetrics)))
- // Dashboard (optional)
- if *enableDashboard {
- dashboardHandler := dashboard.NewHandler()
- mux.HandleFunc("/", corsMiddleware(dashboardHandler.ServeIndex))
- mux.HandleFunc("/dashboard", corsMiddleware(dashboardHandler.ServeIndex))
- mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))))
- }
- // Health check
- mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "application/json")
- json.NewEncoder(w).Encode(map[string]string{
- "status": "ok",
- "time": time.Now().UTC().Format(time.RFC3339),
- })
- })
- addr := fmt.Sprintf(":%d", *port)
- log.Printf("Starting telemetry server on %s", addr)
- log.Printf("Prometheus metrics: http://localhost%s/metrics", addr)
- if *enableDashboard {
- log.Printf("Dashboard: http://localhost%s/dashboard", addr)
- }
- log.Printf("Cleanup interval: %v, Max instance age: %v", *cleanupInterval, *maxInstanceAge)
- if err := http.ListenAndServe(addr, mux); err != nil {
- log.Fatalf("Server failed: %v", err)
- }
- }
- func corsMiddleware(next http.HandlerFunc) http.HandlerFunc {
- return func(w http.ResponseWriter, r *http.Request) {
- if *enableCORS {
- w.Header().Set("Access-Control-Allow-Origin", "*")
- w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
- w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
- }
- if r.Method == "OPTIONS" {
- w.WriteHeader(http.StatusOK)
- return
- }
- next(w, r)
- }
- }
- func logMiddleware(next http.HandlerFunc) http.HandlerFunc {
- return func(w http.ResponseWriter, r *http.Request) {
- if *logRequests {
- start := time.Now()
- next(w, r)
- log.Printf("%s %s %s %v", r.Method, r.URL.Path, r.RemoteAddr, time.Since(start))
- } else {
- next(w, r)
- }
- }
- }
|