Skip to content

Commit 35cd3dd

Browse files
authored
fix(nodebuilder/p2p/metrics): enforce init order for bitswap metrics (#3763)
1 parent f875256 commit 35cd3dd

File tree

3 files changed

+56
-8
lines changed

3 files changed

+56
-8
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ require (
4242
github.com/ipfs/go-ipld-cbor v0.1.0
4343
github.com/ipfs/go-ipld-format v0.6.0
4444
github.com/ipfs/go-log/v2 v2.5.1
45+
github.com/ipfs/go-metrics-interface v0.0.1
4546
github.com/ipfs/go-metrics-prometheus v0.0.2
4647
github.com/ipld/go-car v0.6.2
4748
github.com/libp2p/go-libp2p v0.36.2
@@ -213,7 +214,6 @@ require (
213214
github.com/ipfs/go-ipld-legacy v0.2.1 // indirect
214215
github.com/ipfs/go-log v1.0.5 // indirect
215216
github.com/ipfs/go-merkledag v0.11.0 // indirect
216-
github.com/ipfs/go-metrics-interface v0.0.1 // indirect
217217
github.com/ipfs/go-peertaskqueue v0.8.1 // indirect
218218
github.com/ipfs/go-verifcid v0.0.3 // indirect
219219
github.com/ipld/go-car/v2 v2.13.1 // indirect

nodebuilder/p2p/bitswap.go

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ import (
99
"github.com/ipfs/boxo/blockstore"
1010
"github.com/ipfs/boxo/exchange"
1111
"github.com/ipfs/go-datastore"
12-
metrics "github.com/ipfs/go-metrics-prometheus"
12+
ipfsmetrics "github.com/ipfs/go-metrics-interface"
13+
ipfsprom "github.com/ipfs/go-metrics-prometheus"
1314
routinghelpers "github.com/libp2p/go-libp2p-routing-helpers"
1415
hst "github.com/libp2p/go-libp2p/core/host"
1516
"github.com/libp2p/go-libp2p/core/protocol"
17+
"github.com/prometheus/client_golang/prometheus"
1618
"go.uber.org/fx"
1719

1820
"github.com/celestiaorg/celestia-node/share/eds"
@@ -43,7 +45,14 @@ func dataExchange(params bitSwapParams) exchange.Interface {
4345
bitswap.SetSimulateDontHavesOnTimeout(false),
4446
bitswap.WithoutDuplicatedBlockStats(),
4547
}
46-
bs := bitswap.New(params.Ctx, net, params.Bs, opts...)
48+
49+
ctx := params.Ctx
50+
if params.Metrics != nil {
51+
// metrics scope is required for prometheus metrics and will be used as metrics name
52+
// prefix
53+
ctx = ipfsmetrics.CtxScope(ctx, "bitswap")
54+
}
55+
bs := bitswap.New(ctx, net, params.Bs, opts...)
4756

4857
params.Lifecycle.Append(fx.Hook{
4958
OnStop: func(_ context.Context) (err error) {
@@ -53,7 +62,16 @@ func dataExchange(params bitSwapParams) exchange.Interface {
5362
return bs
5463
}
5564

56-
func blockstoreFromDatastore(ctx context.Context, ds datastore.Batching) (blockstore.Blockstore, error) {
65+
func blockstoreFromDatastore(
66+
ctx context.Context,
67+
ds datastore.Batching,
68+
b blockstoreParams,
69+
) (blockstore.Blockstore, error) {
70+
if b.Metrics != nil {
71+
// metrics scope is required for prometheus metrics and will be used as metrics name
72+
// prefix
73+
ctx = ipfsmetrics.CtxScope(ctx, "blockstore")
74+
}
5775
return blockstore.CachedBlockstore(
5876
ctx,
5977
blockstore.NewBlockstore(ds),
@@ -65,7 +83,16 @@ func blockstoreFromDatastore(ctx context.Context, ds datastore.Batching) (blocks
6583
)
6684
}
6785

68-
func blockstoreFromEDSStore(ctx context.Context, store *eds.Store) (blockstore.Blockstore, error) {
86+
func blockstoreFromEDSStore(
87+
ctx context.Context,
88+
store *eds.Store,
89+
b blockstoreParams,
90+
) (blockstore.Blockstore, error) {
91+
if b.Metrics != nil {
92+
// metrics scope is required for prometheus metrics and will be used as metrics name
93+
// prefix
94+
ctx = ipfsmetrics.CtxScope(ctx, "blockstore")
95+
}
6996
return blockstore.CachedBlockstore(
7097
ctx,
7198
store.Blockstore(),
@@ -75,6 +102,13 @@ func blockstoreFromEDSStore(ctx context.Context, store *eds.Store) (blockstore.B
75102
)
76103
}
77104

105+
type blockstoreParams struct {
106+
fx.In
107+
// Metrics is unused, it is in dependency graph to ensure that prometheus metrics are enabled before bitswap
108+
// is started.
109+
Metrics *bitswapMetrics `optional:"true"`
110+
}
111+
78112
type bitSwapParams struct {
79113
fx.In
80114

@@ -83,12 +117,22 @@ type bitSwapParams struct {
83117
Net Network
84118
Host hst.Host
85119
Bs blockstore.Blockstore
120+
// Metrics is unused, it is in dependency graph to ensure that prometheus metrics are enabled before bitswap
121+
// is started.
122+
Metrics *bitswapMetrics `optional:"true"`
86123
}
87124

88125
func protocolID(network Network) protocol.ID {
89126
return protocol.ID(fmt.Sprintf("/celestia/%s", network))
90127
}
91128

92-
func enableBitswapMetrics() {
93-
_ = metrics.Inject()
129+
type bitswapMetrics struct{}
130+
131+
func enableBitswapMetrics(_ prometheus.Registerer) *bitswapMetrics {
132+
err := ipfsprom.Inject()
133+
if err != nil {
134+
log.Errorf("failed to inject bitswap metrics: %s", err)
135+
return nil
136+
}
137+
return &bitswapMetrics{}
94138
}

nodebuilder/p2p/metrics.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func WithMetrics() fx.Option {
1919
return fx.Options(
2020
fx.Provide(resourceManagerOpt(traceReporter)),
2121
fx.Provide(prometheusMetrics),
22-
fx.Invoke(enableBitswapMetrics),
22+
fx.Provide(enableBitswapMetrics),
2323
)
2424
}
2525

@@ -45,6 +45,10 @@ func prometheusMetrics(lifecycle fx.Lifecycle,
4545
peerIDLabel: peerID.String(),
4646
}
4747
wrapped := prometheus.WrapRegistererWith(labels, reg)
48+
// Set the default global registerer to the wrapped one with labels. This way all the metrics
49+
// registered with the default registerer will be labeled with the provided labels. It is important
50+
// because unlike libp2p metrics, bitswap metrics are registered with the default global registerer.
51+
prometheus.DefaultRegisterer = wrapped
4852

4953
mux := http.NewServeMux()
5054
handler := promhttp.HandlerFor(reg, promhttp.HandlerOpts{Registry: wrapped})

0 commit comments

Comments
 (0)