Add metrics to relay

Add some metrics to the statsd relay.
* The number of StatsD packets relayed.
* The number lines that were too long to relay.

Also convert main.go to use promauto for metric registration.

Signed-off-by: SuperQ <superq@gmail.com>
This commit is contained in:
SuperQ 2021-09-02 11:56:15 +02:00
parent f39c9c3645
commit ae26c506f5
No known key found for this signature in database
GPG key ID: C646B23C9E3245F1
2 changed files with 48 additions and 42 deletions

63
main.go
View file

@ -26,6 +26,7 @@ import (
"github.com/go-kit/log" "github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/prometheus/common/promlog" "github.com/prometheus/common/promlog"
"github.com/prometheus/common/promlog/flag" "github.com/prometheus/common/promlog/flag"
@ -50,118 +51,118 @@ const (
) )
var ( var (
eventStats = prometheus.NewCounterVec( eventStats = promauto.NewCounterVec(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "statsd_exporter_events_total", Name: "statsd_exporter_events_total",
Help: "The total number of StatsD events seen.", Help: "The total number of StatsD events seen.",
}, },
[]string{"type"}, []string{"type"},
) )
eventsFlushed = prometheus.NewCounter( eventsFlushed = promauto.NewCounter(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "statsd_exporter_event_queue_flushed_total", Name: "statsd_exporter_event_queue_flushed_total",
Help: "Number of times events were flushed to exporter", Help: "Number of times events were flushed to exporter",
}, },
) )
eventsUnmapped = prometheus.NewCounter( eventsUnmapped = promauto.NewCounter(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "statsd_exporter_events_unmapped_total", Name: "statsd_exporter_events_unmapped_total",
Help: "The total number of StatsD events no mapping was found for.", Help: "The total number of StatsD events no mapping was found for.",
}) })
udpPackets = prometheus.NewCounter( udpPackets = promauto.NewCounter(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "statsd_exporter_udp_packets_total", Name: "statsd_exporter_udp_packets_total",
Help: "The total number of StatsD packets received over UDP.", Help: "The total number of StatsD packets received over UDP.",
}, },
) )
tcpConnections = prometheus.NewCounter( tcpConnections = promauto.NewCounter(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "statsd_exporter_tcp_connections_total", Name: "statsd_exporter_tcp_connections_total",
Help: "The total number of TCP connections handled.", Help: "The total number of TCP connections handled.",
}, },
) )
tcpErrors = prometheus.NewCounter( tcpErrors = promauto.NewCounter(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "statsd_exporter_tcp_connection_errors_total", Name: "statsd_exporter_tcp_connection_errors_total",
Help: "The number of errors encountered reading from TCP.", Help: "The number of errors encountered reading from TCP.",
}, },
) )
tcpLineTooLong = prometheus.NewCounter( tcpLineTooLong = promauto.NewCounter(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "statsd_exporter_tcp_too_long_lines_total", Name: "statsd_exporter_tcp_too_long_lines_total",
Help: "The number of lines discarded due to being too long.", Help: "The number of lines discarded due to being too long.",
}, },
) )
unixgramPackets = prometheus.NewCounter( unixgramPackets = promauto.NewCounter(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "statsd_exporter_unixgram_packets_total", Name: "statsd_exporter_unixgram_packets_total",
Help: "The total number of StatsD packets received over Unixgram.", Help: "The total number of StatsD packets received over Unixgram.",
}, },
) )
linesReceived = prometheus.NewCounter( linesReceived = promauto.NewCounter(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "statsd_exporter_lines_total", Name: "statsd_exporter_lines_total",
Help: "The total number of StatsD lines received.", Help: "The total number of StatsD lines received.",
}, },
) )
samplesReceived = prometheus.NewCounter( samplesReceived = promauto.NewCounter(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "statsd_exporter_samples_total", Name: "statsd_exporter_samples_total",
Help: "The total number of StatsD samples received.", Help: "The total number of StatsD samples received.",
}, },
) )
sampleErrors = prometheus.NewCounterVec( sampleErrors = promauto.NewCounterVec(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "statsd_exporter_sample_errors_total", Name: "statsd_exporter_sample_errors_total",
Help: "The total number of errors parsing StatsD samples.", Help: "The total number of errors parsing StatsD samples.",
}, },
[]string{"reason"}, []string{"reason"},
) )
tagsReceived = prometheus.NewCounter( tagsReceived = promauto.NewCounter(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "statsd_exporter_tags_total", Name: "statsd_exporter_tags_total",
Help: "The total number of DogStatsD tags processed.", Help: "The total number of DogStatsD tags processed.",
}, },
) )
tagErrors = prometheus.NewCounter( tagErrors = promauto.NewCounter(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "statsd_exporter_tag_errors_total", Name: "statsd_exporter_tag_errors_total",
Help: "The number of errors parsing DogStatsD tags.", Help: "The number of errors parsing DogStatsD tags.",
}, },
) )
configLoads = prometheus.NewCounterVec( configLoads = promauto.NewCounterVec(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "statsd_exporter_config_reloads_total", Name: "statsd_exporter_config_reloads_total",
Help: "The number of configuration reloads.", Help: "The number of configuration reloads.",
}, },
[]string{"outcome"}, []string{"outcome"},
) )
mappingsCount = prometheus.NewGauge(prometheus.GaugeOpts{ mappingsCount = promauto.NewGauge(prometheus.GaugeOpts{
Name: "statsd_exporter_loaded_mappings", Name: "statsd_exporter_loaded_mappings",
Help: "The current number of configured metric mappings.", Help: "The current number of configured metric mappings.",
}) })
conflictingEventStats = prometheus.NewCounterVec( conflictingEventStats = promauto.NewCounterVec(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "statsd_exporter_events_conflict_total", Name: "statsd_exporter_events_conflict_total",
Help: "The total number of StatsD events with conflicting names.", Help: "The total number of StatsD events with conflicting names.",
}, },
[]string{"type"}, []string{"type"},
) )
errorEventStats = prometheus.NewCounterVec( errorEventStats = promauto.NewCounterVec(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "statsd_exporter_events_error_total", Name: "statsd_exporter_events_error_total",
Help: "The total number of StatsD events discarded due to errors.", Help: "The total number of StatsD events discarded due to errors.",
}, },
[]string{"reason"}, []string{"reason"},
) )
eventsActions = prometheus.NewCounterVec( eventsActions = promauto.NewCounterVec(
prometheus.CounterOpts{ prometheus.CounterOpts{
Name: "statsd_exporter_events_actions_total", Name: "statsd_exporter_events_actions_total",
Help: "The total number of StatsD events by action.", Help: "The total number of StatsD events by action.",
}, },
[]string{"action"}, []string{"action"},
) )
metricsCount = prometheus.NewGaugeVec( metricsCount = promauto.NewGaugeVec(
prometheus.GaugeOpts{ prometheus.GaugeOpts{
Name: "statsd_exporter_metrics_total", Name: "statsd_exporter_metrics_total",
Help: "The total number of metrics.", Help: "The total number of metrics.",
@ -170,29 +171,6 @@ var (
) )
) )
func init() {
prometheus.MustRegister(version.NewCollector("statsd_exporter"))
prometheus.MustRegister(eventStats)
prometheus.MustRegister(eventsFlushed)
prometheus.MustRegister(eventsUnmapped)
prometheus.MustRegister(udpPackets)
prometheus.MustRegister(tcpConnections)
prometheus.MustRegister(tcpErrors)
prometheus.MustRegister(tcpLineTooLong)
prometheus.MustRegister(unixgramPackets)
prometheus.MustRegister(linesReceived)
prometheus.MustRegister(samplesReceived)
prometheus.MustRegister(sampleErrors)
prometheus.MustRegister(tagsReceived)
prometheus.MustRegister(tagErrors)
prometheus.MustRegister(configLoads)
prometheus.MustRegister(mappingsCount)
prometheus.MustRegister(conflictingEventStats)
prometheus.MustRegister(errorEventStats)
prometheus.MustRegister(eventsActions)
prometheus.MustRegister(metricsCount)
}
// uncheckedCollector wraps a Collector but its Describe method yields no Desc. // uncheckedCollector wraps a Collector but its Describe method yields no Desc.
// This allows incoming metrics to have inconsistent label sets // This allows incoming metrics to have inconsistent label sets
type uncheckedCollector struct { type uncheckedCollector struct {
@ -310,6 +288,7 @@ func main() {
level.Error(logger).Log("msg", "failed to set log level", "error", err) level.Error(logger).Log("msg", "failed to set log level", "error", err)
os.Exit(1) os.Exit(1)
} }
prometheus.MustRegister(version.NewCollector("statsd_exporter"))
parser := line.NewParser() parser := line.NewParser()
if *dogstatsdTagsEnabled { if *dogstatsdTagsEnabled {

View file

@ -22,6 +22,8 @@ import (
"github.com/go-kit/log" "github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/statsd_exporter/pkg/level" "github.com/prometheus/statsd_exporter/pkg/level"
) )
@ -31,8 +33,28 @@ type Relay struct {
conn *net.UDPConn conn *net.UDPConn
logger log.Logger logger log.Logger
packetLength uint packetLength uint
packetsTotal prometheus.Counter
longLinesTotal prometheus.Counter
} }
var (
relayPacketsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "statsd_exporter_relay_packets_total",
Help: "The number of StatsD packets relayed.",
},
[]string{"target"},
)
relayLongLinesTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "statsd_exporter_relay_long_lines_total",
Help: "The number lines that were too long to relay.",
},
[]string{"target"},
)
)
// NewRelay creates a statsd UDP relay. It can be used to send copies of statsd raw // NewRelay creates a statsd UDP relay. It can be used to send copies of statsd raw
// lines to a separate service. // lines to a separate service.
func NewRelay(l log.Logger, target string, packetLength uint) (*Relay, error) { func NewRelay(l log.Logger, target string, packetLength uint) (*Relay, error) {
@ -53,6 +75,9 @@ func NewRelay(l log.Logger, target string, packetLength uint) (*Relay, error) {
conn: conn, conn: conn,
logger: l, logger: l,
packetLength: packetLength, packetLength: packetLength,
packetsTotal: relayPacketsTotal.WithLabelValues(target),
longLinesTotal: relayLongLinesTotal.WithLabelValues(target),
} }
// Startup the UDP sender. // Startup the UDP sender.
@ -106,6 +131,7 @@ func (r *Relay) sendPacket(buf []byte) error {
} }
level.Debug(r.logger).Log("msg", "Sending packet", "length", len(buf), "data", buf) level.Debug(r.logger).Log("msg", "Sending packet", "length", len(buf), "data", buf)
_, err := r.conn.WriteToUDP(buf, r.addr) _, err := r.conn.WriteToUDP(buf, r.addr)
r.packetsTotal.Inc()
return err return err
} }
@ -118,6 +144,7 @@ func (r *Relay) RelayLine(l string) {
} }
if lineLength > r.packetLength-1 { if lineLength > r.packetLength-1 {
level.Warn(r.logger).Log("msg", "line too long, not relaying", "length", lineLength, "max", r.packetLength) level.Warn(r.logger).Log("msg", "line too long, not relaying", "length", lineLength, "max", r.packetLength)
r.longLinesTotal.Inc()
return return
} }
level.Debug(r.logger).Log("msg", "Relaying line", "line", l) level.Debug(r.logger).Log("msg", "Relaying line", "line", l)