dnstt_exporter/internal/dnstt/exporter.go

100 lines
3.1 KiB
Go
Raw Normal View History

2026-05-05 13:43:02 +02:00
package dnstt
import "github.com/prometheus/client_golang/prometheus"
const namespace = "dnstt"
// Exporter exposes aggregate DNSTT traffic metrics from a Collector.
type Exporter struct {
collector *Collector
activeClients *prometheus.Desc
peakClients *prometheus.Desc
queries *prometheus.Desc
bytesIn *prometheus.Desc
bytesOut *prometheus.Desc
sessions *prometheus.Desc
}
// NewExporter creates a Prometheus collector for DNSTT metrics.
func NewExporter(collector *Collector) *Exporter {
2026-05-05 13:57:12 +02:00
labels := append([]string{"domain"}, collector.GeoLabelNames()...)
2026-05-05 13:43:02 +02:00
return &Exporter{
collector: collector,
activeClients: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", "active_clients"),
"Number of DNSTT client sessions observed within the active timeout window.",
labels,
nil,
),
peakClients: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", "peak_clients"),
"Maximum concurrent active DNSTT client sessions observed.",
labels,
nil,
),
queries: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", "queries_total"),
"Total DNSTT DNS queries observed.",
labels,
nil,
),
bytesIn: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", "bytes_in_total"),
"Total bytes observed in DNSTT DNS queries.",
labels,
nil,
),
bytesOut: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", "bytes_out_total"),
"Total bytes observed in DNSTT DNS responses.",
labels,
nil,
),
sessions: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", "sessions_total"),
"Total unique DNSTT client sessions observed.",
labels,
nil,
),
}
}
// Describe sends metric descriptors to Prometheus.
func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
ch <- e.activeClients
ch <- e.peakClients
ch <- e.queries
ch <- e.bytesIn
ch <- e.bytesOut
ch <- e.sessions
}
// Collect sends current metric values to Prometheus.
func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
for _, tunnel := range e.collector.Snapshot().Tunnels {
2026-05-05 13:57:12 +02:00
for _, series := range tunnel.Series {
labels := e.labelValues(series)
ch <- prometheus.MustNewConstMetric(e.activeClients, prometheus.GaugeValue, float64(series.ActiveClients), labels...)
ch <- prometheus.MustNewConstMetric(e.peakClients, prometheus.GaugeValue, float64(series.PeakClients), labels...)
ch <- prometheus.MustNewConstMetric(e.queries, prometheus.CounterValue, float64(series.TotalQueries), labels...)
ch <- prometheus.MustNewConstMetric(e.bytesIn, prometheus.CounterValue, float64(series.BytesIn), labels...)
ch <- prometheus.MustNewConstMetric(e.bytesOut, prometheus.CounterValue, float64(series.BytesOut), labels...)
ch <- prometheus.MustNewConstMetric(e.sessions, prometheus.CounterValue, float64(series.TotalSessions), labels...)
}
2026-05-05 13:43:02 +02:00
}
}
2026-05-05 13:57:12 +02:00
func (e *Exporter) labelValues(series SeriesSnapshot) []string {
values := []string{series.Domain}
for _, label := range e.collector.GeoLabelNames() {
switch label {
case "country":
values = append(values, series.Country)
case "asn":
values = append(values, series.ASN)
}
}
return values
}