Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[DEPS]: Upgrade deps and migrate to slog / promslog #45

Merged
merged 3 commits into from
Jan 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 29 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ The missing OPNsense exporter for Prometheus
![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/AthennaMind/opnsense-exporter/ci.yml)
![GitHub go.mod Go version (branch)](https://img.shields.io/github/go-mod/go-version/AthennaMind/opnsense-exporter/main)

`Still under heavy development. The full metrics list is not yet implemented. May include breaking changes of the configuration and metrics list.`

## Table of Contents

- **[About](#about)**
Expand All @@ -32,31 +30,31 @@ Focusing specifically on OPNsense, this exporter provides metrics about OPNsense

While the `node_exporter` must be installed on the firewall itself, this exporter can be installed on any machine that has network access to the OPNsense API.


## Grafana Dashboard

**[OPNsense Exporter Dashboard](https://grafana.com/grafana/dashboards/21113)**

![gateways](docs/assets/gateways.png)

Finaly we have a Grafana dashboard to visualize the data from this exporter. The dashboard can be imported into Grafana by using the id `21113` or by importing the `deploy/grafana/dashboard-v1.json` file. Please give a review to the dashboard if you like our work. Thank you!
Finaly we have a Grafana dashboard to visualize the data from this exporter. The dashboard can be imported into Grafana by using the id `21113` or by importing the `deploy/grafana/dashboard-v1.json` file. Please give a review to the dashboard if you like our work. Thank you!

## OPNsense user permissions

| Type | Name |
|----------|:-------------: |
| GUI | Diagnostics: ARP Table |
| GUI | Diagnostics: Firewall statistics |
| GUI | Diagnostics: Netstat |
| GUI | Reporting: Traffic |
| GUI | Services: Unbound (MVC) |
| GUI | Status: DHCP leases |
| GUI | Status: DHCP leases |
| GUI | Status: DNS Overview |
| GUI | Status: OpenVPN |
| GUI | Status: Services |
| GUI | System: Firmware |
| GUI | System: Gateways |
| GUI | System: Settings: Cron |
| GUI | System: Status |
| GUI | System: Status |
| GUI | VPN: OpenVPN: Instances |
| GUI | VPN: WireGuard |

Expand Down Expand Up @@ -147,7 +145,6 @@ services:

**TODO**


## Configuration

The configuration of this tool is following the standard alongside the Prometheus ecosystem. This exporter can be configured using command-line flags or environment variables.
Expand Down Expand Up @@ -190,67 +187,47 @@ To disable the exporter metrics itself use the following flag:

```bash
Flags:
-h, --[no-]help Show context-sensitive help (also try --help-long
and --help-man).
-h, --[no-]help Show context-sensitive help (also try --help-long and --help-man).
--[no-]exporter.disable-arp-table
Disable the scraping of the ARP table
($OPNSENSE_EXPORTER_DISABLE_ARP_TABLE)
Disable the scraping of the ARP table ($OPNSENSE_EXPORTER_DISABLE_ARP_TABLE)
--[no-]exporter.disable-cron-table
Disable the scraping of the cron table
($OPNSENSE_EXPORTER_DISABLE_CRON_TABLE)
Disable the scraping of the cron table ($OPNSENSE_EXPORTER_DISABLE_CRON_TABLE)
--[no-]exporter.disable-wireguard
Disable the scraping of Wireguard service
($OPNSENSE_EXPORTER_DISABLE_WIREGUARD)
Disable the scraping of Wireguard service ($OPNSENSE_EXPORTER_DISABLE_WIREGUARD)
--[no-]exporter.disable-unbound
Disable the scraping of Unbound service
($OPNSENSE_EXPORTER_DISABLE_UNBOUND)
Disable the scraping of Unbound service ($OPNSENSE_EXPORTER_DISABLE_UNBOUND)
--[no-]exporter.disable-openvpn
Disable the scraping of OpenVPN service
($OPNSENSE_EXPORTER_DISABLE_OPENVPN)
Disable the scraping of OpenVPN service ($OPNSENSE_EXPORTER_DISABLE_OPENVPN)
--[no-]exporter.disable-firewall
Disable the scraping of Firewall (pf) metrics
($OPNSENSE_EXPORTER_DISABLE_FIREWALL)
Disable the scraping of the firewall (pf) metrics ($OPNSENSE_EXPORTER_DISABLE_FIREWALL)
--[no-]exporter.disable-firmware
Disable the scraping of Firmware infos
($OPNSENSE_EXPORTER_DISABLE_FIRMWARE)
Disable the scraping of the firmware metrics ($OPNSENSE_EXPORTER_DISABLE_FIRMWARE)
--web.telemetry-path="/metrics"
Path under which to expose metrics.
--[no-]web.disable-exporter-metrics
Exclude metrics about the exporter
itself (promhttp_*, process_*, go_*).
Exclude metrics about the exporter itself (promhttp_*, process_*, go_*).
($OPNSENSE_EXPORTER_DISABLE_EXPORTER_METRICS)
--runtime.gomaxprocs=2 The target number of CPUs that the Go runtime will
run on (GOMAXPROCS) ($GOMAXPROCS)
--runtime.gomaxprocs=2 The target number of CPUs that the Go runtime will run on (GOMAXPROCS) ($GOMAXPROCS)
--exporter.instance-label=EXPORTER.INSTANCE-LABEL
Label to use to identify the instance in
every metric. If you have multiple instances
of the exporter, you can differentiate them
by using different value in this flag, that
represents the instance of the target OPNsense.
($OPNSENSE_EXPORTER_INSTANCE_LABEL)
--[no-]web.systemd-socket Use systemd socket activation listeners instead of
port listeners (Linux only).
Label to use to identify the instance in every metric. If you have multiple instances of the
exporter, you can differentiate them by using different value in this flag, that represents
the instance of the target OPNsense. ($OPNSENSE_EXPORTER_INSTANCE_LABEL)
--[no-]web.systemd-socket Use systemd socket activation listeners instead of port listeners (Linux only).
--web.listen-address=:8080 ...
Addresses on which to expose metrics and web
interface. Repeatable for multiple addresses.
--web.config.file="" Path to configuration file that can
enable TLS or authentication. See:
Addresses on which to expose metrics and web interface. Repeatable for multiple addresses.
Examples: `:9100` or `[::1]:9100` for http, `vsock://:9100` for vsock
--web.config.file="" Path to configuration file that can enable TLS or authentication. See:
https://github.com/prometheus/exporter-toolkit/blob/master/docs/web-configuration.md
--log.level="info" Log level. One of: [debug, info, warn, error]
--log.format="logfmt" Log format. One of: [logfmt, json]
--opnsense.protocol=OPNSENSE.PROTOCOL
Protocol to use to connect to
OPNsense API. One of: [http, https]
Protocol to use to connect to OPNsense API. One of: [http, https]
($OPNSENSE_EXPORTER_OPS_PROTOCOL)
--opnsense.address=OPNSENSE.ADDRESS
Hostname or IP address of OPNsense API
($OPNSENSE_EXPORTER_OPS_API)
--opnsense.api-key="" API key to use to connect to OPNsense API.
This flag/ENV or the OPS_API_KEY_FILE my be set.
Hostname or IP address of OPNsense API ($OPNSENSE_EXPORTER_OPS_API)
--opnsense.api-key="" API key to use to connect to OPNsense API. This flag/ENV or the OPS_API_KEY_FILE my be set.
($OPNSENSE_EXPORTER_OPS_API_KEY)
--opnsense.api-secret="" API secret to use to connect to OPNsense API. This
flag/ENV or the OPS_API_SECRET_FILE my be set.
($OPNSENSE_EXPORTER_OPS_API_SECRET)
--[no-]opnsense.insecure Disable TLS certificate verification
($OPNSENSE_EXPORTER_OPS_INSECURE)
--opnsense.api-secret="" API secret to use to connect to OPNsense API. This flag/ENV or the OPS_API_SECRET_FILE my be
set. ($OPNSENSE_EXPORTER_OPS_API_SECRET)
--[no-]opnsense.insecure Disable TLS certificate verification ($OPNSENSE_EXPORTER_OPS_INSECURE)
--log.level=info Only log messages with the given severity or above. One of: [debug, info, warn, error]
--log.format=logfmt Output format of log messages. One of: [logfmt, json]
```
16 changes: 7 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,16 @@ go 1.23

require (
github.com/alecthomas/kingpin/v2 v2.4.0
github.com/go-kit/log v0.2.1
github.com/prometheus/client_golang v1.20.5
github.com/prometheus/common v0.61.0
github.com/prometheus/exporter-toolkit v0.12.0
github.com/prometheus/common v0.62.0
github.com/prometheus/exporter-toolkit v0.13.2
)

require (
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/jpillora/backoff v1.0.0 // indirect
github.com/klauspost/compress v1.17.11 // indirect
github.com/mdlayher/socket v0.5.1 // indirect
Expand All @@ -25,12 +23,12 @@ require (
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/net v0.32.0 // indirect
golang.org/x/oauth2 v0.24.0 // indirect
golang.org/x/crypto v0.32.0 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/oauth2 v0.25.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/protobuf v1.35.2 // indirect
google.golang.org/protobuf v1.36.4 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
32 changes: 14 additions & 18 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
Expand Down Expand Up @@ -42,10 +38,10 @@ github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ=
github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s=
github.com/prometheus/exporter-toolkit v0.12.0 h1:DkE5RcEZR3lQA2QD5JLVQIf41dFKNsVMXFhgqcif7fo=
github.com/prometheus/exporter-toolkit v0.12.0/go.mod h1:fQH0KtTn0yrrS0S82kqppRjDDiwMfIQUwT+RBRRhwUc=
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
github.com/prometheus/exporter-toolkit v0.13.2 h1:Z02fYtbqTMy2i/f+xZ+UK5jy/bl1Ex3ndzh06T/Q9DQ=
github.com/prometheus/exporter-toolkit v0.13.2/go.mod h1:tCqnfx21q6qN1KA4U3Bfb8uWzXfijIrJz3/kTIqMV7g=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
Expand All @@ -62,20 +58,20 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
Expand Down
10 changes: 4 additions & 6 deletions internal/collector/arp_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ package collector

import (
"fmt"
"log/slog"

"github.com/AthennaMind/opnsense-exporter/opnsense"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/prometheus/client_golang/prometheus"
)

type arpTableCollector struct {
entries *prometheus.Desc
log log.Logger
log *slog.Logger
subsystem string
instance string
}
Expand All @@ -26,12 +25,11 @@ func (c *arpTableCollector) Name() string {
return c.subsystem
}

func (c *arpTableCollector) Register(namespace, instance string, log log.Logger) {
func (c *arpTableCollector) Register(namespace, instance string, log *slog.Logger) {
c.log = log
c.instance = instance

level.Debug(c.log).
Log("msg", "Registering collector", "collector", c.Name())
c.log.Debug("Registering collector", "collector", c.Name())

c.entries = buildPrometheusDesc(c.subsystem, "entries",
"Arp entries by ip, mac, hostname, interface description, type, expired and permanent",
Expand Down
18 changes: 8 additions & 10 deletions internal/collector/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ package collector
import (
"errors"
"fmt"
"log/slog"
"sync"

"github.com/go-kit/log"
"github.com/go-kit/log/level"

"github.com/AthennaMind/opnsense-exporter/opnsense"
"github.com/prometheus/client_golang/prometheus"
)
Expand Down Expand Up @@ -36,7 +34,7 @@ const (

// CollectorInstance is the interface a service specific collectors must implement.
type CollectorInstance interface {
Register(namespace, isntance string, log log.Logger)
Register(namespace, isntance string, log *slog.Logger)
Name() string
Describe(ch chan<- *prometheus.Desc)
Update(client *opnsense.Client, ch chan<- prometheus.Metric) *opnsense.APICallError
Expand All @@ -49,7 +47,7 @@ var collectorInstances []CollectorInstance
type Collector struct {
Client *opnsense.Client
mutex sync.RWMutex
log log.Logger
log *slog.Logger

isUp prometheus.Gauge
firewallHealthStatus prometheus.Gauge
Expand Down Expand Up @@ -116,7 +114,7 @@ func WithoutOpenVPNCollector() Option {
}

// New creates a new Collector instance.
func New(client *opnsense.Client, log log.Logger, instanceName string, options ...Option) (*Collector, error) {
func New(client *opnsense.Client, log *slog.Logger, instanceName string, options ...Option) (*Collector, error) {
c := Collector{
Client: client,
log: log,
Expand Down Expand Up @@ -219,8 +217,8 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) {
defer c.mutex.Unlock()

if err := c.collectHealthMetrics(ch); err != nil {
level.Error(c.log).Log(
"msg", "failed to fetch system health status; skipping other metrics",
c.log.Error(
"failed to fetch system health status; skipping other metrics",
"err", err,
)
}
Expand All @@ -231,8 +229,8 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) {
for _, collector := range c.collectors {
go func(coll CollectorInstance) {
if err := coll.Update(c.Client, ch); err != nil {
level.Error(c.log).Log(
"msg", "failed to update",
c.log.Error(
"failed to update",
"component", "collector",
"collector_name", coll.Name(),
"err", err,
Expand Down
6 changes: 3 additions & 3 deletions internal/collector/collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (

"github.com/AthennaMind/opnsense-exporter/internal/options"
"github.com/AthennaMind/opnsense-exporter/opnsense"
"github.com/go-kit/log"
"github.com/prometheus/common/promslog"
)

func TestCollector(t *testing.T) {
Expand All @@ -17,7 +17,7 @@ func TestCollector(t *testing.T) {
client, err := opnsense.NewClient(
conf,
"test",
log.NewNopLogger(),
promslog.NewNopLogger(),
)
if err != nil {
t.Errorf("expected no error, got %v", err)
Expand All @@ -31,7 +31,7 @@ func TestCollector(t *testing.T) {
WithoutFirewallCollector(),
}

collector, err := New(&client, log.NewNopLogger(), "test", collectOpts...)
collector, err := New(&client, promslog.NewNopLogger(), "test", collectOpts...)
if err != nil {
t.Errorf("expected no error when creating collector, got %v", err)
}
Expand Down
Loading
Loading