github.com/luckypickle/go-ethereum-vet@v1.14.2/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/luckypickle/go-ethereum-vet/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 var diskReadBytesCounter, diskWriteBytesCounter Counter 61 if err := ReadDiskStats(diskstats[0]); err == nil { 62 diskReads = GetOrRegisterMeter("system/disk/readcount", DefaultRegistry) 63 diskReadBytes = GetOrRegisterMeter("system/disk/readdata", DefaultRegistry) 64 diskReadBytesCounter = GetOrRegisterCounter("system/disk/readbytes", DefaultRegistry) 65 diskWrites = GetOrRegisterMeter("system/disk/writecount", DefaultRegistry) 66 diskWriteBytes = GetOrRegisterMeter("system/disk/writedata", DefaultRegistry) 67 diskWriteBytesCounter = GetOrRegisterCounter("system/disk/writebytes", DefaultRegistry) 68 } else { 69 log.Debug("Failed to read disk metrics", "err", err) 70 } 71 // Iterate loading the different stats and updating the meters 72 for i := 1; ; i++ { 73 location1 := i % 2 74 location2 := (i - 1) % 2 75 76 runtime.ReadMemStats(memstats[location1]) 77 memAllocs.Mark(int64(memstats[location1].Mallocs - memstats[location2].Mallocs)) 78 memFrees.Mark(int64(memstats[location1].Frees - memstats[location2].Frees)) 79 memInuse.Mark(int64(memstats[location1].Alloc - memstats[location2].Alloc)) 80 memPauses.Mark(int64(memstats[location1].PauseTotalNs - memstats[location2].PauseTotalNs)) 81 82 if ReadDiskStats(diskstats[location1]) == nil { 83 diskReads.Mark(diskstats[location1].ReadCount - diskstats[location2].ReadCount) 84 diskReadBytes.Mark(diskstats[location1].ReadBytes - diskstats[location2].ReadBytes) 85 diskWrites.Mark(diskstats[location1].WriteCount - diskstats[location2].WriteCount) 86 diskWriteBytes.Mark(diskstats[location1].WriteBytes - diskstats[location2].WriteBytes) 87 88 diskReadBytesCounter.Inc(diskstats[location1].ReadBytes - diskstats[location2].ReadBytes) 89 diskWriteBytesCounter.Inc(diskstats[location1].WriteBytes - diskstats[location2].WriteBytes) 90 } 91 time.Sleep(refresh) 92 } 93 }