blob: 98e249f8879030d5273551ecfff7ca703422af48 [file] [log] [blame]
// Copyright 2016 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package runtimestats exposes metrics related to the Go runtime.
//
// It exports the allocator statistics (go/mem/* metrics) and the current number
// of goroutines (go/goroutine/num).
//
// Should be invoked manually for now. Call Report(c) to populate the metrics
// prior tsmon Flush.
package runtimestats
import (
"context"
"runtime"
"go.chromium.org/luci/common/tsmon/metric"
"go.chromium.org/luci/common/tsmon/types"
)
var (
// Some per-process memory allocator stats.
// See https://golang.org/pkg/runtime/#MemStats
MemAlloc = metric.NewInt("go/mem/alloc", "Bytes allocated and not yet freed.", &types.MetricMetadata{types.Bytes})
MemTotalAlloc = metric.NewCounter("go/mem/total_alloc", "Bytes allocated (even if freed).", &types.MetricMetadata{types.Bytes})
MemMallocs = metric.NewCounter("go/mem/mallocs", "Number of mallocs.", nil)
MemFrees = metric.NewCounter("go/mem/frees", "Number of frees.", nil)
MemNextGC = metric.NewInt("go/mem/next_gc", "Next GC will happen when go/mem/alloc > this amount.", nil)
MemNumGC = metric.NewCounter("go/mem/num_gc", "Number of garbage collections.", nil)
MemPauseTotal = metric.NewCounter("go/mem/pause_total", "Total GC pause, in microseconds.", nil)
MemHeapSys = metric.NewInt("go/mem/heap_sys", "Bytes obtained from system.", &types.MetricMetadata{types.Bytes})
MemHeapIdle = metric.NewInt("go/mem/heap_idle", "Bytes in idle spans.", &types.MetricMetadata{types.Bytes})
MemHeapInuse = metric.NewInt("go/mem/heap_in_use", "Bytes in non-idle span.", &types.MetricMetadata{types.Bytes})
MemHeapObjects = metric.NewInt("go/mem/heap_objects", "Total number of allocated objects.", nil)
MemStackInuse = metric.NewInt("go/mem/stack_in_use", "Bytes used by stack allocator.", &types.MetricMetadata{types.Bytes})
MemStackSys = metric.NewInt("go/mem/stack_in_sys", "Bytes allocated to stack allocator.", &types.MetricMetadata{types.Bytes})
MemMSpanInuse = metric.NewInt("go/mem/mspan_in_use", "Bytes used by mspan structures.", &types.MetricMetadata{types.Bytes})
MemMSpanSys = metric.NewInt("go/mem/mspan_in_sys", "Bytes allocated to mspan structures.", &types.MetricMetadata{types.Bytes})
MemMCacheInuse = metric.NewInt("go/mem/mcache_in_use", "Bytes used by mcache structures.", &types.MetricMetadata{types.Bytes})
MemMCacheSys = metric.NewInt("go/mem/mcache_in_sys", "Bytes allocated to mcache structures.", &types.MetricMetadata{types.Bytes})
// Other runtime stats.
GoroutineNum = metric.NewInt("go/goroutine/num", "The number of goroutines that currently exist.", nil)
)
// Report updates runtime stats metrics.
//
// Call it periodically (ideally right before flushing the metrics) to gather
// runtime stats metrics.
func Report(c context.Context) {
var stats runtime.MemStats
runtime.ReadMemStats(&stats)
MemAlloc.Set(c, int64(stats.Alloc))
MemTotalAlloc.Set(c, int64(stats.TotalAlloc))
MemMallocs.Set(c, int64(stats.Mallocs))
MemFrees.Set(c, int64(stats.Frees))
MemNextGC.Set(c, int64(stats.NextGC))
MemNumGC.Set(c, int64(stats.NumGC))
MemPauseTotal.Set(c, int64(stats.PauseTotalNs/1000))
MemHeapSys.Set(c, int64(stats.HeapSys))
MemHeapIdle.Set(c, int64(stats.HeapIdle))
MemHeapInuse.Set(c, int64(stats.HeapInuse))
MemHeapObjects.Set(c, int64(stats.HeapObjects))
MemStackInuse.Set(c, int64(stats.StackInuse))
MemStackSys.Set(c, int64(stats.StackSys))
MemMSpanInuse.Set(c, int64(stats.MSpanInuse))
MemMSpanSys.Set(c, int64(stats.MSpanSys))
MemMCacheInuse.Set(c, int64(stats.MCacheInuse))
MemMCacheSys.Set(c, int64(stats.MCacheSys))
GoroutineNum.Set(c, int64(runtime.NumGoroutine()))
}