Skip to content

Commit

Permalink
Document how to create a threadsafe registry
Browse files Browse the repository at this point in the history
My first iteration of a metrics client had code like this:

```go
// Increment a counter with the given name.
func Increment(name string) {
	mn := getWithNamespace(name)
	m := metrics.GetOrRegister(mn, metrics.NewMeter()).(metrics.Meter)
	m.Mark(1)
}
```

Which contained a massive resource leak - every anonymous NewMeter() call
appends a new arbiter, so I had one arbiter for each function call! Instead
document the right way to do this so people hopefully don't get as lost.
  • Loading branch information
Kevin Burke authored and kevinburke committed Sep 14, 2016
1 parent 6ee5318 commit 7282ad6
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 3 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ t.Time(func() {})
t.Update(47)
```

Register() is not threadsafe. For threadsafe metric registration use
GetOrRegister:

```
t := metrics.GetOrRegisterTimer("account.create.latency", nil)
t.Time(func() {})
t.Update(47)
```

Periodically log every metric in human-readable form to standard error:

```go
Expand Down
16 changes: 13 additions & 3 deletions gauge_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package metrics

import "testing"
import (
"fmt"
"testing"
)

func BenchmarkGuage(b *testing.B) {
g := NewGauge()
Expand Down Expand Up @@ -51,8 +54,15 @@ func TestFunctionalGauge(t *testing.T) {

func TestGetOrRegisterFunctionalGauge(t *testing.T) {
r := NewRegistry()
NewRegisteredFunctionalGauge("foo", r, func() int64 { return 47})
NewRegisteredFunctionalGauge("foo", r, func() int64 { return 47 })
if g := GetOrRegisterGauge("foo", r); 47 != g.Value() {
t.Fatal(g)
}
}
}

func ExampleGetOrRegisterGauge() {
m := "server.bytes_sent"
g := GetOrRegisterGauge(m, nil)
g.Update(47)
fmt.Println(g.Value()) // Output: 47
}
17 changes: 17 additions & 0 deletions metrics_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package metrics

import (
"fmt"
"io/ioutil"
"log"
"sync"
Expand Down Expand Up @@ -105,3 +106,19 @@ func BenchmarkMetrics(b *testing.B) {
wgR.Wait()
wgW.Wait()
}

func Example() {
c := NewCounter()
Register("money", c)
c.Inc(17)

// Threadsafe registration
t := GetOrRegisterTimer("db.get.latency", nil)
t.Time(func() {})
t.Update(1)

fmt.Println(c.Count())
fmt.Println(t.Min())
// Output: 17
// 1
}
8 changes: 8 additions & 0 deletions timer_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package metrics

import (
"fmt"
"math"
"testing"
"time"
Expand Down Expand Up @@ -79,3 +80,10 @@ func TestTimerZero(t *testing.T) {
t.Errorf("tm.RateMean(): 0.0 != %v\n", rateMean)
}
}

func ExampleGetOrRegisterTimer() {
m := "account.create.latency"
t := GetOrRegisterTimer(m, nil)
t.Update(47)
fmt.Println(t.Max()) // Output: 47
}

0 comments on commit 7282ad6

Please sign in to comment.