Skip to content

Commit 6d9120b

Browse files
committed
wip
1 parent 70cab92 commit 6d9120b

File tree

5 files changed

+248
-0
lines changed

5 files changed

+248
-0
lines changed

flooder/cmd/flood/flood.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package flood
2+
3+
import (
4+
"github.com/DataDog/datadog-go/v5/flooder/pkg/flood"
5+
"os"
6+
"time"
7+
8+
"github.com/spf13/cobra"
9+
)
10+
11+
// floodCmd represents the base command when called without any subcommands
12+
var floodCmd = &cobra.Command{
13+
Use: "v5",
14+
Short: "Sends a lot of statsd points.",
15+
Run: func(cmd *cobra.Command, args []string) {
16+
flood.Flood(cmd, args)
17+
},
18+
}
19+
20+
// Execute adds all child commands to the root command and sets flags appropriately.
21+
// This is called by main.main(). It only needs to happen once to the rootCmd.
22+
func Execute() {
23+
err := floodCmd.Execute()
24+
if err != nil {
25+
os.Exit(1)
26+
}
27+
}
28+
29+
func init() {
30+
floodCmd.Flags().StringP("address", "", "127.0.0.1:8125", "Address of the statsd server")
31+
floodCmd.Flags().StringP("telemetry-address", "", "", "Address of the telemetry server")
32+
floodCmd.Flags().BoolP("client-side-aggregation", "", false, "Enable client-side aggregation")
33+
floodCmd.Flags().BoolP("extended-client-side-aggregation", "", false, "Enable extended client-side aggregation")
34+
floodCmd.Flags().BoolP("channel-mode", "", false, "Enable channel mode")
35+
floodCmd.Flags().IntP("channel-mode-buffer-size", "", 4096, "Set channel mode buffer size")
36+
floodCmd.Flags().IntP("sender-queue-size", "", 512, "Set sender queue size")
37+
floodCmd.Flags().DurationP("buffer-flush-interval", "", time.Duration(4)*time.Second, "Set buffer flush interval")
38+
floodCmd.Flags().DurationP("write-timeout", "", time.Duration(100)*time.Millisecond, "Set write timeout")
39+
floodCmd.Flags().StringSliceP("tags", "", []string{}, "Set tags")
40+
floodCmd.Flags().IntP("points-per-10seconds", "", 100000, "Set points per 10 seconds")
41+
floodCmd.Flags().BoolP("send-at-start-of-bucket", "", false, "Send all the points at the start of the 10 sec time bucket.")
42+
}

flooder/main.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package main
2+
3+
import "github.com/DataDog/datadog-go/v5/flooder/cmd/flood"
4+
5+
func main() {
6+
flood.Execute()
7+
}

