Skip to content

Commit

Permalink
Merge pull request #8 from ethpandaops/feat/instrument-api-jobs
Browse files Browse the repository at this point in the history
Feat/instrument api jobs
  • Loading branch information
Savid authored Oct 4, 2022
2 parents 71521ef + 371496e commit 96bfe10
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 5 deletions.
29 changes: 26 additions & 3 deletions pkg/exporter/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ type executionClient struct {
log logrus.FieldLogger
client http.Client
headers map[string]string

metrics Metrics
}

// NewExecutionClient creates a new ExecutionClient.
func NewExecutionClient(log logrus.FieldLogger, url string, headers map[string]string, timeout time.Duration) ExecutionClient {
func NewExecutionClient(log logrus.FieldLogger, namespace, url string, headers map[string]string, timeout time.Duration) ExecutionClient {
client := http.Client{
Timeout: timeout,
}
Expand All @@ -46,6 +48,8 @@ func NewExecutionClient(log logrus.FieldLogger, url string, headers map[string]s
log: log,
client: client,
headers: headers,

metrics: NewMetrics(fmt.Sprintf("%s_%s", namespace, "http")),
}
}

Expand All @@ -57,6 +61,25 @@ type apiResponse struct {

//nolint:unparam // ctx will probably be used in the future
func (e *executionClient) post(method string, params interface{}, id int) (json.RawMessage, error) {
start := time.Now()

httpMethod := "POST"

e.metrics.ObserveRequest(httpMethod, e.url, method)

var rsp *http.Response

var err error

defer func() {
rspCode := "none"
if rsp != nil {
rspCode = fmt.Sprintf("%d", rsp.StatusCode)
}

e.metrics.ObserveResponse(httpMethod, e.url, method, rspCode, time.Since(start))
}()

body := map[string]interface{}{
"jsonrpc": "2.0",
"method": method,
Expand All @@ -69,7 +92,7 @@ func (e *executionClient) post(method string, params interface{}, id int) (json.
return nil, err
}

req, err := http.NewRequest("POST", e.url, bytes.NewBuffer(jsonData))
req, err := http.NewRequest(httpMethod, e.url, bytes.NewBuffer(jsonData))
if err != nil {
return nil, err
}
Expand All @@ -80,7 +103,7 @@ func (e *executionClient) post(method string, params interface{}, id int) (json.

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

rsp, err := e.client.Do(req)
rsp, err = e.client.Do(req)
if err != nil {
return nil, err
}
Expand Down
49 changes: 49 additions & 0 deletions pkg/exporter/api/metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package api

import (
"time"

"github.com/prometheus/client_golang/prometheus"
)

type Metrics struct {
requests *prometheus.CounterVec
responses *prometheus.CounterVec
requestDuration *prometheus.HistogramVec
}

func NewMetrics(namespace string) Metrics {
m := Metrics{
requests: prometheus.NewCounterVec(prometheus.CounterOpts{
Namespace: namespace,
Name: "request_count",
Help: "Number of requests",
}, []string{"method", "path", "api_method"}),
responses: prometheus.NewCounterVec(prometheus.CounterOpts{
Namespace: namespace,
Name: "response_count",
Help: "Number of responses",
}, []string{"method", "path", "api_method", "code"}),
requestDuration: prometheus.NewHistogramVec(prometheus.HistogramOpts{
Namespace: namespace,
Name: "request_duration_seconds",
Help: "Request duration (in seconds.)",
Buckets: []float64{0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10},
}, []string{"method", "path", "api_method", "code"}),
}

prometheus.MustRegister(m.requests)
prometheus.MustRegister(m.responses)
prometheus.MustRegister(m.requestDuration)

return m
}

func (m Metrics) ObserveRequest(method, path, apiMethod string) {
m.requests.WithLabelValues(method, path, apiMethod).Inc()
}

func (m Metrics) ObserveResponse(method, path, apiMethod, code string, duration time.Duration) {
m.responses.WithLabelValues(method, path, apiMethod, code).Inc()
m.requestDuration.WithLabelValues(method, path, apiMethod, code).Observe(duration.Seconds())
}
2 changes: 1 addition & 1 deletion pkg/exporter/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type exporter struct {
func (e *exporter) Start(ctx context.Context) error {
e.log.Info("Initializing...")

e.execution = api.NewExecutionClient(e.log, e.Cfg.Execution.URL, e.Cfg.Execution.Headers, e.Cfg.Execution.Timeout)
e.execution = api.NewExecutionClient(e.log, e.Cfg.GlobalConfig.Namespace, e.Cfg.Execution.URL, e.Cfg.Execution.Headers, e.Cfg.Execution.Timeout)

e.metrics = NewMetrics(e.execution, e.log, e.Cfg.GlobalConfig.Namespace, e.Cfg.GlobalConfig.Labels, &e.Cfg.Addresses)

Expand Down
19 changes: 19 additions & 0 deletions pkg/exporter/jobs/chainlink_data_feed.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type ChainlinkDataFeed struct {
client api.ExecutionClient
log logrus.FieldLogger
ChainlinkDataFeedBalance prometheus.GaugeVec
ChainlinkDataFeedError prometheus.CounterVec
addresses []*AddressChainlinkDataFeed
labelsMap map[string]int
}
Expand Down Expand Up @@ -72,9 +73,19 @@ func NewChainlinkDataFeed(client api.ExecutionClient, log logrus.FieldLogger, na
},
labels,
),
ChainlinkDataFeedError: *prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: namespace,
Name: "errors_total",
Help: "The total errors when getting the balance of a ethereum chainlink data feed contract.",
ConstLabels: constLabels,
},
labels,
),
}

prometheus.MustRegister(instance.ChainlinkDataFeedBalance)
prometheus.MustRegister(instance.ChainlinkDataFeedError)

return instance
}
Expand Down Expand Up @@ -129,6 +140,14 @@ func (n *ChainlinkDataFeed) getLabelValues(address *AddressChainlinkDataFeed) []
}

func (n *ChainlinkDataFeed) getBalance(address *AddressChainlinkDataFeed) error {
var err error

defer func() {
if err != nil {
n.ChainlinkDataFeedError.WithLabelValues(n.getLabelValues(address)...).Inc()
}
}()

// call latestAnswer() which is 0x50d25bcd
latestAnswerData := "0x50d25bcd000000000000000000000000"

Expand Down
19 changes: 19 additions & 0 deletions pkg/exporter/jobs/eoa.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type EOA struct {
client api.ExecutionClient
log logrus.FieldLogger
EOABalance prometheus.GaugeVec
EOAError prometheus.CounterVec
addresses []*AddressEOA
labelsMap map[string]int
}
Expand Down Expand Up @@ -67,9 +68,19 @@ func NewEOA(client api.ExecutionClient, log logrus.FieldLogger, namespace string
},
labels,
),
EOAError: *prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: namespace,
Name: "errors_total",
Help: "The total errors when getting the balance of a ethereum externally owned account address.",
ConstLabels: constLabels,
},
labels,
),
}

