use metrics struct. include more statistics

This commit is contained in:
Kevin Pike 2015-07-21 20:29:02 -07:00
parent 5e9294fbb7
commit c945ed62c1
1 changed files with 248 additions and 127 deletions

View File

@ -1,26 +1,17 @@
package prometheus package prometheus
import ( import (
"fmt"
"runtime" "runtime"
"runtime/debug" "runtime/debug"
"time" "time"
) )
type goCollector struct { type goCollector struct {
goroutines Gauge goroutines Gauge
gcDesc *Desc gcDesc *Desc
alloc Gauge
totalAlloc Counter memstats *memStatCollector
sys Counter
lookups Counter
mallocs Counter
frees Counter
heapAlloc Gauge
heapSys Gauge
heapIdle Gauge
heapInuse Gauge
heapReleased Gauge
heapObjects Gauge
} }
// NewGoCollector returns a collector which exports metrics about the current // NewGoCollector returns a collector which exports metrics about the current
@ -28,104 +19,233 @@ type goCollector struct {
func NewGoCollector() *goCollector { func NewGoCollector() *goCollector {
return &goCollector{ return &goCollector{
goroutines: NewGauge(GaugeOpts{ goroutines: NewGauge(GaugeOpts{
Name: "go_goroutines", Namespace: "go",
Help: "Number of goroutines that currently exist.", Name: "goroutines",
Help: "Number of goroutines that currently exist.",
}), }),
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.",
nil, nil), nil, nil),
alloc: NewGauge(GaugeOpts{ memstats: &memStatCollector{
Namespace: "go", ms: new(runtime.MemStats),
Subsystem: "memstats", metrics: memStatsMetrics{
Name: "alloc_bytes", {
Help: "Number of bytes allocated and still in use.", desc: NewDesc(
}), memstatNamespace("alloc_bytes"),
totalAlloc: NewCounter(CounterOpts{ "Number of bytes allocated and still in use.",
Namespace: "go", nil, nil,
Subsystem: "memstats", ),
Name: "alloc_bytes_total", eval: func(ms *runtime.MemStats) float64 { return float64(ms.Alloc) },
Help: "Total number of bytes allocated, even if freed.", valType: GaugeValue,
}), }, {
sys: NewGauge(GaugeOpts{ desc: NewDesc(
Namespace: "go", memstatNamespace("alloc_bytes_total"),
Subsystem: "memstats", "Total number of bytes allocated, even if freed.",
Name: "sys_bytes", nil, nil,
Help: "Number of bytes obtained from system", ),
}), eval: func(ms *runtime.MemStats) float64 { return float64(ms.TotalAlloc) },
lookups: NewCounter(CounterOpts{ valType: CounterValue,
Namespace: "go", }, {
Subsystem: "memstats", desc: NewDesc(
Name: "lookups_total", memstatNamespace("sys_bytes"),
Help: "Total number of pointer lookups.", "Number of bytes obtained from system",
}), nil, nil,
mallocs: NewCounter(CounterOpts{ ),
Namespace: "go", eval: func(ms *runtime.MemStats) float64 { return float64(ms.Sys) },
Subsystem: "memstats", valType: CounterValue,
Name: "mallocs_total", }, {
Help: "Total number of mallocs.", desc: NewDesc(
}), memstatNamespace("lookups_total"),
frees: NewCounter(CounterOpts{ "Total number of pointer lookups.",
Namespace: "go", nil, nil,
Subsystem: "memstats", ),
Name: "frees_total", eval: func(ms *runtime.MemStats) float64 { return float64(ms.Lookups) },
Help: "Total number of frees.", valType: CounterValue,
}), }, {
heapAlloc: NewGauge(GaugeOpts{ desc: NewDesc(
Namespace: "go", memstatNamespace("mallocs_total"),
Subsystem: "memstats", "Total number of mallocs.",
Name: "heap_alloc_bytes", nil, nil,
Help: "Number heap bytes allocated and still in use.", ),
}), eval: func(ms *runtime.MemStats) float64 { return float64(ms.Mallocs) },
heapSys: NewGauge(GaugeOpts{ valType: CounterValue,
Namespace: "go", }, {
Subsystem: "memstats", desc: NewDesc(
Name: "heap_sys_bytes", memstatNamespace("frees_total"),
Help: "Total bytes in heap obtained from system.", "Total number of frees.",
}), nil, nil,
heapIdle: NewGauge(GaugeOpts{ ),
Namespace: "go", eval: func(ms *runtime.MemStats) float64 { return float64(ms.Frees) },
Subsystem: "memstats", valType: CounterValue,
Name: "heap_idle_bytes", }, {
Help: "Number bytes in heap waiting to be used.", desc: NewDesc(
}), memstatNamespace("heap_alloc_bytes"),
heapInuse: NewGauge(GaugeOpts{ "Number heap bytes allocated and still in use.",
Namespace: "go", nil, nil,
Subsystem: "memstats", ),
Name: "heap_inuse_bytes", eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapAlloc) },
Help: "Number of bytes in heap that are in use.", valType: GaugeValue,
}), }, {
heapReleased: NewGauge(GaugeOpts{ desc: NewDesc(
Namespace: "go", memstatNamespace("heap_sys_bytes"),
Subsystem: "memstats", "Total bytes in heap obtained from system.",
Name: "heap_released_bytes", nil, nil,
Help: "Number of bytes in heap released to OS.", ),
}), eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapSys) },
heapObjects: NewGauge(GaugeOpts{ valType: GaugeValue,
Namespace: "go", }, {
Subsystem: "memstats", desc: NewDesc(
Name: "heap_objects", memstatNamespace("heap_idle_bytes"),
Help: "Number of allocated objects.", "Number bytes in heap waiting to be used.",
}), nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapIdle) },
valType: GaugeValue,
}, {
desc: NewDesc(
memstatNamespace("heap_inuse_bytes"),
"Number of bytes in heap that are in use.",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapInuse) },
valType: GaugeValue,
}, {
desc: NewDesc(
memstatNamespace("heap_released_bytes"),
"Number of bytes in heap released to OS.",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapReleased) },
valType: GaugeValue,
}, {
desc: NewDesc(
memstatNamespace("heap_objects"),
"Number of allocated objects.",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.HeapObjects) },
valType: GaugeValue,
}, {
desc: NewDesc(
memstatNamespace("stack_bytes_inuse"),
"Number of bytes in use by the stack allocator.",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.StackInuse) },
valType: GaugeValue,
}, {
desc: NewDesc(
memstatNamespace("stack_sys_bytes"),
"Number of bytes in obtained from system for stack allocator.",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.StackSys) },
valType: GaugeValue,
}, {
desc: NewDesc(
memstatNamespace("mspan_inuse"),
"Number of mspan structures in use.",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.MSpanInuse) },
valType: GaugeValue,
}, {
desc: NewDesc(
memstatNamespace("mspan_sys"),
"Number of mspan structures obtained from system.",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.MSpanSys) },
valType: GaugeValue,
}, {
desc: NewDesc(
memstatNamespace("mcache_inuse"),
"Number of mcache structures in use.",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.MCacheInuse) },
valType: GaugeValue,
}, {
desc: NewDesc(
memstatNamespace("mcache_sys"),
"Number of mcache structures obtained from system.",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.MCacheSys) },
valType: GaugeValue,
}, {
desc: NewDesc(
memstatNamespace("buck_hash_sys"),
"Profiling bucket hash table.",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.BuckHashSys) },
valType: GaugeValue,
}, {
desc: NewDesc(
memstatNamespace("gc_metadata"),
"GC metadata.",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.GCSys) },
valType: GaugeValue,
}, {
desc: NewDesc(
memstatNamespace("other_sys"),
"Other system allocations.",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.OtherSys) },
valType: GaugeValue,
}, {
desc: NewDesc(
memstatNamespace("next_gc"),
"Next collection will happen when HeapAlloc ≥ this amount.",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.NextGC) },
valType: GaugeValue,
}, {
desc: NewDesc(
memstatNamespace("last_gc"),
"End time of last garbage collection (nanoseconds since 1970).",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.LastGC) },
valType: CounterValue,
}, {
desc: NewDesc(
memstatNamespace("pause_total"),
"Total garbage collection pauses for all collections.",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.PauseTotalNs) },
valType: CounterValue,
}, {
desc: NewDesc(
memstatNamespace("gc_total"),
"Number of garbage collection.",
nil, nil,
),
eval: func(ms *runtime.MemStats) float64 { return float64(ms.NumGC) },
valType: CounterValue,
},
},
},
} }
} }
func memstatNamespace(s string) string {
return fmt.Sprintf("go_memstats_%s", s)
}
// 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.goroutines.Desc()
ch <- c.gcDesc ch <- c.gcDesc
ch <- c.alloc.Desc()
ch <- c.totalAlloc.Desc() c.memstats.Describe(ch)
ch <- c.sys.Desc()
ch <- c.lookups.Desc()
ch <- c.mallocs.Desc()
ch <- c.frees.Desc()
ch <- c.heapAlloc.Desc()
ch <- c.heapSys.Desc()
ch <- c.heapIdle.Desc()
ch <- c.heapInuse.Desc()
ch <- c.heapReleased.Desc()
ch <- c.heapObjects.Desc()
} }
// Collect returns the current state of all metrics of the collector. // Collect returns the current state of all metrics of the collector.
@ -144,31 +264,32 @@ func (c *goCollector) Collect(ch chan<- Metric) {
quantiles[0.0] = stats.PauseQuantiles[0].Seconds() quantiles[0.0] = stats.PauseQuantiles[0].Seconds()
ch <- MustNewConstSummary(c.gcDesc, uint64(stats.NumGC), float64(stats.PauseTotal.Seconds()), quantiles) ch <- MustNewConstSummary(c.gcDesc, uint64(stats.NumGC), float64(stats.PauseTotal.Seconds()), quantiles)
var ms runtime.MemStats c.memstats.Collect(ch)
runtime.ReadMemStats(&ms) }
c.alloc.Set(float64(ms.Alloc)) // metrics that provide description, value, and value type for memstat metrics
ch <- c.alloc type memStatsMetrics []struct {
c.totalAlloc.Set(float64(ms.TotalAlloc)) desc *Desc
ch <- c.totalAlloc eval func(*runtime.MemStats) float64
c.sys.Set(float64(ms.Sys)) valType ValueType
ch <- c.sys }
c.lookups.Set(float64(ms.Lookups))
ch <- c.lookups type memStatCollector struct {
c.mallocs.Set(float64(ms.Mallocs)) // memstats object to reuse
ch <- c.mallocs ms *runtime.MemStats
c.frees.Set(float64(ms.Frees)) // metrics to describe and collect
ch <- c.frees metrics memStatsMetrics
c.heapAlloc.Set(float64(ms.HeapAlloc)) }
ch <- c.heapAlloc
c.heapSys.Set(float64(ms.HeapSys)) func (c *memStatCollector) Describe(ch chan<- *Desc) {
ch <- c.heapSys for _, i := range c.metrics {
c.heapIdle.Set(float64(ms.HeapIdle)) ch <- i.desc
ch <- c.heapIdle }
c.heapInuse.Set(float64(ms.HeapInuse)) }
ch <- c.heapInuse
c.heapReleased.Set(float64(ms.HeapReleased)) func (c *memStatCollector) Collect(ch chan<- Metric) {
ch <- c.heapReleased runtime.ReadMemStats(c.ms)
c.heapObjects.Set(float64(ms.HeapObjects)) for _, i := range c.metrics {
ch <- c.heapObjects ch <- MustNewConstMetric(i.desc, i.valType, i.eval(c.ms))
}
} }