Explorar el Código

Document how to create a threadsafe registry

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.
Kevin Burke hace 10 años
padre
commit
7282ad6453
Se han modificado 4 ficheros con 47 adiciones y 3 borrados
  1. 9 0
      README.md
  2. 13 3
      gauge_test.go
  3. 17 0
      metrics_test.go
  4. 8 0
      timer_test.go

+ 9 - 0
README.md

@@ -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

+ 13 - 3
gauge_test.go

@@ -1,6 +1,9 @@
 package metrics
 
-import "testing"
+import (
+	"fmt"
+	"testing"
+)
 
 func BenchmarkGuage(b *testing.B) {
 	g := NewGauge()
@@ -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 - 0
metrics_test.go

@@ -1,6 +1,7 @@
 package metrics
 
 import (
+	"fmt"
 	"io/ioutil"
 	"log"
 	"sync"
@@ -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 - 0
timer_test.go

@@ -1,6 +1,7 @@
 package metrics
 
 import (
+	"fmt"
 	"math"
 	"testing"
 	"time"
@@ -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
+}