identify: add some basic metrics (#2069)
This commit is contained in:
parent
a8d6111ba9
commit
5f8fe94f90
|
@ -230,12 +230,14 @@ func NewHost(n network.Network, opts *HostOpts) (*BasicHost, error) {
|
|||
identify.UserAgent(opts.UserAgent),
|
||||
identify.ProtocolVersion(opts.ProtocolVersion),
|
||||
identify.DisableSignedPeerRecord(),
|
||||
identify.WithMetricsTracer(identify.NewMetricsTracer()),
|
||||
)
|
||||
} else {
|
||||
h.ids, err = identify.NewIDService(
|
||||
h,
|
||||
identify.UserAgent(opts.UserAgent),
|
||||
identify.ProtocolVersion(opts.ProtocolVersion),
|
||||
identify.WithMetricsTracer(identify.NewMetricsTracer()),
|
||||
)
|
||||
}
|
||||
if err != nil {
|
||||
|
|
|
@ -8,8 +8,9 @@ import (
|
|||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const metricNamespace = "libp2p_rcmgr"
|
||||
|
||||
var (
|
||||
metricNamespace = "libp2p_rcmgr"
|
||||
|
||||
// Conns
|
||||
conns = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package metricshelper
|
||||
|
||||
import "github.com/libp2p/go-libp2p/core/network"
|
||||
|
||||
func GetDirection(dir network.Direction) string {
|
||||
switch dir {
|
||||
case network.DirOutbound:
|
||||
return "outbound"
|
||||
case network.DirInbound:
|
||||
return "inbound"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
|
@ -94,17 +94,6 @@ func NewMetricsTracer() *metricsTracer {
|
|||
return &metricsTracer{}
|
||||
}
|
||||
|
||||
func getDirection(dir network.Direction) string {
|
||||
switch dir {
|
||||
case network.DirOutbound:
|
||||
return "outbound"
|
||||
case network.DirInbound:
|
||||
return "inbound"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
func appendConnectionState(tags []string, cs network.ConnectionState) []string {
|
||||
if cs.Transport == "" {
|
||||
// This shouldn't happen, unless the transport doesn't properly set the Transport field in the ConnectionState.
|
||||
|
@ -123,12 +112,12 @@ func (m *metricsTracer) OpenedConnection(dir network.Direction, p crypto.PubKey,
|
|||
tags := metricshelper.GetStringSlice()
|
||||
defer metricshelper.PutStringSlice(tags)
|
||||
|
||||
*tags = append(*tags, getDirection(dir))
|
||||
*tags = append(*tags, metricshelper.GetDirection(dir))
|
||||
*tags = appendConnectionState(*tags, cs)
|
||||
connsOpened.WithLabelValues(*tags...).Inc()
|
||||
|
||||
*tags = (*tags)[:0]
|
||||
*tags = append(*tags, getDirection(dir))
|
||||
*tags = append(*tags, metricshelper.GetDirection(dir))
|
||||
*tags = append(*tags, p.Type().String())
|
||||
keyTypes.WithLabelValues(*tags...).Inc()
|
||||
}
|
||||
|
@ -137,12 +126,12 @@ func (m *metricsTracer) ClosedConnection(dir network.Direction, duration time.Du
|
|||
tags := metricshelper.GetStringSlice()
|
||||
defer metricshelper.PutStringSlice(tags)
|
||||
|
||||
*tags = append(*tags, getDirection(dir))
|
||||
*tags = append(*tags, metricshelper.GetDirection(dir))
|
||||
*tags = appendConnectionState(*tags, cs)
|
||||
connsClosed.WithLabelValues(*tags...).Inc()
|
||||
|
||||
*tags = (*tags)[:0]
|
||||
*tags = append(*tags, getDirection(dir))
|
||||
*tags = append(*tags, metricshelper.GetDirection(dir))
|
||||
*tags = appendConnectionState(*tags, cs)
|
||||
connDuration.WithLabelValues(*tags...).Observe(duration.Seconds())
|
||||
}
|
||||
|
|
|
@ -0,0 +1,355 @@
|
|||
{
|
||||
"__inputs": [
|
||||
{
|
||||
"name": "DS_PROMETHEUS",
|
||||
"label": "Prometheus",
|
||||
"description": "",
|
||||
"type": "datasource",
|
||||
"pluginId": "prometheus",
|
||||
"pluginName": "Prometheus"
|
||||
}
|
||||
],
|
||||
"__elements": {},
|
||||
"__requires": [
|
||||
{
|
||||
"type": "grafana",
|
||||
"id": "grafana",
|
||||
"name": "Grafana",
|
||||
"version": "9.3.6"
|
||||
},
|
||||
{
|
||||
"type": "datasource",
|
||||
"id": "prometheus",
|
||||
"name": "Prometheus",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"type": "panel",
|
||||
"id": "timeseries",
|
||||
"name": "Time series",
|
||||
"version": ""
|
||||
}
|
||||
],
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": {
|
||||
"type": "grafana",
|
||||
"uid": "-- Grafana --"
|
||||
},
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"target": {
|
||||
"limit": 100,
|
||||
"matchAny": false,
|
||||
"tags": [],
|
||||
"type": "dashboard"
|
||||
},
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"id": null,
|
||||
"links": [],
|
||||
"liveNow": false,
|
||||
"panels": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_PROMETHEUS}"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"axisCenteredZero": false,
|
||||
"axisColorMode": "text",
|
||||
"axisLabel": "",
|
||||
"axisPlacement": "auto",
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
},
|
||||
"lineInterpolation": "linear",
|
||||
"lineWidth": 1,
|
||||
"pointSize": 5,
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
},
|
||||
"showPoints": "auto",
|
||||
"spanNulls": false,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "off"
|
||||
}
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "multi",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_PROMETHEUS}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "rate(libp2p_identify_identify_total[$__rate_interval])",
|
||||
"legendFormat": "{{dir}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Identify Messages",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_PROMETHEUS}"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"axisCenteredZero": false,
|
||||
"axisColorMode": "text",
|
||||
"axisLabel": "",
|
||||
"axisPlacement": "auto",
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
},
|
||||
"lineInterpolation": "linear",
|
||||
"lineWidth": 1,
|
||||
"pointSize": 5,
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
},
|
||||
"showPoints": "auto",
|
||||
"spanNulls": false,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "off"
|
||||
}
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
},
|
||||
"id": 5,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "multi",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_PROMETHEUS}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "rate(libp2p_identify_identify_push_total[$__rate_interval])",
|
||||
"legendFormat": "{{dir}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Identify Push Messages",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_PROMETHEUS}"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"axisCenteredZero": false,
|
||||
"axisColorMode": "text",
|
||||
"axisLabel": "",
|
||||
"axisPlacement": "auto",
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 0,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
},
|
||||
"lineInterpolation": "linear",
|
||||
"lineWidth": 1,
|
||||
"pointSize": 5,
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
},
|
||||
"showPoints": "auto",
|
||||
"spanNulls": false,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "off"
|
||||
}
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 8
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
"placement": "bottom",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "multi",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_PROMETHEUS}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "rate(libp2p_identify_identify_pushes_triggered_total[$__rate_interval])",
|
||||
"legendFormat": "{{trigger}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Pushes triggered",
|
||||
"type": "timeseries"
|
||||
}
|
||||
],
|
||||
"schemaVersion": 37,
|
||||
"style": "dark",
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": []
|
||||
},
|
||||
"time": {
|
||||
"from": "now-1h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "libp2p Identify",
|
||||
"uid": "0NDzQQ0Vz",
|
||||
"version": 4,
|
||||
"weekStart": ""
|
||||
}
|
|
@ -114,10 +114,11 @@ type idService struct {
|
|||
UserAgent string
|
||||
ProtocolVersion string
|
||||
|
||||
setupCompleted chan struct{} // is closed when Start has finished setting up
|
||||
metricsTracer MetricsTracer
|
||||
|
||||
ctx context.Context
|
||||
ctxCancel context.CancelFunc
|
||||
setupCompleted chan struct{} // is closed when Start has finished setting up
|
||||
ctx context.Context
|
||||
ctxCancel context.CancelFunc
|
||||
// track resources that need to be shut down before we shut down
|
||||
refCount sync.WaitGroup
|
||||
|
||||
|
@ -176,6 +177,7 @@ func NewIDService(h host.Host, opts ...Option) (*idService, error) {
|
|||
conns: make(map[network.Conn]entry),
|
||||
disableSignedPeerRecord: cfg.disableSignedPeerRecord,
|
||||
setupCompleted: make(chan struct{}),
|
||||
metricsTracer: cfg.metricsTracer,
|
||||
}
|
||||
|
||||
observedAddrs, err := NewObservedAddrManager(h)
|
||||
|
@ -245,7 +247,13 @@ func (ids *idService) loop(ctx context.Context) {
|
|||
|
||||
for {
|
||||
select {
|
||||
case <-sub.Out():
|
||||
case e, ok := <-sub.Out():
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if ids.metricsTracer != nil {
|
||||
ids.metricsTracer.TriggeredPushes(e)
|
||||
}
|
||||
ids.updateSnapshot()
|
||||
select {
|
||||
case triggerPush <- struct{}{}:
|
||||
|
@ -299,6 +307,9 @@ func (ids *idService) sendPushes(ctx context.Context) {
|
|||
if err != nil { // connection might have been closed recently
|
||||
return
|
||||
}
|
||||
if ids.metricsTracer != nil {
|
||||
ids.metricsTracer.IdentifyPush(network.DirOutbound)
|
||||
}
|
||||
// TODO: find out if the peer supports push if we didn't have any information about push support
|
||||
if err := ids.sendIdentifyResp(str); err != nil {
|
||||
log.Debugw("failed to send identify push", "peer", c.RemotePeer(), "error", err)
|
||||
|
@ -390,15 +401,24 @@ func (ids *idService) identifyConn(c network.Conn) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if ids.metricsTracer != nil {
|
||||
ids.metricsTracer.Identify(network.DirInbound)
|
||||
}
|
||||
return ids.handleIdentifyResponse(s, false)
|
||||
}
|
||||
|
||||
// handlePush handles incoming identify push streams
|
||||
func (ids *idService) handlePush(s network.Stream) {
|
||||
ids.handleIdentifyResponse(s, true)
|
||||
if ids.metricsTracer != nil {
|
||||
ids.metricsTracer.IdentifyPush(network.DirInbound)
|
||||
}
|
||||
}
|
||||
|
||||
func (ids *idService) handleIdentifyRequest(s network.Stream) {
|
||||
if ids.metricsTracer != nil {
|
||||
ids.metricsTracer.Identify(network.DirOutbound)
|
||||
}
|
||||
_ = ids.sendIdentifyResp(s)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
package identify
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/event"
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/p2p/metricshelper"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const metricNamespace = "libp2p_identify"
|
||||
|
||||
var (
|
||||
pushesTriggered = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Namespace: metricNamespace,
|
||||
Name: "identify_pushes_triggered_total",
|
||||
Help: "Pushes Triggered",
|
||||
},
|
||||
[]string{"trigger"},
|
||||
)
|
||||
identify = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Namespace: metricNamespace,
|
||||
Name: "identify_total",
|
||||
Help: "Identify",
|
||||
},
|
||||
[]string{"dir"},
|
||||
)
|
||||
identifyPush = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Namespace: metricNamespace,
|
||||
Name: "identify_push_total",
|
||||
Help: "Identify Push",
|
||||
},
|
||||
[]string{"dir"},
|
||||
)
|
||||
)
|
||||
|
||||
var initMetricsOnce sync.Once
|
||||
|
||||
func initMetrics() {
|
||||
prometheus.MustRegister(pushesTriggered, identify, identifyPush)
|
||||
}
|
||||
|
||||
type MetricsTracer interface {
|
||||
TriggeredPushes(event any)
|
||||
Identify(network.Direction)
|
||||
IdentifyPush(network.Direction)
|
||||
}
|
||||
|
||||
type metricsTracer struct{}
|
||||
|
||||
var _ MetricsTracer = &metricsTracer{}
|
||||
|
||||
func NewMetricsTracer() MetricsTracer {
|
||||
initMetricsOnce.Do(initMetrics)
|
||||
return &metricsTracer{}
|
||||
}
|
||||
|
||||
func (t *metricsTracer) TriggeredPushes(ev any) {
|
||||
tags := metricshelper.GetStringSlice()
|
||||
defer metricshelper.PutStringSlice(tags)
|
||||
|
||||
typ := "unknown"
|
||||
switch ev.(type) {
|
||||
case event.EvtLocalProtocolsUpdated:
|
||||
typ = "protocols_updated"
|
||||
case event.EvtLocalAddressesUpdated:
|
||||
typ = "addresses_updated"
|
||||
}
|
||||
*tags = append(*tags, typ)
|
||||
pushesTriggered.WithLabelValues(*tags...).Inc()
|
||||
}
|
||||
|
||||
func (t *metricsTracer) Identify(dir network.Direction) {
|
||||
tags := metricshelper.GetStringSlice()
|
||||
defer metricshelper.PutStringSlice(tags)
|
||||
|
||||
*tags = append(*tags, metricshelper.GetDirection(dir))
|
||||
identify.WithLabelValues(*tags...).Inc()
|
||||
}
|
||||
|
||||
func (t *metricsTracer) IdentifyPush(dir network.Direction) {
|
||||
tags := metricshelper.GetStringSlice()
|
||||
defer metricshelper.PutStringSlice(tags)
|
||||
|
||||
*tags = append(*tags, metricshelper.GetDirection(dir))
|
||||
identifyPush.WithLabelValues(*tags...).Inc()
|
||||
}
|
|
@ -4,6 +4,7 @@ type config struct {
|
|||
protocolVersion string
|
||||
userAgent string
|
||||
disableSignedPeerRecord bool
|
||||
metricsTracer MetricsTracer
|
||||
}
|
||||
|
||||
// Option is an option function for identify.
|
||||
|
@ -31,3 +32,9 @@ func DisableSignedPeerRecord() Option {
|
|||
cfg.disableSignedPeerRecord = true
|
||||
}
|
||||
}
|
||||
|
||||
func WithMetricsTracer(tr MetricsTracer) Option {
|
||||
return func(cfg *config) {
|
||||
cfg.metricsTracer = tr
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue