@@ -15,44 +15,39 @@ import (
1515)
1616
1717var (
18- // RPCCallLatency measures RPC duration in milliseconds (bucket upper bounds from 50 ms to 8 s).
19- // Values are latency.Seconds()*1000, not float64(duration) — the latter is nanoseconds and will skew quantiles.
2018 RPCCallLatency = promauto .NewHistogramVec (prometheus.HistogramOpts {
2119 Name : rpcCallLatencyBeholder ,
22- Help : "The duration of an RPC call in milliseconds " ,
20+ Help : "The duration of an RPC call in nanoseconds " ,
2321 Buckets : []float64 {
24- 50 , 100 , 200 , 500 ,
25- 1000 , 2000 , 4000 , 8000 ,
22+ float64 (50 * time .Millisecond ),
23+ float64 (100 * time .Millisecond ),
24+ float64 (200 * time .Millisecond ),
25+ float64 (500 * time .Millisecond ),
26+ float64 (1 * time .Second ),
27+ float64 (2 * time .Second ),
28+ float64 (4 * time .Second ),
29+ float64 (8 * time .Second ),
2630 },
2731 }, []string {"chainFamily" , "chainID" , "rpcUrl" , "isSendOnly" , "success" , "rpcCallName" })
28-
29- RPCCallErrorsTotal = promauto .NewCounterVec (prometheus.CounterOpts {
30- Name : "rpc_call_errors_total" ,
31- Help : "The total number of failed RPC calls" ,
32- }, []string {"chainFamily" , "chainID" , "rpcUrl" , "isSendOnly" , "rpcCallName" })
3332)
3433
35- const (
36- rpcCallLatencyBeholder = "rpc_call_latency"
37- rpcCallErrorsTotalBeholder = "rpc_call_errors_total"
38- )
34+ const rpcCallLatencyBeholder = "rpc_call_latency"
3935
40- // RPCClientMetrics records RPC latency and errors to Prometheus and Beholder (same pattern as multinode metrics).
36+ // RPCClientMetrics records RPC call latency to Prometheus and Beholder (failures: success="false"; same pattern as multinode metrics).
4137// Construct once per chain (or process) with ChainFamily and ChainID; pass rpcUrl and isSendOnly on each call
4238// when they vary by node or request.
4339type RPCClientMetrics interface {
44- // RecordRequest records latency for an RPC call (observed in milliseconds for Prometheus and Beholder).
45- // If err is non-nil, increments rpc_call_errors_total .
40+ // RecordRequest records latency for an RPC call (observed in nanoseconds for Prometheus and Beholder).
41+ // Failures use success="false"; derive error rate from rpc_call_latency_count{success="false"} (or equivalent) .
4642 RecordRequest (ctx context.Context , rpcURL string , isSendOnly bool , callName string , latency time.Duration , err error )
4743}
4844
4945var _ RPCClientMetrics = (* rpcClientMetrics )(nil )
5046
5147type rpcClientMetrics struct {
52- chainFamily string
53- chainID string
54- latencyHis metric.Float64Histogram
55- errorsCounter metric.Int64Counter
48+ chainFamily string
49+ chainID string
50+ latencyHis metric.Float64Histogram
5651}
5752
5853// RPCClientMetricsConfig holds labels that are fixed for the lifetime of the metrics handle (e.g. one per chain).
@@ -67,15 +62,10 @@ func NewRPCClientMetrics(cfg RPCClientMetricsConfig) (RPCClientMetrics, error) {
6762 if err != nil {
6863 return nil , fmt .Errorf ("failed to register RPC call latency metric: %w" , err )
6964 }
70- errorsTotal , err := beholder .GetMeter ().Int64Counter (rpcCallErrorsTotalBeholder )
71- if err != nil {
72- return nil , fmt .Errorf ("failed to register RPC call errors metric: %w" , err )
73- }
7465 return & rpcClientMetrics {
75- chainFamily : cfg .ChainFamily ,
76- chainID : cfg .ChainID ,
77- latencyHis : latency ,
78- errorsCounter : errorsTotal ,
66+ chainFamily : cfg .ChainFamily ,
67+ chainID : cfg .ChainID ,
68+ latencyHis : latency ,
7969 }, nil
8070}
8171
@@ -85,9 +75,9 @@ func (m *rpcClientMetrics) RecordRequest(ctx context.Context, rpcURL string, isS
8575 successStr = "false"
8676 }
8777 sendStr := strconv .FormatBool (isSendOnly )
88- ms := latency . Seconds () * 1000
78+ latencyNs := float64 ( latency )
8979
90- RPCCallLatency .WithLabelValues (m .chainFamily , m .chainID , rpcURL , sendStr , successStr , callName ).Observe (ms )
80+ RPCCallLatency .WithLabelValues (m .chainFamily , m .chainID , rpcURL , sendStr , successStr , callName ).Observe (latencyNs )
9181
9282 latAttrs := metric .WithAttributes (
9383 attribute .String ("chainFamily" , m .chainFamily ),
@@ -97,19 +87,7 @@ func (m *rpcClientMetrics) RecordRequest(ctx context.Context, rpcURL string, isS
9787 attribute .String ("success" , successStr ),
9888 attribute .String ("rpcCallName" , callName ),
9989 )
100- m .latencyHis .Record (ctx , ms , latAttrs )
101-
102- if err != nil {
103- RPCCallErrorsTotal .WithLabelValues (m .chainFamily , m .chainID , rpcURL , sendStr , callName ).Inc ()
104- errAttrs := metric .WithAttributes (
105- attribute .String ("chainFamily" , m .chainFamily ),
106- attribute .String ("chainID" , m .chainID ),
107- attribute .String ("rpcUrl" , rpcURL ),
108- attribute .String ("isSendOnly" , sendStr ),
109- attribute .String ("rpcCallName" , callName ),
110- )
111- m .errorsCounter .Add (ctx , 1 , errAttrs )
112- }
90+ m .latencyHis .Record (ctx , latencyNs , latAttrs )
11391}
11492
11593// NoopRPCClientMetrics is a no-op implementation for when metrics are disabled.
0 commit comments