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