From 223bf165cede2c9c06e444a5b2622e789cc85023 Mon Sep 17 00:00:00 2001 From: sukun Date: Sat, 11 Feb 2023 19:43:34 +0530 Subject: [PATCH 1/7] add autonat metrics --- config/config.go | 1 + p2p/host/autonat/autonat.go | 8 +- p2p/host/autonat/client.go | 8 +- .../autonat/grafana-dashboards/autonat.json | 658 ++++++++++++++++++ p2p/host/autonat/metrics.go | 149 ++++ p2p/host/autonat/options.go | 9 + p2p/host/autonat/svc.go | 6 + p2p/host/autonat/svc_test.go | 2 +- 8 files changed, 837 insertions(+), 4 deletions(-) create mode 100644 p2p/host/autonat/grafana-dashboards/autonat.json create mode 100644 p2p/host/autonat/metrics.go diff --git a/config/config.go b/config/config.go index 874bcb5a5a..50b0193aa3 100644 --- a/config/config.go +++ b/config/config.go @@ -354,6 +354,7 @@ func (cfg *Config) NewNode() (host.Host, error) { autonat.UsingAddresses(func() []ma.Multiaddr { return addrF(h.AllAddrs()) }), + autonat.WithMetricsTracer(autonat.NewMetricsTracer()), } if cfg.AutoNATConfig.ThrottleInterval != 0 { autonatOpts = append(autonatOpts, diff --git a/p2p/host/autonat/autonat.go b/p2p/host/autonat/autonat.go index eee5481aea..900eb8c029 100644 --- a/p2p/host/autonat/autonat.go +++ b/p2p/host/autonat/autonat.go @@ -143,6 +143,9 @@ func (as *AmbientAutoNAT) Status() network.Reachability { func (as *AmbientAutoNAT) emitStatus() { status := as.status.Load() as.emitReachabilityChanged.Emit(event.EvtLocalReachabilityChanged{Reachability: status.Reachability}) + if as.metricsTracer != nil { + as.metricsTracer.ReachabilityStatus(status.Reachability) + } } // PublicAddr returns the publicly connectable Multiaddr of this node if one is known. @@ -345,6 +348,9 @@ func (as *AmbientAutoNAT) recordObservation(observation autoNATResult) { as.emitStatus() } } + if as.metricsTracer != nil { + as.metricsTracer.ReachabilityStatusConfidence(as.confidence) + } } func (as *AmbientAutoNAT) tryProbe(p peer.ID) bool { @@ -372,7 +378,7 @@ func (as *AmbientAutoNAT) tryProbe(p peer.ID) bool { } func (as *AmbientAutoNAT) probe(pi *peer.AddrInfo) { - cli := NewAutoNATClient(as.host, as.config.addressFunc) + cli := NewAutoNATClient(as.host, as.config.addressFunc, as.metricsTracer) ctx, cancel := context.WithTimeout(as.ctx, as.config.requestTimeout) defer cancel() diff --git a/p2p/host/autonat/client.go b/p2p/host/autonat/client.go index 683168d538..51d307a6b2 100644 --- a/p2p/host/autonat/client.go +++ b/p2p/host/autonat/client.go @@ -17,16 +17,17 @@ import ( // NewAutoNATClient creates a fresh instance of an AutoNATClient // If addrFunc is nil, h.Addrs will be used -func NewAutoNATClient(h host.Host, addrFunc AddrFunc) Client { +func NewAutoNATClient(h host.Host, addrFunc AddrFunc, mt MetricsTracer) Client { if addrFunc == nil { addrFunc = h.Addrs } - return &client{h: h, addrFunc: addrFunc} + return &client{h: h, addrFunc: addrFunc, mt: mt} } type client struct { h host.Host addrFunc AddrFunc + mt MetricsTracer } // DialBack asks peer p to dial us back on all addresses returned by the addrFunc. @@ -79,6 +80,9 @@ func (c *client) DialBack(ctx context.Context, p peer.ID) (ma.Multiaddr, error) } status := res.GetDialResponse().GetStatus() + if c.mt != nil { + c.mt.ClientDialResponse(status) + } switch status { case pb.Message_OK: addr := res.GetDialResponse().GetAddr() diff --git a/p2p/host/autonat/grafana-dashboards/autonat.json b/p2p/host/autonat/grafana-dashboards/autonat.json new file mode 100644 index 0000000000..c2d043fb3c --- /dev/null +++ b/p2p/host/autonat/grafana-dashboards/autonat.json @@ -0,0 +1,658 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "panel", + "id": "gauge", + "name": "Gauge", + "version": "" + }, + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "9.3.2" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "state-timeline", + "name": "State timeline", + "version": "" + }, + { + "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}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "continuous-GrYlRd" + }, + "custom": { + "fillOpacity": 70, + "lineWidth": 0, + "spanNulls": true + }, + "mappings": [ + { + "options": { + "0": { + "color": "yellow", + "index": 0, + "text": "Unknown" + }, + "1": { + "color": "green", + "index": 1, + "text": "Public" + }, + "2": { + "color": "red", + "index": 2, + "text": "Private" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 18, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "alignValue": "left", + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "mergeValues": true, + "rowHeight": 0.9, + "showValue": "auto", + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "libp2p_autonat_reachability_status", + "legendFormat": " ", + "range": true, + "refId": "A" + } + ], + "title": "Reachability Status", + "type": "state-timeline" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 5, + "x": 18, + "y": 0 + }, + "id": 10, + "options": { + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "libp2p_autonat_reachability_status_confidnce", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Reachability status confidence", + "type": "gauge" + }, + { + "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": [ + { + "matcher": { + "id": "byName", + "options": "dial error" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "dial refused" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "ok" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 6 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "sum by(response_status) (increase(libp2p_autonat_client_dialresponse_total[$__rate_interval]))", + "instant": false, + "legendFormat": "{{response_status}}", + "range": true, + "refId": "A" + } + ], + "title": "Client: DialResponse by Type", + "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": [ + { + "matcher": { + "id": "byName", + "options": "rate limit" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 15 + }, + "id": 8, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum by(refusal_reason) (increase(libp2p_autonat_server_dialrefused_total[$__rate_interval]))", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Server: Dial requests rate limited", + "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": [ + { + "matcher": { + "id": "byName", + "options": "dial refused" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "ok" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Dial Error" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "dial error" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "OK" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 15 + }, + "id": 6, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "sum by(response_status) (increase(libp2p_autonat_server_dialresponse_total[$__rate_interval]))", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "server: DialResponse By Type", + "type": "timeseries" + } + ], + "schemaVersion": 37, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "libp2p autonat", + "uid": "YNWSyiJ4k", + "version": 18, + "weekStart": "" +} \ No newline at end of file diff --git a/p2p/host/autonat/metrics.go b/p2p/host/autonat/metrics.go new file mode 100644 index 0000000000..fd561b8fd8 --- /dev/null +++ b/p2p/host/autonat/metrics.go @@ -0,0 +1,149 @@ +package autonat + +import ( + "sync" + + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/p2p/host/autonat/pb" + "github.com/libp2p/go-libp2p/p2p/metricshelper" + "github.com/prometheus/client_golang/prometheus" +) + +const metricNamespace = "libp2p_autonat" + +var ( + reachabilityStatus = prometheus.NewGauge( + prometheus.GaugeOpts{ + Namespace: metricNamespace, + Name: "reachability_status", + Help: "Current node reachability", + }, + ) + reachabilityStatusConfidence = prometheus.NewGauge( + prometheus.GaugeOpts{ + Namespace: metricNamespace, + Name: "reachability_status_confidnce", + Help: "Node reachability status confidence", + }, + ) + clientDialResponseTotal = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Namespace: metricNamespace, + Name: "client_dialresponse_total", + Help: "Count of dial responses for client", + }, + []string{"response_status"}, + ) + serverDialResponseTotal = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Namespace: metricNamespace, + Name: "server_dialresponse_total", + Help: "Count of dial responses for server", + }, + []string{"response_status"}, + ) + serverDialRefusedTotal = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Namespace: metricNamespace, + Name: "server_dialrefused_total", + Help: "Count of dial requests refused by server", + }, + []string{"refusal_reason"}, + ) +) + +var initMetricsOnce sync.Once + +func initMetrics(reg prometheus.Registerer) { + reg.MustRegister( + reachabilityStatus, + clientDialResponseTotal, + serverDialResponseTotal, + serverDialRefusedTotal, + reachabilityStatusConfidence, + ) +} + +type MetricsTracer interface { + ReachabilityStatus(status network.Reachability) + ReachabilityStatusConfidence(confidence int) + ClientDialResponse(status pb.Message_ResponseStatus) + ServerDialResponse(status pb.Message_ResponseStatus) + ServerDialRefused(reason string) +} + +func getResponseStatus(status pb.Message_ResponseStatus) string { + var s string + switch status { + case pb.Message_OK: + s = "ok" + case pb.Message_E_DIAL_ERROR: + s = "dial error" + case pb.Message_E_DIAL_REFUSED: + s = "dial refused" + case pb.Message_E_BAD_REQUEST: + s = "bad request" + case pb.Message_E_INTERNAL_ERROR: + s = "internal error" + default: + s = "unknown" + } + return s +} + +const ( + RATE_LIMIT = "rate limit" +) + +type metricsTracerSetting struct { + reg prometheus.Registerer +} + +type metricsTracer struct { +} + +func (mt *metricsTracer) ReachabilityStatus(status network.Reachability) { + reachabilityStatus.Set(float64(status)) +} + +func (mt *metricsTracer) ReachabilityStatusConfidence(confidence int) { + reachabilityStatusConfidence.Set(float64(confidence)) +} + +func (mt *metricsTracer) ClientDialResponse(status pb.Message_ResponseStatus) { + tags := metricshelper.GetStringSlice() + defer metricshelper.PutStringSlice(tags) + *tags = append(*tags, getResponseStatus(status)) + clientDialResponseTotal.WithLabelValues(*tags...).Inc() +} + +func (mt *metricsTracer) ServerDialResponse(status pb.Message_ResponseStatus) { + tags := metricshelper.GetStringSlice() + defer metricshelper.PutStringSlice(tags) + *tags = append(*tags, getResponseStatus(status)) + serverDialResponseTotal.WithLabelValues(*tags...).Inc() +} + +func (mt *metricsTracer) ServerDialRefused(reason string) { + tags := metricshelper.GetStringSlice() + defer metricshelper.PutStringSlice(tags) + *tags = append(*tags, reason) + serverDialRefusedTotal.WithLabelValues(*tags...).Inc() +} + +type MetricsTracerOption = func(*metricsTracerSetting) + +func MustRegisterWith(reg prometheus.Registerer) MetricsTracerOption { + return func(s *metricsTracerSetting) { + s.reg = reg + } +} + +func NewMetricsTracer(opts ...MetricsTracerOption) MetricsTracer { + settings := &metricsTracerSetting{reg: prometheus.DefaultRegisterer} + for _, opt := range opts { + opt(settings) + } + initMetricsOnce.Do(func() { initMetrics(settings.reg) }) + return &metricsTracer{} +} diff --git a/p2p/host/autonat/options.go b/p2p/host/autonat/options.go index 0935dc2337..8e653f8163 100644 --- a/p2p/host/autonat/options.go +++ b/p2p/host/autonat/options.go @@ -17,6 +17,7 @@ type config struct { dialer network.Network forceReachability bool reachability network.Reachability + metricsTracer MetricsTracer // client bootDelay time.Duration @@ -142,3 +143,11 @@ func WithPeerThrottling(amount int) Option { return nil } } + +// WithMetricsTracer uses mt to track autonat metrics +func WithMetricsTracer(mt MetricsTracer) Option { + return func(c *config) error { + c.metricsTracer = mt + return nil + } +} diff --git a/p2p/host/autonat/svc.go b/p2p/host/autonat/svc.go index d2ab8e877a..12deacb8c8 100644 --- a/p2p/host/autonat/svc.go +++ b/p2p/host/autonat/svc.go @@ -100,6 +100,9 @@ func (as *autoNATService) handleStream(s network.Stream) { s.Reset() return } + if as.config.metricsTracer != nil { + as.config.metricsTracer.ServerDialResponse(res.GetDialResponse().GetStatus()) + } } func (as *autoNATService) handleDial(p peer.ID, obsaddr ma.Multiaddr, mpi *pb.Message_PeerInfo) *pb.Message_DialResponse { @@ -202,6 +205,9 @@ func (as *autoNATService) doDial(pi peer.AddrInfo) *pb.Message_DialResponse { if count >= as.config.throttlePeerMax || (as.config.throttleGlobalMax > 0 && as.globalReqs >= as.config.throttleGlobalMax) { as.mx.Unlock() + if as.config.metricsTracer != nil { + as.config.metricsTracer.ServerDialRefused(RATE_LIMIT) + } return newDialResponseError(pb.Message_E_DIAL_REFUSED, "too many dials") } as.reqs[pi.ID] = count + 1 diff --git a/p2p/host/autonat/svc_test.go b/p2p/host/autonat/svc_test.go index e1d751f132..18dc3bce21 100644 --- a/p2p/host/autonat/svc_test.go +++ b/p2p/host/autonat/svc_test.go @@ -38,7 +38,7 @@ func makeAutoNATService(t *testing.T, c *config) *autoNATService { func makeAutoNATClient(t *testing.T) (host.Host, Client) { h := bhost.NewBlankHost(swarmt.GenSwarm(t)) - cli := NewAutoNATClient(h, nil) + cli := NewAutoNATClient(h, nil, nil) return h, cli } From 2f7d1475c130a70a56ef9ffd7d69010e94eb1e74 Mon Sep 17 00:00:00 2001 From: sukun Date: Sat, 11 Feb 2023 20:19:19 +0530 Subject: [PATCH 2/7] add benchmarks --- p2p/host/autonat/metrics_test.go | 44 ++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 p2p/host/autonat/metrics_test.go diff --git a/p2p/host/autonat/metrics_test.go b/p2p/host/autonat/metrics_test.go new file mode 100644 index 0000000000..08ecd2b066 --- /dev/null +++ b/p2p/host/autonat/metrics_test.go @@ -0,0 +1,44 @@ +package autonat + +import ( + "testing" + + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/p2p/host/autonat/pb" +) + +func BenchmarkReachabilityStatus(b *testing.B) { + b.ReportAllocs() + mt := NewMetricsTracer() + for i := 0; i < b.N; i++ { + mt.ReachabilityStatus(network.Reachability(i % 3)) + } +} + +func BenchmarkClientDialResponse(b *testing.B) { + b.ReportAllocs() + mt := NewMetricsTracer() + statuses := []pb.Message_ResponseStatus{ + pb.Message_OK, pb.Message_E_DIAL_ERROR, pb.Message_E_DIAL_REFUSED, pb.Message_E_BAD_REQUEST} + for i := 0; i < b.N; i++ { + mt.ClientDialResponse(statuses[i%len(statuses)]) + } +} + +func BenchmarkServerDialResponse(b *testing.B) { + b.ReportAllocs() + mt := NewMetricsTracer() + statuses := []pb.Message_ResponseStatus{ + pb.Message_OK, pb.Message_E_DIAL_ERROR, pb.Message_E_DIAL_REFUSED, pb.Message_E_BAD_REQUEST} + for i := 0; i < b.N; i++ { + mt.ServerDialResponse(statuses[i%len(statuses)]) + } +} + +func BenchmarkServerDialRefused(b *testing.B) { + b.ReportAllocs() + mt := NewMetricsTracer() + for i := 0; i < b.N; i++ { + mt.ServerDialRefused(RATE_LIMIT) + } +} From 326384826a5b3881d2aa4bc97124bd5175d2477e Mon Sep 17 00:00:00 2001 From: sukun Date: Sat, 11 Feb 2023 23:09:09 +0530 Subject: [PATCH 3/7] use increase instead of sum by with rate in dashboard --- p2p/host/autonat/grafana-dashboards/autonat.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/p2p/host/autonat/grafana-dashboards/autonat.json b/p2p/host/autonat/grafana-dashboards/autonat.json index c2d043fb3c..2c44e37017 100644 --- a/p2p/host/autonat/grafana-dashboards/autonat.json +++ b/p2p/host/autonat/grafana-dashboards/autonat.json @@ -352,7 +352,7 @@ }, "editorMode": "code", "exemplar": false, - "expr": "sum by(response_status) (increase(libp2p_autonat_client_dialresponse_total[$__rate_interval]))", + "expr": "increase(libp2p_autonat_client_dialresponse_total[$__rate_interval])", "instant": false, "legendFormat": "{{response_status}}", "range": true, @@ -460,9 +460,9 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "editorMode": "builder", - "expr": "sum by(refusal_reason) (increase(libp2p_autonat_server_dialrefused_total[$__rate_interval]))", - "legendFormat": "__auto", + "editorMode": "code", + "expr": "increase(libp2p_autonat_server_dialrefused_total[$__rate_interval])", + "legendFormat": "{{refusal_reason}}", "range": true, "refId": "A" } @@ -628,9 +628,9 @@ "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "editorMode": "builder", - "expr": "sum by(response_status) (increase(libp2p_autonat_server_dialresponse_total[$__rate_interval]))", - "legendFormat": "__auto", + "editorMode": "code", + "expr": "increase(libp2p_autonat_server_dialresponse_total[$__rate_interval])", + "legendFormat": "{{response_status}}", "range": true, "refId": "A" } @@ -653,6 +653,6 @@ "timezone": "", "title": "libp2p autonat", "uid": "YNWSyiJ4k", - "version": 18, + "version": 19, "weekStart": "" } \ No newline at end of file From fe668158b67eb0858e11a88c17c955ccb2ddb9fa Mon Sep 17 00:00:00 2001 From: sukun Date: Sun, 12 Feb 2023 15:26:06 +0530 Subject: [PATCH 4/7] add interface assertion --- p2p/host/autonat/metrics.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/p2p/host/autonat/metrics.go b/p2p/host/autonat/metrics.go index fd561b8fd8..93721ef444 100644 --- a/p2p/host/autonat/metrics.go +++ b/p2p/host/autonat/metrics.go @@ -57,10 +57,10 @@ var initMetricsOnce sync.Once func initMetrics(reg prometheus.Registerer) { reg.MustRegister( reachabilityStatus, + reachabilityStatusConfidence, clientDialResponseTotal, serverDialResponseTotal, serverDialRefusedTotal, - reachabilityStatusConfidence, ) } @@ -102,6 +102,8 @@ type metricsTracerSetting struct { type metricsTracer struct { } +var _ MetricsTracer = &metricsTracer{} + func (mt *metricsTracer) ReachabilityStatus(status network.Reachability) { reachabilityStatus.Set(float64(status)) } From 12893e2e7253314fcd5acb941f90499e6942c1d6 Mon Sep 17 00:00:00 2001 From: sukun Date: Wed, 15 Feb 2023 13:33:42 +0530 Subject: [PATCH 5/7] add no alloc test --- p2p/host/autonat/autonat.go | 4 +- p2p/host/autonat/client.go | 2 +- .../autonat/grafana-dashboards/autonat.json | 4 +- p2p/host/autonat/metrics.go | 56 ++++++++++++------- p2p/host/autonat/metrics_test.go | 42 +++++++++++++- p2p/host/autonat/svc.go | 10 +++- 6 files changed, 89 insertions(+), 29 deletions(-) diff --git a/p2p/host/autonat/autonat.go b/p2p/host/autonat/autonat.go index 900eb8c029..17122d4ec9 100644 --- a/p2p/host/autonat/autonat.go +++ b/p2p/host/autonat/autonat.go @@ -282,7 +282,9 @@ func (as *AmbientAutoNAT) scheduleProbe() time.Duration { nextProbe = as.lastProbe.Add(untilNext) } } - + if as.metricsTracer != nil { + as.metricsTracer.NextProbeTime(nextProbe) + } return nextProbe.Sub(fixedNow) } diff --git a/p2p/host/autonat/client.go b/p2p/host/autonat/client.go index 51d307a6b2..46e20eba2a 100644 --- a/p2p/host/autonat/client.go +++ b/p2p/host/autonat/client.go @@ -81,7 +81,7 @@ func (c *client) DialBack(ctx context.Context, p peer.ID) (ma.Multiaddr, error) status := res.GetDialResponse().GetStatus() if c.mt != nil { - c.mt.ClientDialResponse(status) + c.mt.ReceivedDialResponse(status) } switch status { case pb.Message_OK: diff --git a/p2p/host/autonat/grafana-dashboards/autonat.json b/p2p/host/autonat/grafana-dashboards/autonat.json index 2c44e37017..750ea86861 100644 --- a/p2p/host/autonat/grafana-dashboards/autonat.json +++ b/p2p/host/autonat/grafana-dashboards/autonat.json @@ -213,7 +213,7 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "builder", - "expr": "libp2p_autonat_reachability_status_confidnce", + "expr": "libp2p_autonat_reachability_status_confidence", "legendFormat": "__auto", "range": true, "refId": "A" @@ -359,7 +359,7 @@ "refId": "A" } ], - "title": "Client: DialResponse by Type", + "title": "Received Dial Responses", "type": "timeseries" }, { diff --git a/p2p/host/autonat/metrics.go b/p2p/host/autonat/metrics.go index 93721ef444..a134598235 100644 --- a/p2p/host/autonat/metrics.go +++ b/p2p/host/autonat/metrics.go @@ -2,6 +2,7 @@ package autonat import ( "sync" + "time" "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/p2p/host/autonat/pb" @@ -22,34 +23,41 @@ var ( reachabilityStatusConfidence = prometheus.NewGauge( prometheus.GaugeOpts{ Namespace: metricNamespace, - Name: "reachability_status_confidnce", + Name: "reachability_status_confidence", Help: "Node reachability status confidence", }, ) - clientDialResponseTotal = prometheus.NewCounterVec( + receivedDialResponseTotal = prometheus.NewCounterVec( prometheus.CounterOpts{ Namespace: metricNamespace, - Name: "client_dialresponse_total", + Name: "received_dial_response_total", Help: "Count of dial responses for client", }, []string{"response_status"}, ) - serverDialResponseTotal = prometheus.NewCounterVec( + outgoingDialResponseTotal = prometheus.NewCounterVec( prometheus.CounterOpts{ Namespace: metricNamespace, - Name: "server_dialresponse_total", + Name: "outgoing_dial_response_total", Help: "Count of dial responses for server", }, []string{"response_status"}, ) - serverDialRefusedTotal = prometheus.NewCounterVec( + outgoingDialRefusedTotal = prometheus.NewCounterVec( prometheus.CounterOpts{ Namespace: metricNamespace, - Name: "server_dialrefused_total", + Name: "outgoing_dial_refused_total", Help: "Count of dial requests refused by server", }, []string{"refusal_reason"}, ) + nextProbeTimestamp = prometheus.NewGauge( + prometheus.GaugeOpts{ + Namespace: metricNamespace, + Name: "next_probe_timestamp", + Help: "Time of next probe", + }, + ) ) var initMetricsOnce sync.Once @@ -58,18 +66,20 @@ func initMetrics(reg prometheus.Registerer) { reg.MustRegister( reachabilityStatus, reachabilityStatusConfidence, - clientDialResponseTotal, - serverDialResponseTotal, - serverDialRefusedTotal, + receivedDialResponseTotal, + outgoingDialResponseTotal, + outgoingDialRefusedTotal, + nextProbeTimestamp, ) } type MetricsTracer interface { ReachabilityStatus(status network.Reachability) ReachabilityStatusConfidence(confidence int) - ClientDialResponse(status pb.Message_ResponseStatus) - ServerDialResponse(status pb.Message_ResponseStatus) - ServerDialRefused(reason string) + ReceivedDialResponse(status pb.Message_ResponseStatus) + OutgoingDialResponse(status pb.Message_ResponseStatus) + OutgoingDialRefused(reason string) + NextProbeTime(t time.Time) } func getResponseStatus(status pb.Message_ResponseStatus) string { @@ -92,7 +102,9 @@ func getResponseStatus(status pb.Message_ResponseStatus) string { } const ( - RATE_LIMIT = "rate limit" + rate_limited = "rate limited" + dial_blocked = "dial blocked" + no_valid_address = "no valid address" ) type metricsTracerSetting struct { @@ -112,25 +124,29 @@ func (mt *metricsTracer) ReachabilityStatusConfidence(confidence int) { reachabilityStatusConfidence.Set(float64(confidence)) } -func (mt *metricsTracer) ClientDialResponse(status pb.Message_ResponseStatus) { +func (mt *metricsTracer) ReceivedDialResponse(status pb.Message_ResponseStatus) { tags := metricshelper.GetStringSlice() defer metricshelper.PutStringSlice(tags) *tags = append(*tags, getResponseStatus(status)) - clientDialResponseTotal.WithLabelValues(*tags...).Inc() + receivedDialResponseTotal.WithLabelValues(*tags...).Inc() } -func (mt *metricsTracer) ServerDialResponse(status pb.Message_ResponseStatus) { +func (mt *metricsTracer) OutgoingDialResponse(status pb.Message_ResponseStatus) { tags := metricshelper.GetStringSlice() defer metricshelper.PutStringSlice(tags) *tags = append(*tags, getResponseStatus(status)) - serverDialResponseTotal.WithLabelValues(*tags...).Inc() + outgoingDialResponseTotal.WithLabelValues(*tags...).Inc() } -func (mt *metricsTracer) ServerDialRefused(reason string) { +func (mt *metricsTracer) OutgoingDialRefused(reason string) { tags := metricshelper.GetStringSlice() defer metricshelper.PutStringSlice(tags) *tags = append(*tags, reason) - serverDialRefusedTotal.WithLabelValues(*tags...).Inc() + outgoingDialRefusedTotal.WithLabelValues(*tags...).Inc() +} + +func (mt *metricsTracer) NextProbeTime(t time.Time) { + nextProbeTimestamp.Set(float64(t.Unix())) } type MetricsTracerOption = func(*metricsTracerSetting) diff --git a/p2p/host/autonat/metrics_test.go b/p2p/host/autonat/metrics_test.go index 08ecd2b066..a7aa290c7b 100644 --- a/p2p/host/autonat/metrics_test.go +++ b/p2p/host/autonat/metrics_test.go @@ -1,7 +1,9 @@ package autonat import ( + "math/rand" "testing" + "time" "github.com/libp2p/go-libp2p/core/network" "github.com/libp2p/go-libp2p/p2p/host/autonat/pb" @@ -21,7 +23,7 @@ func BenchmarkClientDialResponse(b *testing.B) { statuses := []pb.Message_ResponseStatus{ pb.Message_OK, pb.Message_E_DIAL_ERROR, pb.Message_E_DIAL_REFUSED, pb.Message_E_BAD_REQUEST} for i := 0; i < b.N; i++ { - mt.ClientDialResponse(statuses[i%len(statuses)]) + mt.ReceivedDialResponse(statuses[i%len(statuses)]) } } @@ -31,7 +33,7 @@ func BenchmarkServerDialResponse(b *testing.B) { statuses := []pb.Message_ResponseStatus{ pb.Message_OK, pb.Message_E_DIAL_ERROR, pb.Message_E_DIAL_REFUSED, pb.Message_E_BAD_REQUEST} for i := 0; i < b.N; i++ { - mt.ServerDialResponse(statuses[i%len(statuses)]) + mt.OutgoingDialResponse(statuses[i%len(statuses)]) } } @@ -39,6 +41,40 @@ func BenchmarkServerDialRefused(b *testing.B) { b.ReportAllocs() mt := NewMetricsTracer() for i := 0; i < b.N; i++ { - mt.ServerDialRefused(RATE_LIMIT) + mt.OutgoingDialRefused(rate_limited) + } +} + +func TestMetricsNoAllocNoCover(t *testing.T) { + mt := NewMetricsTracer() + statuses := []network.Reachability{ + network.ReachabilityPublic, + network.ReachabilityPrivate, + network.ReachabilityUnknown, + } + respStatuses := []pb.Message_ResponseStatus{ + pb.Message_OK, + pb.Message_E_BAD_REQUEST, + pb.Message_E_DIAL_REFUSED, + pb.Message_E_INTERNAL_ERROR, + } + reasons := []string{ + rate_limited, + "bad request", + "no valid address", + } + tests := map[string]func(){ + "ReachabilityStatus": func() { mt.ReachabilityStatus(statuses[rand.Intn(len(statuses))]) }, + "ReachabilityStatusConfidence": func() { mt.ReachabilityStatusConfidence(rand.Intn(4)) }, + "ReceivedDialResponse": func() { mt.ReceivedDialResponse(respStatuses[rand.Intn(len(respStatuses))]) }, + "OutgoingDialResponse": func() { mt.OutgoingDialResponse(respStatuses[rand.Intn(len(respStatuses))]) }, + "OutgoingDialRefused": func() { mt.OutgoingDialRefused(reasons[rand.Intn(len(reasons))]) }, + "NextProbeTime": func() { mt.NextProbeTime(time.Now()) }, + } + for method, f := range tests { + allocs := testing.AllocsPerRun(1000, f) + if allocs > 0 { + t.Fatalf("%s alloc test failed expected 0 received %0.2f", method, allocs) + } } } diff --git a/p2p/host/autonat/svc.go b/p2p/host/autonat/svc.go index 12deacb8c8..98b421c9b2 100644 --- a/p2p/host/autonat/svc.go +++ b/p2p/host/autonat/svc.go @@ -101,7 +101,7 @@ func (as *autoNATService) handleStream(s network.Stream) { return } if as.config.metricsTracer != nil { - as.config.metricsTracer.ServerDialResponse(res.GetDialResponse().GetStatus()) + as.config.metricsTracer.OutgoingDialResponse(res.GetDialResponse().GetStatus()) } } @@ -129,6 +129,9 @@ func (as *autoNATService) handleDial(p peer.ID, obsaddr ma.Multiaddr, mpi *pb.Me // need to know their public IP address, and it needs to be different from our public IP // address. if as.config.dialPolicy.skipDial(obsaddr) { + if as.config.metricsTracer != nil { + as.config.metricsTracer.OutgoingDialRefused(dial_blocked) + } // Note: versions < v0.20.0 return Message_E_DIAL_ERROR here, thus we can not rely on this error code. return newDialResponseError(pb.Message_E_DIAL_REFUSED, "refusing to dial peer with blocked observed address") } @@ -191,6 +194,9 @@ func (as *autoNATService) handleDial(p peer.ID, obsaddr ma.Multiaddr, mpi *pb.Me } if len(addrs) == 0 { + if as.config.metricsTracer != nil { + as.config.metricsTracer.OutgoingDialRefused(no_valid_address) + } // Note: versions < v0.20.0 return Message_E_DIAL_ERROR here, thus we can not rely on this error code. return newDialResponseError(pb.Message_E_DIAL_REFUSED, "no dialable addresses") } @@ -206,7 +212,7 @@ func (as *autoNATService) doDial(pi peer.AddrInfo) *pb.Message_DialResponse { as.globalReqs >= as.config.throttleGlobalMax) { as.mx.Unlock() if as.config.metricsTracer != nil { - as.config.metricsTracer.ServerDialRefused(RATE_LIMIT) + as.config.metricsTracer.OutgoingDialRefused(rate_limited) } return newDialResponseError(pb.Message_E_DIAL_REFUSED, "too many dials") } From 5f5857b37401e6cc2d8ae6f7e130a8ac6cd010ba Mon Sep 17 00:00:00 2001 From: sukun Date: Wed, 15 Feb 2023 13:44:13 +0530 Subject: [PATCH 6/7] update dashboard --- .../autonat/grafana-dashboards/autonat.json | 213 +++++++++++------- 1 file changed, 129 insertions(+), 84 deletions(-) diff --git a/p2p/host/autonat/grafana-dashboards/autonat.json b/p2p/host/autonat/grafana-dashboards/autonat.json index 750ea86861..c058565e58 100644 --- a/p2p/host/autonat/grafana-dashboards/autonat.json +++ b/p2p/host/autonat/grafana-dashboards/autonat.json @@ -29,6 +29,12 @@ "name": "Prometheus", "version": "1.0.0" }, + { + "type": "panel", + "id": "stat", + "name": "Stat", + "version": "" + }, { "type": "panel", "id": "state-timeline", @@ -101,7 +107,7 @@ "text": "Public" }, "2": { - "color": "red", + "color": "purple", "index": 2, "text": "Private" } @@ -170,6 +176,8 @@ "mode": "thresholds" }, "mappings": [], + "max": 3, + "min": 0, "thresholds": { "mode": "absolute", "steps": [ @@ -182,7 +190,8 @@ "value": 80 } ] - } + }, + "unit": "none" }, "overrides": [] }, @@ -222,6 +231,72 @@ "title": "Reachability status confidence", "type": "gauge" }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "green", + "mode": "fixed" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "dateTimeAsLocalNoDateIfToday" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 14, + "x": 5, + "y": 6 + }, + "id": 12, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^Value$/", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "libp2p_autonat_next_probe_timestamp * 1000", + "format": "table", + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "A" + } + ], + "title": "Next Probe Time", + "type": "stat" + }, { "datasource": { "type": "prometheus", @@ -287,7 +362,7 @@ { "id": "color", "value": { - "fixedColor": "red", + "fixedColor": "purple", "mode": "fixed" } } @@ -329,7 +404,7 @@ "h": 9, "w": 24, "x": 0, - "y": 6 + "y": 9 }, "id": 4, "options": { @@ -352,7 +427,7 @@ }, "editorMode": "code", "exemplar": false, - "expr": "increase(libp2p_autonat_client_dialresponse_total[$__rate_interval])", + "expr": "increase(libp2p_autonat_received_dial_response_total[$__rate_interval])", "instant": false, "legendFormat": "{{response_status}}", "range": true, @@ -421,13 +496,43 @@ { "matcher": { "id": "byName", - "options": "rate limit" + "options": "dial refused" }, "properties": [ { "id": "color", "value": { - "fixedColor": "red", + "fixedColor": "yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "dial error" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "OK" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", "mode": "fixed" } } @@ -436,12 +541,12 @@ ] }, "gridPos": { - "h": 8, - "w": 12, + "h": 9, + "w": 24, "x": 0, - "y": 15 + "y": 18 }, - "id": 8, + "id": 6, "options": { "legend": { "calcs": [], @@ -461,13 +566,13 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "increase(libp2p_autonat_server_dialrefused_total[$__rate_interval])", - "legendFormat": "{{refusal_reason}}", + "expr": "increase(libp2p_autonat_outgoing_dial_response_total[$__rate_interval])", + "legendFormat": "{{response_status}}", "range": true, "refId": "A" } ], - "title": "Server: Dial requests rate limited", + "title": "Outgoing Dial Responses", "type": "timeseries" }, { @@ -529,52 +634,7 @@ { "matcher": { "id": "byName", - "options": "dial refused" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "yellow", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "ok" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "green", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "Dial Error" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "red", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "dial error" + "options": "rate limited" }, "properties": [ { @@ -585,31 +645,16 @@ } } ] - }, - { - "matcher": { - "id": "byName", - "options": "OK" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "green", - "mode": "fixed" - } - } - ] } ] }, "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 15 + "h": 10, + "w": 24, + "x": 0, + "y": 27 }, - "id": 6, + "id": 14, "options": { "legend": { "calcs": [], @@ -629,13 +674,13 @@ "uid": "${DS_PROMETHEUS}" }, "editorMode": "code", - "expr": "increase(libp2p_autonat_server_dialresponse_total[$__rate_interval])", - "legendFormat": "{{response_status}}", + "expr": "increase(libp2p_autonat_outgoing_dial_refused_total[$__rate_interval])", + "legendFormat": "{{refusal_reason}}", "range": true, "refId": "A" } ], - "title": "server: DialResponse By Type", + "title": "Outgoing Dial Refused", "type": "timeseries" } ], @@ -653,6 +698,6 @@ "timezone": "", "title": "libp2p autonat", "uid": "YNWSyiJ4k", - "version": 19, + "version": 16, "weekStart": "" } \ No newline at end of file From eefe60b4c8ff15ccde1e30dffda0887e1de378fc Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 16 Feb 2023 18:02:45 +1300 Subject: [PATCH 7/7] autonat: minor dashboard tweaks --- .../autonat/grafana-dashboards/autonat.json | 1392 +++++++++-------- 1 file changed, 697 insertions(+), 695 deletions(-) diff --git a/p2p/host/autonat/grafana-dashboards/autonat.json b/p2p/host/autonat/grafana-dashboards/autonat.json index c058565e58..fabb18b65b 100644 --- a/p2p/host/autonat/grafana-dashboards/autonat.json +++ b/p2p/host/autonat/grafana-dashboards/autonat.json @@ -1,703 +1,705 @@ { - "__inputs": [ - { - "name": "DS_PROMETHEUS", - "label": "Prometheus", - "description": "", - "type": "datasource", - "pluginId": "prometheus", - "pluginName": "Prometheus" - } - ], - "__elements": {}, - "__requires": [ - { - "type": "panel", - "id": "gauge", - "name": "Gauge", - "version": "" - }, - { - "type": "grafana", - "id": "grafana", - "name": "Grafana", - "version": "9.3.2" - }, - { - "type": "datasource", - "id": "prometheus", - "name": "Prometheus", - "version": "1.0.0" - }, - { - "type": "panel", - "id": "stat", - "name": "Stat", - "version": "" + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "panel", + "id": "gauge", + "name": "Gauge", + "version": "" + }, + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "9.3.6" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "stat", + "name": "Stat", + "version": "" + }, + { + "type": "panel", + "id": "state-timeline", + "name": "State timeline", + "version": "" + }, + { + "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}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "continuous-GrYlRd" + }, + "custom": { + "fillOpacity": 70, + "lineWidth": 0, + "spanNulls": true + }, + "mappings": [ + { + "options": { + "0": { + "color": "yellow", + "index": 0, + "text": "Unknown" }, - { - "type": "panel", - "id": "state-timeline", - "name": "State timeline", - "version": "" + "1": { + "color": "green", + "index": 1, + "text": "Public" }, - { - "type": "panel", - "id": "timeseries", - "name": "Time series", - "version": "" + "2": { + "color": "purple", + "index": 2, + "text": "Private" } - ], - "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" - } - ] + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 0, - "id": null, - "links": [], - "liveNow": false, - "panels": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "continuous-GrYlRd" - }, - "custom": { - "fillOpacity": 70, - "lineWidth": 0, - "spanNulls": true - }, - "mappings": [ - { - "options": { - "0": { - "color": "yellow", - "index": 0, - "text": "Unknown" - }, - "1": { - "color": "green", - "index": 1, - "text": "Public" - }, - "2": { - "color": "purple", - "index": 2, - "text": "Private" - } - }, - "type": "value" - } - ], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 6, - "w": 18, - "x": 0, - "y": 0 - }, - "id": 2, - "options": { - "alignValue": "left", - "legend": { - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "mergeValues": true, - "rowHeight": 0.9, - "showValue": "auto", - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "libp2p_autonat_reachability_status", - "legendFormat": " ", - "range": true, - "refId": "A" - } - ], - "title": "Reachability Status", - "type": "state-timeline" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "max": 3, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "none" - }, - "overrides": [] - }, - "gridPos": { - "h": 6, - "w": 5, - "x": 18, - "y": 0 - }, - "id": 10, - "options": { - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "showThresholdLabels": false, - "showThresholdMarkers": true - }, - "pluginVersion": "9.3.2", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "builder", - "expr": "libp2p_autonat_reachability_status_confidence", - "legendFormat": "__auto", - "range": true, - "refId": "A" - } - ], - "title": "Reachability status confidence", - "type": "gauge" - }, - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "fieldConfig": { - "defaults": { - "color": { - "fixedColor": "green", - "mode": "fixed" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - } - ] - }, - "unit": "dateTimeAsLocalNoDateIfToday" - }, - "overrides": [] - }, - "gridPos": { - "h": 3, - "w": 14, - "x": 5, - "y": 6 - }, - "id": 12, - "options": { - "colorMode": "value", - "graphMode": "area", - "justifyMode": "auto", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "/^Value$/", - "values": false - }, - "textMode": "auto" - }, - "pluginVersion": "9.3.2", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "exemplar": false, - "expr": "libp2p_autonat_next_probe_timestamp * 1000", - "format": "table", - "instant": true, - "legendFormat": "__auto", - "range": false, - "refId": "A" - } - ], - "title": "Next Probe Time", - "type": "stat" - }, - { - "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": [ - { - "matcher": { - "id": "byName", - "options": "dial error" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "purple", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "dial refused" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "yellow", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "ok" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "green", - "mode": "fixed" - } - } - ] - } - ] - }, - "gridPos": { - "h": 9, - "w": 24, - "x": 0, - "y": 9 - }, - "id": 4, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "exemplar": false, - "expr": "increase(libp2p_autonat_received_dial_response_total[$__rate_interval])", - "instant": false, - "legendFormat": "{{response_status}}", - "range": true, - "refId": "A" - } - ], - "title": "Received Dial Responses", - "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": [ - { - "matcher": { - "id": "byName", - "options": "dial refused" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "yellow", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "dial error" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "purple", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "OK" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "green", - "mode": "fixed" - } - } - ] - } - ] - }, - "gridPos": { - "h": 9, - "w": 24, - "x": 0, - "y": 18 - }, - "id": 6, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "increase(libp2p_autonat_outgoing_dial_response_total[$__rate_interval])", - "legendFormat": "{{response_status}}", - "range": true, - "refId": "A" - } - ], - "title": "Outgoing Dial Responses", - "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": [ - { - "matcher": { - "id": "byName", - "options": "rate limited" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "red", - "mode": "fixed" - } - } - ] - } - ] - }, - "gridPos": { - "h": 10, - "w": 24, - "x": 0, - "y": 27 - }, - "id": 14, - "options": { - "legend": { - "calcs": [], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" - }, - "editorMode": "code", - "expr": "increase(libp2p_autonat_outgoing_dial_refused_total[$__rate_interval])", - "legendFormat": "{{refusal_reason}}", - "range": true, - "refId": "A" - } - ], - "title": "Outgoing Dial Refused", - "type": "timeseries" + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 18, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "alignValue": "center", + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "mergeValues": true, + "rowHeight": 0.9, + "showValue": "auto", + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "libp2p_autonat_reachability_status", + "legendFormat": " ", + "range": true, + "refId": "A" + } + ], + "title": "Reachability Status", + "type": "state-timeline" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 3, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 0 + }, + "id": 10, + "options": { + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true + }, + "pluginVersion": "9.3.6", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "builder", + "expr": "libp2p_autonat_reachability_status_confidence", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "Reachability status confidence", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "green", + "mode": "fixed" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "dateTimeFromNow" + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 3, + "x": 0, + "y": 7 + }, + "id": 12, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "/^Value$/", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.3.6", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "libp2p_autonat_next_probe_timestamp * 1000", + "format": "table", + "instant": true, + "legendFormat": "__auto", + "range": false, + "refId": "A" + } + ], + "title": "Next Probe Time", + "type": "stat" + }, + { + "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": [ + { + "matcher": { + "id": "byName", + "options": "dial error" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "purple", + "mode": "fixed" } - ], - "schemaVersion": 37, - "style": "dark", - "tags": [], - "templating": { - "list": [] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "dial refused" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "ok" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 21, + "x": 3, + "y": 7 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": false, + "expr": "increase(libp2p_autonat_received_dial_response_total[$__rate_interval])", + "instant": false, + "legendFormat": "{{response_status}}", + "range": true, + "refId": "A" + } + ], + "title": "Received Dial Responses", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Responses sent to peers that are asking us to dial them", + "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 + } + ] + } }, - "time": { - "from": "now-6h", - "to": "now" + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "dial refused" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "dial error" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "ok" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 16 + }, + "id": 6, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "increase(libp2p_autonat_outgoing_dial_response_total[$__rate_interval])", + "legendFormat": "{{response_status}}", + "range": true, + "refId": "A" + } + ], + "title": "Outgoing Dial Responses", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "There are multiple reasons why we'd refuse a dial-back request from a remote node:\n* rate limiting\n* no valid addresses\n* dial blocked by policy", + "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": [ + { + "matcher": { + "id": "byName", + "options": "rate limited" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 16 + }, + "id": 14, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true }, - "timepicker": {}, - "timezone": "", - "title": "libp2p autonat", - "uid": "YNWSyiJ4k", - "version": 16, - "weekStart": "" -} \ No newline at end of file + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "increase(libp2p_autonat_outgoing_dial_refused_total[$__rate_interval])", + "legendFormat": "{{refusal_reason}}", + "range": true, + "refId": "A" + } + ], + "title": "Outgoing Dial Refused", + "type": "timeseries" + } + ], + "schemaVersion": 37, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "libp2p autonat", + "uid": "YNWSyiJ4k", + "version": 5, + "weekStart": "" +}