1package statsd_test 2 3import ( 4 "fmt" 5 "io" 6 "log" 7 "net" 8 "os" 9 "sync/atomic" 10 "testing" 11 12 "github.com/DataDog/datadog-go/statsd" 13) 14 15func setupUDSClientServer(b *testing.B, options []statsd.Option) (*statsd.Client, net.Listener) { 16 sockAddr := "/tmp/test.sock" 17 if err := os.RemoveAll(sockAddr); err != nil { 18 log.Fatal(err) 19 } 20 conn, err := net.Listen("unix", sockAddr) 21 if err != nil { 22 log.Fatal("listen error:", err) 23 } 24 go func() { 25 for { 26 _, err := conn.Accept() 27 if err != nil { 28 return 29 } 30 } 31 }() 32 client, err := statsd.New("unix://"+sockAddr, options...) 33 if err != nil { 34 b.Error(err) 35 } 36 return client, conn 37} 38 39func setupUDPClientServer(b *testing.B, options []statsd.Option) (*statsd.Client, *net.UDPConn) { 40 addr, err := net.ResolveUDPAddr("udp", ":0") 41 if err != nil { 42 b.Error(err) 43 } 44 conn, err := net.ListenUDP("udp", addr) 45 if err != nil { 46 b.Error(err) 47 } 48 49 client, err := statsd.New(conn.LocalAddr().String(), options...) 50 if err != nil { 51 b.Error(err) 52 } 53 return client, conn 54} 55 56func setupClient(b *testing.B, transport string, extraOptions []statsd.Option) (*statsd.Client, io.Closer) { 57 options := []statsd.Option{statsd.WithMaxMessagesPerPayload(1024), statsd.WithoutTelemetry()} 58 options = append(options, extraOptions...) 59 60 if transport == statsd.WriterNameUDP { 61 return setupUDPClientServer(b, options) 62 } 63 return setupUDSClientServer(b, options) 64} 65 66func benchmarkStatsdDifferentMetrics(b *testing.B, transport string, extraOptions ...statsd.Option) { 67 client, conn := setupClient(b, transport, extraOptions) 68 defer conn.Close() 69 70 n := int32(0) 71 b.ResetTimer() 72 73 b.RunParallel(func(pb *testing.PB) { 74 testNumber := atomic.AddInt32(&n, 1) 75 name := fmt.Sprintf("test.metric%d", testNumber) 76 for pb.Next() { 77 client.Gauge(name, 1, []string{"tag:tag"}, 1) 78 } 79 }) 80 client.Flush() 81 t := client.FlushTelemetryMetrics() 82 reportMetric(b, float64(t.TotalDroppedOnReceive)/float64(t.TotalMetrics)*100, "%_dropRate") 83 84 b.StopTimer() 85 client.Close() 86} 87 88func benchmarkStatsdSameMetrics(b *testing.B, transport string, extraOptions ...statsd.Option) { 89 client, conn := setupClient(b, transport, extraOptions) 90 defer conn.Close() 91 92 b.ResetTimer() 93 94 b.RunParallel(func(pb *testing.PB) { 95 for pb.Next() { 96 client.Gauge("test.metric", 1, []string{"tag:tag"}, 1) 97 } 98 }) 99 client.Flush() 100 t := client.FlushTelemetryMetrics() 101 reportMetric(b, float64(t.TotalDroppedOnReceive)/float64(t.TotalMetrics)*100, "%_dropRate") 102 103 b.StopTimer() 104 client.Close() 105} 106 107/* 108UDP with the same metric 109*/ 110 111// blocking + no aggregation 112func BenchmarkStatsdUDPSameMetricMutex(b *testing.B) { 113 benchmarkStatsdSameMetrics(b, statsd.WriterNameUDP, statsd.WithMutexMode(), statsd.WithoutClientSideAggregation()) 114} 115 116// dropping + no aggregation 117func BenchmarkStatsdUDPSameMetricChannel(b *testing.B) { 118 benchmarkStatsdSameMetrics(b, statsd.WriterNameUDP, statsd.WithChannelMode(), statsd.WithoutClientSideAggregation()) 119} 120 121// blocking + aggregation 122func BenchmarkStatsdUDPSameMetricMutexAggregation(b *testing.B) { 123 benchmarkStatsdSameMetrics(b, statsd.WriterNameUDP, statsd.WithMutexMode(), statsd.WithClientSideAggregation()) 124} 125 126// dropping + aggregation 127func BenchmarkStatsdUDPSameMetricChannelAggregation(b *testing.B) { 128 benchmarkStatsdSameMetrics(b, statsd.WriterNameUDP, statsd.WithChannelMode(), statsd.WithClientSideAggregation()) 129} 130 131/* 132UDP with the different metrics 133*/ 134 135// blocking + no aggregation 136func BenchmarkStatsdUDPDifferentMetricMutex(b *testing.B) { 137 benchmarkStatsdDifferentMetrics(b, statsd.WriterNameUDP, statsd.WithMutexMode(), statsd.WithoutClientSideAggregation()) 138} 139 140// dropping + no aggregation 141func BenchmarkStatsdUDPDifferentMetricChannel(b *testing.B) { 142 benchmarkStatsdDifferentMetrics(b, statsd.WriterNameUDP, statsd.WithChannelMode(), statsd.WithoutClientSideAggregation()) 143} 144 145// blocking + aggregation 146func BenchmarkStatsdUDPDifferentMetricMutexAggregation(b *testing.B) { 147 benchmarkStatsdDifferentMetrics(b, statsd.WriterNameUDP, statsd.WithMutexMode(), statsd.WithClientSideAggregation()) 148} 149 150// dropping + aggregation 151func BenchmarkStatsdUDPDifferentMetricChannelAggregation(b *testing.B) { 152 benchmarkStatsdDifferentMetrics(b, statsd.WriterNameUDP, statsd.WithChannelMode(), statsd.WithClientSideAggregation()) 153} 154 155/* 156UDS with the same metric 157*/ 158// blocking + no aggregation 159func BenchmarkStatsdUDSSameMetricMutex(b *testing.B) { 160 benchmarkStatsdSameMetrics(b, statsd.WriterNameUDS, statsd.WithMutexMode(), statsd.WithoutClientSideAggregation()) 161} 162 163// dropping + no aggregation 164func BenchmarkStatsdUDSSameMetricChannel(b *testing.B) { 165 benchmarkStatsdSameMetrics(b, statsd.WriterNameUDS, statsd.WithChannelMode(), statsd.WithoutClientSideAggregation()) 166} 167 168// blocking + aggregation 169func BenchmarkStatsdUDSSameMetricMutexAggregation(b *testing.B) { 170 benchmarkStatsdSameMetrics(b, statsd.WriterNameUDS, statsd.WithMutexMode(), statsd.WithClientSideAggregation()) 171} 172 173// dropping + aggregation 174func BenchmarkStatsdUDSSameMetricChannelAggregation(b *testing.B) { 175 benchmarkStatsdSameMetrics(b, statsd.WriterNameUDS, statsd.WithChannelMode(), statsd.WithClientSideAggregation()) 176} 177 178/* 179UDS with different metrics 180*/ 181// blocking + no aggregation 182func BenchmarkStatsdUDPSifferentMetricMutex(b *testing.B) { 183 benchmarkStatsdDifferentMetrics(b, statsd.WriterNameUDS, statsd.WithMutexMode(), statsd.WithoutClientSideAggregation()) 184} 185 186// dropping + no aggregation 187func BenchmarkStatsdUDSDifferentMetricChannel(b *testing.B) { 188 benchmarkStatsdDifferentMetrics(b, statsd.WriterNameUDS, statsd.WithChannelMode(), statsd.WithoutClientSideAggregation()) 189} 190 191// blocking + aggregation 192func BenchmarkStatsdUDPSifferentMetricMutexAggregation(b *testing.B) { 193 benchmarkStatsdDifferentMetrics(b, statsd.WriterNameUDS, statsd.WithMutexMode(), statsd.WithClientSideAggregation()) 194} 195 196// dropping + aggregation 197func BenchmarkStatsdUDSDifferentMetricChannelAggregation(b *testing.B) { 198 benchmarkStatsdDifferentMetrics(b, statsd.WriterNameUDS, statsd.WithChannelMode(), statsd.WithClientSideAggregation()) 199} 200