prometheus.MustRegister(instance.EOABalance)
prometheus.MustRegister(instance.EOAError)

return instance
}
Expand Down Expand Up @@ -120,6 +131,14 @@ func (n *EOA) getLabelValues(address *AddressEOA) []string {
}

func (n *EOA) getBalance(address *AddressEOA) error {
var err error

defer func() {
if err != nil {
n.EOAError.WithLabelValues(n.getLabelValues(address)...).Inc()
}
}()

balance, err := n.client.ETHGetBalance(address.Address, "latest")
if err != nil {
return err
Expand Down
19 changes: 19 additions & 0 deletions pkg/exporter/jobs/erc1155.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type ERC1155 struct {
client api.ExecutionClient
log logrus.FieldLogger
ERC1155Balance prometheus.GaugeVec
ERC1155Error prometheus.CounterVec
addresses []*AddressERC1155
labelsMap map[string]int
}
Expand Down Expand Up @@ -74,9 +75,19 @@ func NewERC1155(client api.ExecutionClient, log logrus.FieldLogger, namespace st
},
labels,
),
ERC1155Error: *prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: namespace,
Name: "errors_total",
Help: "The total errors when getting the balance of a ethereum ERC115 contract by address and token id.",
ConstLabels: constLabels,
},
labels,
),
}

prometheus.MustRegister(instance.ERC1155Balance)
prometheus.MustRegister(instance.ERC1155Error)

return instance
}
Expand Down Expand Up @@ -131,6 +142,14 @@ func (n *ERC1155) getLabelValues(address *AddressERC1155) []string {
}

