Merge pull request #277 from ggaaooppeenngg/goCollector
goCollector: add thread count gauge in goCollector
This commit is contained in:
commit
9c2f725467
|
@ -8,8 +8,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type goCollector struct {
|
type goCollector struct {
|
||||||
goroutines Gauge
|
goroutinesDesc *Desc
|
||||||
gcDesc *Desc
|
threadsDesc *Desc
|
||||||
|
gcDesc *Desc
|
||||||
|
|
||||||
// metrics to describe and collect
|
// metrics to describe and collect
|
||||||
metrics memStatsMetrics
|
metrics memStatsMetrics
|
||||||
|
@ -19,11 +20,14 @@ type goCollector struct {
|
||||||
// go process.
|
// go process.
|
||||||
func NewGoCollector() Collector {
|
func NewGoCollector() Collector {
|
||||||
return &goCollector{
|
return &goCollector{
|
||||||
goroutines: NewGauge(GaugeOpts{
|
goroutinesDesc: NewDesc(
|
||||||
Namespace: "go",
|
"go_goroutines",
|
||||||
Name: "goroutines",
|
"Number of goroutines that currently exist.",
|
||||||
Help: "Number of goroutines that currently exist.",
|
nil, nil),
|
||||||
}),
|
threadsDesc: NewDesc(
|
||||||
|
"go_threads",
|
||||||
|
"Number of OS threads created",
|
||||||
|
nil, nil),
|
||||||
gcDesc: NewDesc(
|
gcDesc: NewDesc(
|
||||||
"go_gc_duration_seconds",
|
"go_gc_duration_seconds",
|
||||||
"A summary of the GC invocation durations.",
|
"A summary of the GC invocation durations.",
|
||||||
|
@ -224,9 +228,9 @@ func memstatNamespace(s string) string {
|
||||||
|
|
||||||
// Describe returns all descriptions of the collector.
|
// Describe returns all descriptions of the collector.
|
||||||
func (c *goCollector) Describe(ch chan<- *Desc) {
|
func (c *goCollector) Describe(ch chan<- *Desc) {
|
||||||
ch <- c.goroutines.Desc()
|
ch <- c.goroutinesDesc
|
||||||
|
ch <- c.threadsDesc
|
||||||
ch <- c.gcDesc
|
ch <- c.gcDesc
|
||||||
|
|
||||||
for _, i := range c.metrics {
|
for _, i := range c.metrics {
|
||||||
ch <- i.desc
|
ch <- i.desc
|
||||||
}
|
}
|
||||||
|
@ -234,8 +238,9 @@ func (c *goCollector) Describe(ch chan<- *Desc) {
|
||||||
|
|
||||||
// Collect returns the current state of all metrics of the collector.
|
// Collect returns the current state of all metrics of the collector.
|
||||||
func (c *goCollector) Collect(ch chan<- Metric) {
|
func (c *goCollector) Collect(ch chan<- Metric) {
|
||||||
c.goroutines.Set(float64(runtime.NumGoroutine()))
|
ch <- MustNewConstMetric(c.goroutinesDesc, GaugeValue, float64(runtime.NumGoroutine()))
|
||||||
ch <- c.goroutines
|
n, _ := runtime.ThreadCreateProfile(nil)
|
||||||
|
ch <- MustNewConstMetric(c.threadsDesc, GaugeValue, float64(n))
|
||||||
|
|
||||||
var stats debug.GCStats
|
var stats debug.GCStats
|
||||||
stats.PauseQuantiles = make([]time.Duration, 5)
|
stats.PauseQuantiles = make([]time.Duration, 5)
|
||||||
|
|
|
@ -29,33 +29,36 @@ func TestGoCollector(t *testing.T) {
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case metric := <-ch:
|
case m := <-ch:
|
||||||
switch m := metric.(type) {
|
// m can be Gauge or Counter,
|
||||||
// Attention, this also catches Counter...
|
// currently just test the go_goroutines Gauge
|
||||||
case Gauge:
|
// and ignore others.
|
||||||
pb := &dto.Metric{}
|
if m.Desc().fqName != "go_goroutines" {
|
||||||
m.Write(pb)
|
continue
|
||||||
if pb.GetGauge() == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if old == -1 {
|
|
||||||
old = int(pb.GetGauge().GetValue())
|
|
||||||
close(waitc)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if diff := int(pb.GetGauge().GetValue()) - old; diff != 1 {
|
|
||||||
// TODO: This is flaky in highly concurrent situations.
|
|
||||||
t.Errorf("want 1 new goroutine, got %d", diff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GoCollector performs two sends per call.
|
|
||||||
// On line 27 we need to receive the second send
|
|
||||||
// to shut down cleanly.
|
|
||||||
<-ch
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
pb := &dto.Metric{}
|
||||||
|
m.Write(pb)
|
||||||
|
if pb.GetGauge() == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if old == -1 {
|
||||||
|
old = int(pb.GetGauge().GetValue())
|
||||||
|
close(waitc)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if diff := int(pb.GetGauge().GetValue()) - old; diff != 1 {
|
||||||
|
// TODO: This is flaky in highly concurrent situations.
|
||||||
|
t.Errorf("want 1 new goroutine, got %d", diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GoCollector performs three sends per call.
|
||||||
|
// On line 27 we need to receive the second send
|
||||||
|
// to shut down cleanly.
|
||||||
|
<-ch
|
||||||
|
<-ch
|
||||||
|
return
|
||||||
case <-time.After(1 * time.Second):
|
case <-time.After(1 * time.Second):
|
||||||
t.Fatalf("expected collect timed out")
|
t.Fatalf("expected collect timed out")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue