Skip to content

Commit a4cb757

Browse files
committed
Add healthcheck to archiver service
1 parent fb94a5e commit a4cb757

File tree

11 files changed

+115
-39
lines changed

11 files changed

+115
-39
lines changed

api/cmd/main.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
opservice "github.com/ethereum-optimism/optimism/op-service"
1414
"github.com/ethereum-optimism/optimism/op-service/cliapp"
1515
oplog "github.com/ethereum-optimism/optimism/op-service/log"
16-
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
1716
"github.com/ethereum/go-ethereum/log"
1817
"github.com/urfave/cli/v2"
1918
)
@@ -54,8 +53,7 @@ func Main() cliapp.LifecycleAction {
5453
oplog.SetGlobalLogHandler(l.GetHandler())
5554
opservice.ValidateEnvVars(flags.EnvVarPrefix, flags.Flags, l)
5655

57-
registry := opmetrics.NewRegistry()
58-
m := metrics.NewMetrics(registry)
56+
m := metrics.NewMetrics()
5957

6058
storageClient, err := storage.NewStorage(cfg.StorageConfig, l)
6159
if err != nil {
@@ -68,6 +66,7 @@ func Main() cliapp.LifecycleAction {
6866
}
6967

7068
l.Info("Initializing API Service")
71-
return service.NewAPIService(l, storageClient, beaconClient, cfg, registry, m), nil
69+
api := service.NewAPI(storageClient, beaconClient, m, l)
70+
return service.NewService(l, api, cfg, m.Registry()), nil
7271
}
7372
}

api/metrics/metrics.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package metrics
22

33
import (
44
"github.com/ethereum-optimism/optimism/op-service/metrics"
5+
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
56
"github.com/prometheus/client_golang/prometheus"
67
)
78

@@ -16,16 +17,20 @@ var (
1617
)
1718

1819
type Metricer interface {
20+
Registry() *prometheus.Registry
1921
RecordBlockIdType(t BlockIdType)
2022
}
2123

2224
type metricsRecorder struct {
2325
inputType *prometheus.CounterVec
26+
registry *prometheus.Registry
2427
}
2528

