Contributing¶
This guide covers the development workflow, tooling, and conventions for contributing to the OPNsense Exporter.
This page is the canonical contribution guide. The repository root CONTRIBUTING.md is a short
pointer to this page — edit only this file; do not duplicate content into the root file.
Prerequisites¶
- Go - Check
go.modfor the required version (currently Go 1.26) - Make - For build automation
- golangci-lint - Optional; runs in CI but can be used locally
- Docker - Optional; for container builds
Getting started¶
Clone the repository:
Build commands¶
| Command | Description |
|---|---|
make |
Build the binary (static, version-embedded) |
make test |
Run all tests: go test ./... |
make lint |
Run gofmt and golangci-lint --fix |
make sync-vendor |
go mod tidy && go mod vendor |
make clean |
Format source and remove the binary |
Building on macOS¶
The Makefile uses -extldflags "-static" which does not work on macOS. Use this instead:
Running a single test¶
Project conventions¶
Vendor directory¶
The vendor directory is committed to the repository. Always run make sync-vendor after modifying go.mod:
Static binary¶
The build produces a fully static binary with:
CGO_ENABLED=0-ldflags "-s -w"for stripped, optimized output-trimpathand-mod=vendorfor reproducibility
Version¶
The version is embedded at build time via -ldflags -X main.version=.... The version.txt file at the repository root is managed by release-please and tracks the current released version; GoReleaser embeds the git tag as the version in release builds, while local make builds embed local-test.
Linters¶
The project uses golangci-lint with:
misspellandreviveenabledunuseddisabled
Linting runs in CI. Locally, make lint will run gofmt formatting (the golangci-lint step may fail if the tool is not installed, which is expected).
Commit messages¶
This project uses conventional commits for automated changelog generation via release-please:
feat(collector): add new subsystem collector
fix(kea): handle disabled DHCP service response
docs: update README with new collector descriptions
refactor: modernize Go syntax patterns
Changelog¶
Release history lives entirely in CHANGELOG.md, generated by release-please
from conventional commit messages. There is no separate "changes from upstream" section to maintain —
do not add one to README.md; it was deliberately removed and conventional commit messages are what
drive the changelog instead.
Pull request checklist¶
Before submitting a PR, the local equivalent of everything ci-success requires:
- Code compiles:
makeorCGO_ENABLED=0 go build - Tests pass:
go test ./...(make test) - Tests pass under the race detector:
go test -race ./... - Linters pass:
golangci-lint run ./...(make lintrunsgofmtplusgolangci-lint --fix) - Generated docs are current:
make docs-check(runmake docsfirst if it fails, then commit the regenerated files — never hand-edit content between<!-- docgen:begin/end -->markers) - Grafana dashboard/alerts are current:
make grafana-check(runmake dashboardand, if alert rules changed,make rules, then commit the regenerated files — seegrafana/README.md) - Vendor is synced (if dependencies changed):
make sync-vendor - Conventional commit messages used
- New collectors follow the adding a collector guide
CI additionally verifies the container image builds and embeds the correct version
(docker-build-verify); this can optionally be reproduced locally with docker build . but is not
required before opening a PR.
Project structure¶
.
+-- main.go # Entry point
+-- internal/
| +-- collector/ # Prometheus collectors
| | +-- collector.go # Top-level collector, interface
| | +-- arp_table.go # Per-subsystem collector files
| | +-- gateways.go
| | +-- ...
| +-- options/ # CLI flags and configuration
| | +-- ops.go # OPNsense connection config
| | +-- exporter.go # Server config
| | +-- collectors.go # Collector enable/disable switches
| +-- logship/ # Syslog + Zenarmor receivers, log enrichment, OTLP log sink
| | +-- syslog/ # Per-program syslog parsers
| | +-- zenarmor/ # Zenarmor HTTP receiver
| | +-- enrich/ # Device/service enrichment
| | +-- flowlog/ # Sink for internal/flow's correlated flow logs
| | +-- ...
| +-- flow/ # NetFlow receiver, rollup, correlator
| | +-- netflow/ # NetFlow wire decode + listener
| | +-- correlate.go # NetFlow + Zenarmor conn merge
| | +-- ...
| +-- webui/ # Operator console served at /
| | +-- server.go # Route registration, self-registering tabs
| | +-- status.go
| | +-- ...
| +-- metricsnap/ # Passive metric capture, teed at both scrape sites
| +-- recorder.go
+-- opnsense/ # API client
| +-- client.go # HTTP client, TLS, retries
| +-- gateways.go # Per-subsystem Fetch methods
| +-- ...
+-- deploy/ # Deployment manifests
| +-- k8s/ # Kubernetes manifests
+-- grafana/ # Grafana dashboard builder, panels, alert rules
+-- docs/ # Documentation (this site)
+-- vendor/ # Vendored dependencies