diff --git a/collectors/channels_collector.go b/collectors/channels_collector.go index b5ee79c..e8e1bb3 100644 --- a/collectors/channels_collector.go +++ b/collectors/channels_collector.go @@ -23,6 +23,7 @@ type ChannelsCollector struct { numActiveChansDesc *prometheus.Desc numInactiveChansDesc *prometheus.Desc numPendingChansDesc *prometheus.Desc + numClosedChannels *prometheus.Desc satsSentDesc *prometheus.Desc satsRecvDesc *prometheus.Desc @@ -99,7 +100,12 @@ func NewChannelsCollector(lnd lndclient.LightningClient, errChan chan<- error, numPendingChansDesc: prometheus.NewDesc( "lnd_channels_pending_total", "total number of inactive channels", - nil, nil, + []string{"state"}, nil, + ), + numClosedChannels: prometheus.NewDesc( + "lnd_closed_channels_total", + "total number of closed channels", + []string{"close_type"}, nil, ), csvDelayDesc: prometheus.NewDesc( "lnd_channels_csv_delay", @@ -237,10 +243,6 @@ func (c *ChannelsCollector) Collect(ch chan<- prometheus.Metric) { c.numInactiveChansDesc, prometheus.GaugeValue, float64(getInfoResp.InactiveChannels), ) - ch <- prometheus.MustNewConstMetric( - c.numPendingChansDesc, prometheus.GaugeValue, - float64(getInfoResp.PendingChannels), - ) // Next, for each channel we'll export the total sum of our balances, // as well as the number of pending HTLCs. @@ -352,6 +354,53 @@ func (c *ChannelsCollector) Collect(ch chan<- prometheus.Metric) { } } + // Get the list of pending channels + pendingChannelsResp, err := c.lnd.PendingChannels(context.Background()) + if err != nil { + c.errChan <- fmt.Errorf("ChannelsCollector PendingChannels "+ + "failed with: %v", err) + return + } + ch <- prometheus.MustNewConstMetric( + c.numPendingChansDesc, prometheus.GaugeValue, + float64(len(pendingChannelsResp.PendingForceClose)), + "pending_force_close", + ) + ch <- prometheus.MustNewConstMetric( + c.numPendingChansDesc, prometheus.GaugeValue, + float64(len(pendingChannelsResp.PendingOpen)), + "pending_open", + ) + ch <- prometheus.MustNewConstMetric( + c.numPendingChansDesc, prometheus.GaugeValue, + float64(len(pendingChannelsResp.WaitingClose)), + "waiting_close", + ) + + // Get the list of closed channels. + closedChannelsResp, err := c.lnd.ClosedChannels(context.Background()) + if err != nil { + c.errChan <- fmt.Errorf("ChannelsCollector ClosedChannels "+ + "failed with: %v", err) + return + } + closeCounts := make(map[string]int) + for _, channel := range closedChannelsResp { + typeString, ok := closeTypeLabelMap[channel.CloseType] + if !ok { + Logger.Warnf("Unrecognized close type: %v", channel.CloseType) + continue + } + closeCounts[typeString]++ + } + for _, closeType := range closeTypeLabelMap { + count := closeCounts[closeType] + ch <- prometheus.MustNewConstMetric( + c.numClosedChannels, prometheus.GaugeValue, + float64(count), closeType, + ) + } + // Get all remote policies remotePolicies, err := c.getRemotePolicies(getInfoResp.IdentityPubkey) if err != nil { @@ -386,6 +435,15 @@ func (c *ChannelsCollector) Collect(ch chan<- prometheus.Metric) { } } +var closeTypeLabelMap = map[lndclient.CloseType]string{ + lndclient.CloseTypeCooperative: "cooperative", + lndclient.CloseTypeLocalForce: "local_force", + lndclient.CloseTypeRemoteForce: "remote_force", + lndclient.CloseTypeBreach: "breach", + lndclient.CloseTypeFundingCancelled: "funding_cancelled", + lndclient.CloseTypeAbandoned: "abandoned", +} + // approximateInboundFee calculates to forward fee for a specific amount charged by the // last hop before this node. func approximateInboundFee(amt btcutil.Amount, remotePolicies map[uint64]*lndclient.RoutingPolicy, diff --git a/grafana/provisioning/dashboards/channels.json b/grafana/provisioning/dashboards/channels.json index b622653..24644a8 100644 --- a/grafana/provisioning/dashboards/channels.json +++ b/grafana/provisioning/dashboards/channels.json @@ -15,7 +15,6 @@ "editable": true, "gnetId": null, "graphTooltip": 0, - "id": 8, "links": [], "panels": [ { @@ -59,21 +58,21 @@ "expr": "lnd_channels_pending_total", "format": "time_series", "intervalFactor": 1, - "legendFormat": "num_pending_chans", + "legendFormat": "{{state}}", "refId": "A" }, { "expr": "lnd_channels_active_total", "format": "time_series", "intervalFactor": 1, - "legendFormat": "num_active_chans", + "legendFormat": "active", "refId": "B" }, { "expr": "lnd_channels_inactive_total", "format": "time_series", "intervalFactor": 1, - "legendFormat": "num_inactive_chans", + "legendFormat": "inactive", "refId": "C" } ], @@ -864,13 +863,101 @@ "dashLength": 10, "dashes": false, "datasource": "Prometheus", + "description": "Uptime percentage of remote peer that we have the channel with. ", "fill": 1, "gridPos": { - "h": 8, + "h": 7, "w": 24, "x": 0, "y": 43 }, + "id": 22, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": {}, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "lnd_channel_uptime_percentage", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "cid: {{ chan_id }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Channel Uptime Percentage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": "1", + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 50 + }, "id": 8, "legend": { "avg": false, @@ -951,15 +1038,14 @@ "dashLength": 10, "dashes": false, "datasource": "Prometheus", - "description": "Uptime percentage of remote peer that we have the channel with. ", "fill": 1, "gridPos": { - "h": 7, - "w": 24, + "h": 8, + "w": 12, "x": 0, - "y": 34 + "y": 58 }, - "id": 22, + "id": 26, "legend": { "avg": false, "current": false, @@ -980,15 +1066,14 @@ "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, - "stack": true, + "stack": false, "steppedLine": false, "targets": [ { - "expr": "lnd_channel_uptime_percentage", + "expr": "lnd_closed_channels_total", "format": "time_series", - "hide": false, "intervalFactor": 1, - "legendFormat": "cid: {{ chan_id }}", + "legendFormat": "{{close_type}}", "refId": "A" } ], @@ -996,7 +1081,7 @@ "timeFrom": null, "timeRegions": [], "timeShift": null, - "title": "Channel Uptime Percentage", + "title": "Closed Channels", "tooltip": { "shared": true, "sort": 0, @@ -1012,11 +1097,11 @@ }, "yaxes": [ { - "format": "percentunit", + "format": "short", "label": null, "logBase": 1, - "max": "1", - "min": "0", + "max": null, + "min": null, "show": true }, {