99 lines
3.1 KiB
Go
99 lines
3.1 KiB
Go
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 {
|
|
labels := append([]string{"domain"}, collector.GeoLabelNames()...)
|
|
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 {
|
|
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...)
|
|
}
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|