Skip to content

Commit

Permalink
fix(Tags): tags option now updates existing tags correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
joeycumines committed Aug 26, 2020
1 parent 23eed68 commit 111b368
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 27 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ No releases but `master` will remain stable™.

**Changelog**

* 2020-08-27 - Fixed bug in `statsd.Tags` identified by https://github.com/alexcesaro/statsd/issues/41

* 2019-05-22 - Added support for arbitrary output streams via new `statsd.WriteCloser` option

* 2019-05-22 - Added support for simplified inline flush logic via new `statsd.InlineFlush` option
Expand Down
30 changes: 8 additions & 22 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,33 +166,19 @@ func Tags(tags ...string) Option {
if len(tags)%2 != 0 {
panic("statsd: Tags only accepts an even number of arguments")
}

return Option(func(c *config) {
if len(tags) == 0 {
return
}

newTags := make([]tag, len(tags)/2)
return func(c *config) {
UpdateLoop:
for i := 0; i < len(tags)/2; i++ {
newTags[i] = tag{K: tags[2*i], V: tags[2*i+1]}
}

for _, newTag := range newTags {
exists := false
for _, oldTag := range c.Client.Tags {
newTag := tag{K: tags[2*i], V: tags[2*i+1]}
for i, oldTag := range c.Client.Tags {
if newTag.K == oldTag.K {
exists = true
oldTag.V = newTag.V
c.Client.Tags[i] = newTag
continue UpdateLoop
}
}
if !exists {
c.Client.Tags = append(c.Client.Tags, tag{
K: newTag.K,
V: newTag.V,
})
}
c.Client.Tags = append(c.Client.Tags, newTag)
}
})
}
}

type tag struct {
Expand Down
13 changes: 8 additions & 5 deletions statsd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,17 +340,17 @@ func TestCloneRate(t *testing.T) {
}

func TestCloneInfluxDBTags(t *testing.T) {
testOutput(t, "test_key,tag1=value1,tag2=value2:5|c", func(c *Client) {
clone := c.Clone(Tags("tag1", "value3", "tag2", "value2"))
testOutput(t, "test_key,tag1=value3,tag3=value4,tag4=value9,tag5=value6,tag2=value2:5|c", func(c *Client) {
clone := c.Clone(Tags("tag2", "value2", "tag1", "value3", "tag4", "value8", "tag4", "value9"))
clone.Count(testKey, 5)
}, TagsFormat(InfluxDB), Tags("tag1", "value1"))
}, TagsFormat(InfluxDB), Tags("tag1", "value1", "tag3", "value4", "tag4", "value5", "tag5", "value6", "tag4", "value7"))
}

func TestCloneDatadogTags(t *testing.T) {
testOutput(t, "test_key:5|c|#tag1:value1,tag2:value2", func(c *Client) {
testOutput(t, "test_key:5|c|#tag1:value3,tag3:value4,tag2:value2", func(c *Client) {
clone := c.Clone(Tags("tag1", "value3", "tag2", "value2"))
clone.Count(testKey, 5)
}, TagsFormat(Datadog), Tags("tag1", "value1"))
}, TagsFormat(Datadog), Tags("tag1", "value1", "tag3", "value4"))
}

func TestDialError(t *testing.T) {
Expand Down Expand Up @@ -557,6 +557,7 @@ func mockUDPClosed(string, string, time.Duration) (net.Conn, error) {
}

func testClient(t *testing.T, f func(*Client), options ...Option) {
t.Helper()
dialTimeout = mockDial
defer func() { dialTimeout = net.DialTimeout }()

Expand All @@ -573,7 +574,9 @@ func testClient(t *testing.T, f func(*Client), options ...Option) {
}

func testOutput(t *testing.T, want string, f func(*Client), options ...Option) {
t.Helper()
testClient(t, func(c *Client) {
t.Helper()
f(c)
c.Close()

Expand Down

0 comments on commit 111b368

Please sign in to comment.