Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: export ipfs_p2p metrics like Kubo does #32

Merged
merged 1 commit into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@
}
fmt.Printf("PeerID: %s\n\n", pid)
registerVersionMetric(version)
registerIpfsNodeCollector(gnd)

Check warning on line 313 in main.go

View check run for this annotation

Codecov / codecov/patch

main.go#L313

Added line #L313 was not covered by tests

tp, shutdown, err := newTracerProvider(cctx.Context)
if err != nil {
Expand Down
55 changes: 55 additions & 0 deletions metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,58 @@

return handler
}

var peersTotalMetric = prometheus.NewDesc(
prometheus.BuildFQName("ipfs", "p2p", "peers_total"),
"Number of connected peers",
[]string{"transport"},
nil,
)

// IpfsNodeCollector collects peer metrics
type IpfsNodeCollector struct {
Node *Node
}

func (IpfsNodeCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- peersTotalMetric

Check warning on line 116 in metrics.go

View check run for this annotation

Codecov / codecov/patch

metrics.go#L115-L116

Added lines #L115 - L116 were not covered by tests
}

func (c IpfsNodeCollector) Collect(ch chan<- prometheus.Metric) {
for tr, val := range c.PeersTotalValues() {
ch <- prometheus.MustNewConstMetric(
peersTotalMetric,
prometheus.GaugeValue,
val,
tr,
)
}

Check warning on line 127 in metrics.go

View check run for this annotation

Codecov / codecov/patch

metrics.go#L119-L127

Added lines #L119 - L127 were not covered by tests
}

func (c IpfsNodeCollector) PeersTotalValues() map[string]float64 {
vals := make(map[string]float64)
if c.Node.host == nil {
return vals
}
for _, peerID := range c.Node.host.Network().Peers() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we only want the data transfer peers or, also the DHT peers. Since they are (optionally) on different hosts we may need to check there as well. If both do we want to deduplicate by peerID?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aschmahmann good point.

Now, I would like to compare perf between using a single host and using two hosts. I'm not sure it makes a difference tbh. Would you be ok with using a single host for everything if thunderdome shows it is not worse?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with one host if behavior looks the same (i.e. if it's less complexity for a similar result).

IIUC this metric just tracks the peers we're connected to, not other things like bandwidth. Not sure how those are currently set up given two hosts.

// Each peer may have more than one connection (see for an explanation
// https://github.com/libp2p/go-libp2p-swarm/commit/0538806), so we grab
// only one, the first (an arbitrary and non-deterministic choice), which
// according to ConnsToPeer is the oldest connection in the list
// (https://github.com/libp2p/go-libp2p-swarm/blob/v0.2.6/swarm.go#L362-L364).
conns := c.Node.host.Network().ConnsToPeer(peerID)
if len(conns) == 0 {
continue

Check warning on line 143 in metrics.go

View check run for this annotation

Codecov / codecov/patch

metrics.go#L130-L143

Added lines #L130 - L143 were not covered by tests
}
tr := ""
for _, proto := range conns[0].RemoteMultiaddr().Protocols() {
tr = tr + "/" + proto.Name
}
vals[tr] = vals[tr] + 1

Check warning on line 149 in metrics.go

View check run for this annotation

Codecov / codecov/patch

metrics.go#L145-L149

Added lines #L145 - L149 were not covered by tests
}
return vals

Check warning on line 151 in metrics.go

View check run for this annotation

Codecov / codecov/patch

metrics.go#L151

Added line #L151 was not covered by tests
}

func registerIpfsNodeCollector(nd *Node) {
prometheus.MustRegister(&IpfsNodeCollector{Node: nd})

Check warning on line 155 in metrics.go

View check run for this annotation

Codecov / codecov/patch

metrics.go#L154-L155

Added lines #L154 - L155 were not covered by tests
}
Loading