forked from mirrors/statsd_exporter
Merge pull request #106 from prometheus/mr/rework-sample-counters
Break out the telemetry during sample processing
This commit is contained in:
commit
d9db83b9be
2 changed files with 79 additions and 18 deletions
31
exporter.go
31
exporter.go
|
@ -402,14 +402,14 @@ func buildEvent(statType, metric string, value float64, relative bool, labels ma
|
|||
|
||||
func parseDogStatsDTagsToLabels(component string) map[string]string {
|
||||
labels := map[string]string{}
|
||||
networkStats.WithLabelValues("dogstatsd_tags").Inc()
|
||||
tagsReceived.Inc()
|
||||
tags := strings.Split(component, ",")
|
||||
for _, t := range tags {
|
||||
t = strings.TrimPrefix(t, "#")
|
||||
kv := strings.SplitN(t, ":", 2)
|
||||
|
||||
if len(kv) < 2 || len(kv[1]) == 0 {
|
||||
networkStats.WithLabelValues("malformed_dogstatsd_tag").Inc()
|
||||
tagErrors.Inc()
|
||||
log.Debugf("Malformed or empty DogStatsD tag %s in component %s", t, component)
|
||||
continue
|
||||
}
|
||||
|
@ -427,7 +427,7 @@ func lineToEvents(line string) Events {
|
|||
|
||||
elements := strings.SplitN(line, ":", 2)
|
||||
if len(elements) < 2 || len(elements[0]) == 0 || !utf8.ValidString(line) {
|
||||
networkStats.WithLabelValues("malformed_line").Inc()
|
||||
sampleErrors.WithLabelValues("malformed_line").Inc()
|
||||
log.Debugln("Bad line from StatsD:", line)
|
||||
return events
|
||||
}
|
||||
|
@ -441,10 +441,11 @@ func lineToEvents(line string) Events {
|
|||
}
|
||||
samples:
|
||||
for _, sample := range samples {
|
||||
samplesReceived.Inc()
|
||||
components := strings.Split(sample, "|")
|
||||
samplingFactor := 1.0
|
||||
if len(components) < 2 || len(components) > 4 {
|
||||
networkStats.WithLabelValues("malformed_component").Inc()
|
||||
sampleErrors.WithLabelValues("malformed_component").Inc()
|
||||
log.Debugln("Bad component on line:", line)
|
||||
continue
|
||||
}
|
||||
|
@ -458,7 +459,7 @@ samples:
|
|||
value, err := strconv.ParseFloat(valueStr, 64)
|
||||
if err != nil {
|
||||
log.Debugf("Bad value %s on line: %s", valueStr, line)
|
||||
networkStats.WithLabelValues("malformed_value").Inc()
|
||||
sampleErrors.WithLabelValues("malformed_value").Inc()
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -468,7 +469,7 @@ samples:
|
|||
for _, component := range components[2:] {
|
||||
if len(component) == 0 {
|
||||
log.Debugln("Empty component on line: ", line)
|
||||
networkStats.WithLabelValues("malformed_component").Inc()
|
||||
sampleErrors.WithLabelValues("malformed_component").Inc()
|
||||
continue samples
|
||||
}
|
||||
}
|
||||
|
@ -478,13 +479,13 @@ samples:
|
|||
case '@':
|
||||
if statType != "c" && statType != "ms" {
|
||||
log.Debugln("Illegal sampling factor for non-counter metric on line", line)
|
||||
networkStats.WithLabelValues("illegal_sample_factor").Inc()
|
||||
sampleErrors.WithLabelValues("illegal_sample_factor").Inc()
|
||||
continue
|
||||
}
|
||||
samplingFactor, err = strconv.ParseFloat(component[1:], 64)
|
||||
if err != nil {
|
||||
log.Debugf("Invalid sampling factor %s on line %s", component[1:], line)
|
||||
networkStats.WithLabelValues("invalid_sample_factor").Inc()
|
||||
sampleErrors.WithLabelValues("invalid_sample_factor").Inc()
|
||||
}
|
||||
if samplingFactor == 0 {
|
||||
samplingFactor = 1
|
||||
|
@ -499,7 +500,7 @@ samples:
|
|||
labels = parseDogStatsDTagsToLabels(component)
|
||||
default:
|
||||
log.Debugf("Invalid sampling factor or tag section %s on line %s", components[2], line)
|
||||
networkStats.WithLabelValues("invalid_sample_factor").Inc()
|
||||
sampleErrors.WithLabelValues("invalid_sample_factor").Inc()
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
@ -509,12 +510,11 @@ samples:
|
|||
event, err := buildEvent(statType, metric, value, relative, labels)
|
||||
if err != nil {
|
||||
log.Debugf("Error building event on line %s: %s", line, err)
|
||||
networkStats.WithLabelValues("illegal_event").Inc()
|
||||
sampleErrors.WithLabelValues("illegal_event").Inc()
|
||||
continue
|
||||
}
|
||||
events = append(events, event)
|
||||
}
|
||||
networkStats.WithLabelValues("legal").Inc()
|
||||
}
|
||||
return events
|
||||
}
|
||||
|
@ -535,9 +535,11 @@ func (l *StatsDUDPListener) Listen(e chan<- Events) {
|
|||
}
|
||||
|
||||
func (l *StatsDUDPListener) handlePacket(packet []byte, e chan<- Events) {
|
||||
udpPackets.Inc()
|
||||
lines := strings.Split(string(packet), "\n")
|
||||
events := Events{}
|
||||
for _, line := range lines {
|
||||
linesReceived.Inc()
|
||||
events = append(events, lineToEvents(line)...)
|
||||
}
|
||||
e <- events
|
||||
|
@ -560,21 +562,24 @@ func (l *StatsDTCPListener) Listen(e chan<- Events) {
|
|||
func (l *StatsDTCPListener) handleConn(c *net.TCPConn, e chan<- Events) {
|
||||
defer c.Close()
|
||||
|
||||
tcpConnections.Inc()
|
||||
|
||||
r := bufio.NewReader(c)
|
||||
for {
|
||||
line, isPrefix, err := r.ReadLine()
|
||||
if err != nil {
|
||||
if err != io.EOF {
|
||||
networkStats.WithLabelValues("tcp_error").Inc()
|
||||
tcpErrors.Inc()
|
||||
log.Debugf("Read %s failed: %v", c.RemoteAddr(), err)
|
||||
}
|
||||
break
|
||||
}
|
||||
if isPrefix {
|
||||
networkStats.WithLabelValues("tcp_line_too_long").Inc()
|
||||
tcpLineTooLong.Inc()
|
||||
log.Debugf("Read %s failed: line too long", c.RemoteAddr())
|
||||
break
|
||||
}
|
||||
linesReceived.Inc()
|
||||
e <- lineToEvents(string(line))
|
||||
}
|
||||
}
|
||||
|
|
66
telemetry.go
66
telemetry.go
|
@ -29,12 +29,60 @@ var (
|
|||
Name: "statsd_exporter_events_unmapped_total",
|
||||
Help: "The total number of StatsD events no mapping was found for.",
|
||||
})
|
||||
networkStats = prometheus.NewCounterVec(
|
||||
udpPackets = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_packets_total",
|
||||
Help: "The total number of StatsD packets seen.",
|
||||
Name: "statsd_exporter_udp_packets_total",
|
||||
Help: "The total number of StatsD packets received over UDP.",
|
||||
},
|
||||
)
|
||||
tcpConnections = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_tcp_connections_total",
|
||||
Help: "The total number of TCP connections handled.",
|
||||
},
|
||||
)
|
||||
tcpErrors = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_tcp_connection_errors_total",
|
||||
Help: "The number of errors encountered reading from TCP.",
|
||||
},
|
||||
)
|
||||
tcpLineTooLong = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_tcp_too_long_lines_total",
|
||||
Help: "The number of lines discarded due to being too long.",
|
||||
},
|
||||
)
|
||||
linesReceived = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_lines_total",
|
||||
Help: "The total number of StatsD lines received.",
|
||||
},
|
||||
)
|
||||
samplesReceived = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_samples_total",
|
||||
Help: "The total number of StatsD samples received.",
|
||||
},
|
||||
)
|
||||
sampleErrors = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_sample_errors_total",
|
||||
Help: "The total number of errors parsing StatsD samples.",
|
||||
},
|
||||
[]string{"reason"},
|
||||
)
|
||||
tagsReceived = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_tags_total",
|
||||
Help: "The total number of DogStatsD tags processed.",
|
||||
},
|
||||
)
|
||||
tagErrors = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "statsd_exporter_tag_errors_total",
|
||||
Help: "The number of errors parsign DogStatsD tags.",
|
||||
},
|
||||
[]string{"type"},
|
||||
)
|
||||
configLoads = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
|
@ -58,7 +106,15 @@ var (
|
|||
|
||||
func init() {
|
||||
prometheus.MustRegister(eventStats)
|
||||
prometheus.MustRegister(networkStats)
|
||||
prometheus.MustRegister(udpPackets)
|
||||
prometheus.MustRegister(tcpConnections)
|
||||
prometheus.MustRegister(tcpErrors)
|
||||
prometheus.MustRegister(tcpLineTooLong)
|
||||
prometheus.MustRegister(linesReceived)
|
||||
prometheus.MustRegister(samplesReceived)
|
||||
prometheus.MustRegister(sampleErrors)
|
||||
prometheus.MustRegister(tagsReceived)
|
||||
prometheus.MustRegister(tagErrors)
|
||||
prometheus.MustRegister(configLoads)
|
||||
prometheus.MustRegister(mappingsCount)
|
||||
prometheus.MustRegister(conflictingEventStats)
|
||||
|
|
Loading…
Reference in a new issue