func (c *DownloadsCollector) collectDownloadCounts(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
	all, err := c.ds.All()
	if err != nil {
		return c.Downloads, err
	}
	started, err := c.ds.Started()
	if err != nil {
		return c.DownloadsStarted, err
	}
	stopped, err := c.ds.Stopped()
	if err != nil {
		return c.DownloadsStopped, err
	}
	complete, err := c.ds.Complete()
	if err != nil {
		return c.DownloadsComplete, err
	}
	incomplete, err := c.ds.Incomplete()
	if err != nil {
		return c.DownloadsIncomplete, err
	}
	hashing, err := c.ds.Hashing()
	if err != nil {
		return c.DownloadsHashing, err
	}
	seeding, err := c.ds.Seeding()
	if err != nil {
		return c.DownloadsSeeding, err
	}
	leeching, err := c.ds.Leeching()
	if err != nil {
		return c.DownloadsLeeching, err
	}
	ch <- prometheus.MustNewConstMetric(
		c.Downloads,
		prometheus.GaugeValue,
		float64(len(all)),
	)
	ch <- prometheus.MustNewConstMetric(
		c.DownloadsStarted,
		prometheus.GaugeValue,
		float64(len(started)),
	)
	ch <- prometheus.MustNewConstMetric(
		c.DownloadsStopped,
		prometheus.GaugeValue,
		float64(len(stopped)),
	)
	ch <- prometheus.MustNewConstMetric(
		c.DownloadsComplete,
		prometheus.GaugeValue,
		float64(len(complete)),
	)
	ch <- prometheus.MustNewConstMetric(
		c.DownloadsIncomplete,
		prometheus.GaugeValue,
		float64(len(incomplete)),
	)
	ch <- prometheus.MustNewConstMetric(
		c.DownloadsHashing,
		prometheus.GaugeValue,
		float64(len(hashing)),
	)
	ch <- prometheus.MustNewConstMetric(
		c.DownloadsSeeding,
		prometheus.GaugeValue,
		float64(len(seeding)),
	)
	ch <- prometheus.MustNewConstMetric(
		c.DownloadsLeeching,
		prometheus.GaugeValue,
		float64(len(leeching)),
	)
	return nil, nil
}
collectDownloadCounts collects metrics which track number of downloads in
various possible states.
package rtorrentexporter
import (
	"log"
	"github.com/mdlayher/rtorrent"
	"github.com/prometheus/client_golang/prometheus"
)
var _ DownloadsSource = &rtorrent.DownloadService{}
type DownloadsSource interface {
	All() ([]string, error)
	Started() ([]string, error)
	Stopped() ([]string, error)
	Complete() ([]string, error)
	Incomplete() ([]string, error)
	Hashing() ([]string, error)
	Seeding() ([]string, error)
	Leeching() ([]string, error)
	Active() ([]string, error)
	BaseFilename(infoHash string) (string, error)
	DownloadRate(infoHash string) (int, error)
	DownloadTotal(infoHash string) (int, error)
	UploadRate(infoHash string) (int, error)
	UploadTotal(infoHash string) (int, error)
}
type DownloadsCollector struct {
	Downloads           *prometheus.Desc
	DownloadsStarted    *prometheus.Desc
	DownloadsStopped    *prometheus.Desc
	DownloadsComplete   *prometheus.Desc
	DownloadsIncomplete *prometheus.Desc
	DownloadsHashing    *prometheus.Desc
	DownloadsSeeding    *prometheus.Desc
	DownloadsLeeching   *prometheus.Desc
	DownloadsActive     *prometheus.Desc
	DownloadRateBytes  *prometheus.Desc
	DownloadTotalBytes *prometheus.Desc
	UploadRateBytes    *prometheus.Desc
	UploadTotalBytes   *prometheus.Desc
	ds DownloadsSource
}
var _ prometheus.Collector = &DownloadsCollector{}
func NewDownloadsCollector(ds DownloadsSource) *DownloadsCollector {
	const (
		subsystem = "downloads"
	)
	var (
		labels = []string{"info_hash", "name"}
	)
	return &DownloadsCollector{
		Downloads: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "", subsystem),
			"Total number of downloads.",
			nil,
			nil,
		),
		DownloadsStarted: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, subsystem, "started"),
			"Number of started downloads.",
			nil,
			nil,
		),
		DownloadsStopped: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, subsystem, "stopped"),
			"Number of stopped downloads.",
			nil,
			nil,
		),
		DownloadsComplete: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, subsystem, "complete"),
			"Number of complete downloads.",
			nil,
			nil,
		),
		DownloadsIncomplete: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, subsystem, "incomplete"),
			"Number of incomplete downloads.",
			nil,
			nil,
		),
		DownloadsHashing: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, subsystem, "hashing"),
			"Number of hashing downloads.",
			nil,
			nil,
		),
		DownloadsSeeding: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, subsystem, "seeding"),
			"Number of seeding downloads.",
			nil,
			nil,
		),
		DownloadsLeeching: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, subsystem, "leeching"),
			"Number of leeching downloads.",
			nil,
			nil,
		),
		DownloadsActive: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, subsystem, "active"),
			"Number of active downloads.",
			nil,
			nil,
		),
		DownloadRateBytes: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, subsystem, "download_rate_bytes"),
			"Current download rate in bytes.",
			labels,
			nil,
		),
		DownloadTotalBytes: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, subsystem, "download_total_bytes"),
			"Total Bytes downloaded.",
			labels,
			nil,
		),
		UploadRateBytes: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, subsystem, "upload_rate_bytes"),
			"Current upload rate in bytes.",
			labels,
			nil,
		),
		UploadTotalBytes: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, subsystem, "upload_total_bytes"),
			"Total Bytes uploaded.",
			labels,
			nil,
		),
		ds: ds,
	}
}
func (c *DownloadsCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
	if desc, err := c.collectDownloadCounts(ch); err != nil {
		return desc, err
	}
	if desc, err := c.collectActiveDownloads(ch); err != nil {
		return desc, err
	}
	return nil, nil
}