core/metrics/helper.go
package metrics
import (
"context"
"fmt"
"github.com/ImVexed/fasturl"
"github.com/ethereum/go-ethereum/rpc"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"net/http"
"sync"
)
// logOnce ensures that log messages related to unsuppported clients are used only once.
var logOnce = sync.Once{}
const httpScheme = "http"
const httpsScheme = "https"
// RPCClient is a wrapper around rpc.Client that adds metrics/tracing.
func RPCClient(ctx context.Context, metrics Handler, url string, client *http.Client, opts ...otelhttp.Option) (*rpc.Client, error) {
u, err := fasturl.ParseURL(url)
if err != nil {
return nil, fmt.Errorf("could not parse url: %w", err)
}
switch u.Protocol {
case httpScheme, httpsScheme:
metrics.ConfigureHTTPClient(client, opts...)
rpcclient, err := rpc.DialHTTPWithClient(url, client)
if err != nil {
return nil, fmt.Errorf("could not dial http: %w", err)
}
return rpcclient, nil
default:
logOnce.Do(func() {
logger.Warnf("unsupported protocol: %s: only %s and %s are supported for metrics, future warnings will be surprssed", u.Protocol, httpScheme, httpsScheme)
})
//nolint: wrapcheck
return rpc.DialContext(ctx, url)
}
}