26-
func NewMetrics(registry *prometheus.Registry) Metricer {
29+
func NewMetrics() Metricer {
30+
registry := opmetrics.NewRegistry()
2731
factory := metrics.With(registry)
2832
return &metricsRecorder{
33+
registry: registry,
2934
inputType: factory.NewCounterVec(prometheus.CounterOpts{
3035
Namespace: MetricsNamespace,
3136
Name: "block_id_type",
@@ -37,3 +42,7 @@ func NewMetrics(registry *prometheus.Registry) Metricer {
3742
func (m *metricsRecorder) RecordBlockIdType(t BlockIdType) {
3843
m.inputType.WithLabelValues(string(t)).Inc()
3944
}
45+
46+
func (m *metricsRecorder) Registry() *prometheus.Registry {
47+
return m.registry
48+
}

api/service/api.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"github.com/ethereum/go-ethereum/log"
2323
"github.com/go-chi/chi/v5"
2424
"github.com/go-chi/chi/v5/middleware"
25-
"github.com/prometheus/client_golang/prometheus"
2625
)
2726

2827
type httpError struct {
@@ -77,7 +76,7 @@ type API struct {
7776
metrics m.Metricer
7877
}
7978

80-
func NewAPI(dataStoreClient storage.DataStoreReader, beaconClient client.BeaconBlockHeadersProvider, metrics m.Metricer, registry *prometheus.Registry, logger log.Logger) *API {
79+
func NewAPI(dataStoreClient storage.DataStoreReader, beaconClient client.BeaconBlockHeadersProvider, metrics m.Metricer, logger log.Logger) *API {
8180
result := &API{
8281
dataStoreClient: dataStoreClient,
8382
beaconClient: beaconClient,
@@ -92,7 +91,7 @@ func NewAPI(dataStoreClient storage.DataStoreReader, beaconClient client.BeaconB
9291
r.Use(middleware.Recoverer)
9392
r.Use(middleware.Heartbeat("/healthz"))
9493

95-
recorder := opmetrics.NewPromHTTPRecorder(registry, m.MetricsNamespace)
94+
recorder := opmetrics.NewPromHTTPRecorder(metrics.Registry(), m.MetricsNamespace)
9695
r.Use(func(handler http.Handler) http.Handler {
9796
return opmetrics.NewHTTPRecordingMiddleware(recorder, handler)
9897
})

api/service/api_test.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
"github.com/base-org/blob-archiver/common/beacon/beacontest"
1717
"github.com/base-org/blob-archiver/common/blobtest"
1818
"github.com/base-org/blob-archiver/common/storage"
19-
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
2019
"github.com/ethereum-optimism/optimism/op-service/testlog"
2120
"github.com/ethereum/go-ethereum/common"
2221
"github.com/ethereum/go-ethereum/log"
@@ -58,10 +57,9 @@ func setup(t *testing.T) (*API, *storage.FileStorage, *beacontest.StubBeaconClie
5857
require.NoError(t, err)
5958
fs := storage.NewFileStorage(tempDir, logger)
6059
beacon := beacontest.NewEmptyStubBeaconClient()
61-
r := opmetrics.NewRegistry()
62-
m := metrics.NewMetrics(r)
63-
api := NewAPI(fs, beacon, m, r, logger)
64-
return api, fs, beacon, func() {
60+
m := metrics.NewMetrics()
61+
a := NewAPI(fs, beacon, m, logger)
62+
return a, fs, beacon, func() {
6563
require.NoError(t, os.RemoveAll(tempDir))
6664
}
6765
}

api/service/service.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ import (
66
"fmt"
77
"sync/atomic"
88

9-
client "github.com/attestantio/go-eth2-client"
109
"github.com/base-org/blob-archiver/api/flags"
11-
"github.com/base-org/blob-archiver/api/metrics"
12-
"github.com/base-org/blob-archiver/common/storage"
1310
"github.com/ethereum-optimism/optimism/op-service/httputil"
1411
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
1512
"github.com/ethereum/go-ethereum/log"
@@ -18,13 +15,12 @@ import (
1815

1916
var ErrAlreadyStopped = errors.New("already stopped")
2017

21-
func NewAPIService(l log.Logger, dataStoreClient storage.DataStoreReader, beaconClient client.BeaconBlockHeadersProvider, cfg flags.APIConfig, registry *prometheus.Registry, m metrics.Metricer) *APIService {
22-
router := NewAPI(dataStoreClient, beaconClient, m, registry, l)
18+
func NewService(l log.Logger, api *API, cfg flags.APIConfig, registry *prometheus.Registry) *APIService {
2319
return &APIService{
2420
log: l,
2521
cfg: cfg,
2622
registry: registry,
27-
router: router,
23+
api: api,
2824
}
2925
}
3026

@@ -35,7 +31,7 @@ type APIService struct {
3531
registry *prometheus.Registry
3632
metricsServer *httputil.HTTPServer
3733
apiServer *httputil.HTTPServer
38-
router *API
34+
api *API
3935
}
4036

4137
func (a *APIService) Start(ctx context.Context) error {
@@ -52,7 +48,7 @@ func (a *APIService) Start(ctx context.Context) error {
5248

5349
a.log.Debug("starting API server", "address", a.cfg.ListenAddr)
5450

55-
srv, err := httputil.StartHTTPServer(a.cfg.ListenAddr, a.router.router)
51+
srv, err := httputil.StartHTTPServer(a.cfg.ListenAddr, a.api.router)
5652
if err != nil {
5753
return fmt.Errorf("failed to start API server: %w", err)
5854
}

archiver/cmd/main.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
opservice "github.com/ethereum-optimism/optimism/op-service"
1414
"github.com/ethereum-optimism/optimism/op-service/cliapp"
1515
oplog "github.com/ethereum-optimism/optimism/op-service/log"
16-
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
1716
"github.com/ethereum/go-ethereum/log"
1817
"github.com/urfave/cli/v2"
1918
)
@@ -55,8 +54,7 @@ func Main() cliapp.LifecycleAction {
5554
oplog.SetGlobalLogHandler(l.GetHandler())
5655
opservice.ValidateEnvVars(flags.EnvVarPrefix, flags.Flags, l)
5756

58-
registry := opmetrics.NewRegistry()
59-
m := metrics.NewMetrics(registry)
57+
m := metrics.NewMetrics()
6058

6159
beaconClient, err := beacon.NewBeaconClient(context.Background(), cfg.BeaconConfig)
6260
if err != nil {
@@ -69,6 +67,6 @@ func Main() cliapp.LifecycleAction {
6967
}
7068

7169
l.Info("Initializing Archiver Service")
72-
return service.NewArchiverService(l, cfg, storageClient, beaconClient, m, registry)
70+
return service.NewService(l, cfg, storageClient, beaconClient, m)
7371
}
7472
}

archiver/metrics/metrics.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,53 @@ package metrics
22

33
import (
44
"github.com/ethereum-optimism/optimism/op-service/metrics"
5+
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
56
"github.com/prometheus/client_golang/prometheus"
67
)
78

89
type BlockSource string
910

1011
var (
11-
metricsNamespace = "blob_archiver"
12+
MetricsNamespace = "blob_archiver"
1213

1314
BlockSourceBackfill BlockSource = "backfill"
1415
BlockSourceLive BlockSource = "live"
1516
)
1617

1718
type Metricer interface {
19+
Registry() *prometheus.Registry
1820
RecordProcessedBlock(source BlockSource)
1921
RecordStoredBlobs(count int)
2022
}
2123

2224
type metricsRecorder struct {
2325
blockProcessedCounter *prometheus.CounterVec
2426
blobsStored prometheus.Counter
27+
registry *prometheus.Registry
2528
}
2629

27-
func NewMetrics(registry *prometheus.Registry) Metricer {
30+
func NewMetrics() Metricer {
31+
registry := opmetrics.NewRegistry()
2832
factory := metrics.With(registry)
2933
return &metricsRecorder{
34+
registry: registry,
3035
blockProcessedCounter: factory.NewCounterVec(prometheus.CounterOpts{
31-
Namespace: metricsNamespace,
36+
Namespace: MetricsNamespace,
3237
Name: "blocks_processed",
3338
Help: "number of times processing loop has run",
3439
}, []string{"source"}),
3540
blobsStored: factory.NewCounter(prometheus.CounterOpts{
36-
Namespace: metricsNamespace,
41+
Namespace: MetricsNamespace,
3742
Name: "blobs_stored",
3843
Help: "number of blobs stored",
3944
}),
4045
}
4146
}
4247

48+
func (m *metricsRecorder) Registry() *prometheus.Registry {
49+
return m.registry
50+
}
51+
4352
func (m *metricsRecorder) RecordStoredBlobs(count int) {
4453
m.blobsStored.Add(float64(count))
4554
}

archiver/service/api.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package service
2+
3+
import (
4+
"net/http"
5+
"time"
6+
7+
m "github.com/base-org/blob-archiver/archiver/metrics"
8+
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
9+
"github.com/ethereum/go-ethereum/log"
10+
"github.com/go-chi/chi/v5"
11+
"github.com/go-chi/chi/v5/middleware"
12+
)
13+
14+
const (
15+
serverTimeout = 60 * time.Second
16+
)
17+
18+
type API struct {
19+
router *chi.Mux
20+
logger log.Logger
21+
metrics m.Metricer
22+
}
23+
24+
func NewAPI(metrics m.Metricer, logger log.Logger) *API {
25+
result := &API{
26+
router: chi.NewRouter(),
27+
logger: logger,
28+
metrics: metrics,
29+
}
30+
31+
r := result.router
32+
r.Use(middleware.Logger)
33+
r.Use(middleware.Timeout(serverTimeout))
34+
r.Use(middleware.Recoverer)
35+
r.Use(middleware.Heartbeat("/healthz"))
36+
37+
recorder := opmetrics.NewPromHTTPRecorder(metrics.Registry(), m.MetricsNamespace)
38+
r.Use(func(handler http.Handler) http.Handler {
39+
return opmetrics.NewHTTPRecordingMiddleware(recorder, handler)
40+
})
41+
42+
r.Get("/", http.NotFound)
43+
44+
return result
45+
}

archiver/service/api_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package service
2+
3+
import (
4+
"net/http/httptest"
5+
"testing"
6+
7+
"github.com/base-org/blob-archiver/archiver/metrics"
8+
"github.com/ethereum-optimism/optimism/op-service/testlog"
9+
"github.com/ethereum/go-ethereum/log"
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
func setupAPI(t *testing.T) *API {
14+
logger := testlog.Logger(t, log.LvlInfo)
15+
m := metrics.NewMetrics()
16+
return NewAPI(m, logger)
17+
}
18+
19+
func TestHealthHandler(t *testing.T) {
20+
a := setupAPI(t)
21+
22+
request := httptest.NewRequest("GET", "/healthz", nil)
23+
response := httptest.NewRecorder()
24+
25+
a.router.ServeHTTP(response, request)
26+
27+
require.Equal(t, 200, response.Code)
28+
}

archiver/service/archiver.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics"
1717
"github.com/ethereum/go-ethereum/common"
1818
"github.com/ethereum/go-ethereum/log"
19-
"github.com/prometheus/client_golang/prometheus"
2019
)
2120

2221
const backfillErrorRetryInterval = 5 * time.Second
@@ -28,11 +27,10 @@ type BeaconClient interface {
2827
client.BeaconBlockHeadersProvider
2928
}
3029

31-
func NewArchiverService(l log.Logger, cfg flags.ArchiverConfig, dataStoreClient storage.DataStore, client BeaconClient, m metrics.Metricer, registry *prometheus.Registry) (*ArchiverService, error) {
30+
func NewService(l log.Logger, cfg flags.ArchiverConfig, dataStoreClient storage.DataStore, client BeaconClient, m metrics.Metricer) (*ArchiverService, error) {
3231
return &ArchiverService{
3332
log: l,
3433
cfg: cfg,
35-
registry: registry,
3634
dataStoreClient: dataStoreClient,
3735
metrics: m,
3836
stopCh: make(chan struct{}),
@@ -46,7 +44,6 @@ type ArchiverService struct {
4644
log log.Logger
4745
dataStoreClient storage.DataStore
4846
beaconClient BeaconClient
49-
registry *prometheus.Registry
5047
metricsServer *httputil.HTTPServer
5148
cfg flags.ArchiverConfig
5249
metrics metrics.Metricer
@@ -55,7 +52,7 @@ type ArchiverService struct {
5552
func (a *ArchiverService) Start(ctx context.Context) error {
5653
if a.cfg.MetricsConfig.Enabled {
5754
a.log.Info("starting metrics server", "addr", a.cfg.MetricsConfig.ListenAddr, "port", a.cfg.MetricsConfig.ListenPort)
58-
srv, err := opmetrics.StartServer(a.registry, a.cfg.MetricsConfig.ListenAddr, a.cfg.MetricsConfig.ListenPort)
55+
srv, err := opmetrics.StartServer(a.metrics.Registry(), a.cfg.MetricsConfig.ListenAddr, a.cfg.MetricsConfig.ListenPort)
5956
if err != nil {
6057
return err
6158
}

0 commit comments

Comments
 (0)