package main import ( "context" "log/slog" "net/http" "os" "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" ) var ( times = promauto.NewHistogramVec(prometheus.HistogramOpts{ Name: "app_times_seconds", Buckets: []float64{0.01, 0.013, 0.015, 0.02, 0.03, 0.04, 0.05, 0.06, 1, 2, 3, 4, 5, 6, 7}, }, []string{"status"}) timesSummary = promauto.NewSummaryVec(prometheus.SummaryOpts{ Name: "app_times_summary_seconds", Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, }, []string{"status"}) timesNative = promauto.NewHistogramVec(prometheus.HistogramOpts{ Name: "app_times_native_seconds", NativeHistogramBucketFactor: 1.1, }, []string{"status"}) ) func main() { slog.Info("application started") if err := start(context.Background()); err != nil { slog.Error("unable to start application", "error", err) os.Exit(1) } slog.Info("application stopped") } func start(_ context.Context) error { port := os.Getenv("APP_PORT") go func() { var max time.Duration for { t := time.Now() time.Sleep(10 * time.Millisecond) duration := time.Since(t) times.WithLabelValues("10ms").Observe(duration.Seconds()) timesNative.WithLabelValues("10ms").Observe(duration.Seconds()) timesSummary.WithLabelValues("10ms").Observe(duration.Seconds()) if duration > max { max = duration } slog.Info("duration", "duration", duration, "max", max) } }() go func() { var max time.Duration for { t := time.Now() time.Sleep(100 * time.Millisecond) duration := time.Since(t) times.WithLabelValues("100ms").Observe(duration.Seconds()) timesNative.WithLabelValues("100ms").Observe(duration.Seconds()) timesSummary.WithLabelValues("100ms").Observe(duration.Seconds()) if duration > max { max = duration } // slog.Info("duration", "duration", duration, "max", max) } }() http.Handle("/metrics", promhttp.Handler()) return http.ListenAndServe(":"+port, nil) }