Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions metrics/dogstatsd/dogstatsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,14 @@ func (d *Dogstatsd) SendLoop(ctx context.Context, c <-chan time.Time, network, a
// lost if there is a problem with the write. Clients should be sure to call
// WriteTo regularly, ideally through the WriteLoop or SendLoop helper methods.
func (d *Dogstatsd) WriteTo(w io.Writer) (count int64, err error) {
var n int

d.counters.Reset().Walk(func(name string, lvs lv.LabelValues, values []float64) bool {
var (
n int
counters = d.counters.Reset()
timings = d.timings.Reset()
histograms = d.histograms.Reset()
)

counters.Walk(func(name string, lvs lv.LabelValues, values []float64) bool {
n, err = fmt.Fprintf(w, "%s%s:%f|c%s%s\n", d.prefix, name, sum(values), sampling(d.rates.Get(name)), d.tagValues(lvs))
if err != nil {
return false
Expand All @@ -168,7 +173,7 @@ func (d *Dogstatsd) WriteTo(w io.Writer) (count int64, err error) {
}
d.mtx.RUnlock()

d.timings.Reset().Walk(func(name string, lvs lv.LabelValues, values []float64) bool {
timings.Walk(func(name string, lvs lv.LabelValues, values []float64) bool {
sampleRate := d.rates.Get(name)
for _, value := range values {
n, err = fmt.Fprintf(w, "%s%s:%f|ms%s%s\n", d.prefix, name, value, sampling(sampleRate), d.tagValues(lvs))
Expand All @@ -183,7 +188,7 @@ func (d *Dogstatsd) WriteTo(w io.Writer) (count int64, err error) {
return count, err
}

d.histograms.Reset().Walk(func(name string, lvs lv.LabelValues, values []float64) bool {
histograms.Walk(func(name string, lvs lv.LabelValues, values []float64) bool {
sampleRate := d.rates.Get(name)
for _, value := range values {
n, err = fmt.Fprintf(w, "%s%s:%f|h%s%s\n", d.prefix, name, value, sampling(sampleRate), d.tagValues(lvs))
Expand Down
73 changes: 73 additions & 0 deletions metrics/dogstatsd/dogstatsd_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package dogstatsd

import (
"errors"
"testing"

"github.com/go-kit/kit/metrics/internal/lv"
"github.com/go-kit/kit/metrics/teststat"
"github.com/go-kit/log"
)
Expand Down Expand Up @@ -88,3 +90,74 @@ func TestTimingSampled(t *testing.T) {
t.Fatal(err)
}
}

func TestDogstatsd_WriteToDiscardsMetricsOnError(t *testing.T) {
walker := func(counter *int) func(string, lv.LabelValues, []float64) bool {
return func(string, lv.LabelValues, []float64) bool {
*counter++
return true
}
}

d := New("dogstatsd.", log.NewNopLogger())

// Add some metrics.
d.NewCounter("counter-1", 1.0).Add(1.0)
d.NewTiming("timing-1", 1.0).Observe(1.0)
d.NewHistogram("histogram-1", 1.0).Observe(1.0)

// Count metrics buffered in the Dogstatsd object.
var (
countersCount int
timingsCount int
histogramsCount int
)
d.counters.Walk(walker(&countersCount))
d.timings.Walk(walker(&timingsCount))
d.histograms.Walk(walker(&histogramsCount))

// Assert we have one of each type.
if countersCount != 1 {
t.Fatalf("expected counters count to be 1; got %d", countersCount)
}
if timingsCount != 1 {
t.Fatalf("expected timings count to be 1; got %d", timingsCount)
}
if histogramsCount != 1 {
t.Fatalf("expected histograms count to be 1; got %d", histogramsCount)
}

// Simulate an error while sending metrics.
count, err := d.WriteTo(errorWriter{})
if count != 0 {
t.Fatalf("expected count to be 0; got %d", count)
}
if err == nil {
t.Fatalf("expected error to be nil; got %v", err)
}

// Reset counters and count again.
countersCount = 0
timingsCount = 0
histogramsCount = 0
d.counters.Walk(walker(&countersCount))
d.timings.Walk(walker(&timingsCount))
d.histograms.Walk(walker(&histogramsCount))

// Assert buffered metrics were cleared.
if countersCount != 0 {
t.Fatalf("expected counters count to be 0; got %d", countersCount)
}
if timingsCount != 0 {
t.Fatalf("expected timings count to be 0; got %d", timingsCount)
}
if histogramsCount != 0 {
t.Fatalf("expected histograms count to be 0; got %d", histogramsCount)
}
}

type errorWriter struct{}

func (w errorWriter) Write([]byte) (int, error) {
return 0, errors.New("boom")
}