github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/metrics/metrics.go (about)

     1  // Go port of Coda Hale's Metrics library
     2  // <https://github.com/rcrowley/go-metrics>
     3  // Coda Hale's original work: <https://github.com/codahale/metrics>
     4  package metrics
     5  
     6  import (
     7  	"os"
     8  	"runtime"
     9  	"strings"
    10  	"time"
    11  
    12  	"github.com/quickchainproject/quickchain/log"
    13  )
    14  
    15  // Enabled is checked by the constructor functions for all of the
    16  // standard metrics.  If it is true, the metric returned is a stub.
    17  //
    18  // This global kill-switch helps quantify the observer effect and makes
    19  // for less cluttered pprof profiles.
    20  var Enabled bool = false
    21  
    22  // MetricsEnabledFlag is the CLI flag name to use to enable metrics collections.
    23  const MetricsEnabledFlag = "metrics"
    24  const DashboardEnabledFlag = "dashboard"
    25  
    26  // Init enables or disables the metrics system. Since we need this to run before
    27  // any other code gets to create meters and timers, we'll actually do an ugly hack
    28  // and peek into the command line args for the metrics flag.
    29  func init() {
    30  	for _, arg := range os.Args {
    31  		if flag := strings.TrimLeft(arg, "-"); flag == MetricsEnabledFlag || flag == DashboardEnabledFlag {
    32  			log.Info("Enabling metrics collection")
    33  			Enabled = true
    34  		}
    35  	}
    36  }
    37  
    38  // CollectProcessMetrics periodically collects various metrics about the running
    39  // process.
    40  func CollectProcessMetrics(refresh time.Duration) {
    41  	// Short circuit if the metrics system is disabled
    42  	if !Enabled {
    43  		return
    44  	}
    45  	// Create the various data collectors
    46  	memstats := make([]*runtime.MemStats, 2)
    47  	diskstats := make([]*DiskStats, 2)
    48  	for i := 0; i < len(memstats); i++ {
    49  		memstats[i] = new(runtime.MemStats)
    50  		diskstats[i] = new(DiskStats)
    51  	}
    52  	// Define the various metrics to collect
    53  	memAllocs := GetOrRegisterMeter("system/memory/allocs", DefaultRegistry)
    54  	memFrees := GetOrRegisterMeter("system/memory/frees", DefaultRegistry)
    55  	memInuse := GetOrRegisterMeter("system/memory/inuse", DefaultRegistry)
    56  	memPauses := GetOrRegisterMeter("system/memory/pauses", DefaultRegistry)
    57  
    58  	var diskReads, diskReadBytes, diskWrites, diskWriteBytes Meter
    59  	if err := ReadDiskStats(diskstats[0]); err == nil {
    60  		diskReads = GetOrRegisterMeter("system/disk/readcount", DefaultRegistry)
    61  		diskReadBytes = GetOrRegisterMeter("system/disk/readdata", DefaultRegistry)
    62  		diskWrites = GetOrRegisterMeter("system/disk/writecount", DefaultRegistry)
    63  		diskWriteBytes = GetOrRegisterMeter("system/disk/writedata", DefaultRegistry)
    64  	} else {
    65  		log.Debug("Failed to read disk metrics", "err", err)
    66  	}
    67  	// Iterate loading the different stats and updating the meters
    68  	for i := 1; ; i++ {
    69  		runtime.ReadMemStats(memstats[i%2])
    70  		memAllocs.Mark(int64(memstats[i%2].Mallocs - memstats[(i-1)%2].Mallocs))
    71  		memFrees.Mark(int64(memstats[i%2].Frees - memstats[(i-1)%2].Frees))
    72  		memInuse.Mark(int64(memstats[i%2].Alloc - memstats[(i-1)%2].Alloc))
    73  		memPauses.Mark(int64(memstats[i%2].PauseTotalNs - memstats[(i-1)%2].PauseTotalNs))
    74  
    75  		if ReadDiskStats(diskstats[i%2]) == nil {
    76  			diskReads.Mark(diskstats[i%2].ReadCount - diskstats[(i-1)%2].ReadCount)
    77  			diskReadBytes.Mark(diskstats[i%2].ReadBytes - diskstats[(i-1)%2].ReadBytes)
    78  			diskWrites.Mark(diskstats[i%2].WriteCount - diskstats[(i-1)%2].WriteCount)
    79  			diskWriteBytes.Mark(diskstats[i%2].WriteBytes - diskstats[(i-1)%2].WriteBytes)
    80  		}
    81  		time.Sleep(refresh)
    82  	}
    83  }