package oracle import ( "strings" "sync" "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) var ( metricsOnce sync.Once rpcRequestsTotal *prometheus.CounterVec rpcLatency *prometheus.HistogramVec ) func initMetrics() { metricsOnce.Do(func() { rpcRequestsTotal = promauto.NewCounterVec( prometheus.CounterOpts{ Namespace: "fx", Subsystem: "oracle", Name: "requests_total", Help: "Total number of FX oracle RPC calls handled.", }, []string{"method", "result"}, ) rpcLatency = promauto.NewHistogramVec( prometheus.HistogramOpts{ Namespace: "fx", Subsystem: "oracle", Name: "request_latency_seconds", Help: "Latency of FX oracle RPC calls.", Buckets: prometheus.DefBuckets, }, []string{"method", "result"}, ) }) } func observeRPC(start time.Time, method string, err error) { result := labelFromError(err) rpcRequestsTotal.WithLabelValues(method, result).Inc() rpcLatency.WithLabelValues(method, result).Observe(time.Since(start).Seconds()) } func labelFromError(err error) string { if err == nil { return strings.ToLower(codes.OK.String()) } st, ok := status.FromError(err) if !ok { return "error" } code := st.Code() if code == codes.OK { return strings.ToLower(code.String()) } return strings.ToLower(code.String()) }