Browse Source

Merge pull request #138 from sendgrid/master

Add native thread count metric
Mikhail P 9 years ago
parent
commit
eeba7bd0dd
2 changed files with 18 additions and 0 deletions
  1. 8 0
      runtime.go
  2. 10 0
      runtime_test.go

+ 8 - 0
runtime.go

@@ -2,6 +2,7 @@ package metrics
 
 
 import (
 import (
 	"runtime"
 	"runtime"
+	"runtime/pprof"
 	"time"
 	"time"
 )
 )
 
 
@@ -39,6 +40,7 @@ var (
 		}
 		}
 		NumCgoCall   Gauge
 		NumCgoCall   Gauge
 		NumGoroutine Gauge
 		NumGoroutine Gauge
+		NumThread    Gauge
 		ReadMemStats Timer
 		ReadMemStats Timer
 	}
 	}
 	frees       uint64
 	frees       uint64
@@ -46,6 +48,8 @@ var (
 	mallocs     uint64
 	mallocs     uint64
 	numGC       uint32
 	numGC       uint32
 	numCgoCalls int64
 	numCgoCalls int64
+
+	threadCreateProfile = pprof.Lookup("threadcreate")
 )
 )
 
 
 // Capture new values for the Go runtime statistics exported in
 // Capture new values for the Go runtime statistics exported in
@@ -134,6 +138,8 @@ func CaptureRuntimeMemStatsOnce(r Registry) {
 	numCgoCalls = currentNumCgoCalls
 	numCgoCalls = currentNumCgoCalls
 
 
 	runtimeMetrics.NumGoroutine.Update(int64(runtime.NumGoroutine()))
 	runtimeMetrics.NumGoroutine.Update(int64(runtime.NumGoroutine()))
+
+	runtimeMetrics.NumThread.Update(int64(threadCreateProfile.Count()))
 }
 }
 
 
 // Register runtimeMetrics for the Go runtime statistics exported in runtime and
 // Register runtimeMetrics for the Go runtime statistics exported in runtime and
@@ -169,6 +175,7 @@ func RegisterRuntimeMemStats(r Registry) {
 	runtimeMetrics.MemStats.TotalAlloc = NewGauge()
 	runtimeMetrics.MemStats.TotalAlloc = NewGauge()
 	runtimeMetrics.NumCgoCall = NewGauge()
 	runtimeMetrics.NumCgoCall = NewGauge()
 	runtimeMetrics.NumGoroutine = NewGauge()
 	runtimeMetrics.NumGoroutine = NewGauge()
+	runtimeMetrics.NumThread = NewGauge()
 	runtimeMetrics.ReadMemStats = NewTimer()
 	runtimeMetrics.ReadMemStats = NewTimer()
 
 
 	r.Register("runtime.MemStats.Alloc", runtimeMetrics.MemStats.Alloc)
 	r.Register("runtime.MemStats.Alloc", runtimeMetrics.MemStats.Alloc)
@@ -200,5 +207,6 @@ func RegisterRuntimeMemStats(r Registry) {
 	r.Register("runtime.MemStats.TotalAlloc", runtimeMetrics.MemStats.TotalAlloc)
 	r.Register("runtime.MemStats.TotalAlloc", runtimeMetrics.MemStats.TotalAlloc)
 	r.Register("runtime.NumCgoCall", runtimeMetrics.NumCgoCall)
 	r.Register("runtime.NumCgoCall", runtimeMetrics.NumCgoCall)
 	r.Register("runtime.NumGoroutine", runtimeMetrics.NumGoroutine)
 	r.Register("runtime.NumGoroutine", runtimeMetrics.NumGoroutine)
+	r.Register("runtime.NumThread", runtimeMetrics.NumThread)
 	r.Register("runtime.ReadMemStats", runtimeMetrics.ReadMemStats)
 	r.Register("runtime.ReadMemStats", runtimeMetrics.ReadMemStats)
 }
 }

+ 10 - 0
runtime_test.go

@@ -47,6 +47,16 @@ func TestRuntimeMemStats(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestRuntimeMemStatsNumThread(t *testing.T) {
+	r := NewRegistry()
+	RegisterRuntimeMemStats(r)
+	CaptureRuntimeMemStatsOnce(r)
+
+	if value := runtimeMetrics.NumThread.Value(); value < 1 {
+		t.Fatalf("got NumThread: %d, wanted at least 1", value)
+	}
+}
+
 func TestRuntimeMemStatsBlocking(t *testing.T) {
 func TestRuntimeMemStatsBlocking(t *testing.T) {
 	if g := runtime.GOMAXPROCS(0); g < 2 {
 	if g := runtime.GOMAXPROCS(0); g < 2 {
 		t.Skipf("skipping TestRuntimeMemStatsBlocking with GOMAXPROCS=%d\n", g)
 		t.Skipf("skipping TestRuntimeMemStatsBlocking with GOMAXPROCS=%d\n", g)