flooder/pkg/flood/flood.go

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
package flood
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
"hash/fnv"
6+
"log"
7+
"strconv"
8+
"strings"
9+
"time"
10+
11+
"github.com/DataDog/datadog-go/v5/statsd"
12+
)
13+
14+
type client struct {
15+
client *statsd.Client
16+
pointsPer10Seconds int
17+
sendAtStartOfBucket bool
18+
}
19+
20+
func initClient(command *cobra.Command) (*client, error) {
21+
var options []statsd.Option
22+
23+
tags := []string{}
24+
25+
b, err := command.Flags().GetBool("client-side-aggregation")
26+
if err != nil {
27+
return nil, err
28+
}
29+
if b {
30+
options = append(options, statsd.WithClientSideAggregation())
31+
} else {
32+
options = append(options, statsd.WithoutClientSideAggregation())
33+
}
34+
tags = append(tags, "client-side-aggregation:"+strconv.FormatBool(b))
35+
36+
b, err = command.Flags().GetBool("extended-client-side-aggregation")
37+
if err != nil {
38+
return nil, err
39+
}
40+
if b {
41+
options = append(options, statsd.WithExtendedClientSideAggregation())
42+
}
43+
tags = append(tags, "extended-client-side-aggregation"+strconv.FormatBool(b))
44+
45+
b, err = command.Flags().GetBool("channel-mode")
46+
if err != nil {
47+
return nil, err
48+
}
49+
if b {
50+
options = append(options, statsd.WithChannelMode())
51+
}
52+
tags = append(tags, "channel-mode:"+strconv.FormatBool(b))
53+
54+
i, err := command.Flags().GetInt("channel-mode-buffer-size")
55+
if err != nil {
56+
return nil, err
57+
}
58+
options = append(options, statsd.WithChannelModeBufferSize(i))
59+
tags = append(tags, "channel-mode-buffer-size:"+strconv.Itoa(i))
60+
61+
i, err = command.Flags().GetInt("sender-queue-size")
62+
if err != nil {
63+
return nil, err
64+
}
65+
options = append(options, statsd.WithSenderQueueSize(i))
66+
tags = append(tags, "sender-queue-size:"+strconv.Itoa(i))
67+
68+
d, err := command.Flags().GetDuration("buffer-flush-interval")
69+
if err != nil {
70+
return nil, err
71+
}
72+
options = append(options, statsd.WithBufferFlushInterval(d))
73+
tags = append(tags, "buffer-flush-interval:"+d.String())
74+
75+
d, err = command.Flags().GetDuration("write-timeout")
76+
if err != nil {
77+
return nil, err
78+
}
79+
options = append(options, statsd.WithWriteTimeout(d))
80+
tags = append(tags, "write-timeout:"+d.String())
81+
82+
pointsPer10Seconds, err := command.Flags().GetInt("points-per-10seconds")
83+
if err != nil {
84+
return nil, err
85+
}
86+
tags = append(tags, "points-per-10seconds:"+strconv.Itoa(pointsPer10Seconds))
87+
88+
sendAtStart, err := command.Flags().GetBool("send-at-start-of-bucket")
89+
if err != nil {
90+
return nil, err
91+
}
92+
tags = append(tags, "send-at-start-of-bucket:"+strconv.FormatBool(sendAtStart))
93+
94+
address, err := command.Flags().GetString("address")
95+
if err != nil {
96+
return nil, err
97+
}
98+
tags = append(tags, "address:"+address)
99+
100+
transport := "udp"
101+
if strings.HasPrefix(address, statsd.UnixAddressPrefix) {
102+
transport = "unix"
103+
}
104+
tags = append(tags, "transport:"+transport)
105+
106+
telemetryAddress, err := command.Flags().GetString("telemetry-address")
107+
if err != nil {
108+
return nil, err
109+
}
110+
if telemetryAddress == "" {
111+
telemetryAddress = address
112+
}
113+
tags = append(tags, "telemetry-address:"+telemetryAddress)
114+
options = append(options, statsd.WithTelemetryAddr(telemetryAddress))
115+
116+
telemetryTransport := "udp"
117+
if strings.HasPrefix(telemetryAddress, statsd.UnixAddressPrefix) {
118+
telemetryTransport = "unix"
119+
}
120+
tags = append(tags, "telemetry-transport:"+telemetryTransport)
121+
122+
t, err := command.Flags().GetStringSlice("tags")
123+
tags = append(tags, t...)
124+
h := hash(tags)
125+
tags = append(tags, "client-hash:"+strconv.Itoa(int(h)))
126+
127+
options = append(options, statsd.WithTags(tags))
128+
129+
log.Printf("Tags: %v - Hash: %x", tags, h)
130+
131+
options = append(options, statsd.WithOriginDetection())
132+
133+
c, err := statsd.New(address, options...)
134+
if err != nil {
135+
return nil, err
136+
}
137+
138+
return &client{
139+
client: c,
140+
pointsPer10Seconds: pointsPer10Seconds,
141+
sendAtStartOfBucket: sendAtStart,
142+
}, nil
143+
}
144+
145+
func hash(s []string) uint32 {
146+
h := fnv.New32a()
147+
for _, e := range s {
148+
h.Write([]byte(e))
149+
}
150+
return h.Sum32()
151+
}
152+
153+
func Flood(command *cobra.Command, args []string) {
154+
c, err := initClient(command)
155+
if err != nil {
156+
log.Fatal(err)
157+
}
158+
log.Printf("Sending %d points per 10 seconds", c.pointsPer10Seconds)
159+
160+
for {
161+
t1 := time.Now()
162+
163+
for sent := 0; sent < c.pointsPer10Seconds; sent++ {
164+
err := c.client.Incr("flood.dogstatsd.count", []string{}, 1)
165+
if err != nil {
166+
log.Printf("Error: %v", err)
167+
}
168+
if !c.sendAtStartOfBucket {
169+
time.Sleep(time.Duration(8) * time.Second / time.Duration(c.pointsPer10Seconds))
170+
}
171+
}
172+
err := c.client.Count("flood.dogstatsd.expected", int64(c.pointsPer10Seconds), []string{}, 1)
173+
if err != nil {
174+
log.Printf("Error: %v", err)
175+
}
176+
177+
t2 := time.Now()
178+
179+
duration := t2.Sub(t1)
180+
s := time.Duration(10)*time.Second - duration
181+
if s > 0 {
182+
// Sleep until the next bucket
183+
log.Printf("Sleeping for %f seconds", s.Seconds())
184+
time.Sleep(s)
185+
} else {
186+
log.Printf("We're %f seconds behind", s.Seconds()*-1)
187+
}
188+
}
189+
c.client.Close()
190+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ go 1.13
55
require (
66
github.com/Microsoft/go-winio v0.5.0
77
github.com/golang/mock v1.6.0
8+
github.com/spf13/cobra v1.7.0 // indirect
89
github.com/stretchr/testify v1.8.1
910
)

go.sum

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU=
22
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
3+
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
34
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
45
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
56
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
67
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
78
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
9+
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
10+
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
811
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
912
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1013
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
14+
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
1115
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
16+
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
17+
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
18+
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
19+
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
1220
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
1321
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
1422
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=

0 commit comments

Comments
 (0)