Skip to content

Commit

Permalink
Add prom metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
swift1337 committed Jan 14, 2025
1 parent b1e472d commit c6a8a68
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 33 deletions.
83 changes: 50 additions & 33 deletions zetaclient/chains/bitcoin/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@ import (

"github.com/zeta-chain/node/zetaclient/config"
"github.com/zeta-chain/node/zetaclient/logs"
"github.com/zeta-chain/node/zetaclient/metrics"
)

type Client struct {
hostURL string
client *http.Client
config config.BTCConfig
params chains.Params
logger zerolog.Logger
hostURL string
client *http.Client
clientName string
config config.BTCConfig
params chains.Params
logger zerolog.Logger
}

type Opt func(c *Client)
Expand All @@ -50,17 +52,23 @@ func WithHTTP(httpClient *http.Client) Opt {
}

// New Client constructor
func New(cfg config.BTCConfig, logger zerolog.Logger, opts ...Opt) (*Client, error) {
func New(cfg config.BTCConfig, chainID int64, logger zerolog.Logger, opts ...Opt) (*Client, error) {
params, err := resolveParams(cfg.RPCParams)
if err != nil {
return nil, errors.Wrap(err, "unable to resolve chain params")
}

Check warning on line 59 in zetaclient/chains/bitcoin/client/client.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/bitcoin/client/client.go#L55-L59

Added lines #L55 - L59 were not covered by tests

clientName := fmt.Sprintf("btc:%d", chainID)

c := &Client{
hostURL: normalizeHostURL(cfg.RPCHost, true),
client: defaultHTTPClient(),
params: params,
logger: logger.With().Str(logs.FieldModule, "btc_client").Logger(),
hostURL: normalizeHostURL(cfg.RPCHost, true),
client: defaultHTTPClient(),
params: params,
clientName: clientName,
logger: logger.With().
Str(logs.FieldModule, "btc_client").
Int64(logs.FieldChain, chainID).
Logger(),
}

for _, opt := range opts {
Expand Down Expand Up @@ -95,17 +103,31 @@ func (c *Client) sendCommand(ctx context.Context, cmd any) (json.RawMessage, err
return out.Result, nil

Check warning on line 103 in zetaclient/chains/bitcoin/client/client.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/bitcoin/client/client.go#L103

Added line #L103 was not covered by tests
}

func (c *Client) sendRequest(req *http.Request, method string) (out rawResponse, err error) {
// todo prometheus metrics (chain_id, method, latency, ok/fail)
func (c *Client) newRequest(ctx context.Context, body []byte) (*http.Request, error) {
payload := bytes.NewReader(body)

req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.hostURL, payload)
if err != nil {
return nil, err
}

Check warning on line 112 in zetaclient/chains/bitcoin/client/client.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/bitcoin/client/client.go#L106-L112

Added lines #L106 - L112 were not covered by tests

req.Header.Set("Content-Type", "application/json")

if c.config.RPCPassword != "" || c.config.RPCUsername != "" {
req.SetBasicAuth(c.config.RPCUsername, c.config.RPCPassword)
}

Check warning on line 118 in zetaclient/chains/bitcoin/client/client.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/bitcoin/client/client.go#L114-L118

Added lines #L114 - L118 were not covered by tests

return req, nil

Check warning on line 120 in zetaclient/chains/bitcoin/client/client.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/bitcoin/client/client.go#L120

Added line #L120 was not covered by tests
}

func (c *Client) sendRequest(req *http.Request, method string) (out rawResponse, err error) {
c.logger.Debug().Str("rpc.method", method).Msg("Sending request")
start := time.Now()

defer func() {
c.logger.Debug().
Str("rpc.method", method).
Dur("rpc.duration", time.Since(start)).
Err(err).
c.recordMetrics(method, start, out, err)
c.logger.Debug().Err(err).
Str("rpc.method", method).Dur("rpc.duration", time.Since(start)).
Msg("Sent request")
}()

Check warning on line 132 in zetaclient/chains/bitcoin/client/client.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/bitcoin/client/client.go#L123-L132

Added lines #L123 - L132 were not covered by tests

Expand All @@ -128,6 +150,18 @@ func (c *Client) sendRequest(req *http.Request, method string) (out rawResponse,
return out, nil

Check warning on line 150 in zetaclient/chains/bitcoin/client/client.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/bitcoin/client/client.go#L150

Added line #L150 was not covered by tests
}

func (c *Client) recordMetrics(method string, start time.Time, out rawResponse, err error) {
dur := time.Since(start).Seconds()

status := "ok"
if err != nil || out.Error != nil {
status = "failed"
}

Check warning on line 159 in zetaclient/chains/bitcoin/client/client.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/bitcoin/client/client.go#L153-L159

Added lines #L153 - L159 were not covered by tests

// "status", "client", "method"
metrics.RPCClientDuration.WithLabelValues(status, c.clientName, method).Observe(dur)

Check warning on line 162 in zetaclient/chains/bitcoin/client/client.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/bitcoin/client/client.go#L162

Added line #L162 was not covered by tests
}

func (c *Client) marshalCmd(cmd any) (string, []byte, error) {
methodName, err := types.CmdMethod(cmd)
if err != nil {
Expand Down Expand Up @@ -161,23 +195,6 @@ func unmarshalPtr[T any](raw json.RawMessage) (*T, error) {
return &tt, nil

Check warning on line 195 in zetaclient/chains/bitcoin/client/client.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/bitcoin/client/client.go#L195

Added line #L195 was not covered by tests
}

func (c *Client) newRequest(ctx context.Context, body []byte) (*http.Request, error) {
payload := bytes.NewReader(body)

req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.hostURL, payload)
if err != nil {
return nil, err
}

req.Header.Set("Content-Type", "application/json")

if c.config.RPCPassword != "" || c.config.RPCUsername != "" {
req.SetBasicAuth(c.config.RPCUsername, c.config.RPCPassword)
}

return req, nil
}

func resolveParams(name string) (chains.Params, error) {
switch name {
case chains.MainNetParams.Name:
Expand Down
10 changes: 10 additions & 0 deletions zetaclient/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,16 @@ var (
},
[]string{"status", "task_group", "task_name"},
)

RPCClientDuration = promauto.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: ZetaClientNamespace,
Name: "rpc_client_duration_seconds",
Help: "Histogram of rpc client calls durations in seconds",
Buckets: []float64{0.05, 0.1, 0.2, 0.3, 0.5, 1, 1.5, 2, 3, 5, 7.5, 10, 15}, // 50ms to 15s
},
[]string{"status", "client", "method"},
)
)

// NewMetrics creates a new Metrics instance
Expand Down

0 comments on commit c6a8a68

Please sign in to comment.