func (n *ERC1155) getBalance(address *AddressERC1155) error {
var err error

defer func() {
if err != nil {
n.ERC1155Error.WithLabelValues(n.getLabelValues(address)...).Inc()
}
}()

// call balanceOf(address,uint256) which is 0x00fdd58e
balanceOfData := "0x00fdd58e000000000000000000000000" + address.Address[2:] + fmt.Sprintf("%064x", &address.TokenID)

Expand Down
23 changes: 22 additions & 1 deletion pkg/exporter/jobs/erc20.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type ERC20 struct {
client api.ExecutionClient
log logrus.FieldLogger
ERC20Balance prometheus.GaugeVec
ERC20Error prometheus.CounterVec
addresses []*AddressERC20
labelsMap map[string]int
}
Expand Down Expand Up @@ -71,9 +72,19 @@ func NewERC20(client api.ExecutionClient, log logrus.FieldLogger, namespace stri
},
labels,
),
ERC20Error: *prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: namespace,
Name: "errors_total",
Help: "The total errors when getting the balance of a ethereum ERC20 contract by address.",
ConstLabels: constLabels,
},
labels,
),
}

prometheus.MustRegister(instance.ERC20Balance)
prometheus.MustRegister(instance.ERC20Error)

return instance
}
Expand Down Expand Up @@ -128,6 +139,16 @@ func (n *ERC20) getLabelValues(address *AddressERC20, symbol string) []string {
}

func (n *ERC20) getBalance(address *AddressERC20) error {
var err error

symbol := ""

defer func() {
if err != nil {
n.ERC20Error.WithLabelValues(n.getLabelValues(address, symbol)...).Inc()
}
}()

// call balanceOf(address) which is 0x70a08231
balanceOfData := "0x70a08231000000000000000000000000" + address.Address[2:]

Expand All @@ -150,7 +171,7 @@ func (n *ERC20) getBalance(address *AddressERC20) error {
return err
}

symbol, err := hexStringToString(symbolHex)
symbol, err = hexStringToString(symbolHex)
if err != nil {
return err
}
Expand Down
19 changes: 19 additions & 0 deletions pkg/exporter/jobs/erc721.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type ERC721 struct {
client api.ExecutionClient
log logrus.FieldLogger
ERC721Balance prometheus.GaugeVec
ERC721Error prometheus.CounterVec
addresses []*AddressERC721
labelsMap map[string]int
}
Expand Down Expand Up @@ -70,9 +71,19 @@ func NewERC721(client api.ExecutionClient, log logrus.FieldLogger, namespace str
},
labels,
),
ERC721Error: *prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: namespace,
Name: "errors_total",
Help: "The total errors when getting the balance of a ethereum ERC721 contract by address.",
ConstLabels: constLabels,
},
labels,
),
}

prometheus.MustRegister(instance.ERC721Balance)
prometheus.MustRegister(instance.ERC721Error)

return instance
}
Expand Down Expand Up @@ -125,6 +136,14 @@ func (n *ERC721) getLabelValues(address *AddressERC721) []string {
}

func (n *ERC721) getBalance(address *AddressERC721) error {
var err error

defer func() {
if err != nil {
n.ERC721Error.WithLabelValues(n.getLabelValues(address)...).Inc()
}
}()

// call balanceOf(address) which is 0x70a08231
balanceOfData := "0x70a08231000000000000000000000000" + address.Address[2:]

Expand Down
19 changes: 19 additions & 0 deletions pkg/exporter/jobs/uniswap_pair.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type UniswapPair struct {
client api.ExecutionClient
log logrus.FieldLogger
UniswapPairBalance prometheus.GaugeVec
UniswapPairError prometheus.CounterVec
addresses []*AddressUniswapPair
labelsMap map[string]int
}
Expand Down Expand Up @@ -72,9 +73,19 @@ func NewUniswapPair(client api.ExecutionClient, log logrus.FieldLogger, namespac
},
labels,
),
UniswapPairError: *prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: namespace,
Name: "errors_total",
Help: "The total errors when getting the balance of a ethereum uniswap pair contract.",
ConstLabels: constLabels,
},
labels,
),
}

prometheus.MustRegister(instance.UniswapPairBalance)
prometheus.MustRegister(instance.UniswapPairError)

return instance
}
Expand Down Expand Up @@ -129,6 +140,14 @@ func (n *UniswapPair) getLabelValues(address *AddressUniswapPair) []string {
}

func (n *UniswapPair) getBalance(address *AddressUniswapPair) error {
var err error

defer func() {
if err != nil {
n.UniswapPairError.WithLabelValues(n.getLabelValues(address)...).Inc()
}
}()

// call getReserves() which is 0x0902f1ac
getReservesData := "0x0902f1ac000000000000000000000000"

Expand Down

0 comments on commit 96bfe10

Please sign in to comment.