| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- // Copyright 2015 The go-ethereum Authors
- // This file is part of the go-ethereum library.
- //
- // The go-ethereum library is free software: you can redistribute it and/or modify
- // it under the terms of the GNU Lesser General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // The go-ethereum library is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU Lesser General Public License for more details.
- //
- // You should have received a copy of the GNU Lesser General Public License
- // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
- // Package metrics provides general system and process level metrics collection.
- package metrics
- import (
- "os"
- "runtime"
- "strings"
- "time"
- "github.com/ethereum/go-ethereum/logger"
- "github.com/ethereum/go-ethereum/logger/glog"
- "github.com/rcrowley/go-metrics"
- "github.com/rcrowley/go-metrics/exp"
- )
- // MetricsEnabledFlag is the CLI flag name to use to enable metrics collections.
- var MetricsEnabledFlag = "metrics"
- // Enabled is the flag specifying if metrics are enable or not.
- var Enabled = false
- // Init enables or disables the metrics system. Since we need this to run before
- // any other code gets to create meters and timers, we'll actually do an ugly hack
- // and peek into the command line args for the metrics flag.
- func init() {
- for _, arg := range os.Args {
- if strings.TrimLeft(arg, "-") == MetricsEnabledFlag {
- glog.V(logger.Info).Infof("Enabling metrics collection")
- Enabled = true
- }
- }
- exp.Exp(metrics.DefaultRegistry)
- }
- // NewCounter create a new metrics Counter, either a real one of a NOP stub depending
- // on the metrics flag.
- func NewCounter(name string) metrics.Counter {
- if !Enabled {
- return new(metrics.NilCounter)
- }
- return metrics.GetOrRegisterCounter(name, metrics.DefaultRegistry)
- }
- // NewMeter create a new metrics Meter, either a real one of a NOP stub depending
- // on the metrics flag.
- func NewMeter(name string) metrics.Meter {
- if !Enabled {
- return new(metrics.NilMeter)
- }
- return metrics.GetOrRegisterMeter(name, metrics.DefaultRegistry)
- }
- // NewTimer create a new metrics Timer, either a real one of a NOP stub depending
- // on the metrics flag.
- func NewTimer(name string) metrics.Timer {
- if !Enabled {
- return new(metrics.NilTimer)
- }
- return metrics.GetOrRegisterTimer(name, metrics.DefaultRegistry)
- }
- // CollectProcessMetrics periodically collects various metrics about the running
- // process.
- func CollectProcessMetrics(refresh time.Duration) {
- // Short circuit if the metrics system is disabled
- if !Enabled {
- return
- }
- // Create the various data collectors
- memstats := make([]*runtime.MemStats, 2)
- diskstats := make([]*DiskStats, 2)
- for i := 0; i < len(memstats); i++ {
- memstats[i] = new(runtime.MemStats)
- diskstats[i] = new(DiskStats)
- }
- // Define the various metrics to collect
- memAllocs := metrics.GetOrRegisterMeter("system/memory/allocs", metrics.DefaultRegistry)
- memFrees := metrics.GetOrRegisterMeter("system/memory/frees", metrics.DefaultRegistry)
- memInuse := metrics.GetOrRegisterMeter("system/memory/inuse", metrics.DefaultRegistry)
- memPauses := metrics.GetOrRegisterMeter("system/memory/pauses", metrics.DefaultRegistry)
- var diskReads, diskReadBytes, diskWrites, diskWriteBytes metrics.Meter
- if err := ReadDiskStats(diskstats[0]); err == nil {
- diskReads = metrics.GetOrRegisterMeter("system/disk/readcount", metrics.DefaultRegistry)
- diskReadBytes = metrics.GetOrRegisterMeter("system/disk/readdata", metrics.DefaultRegistry)
- diskWrites = metrics.GetOrRegisterMeter("system/disk/writecount", metrics.DefaultRegistry)
- diskWriteBytes = metrics.GetOrRegisterMeter("system/disk/writedata", metrics.DefaultRegistry)
- } else {
- glog.V(logger.Debug).Infof("failed to read disk metrics: %v", err)
- }
- // Iterate loading the different stats and updating the meters
- for i := 1; ; i++ {
- runtime.ReadMemStats(memstats[i%2])
- memAllocs.Mark(int64(memstats[i%2].Mallocs - memstats[(i-1)%2].Mallocs))
- memFrees.Mark(int64(memstats[i%2].Frees - memstats[(i-1)%2].Frees))
- memInuse.Mark(int64(memstats[i%2].Alloc - memstats[(i-1)%2].Alloc))
- memPauses.Mark(int64(memstats[i%2].PauseTotalNs - memstats[(i-1)%2].PauseTotalNs))
- if ReadDiskStats(diskstats[i%2]) == nil {
- diskReads.Mark(int64(diskstats[i%2].ReadCount - diskstats[(i-1)%2].ReadCount))
- diskReadBytes.Mark(int64(diskstats[i%2].ReadBytes - diskstats[(i-1)%2].ReadBytes))
- diskWrites.Mark(int64(diskstats[i%2].WriteCount - diskstats[(i-1)%2].WriteCount))
- diskWriteBytes.Mark(int64(diskstats[i%2].WriteBytes - diskstats[(i-1)%2].WriteBytes))
- }
- time.Sleep(refresh)
- }
- }
|