116 lines
3.4 KiB
Go
116 lines
3.4 KiB
Go
package metrics
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
grpcprom "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
"github.com/rs/zerolog/log"
|
|
"google.golang.org/grpc"
|
|
)
|
|
|
|
var (
|
|
CacheHits = promauto.NewCounterVec(prometheus.CounterOpts{
|
|
Name: "metadata_cache_hits_total",
|
|
Help: "Number of cache hits by entity type",
|
|
}, []string{"entity"})
|
|
|
|
CacheMisses = promauto.NewCounterVec(prometheus.CounterOpts{
|
|
Name: "metadata_cache_misses_total",
|
|
Help: "Number of cache misses by entity type",
|
|
}, []string{"entity"})
|
|
|
|
ProviderRequests = promauto.NewCounterVec(prometheus.CounterOpts{
|
|
Name: "metadata_provider_requests_total",
|
|
Help: "Number of requests to external providers",
|
|
}, []string{"provider", "operation", "status"})
|
|
|
|
ProviderLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{
|
|
Name: "metadata_provider_request_duration_seconds",
|
|
Help: "Latency of external provider requests",
|
|
Buckets: []float64{0.01, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10},
|
|
}, []string{"provider", "operation"})
|
|
|
|
DBQueryLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{
|
|
Name: "metadata_db_query_duration_seconds",
|
|
Help: "Latency of database queries",
|
|
Buckets: prometheus.ExponentialBuckets(0.001, 2, 10),
|
|
}, []string{"operation"})
|
|
)
|
|
|
|
type ServerMetrics struct {
|
|
grpcMetrics *grpcprom.ServerMetrics
|
|
registry *prometheus.Registry
|
|
}
|
|
|
|
func NewServerMetrics() *ServerMetrics {
|
|
reg := prometheus.NewRegistry()
|
|
reg.MustRegister(prometheus.NewGoCollector())
|
|
reg.MustRegister(prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{}))
|
|
|
|
srvMetrics := grpcprom.NewServerMetrics(
|
|
grpcprom.WithServerHandlingTimeHistogram(
|
|
grpcprom.WithHistogramBuckets([]float64{
|
|
0.001, 0.01, 0.05, 0.1, 0.3, 0.6, 1, 3, 6, 10, 30,
|
|
}),
|
|
),
|
|
)
|
|
reg.MustRegister(srvMetrics)
|
|
reg.MustRegister(CacheHits)
|
|
reg.MustRegister(CacheMisses)
|
|
reg.MustRegister(ProviderRequests)
|
|
reg.MustRegister(ProviderLatency)
|
|
reg.MustRegister(DBQueryLatency)
|
|
|
|
return &ServerMetrics{
|
|
grpcMetrics: srvMetrics,
|
|
registry: reg,
|
|
}
|
|
}
|
|
|
|
func (m *ServerMetrics) UnaryServerInterceptor() grpc.UnaryServerInterceptor {
|
|
return m.grpcMetrics.UnaryServerInterceptor()
|
|
}
|
|
|
|
func (m *ServerMetrics) StreamServerInterceptor() grpc.StreamServerInterceptor {
|
|
return m.grpcMetrics.StreamServerInterceptor()
|
|
}
|
|
|
|
func (m *ServerMetrics) InitializeMetrics(srv *grpc.Server) {
|
|
m.grpcMetrics.InitializeMetrics(srv)
|
|
}
|
|
|
|
func (m *ServerMetrics) StartHTTPServer(ctx context.Context, port int) {
|
|
mux := http.NewServeMux()
|
|
mux.Handle("/metrics", promhttp.HandlerFor(m.registry, promhttp.HandlerOpts{
|
|
EnableOpenMetrics: true,
|
|
}))
|
|
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = w.Write([]byte("OK"))
|
|
})
|
|
|
|
srv := &http.Server{
|
|
Addr: fmt.Sprintf(":%d", port),
|
|
Handler: mux,
|
|
ReadHeaderTimeout: 5 * time.Second,
|
|
}
|
|
|
|
go func() {
|
|
<-ctx.Done()
|
|
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
_ = srv.Shutdown(shutdownCtx)
|
|
}()
|
|
|
|
log.Info().Int("port", port).Msg("metrics HTTP server starting")
|
|
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
|
log.Error().Err(err).Msg("metrics HTTP server failed")
|
|
}
|
|
}
|