gitlab.com/aquachain/aquachain@v1.17.16-rc3.0.20221018032414-e3ddf1e1c055/common/metrics/metrics.go (about) 1 // Copyright 2018 The aquachain Authors 2 // This file is part of the aquachain library. 3 // 4 // The aquachain library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The aquachain library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the aquachain library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Go port of Coda Hale's Metrics library 18 // 19 // <https://github.com/rcrowley/go-metrics> 20 // 21 // Coda Hale's original work: <https://github.com/codahale/metrics> 22 package metrics 23 24 import ( 25 "os" 26 "runtime" 27 "strings" 28 "time" 29 30 "gitlab.com/aquachain/aquachain/common/log" 31 ) 32 33 // Enabled is checked by the constructor functions for all of the 34 // standard metrics. If it is true, the metric returned is a stub. 35 // 36 // This global kill-switch helps quantify the observer effect and makes 37 // for less cluttered pprof profiles. 38 var Enabled bool = false 39 40 // MetricsEnabledFlag is the CLI flag name to use to enable metrics collections. 41 const MetricsEnabledFlag = "metrics" 42 const DashboardEnabledFlag = "dashboard" 43 44 // Init enables or disables the metrics system. Since we need this to run before 45 // any other code gets to create meters and timers, we'll actually do an ugly hack 46 // and peek into the command line args for the metrics flag. 47 func init() { 48 for _, arg := range os.Args { 49 if flag := strings.TrimLeft(arg, "-"); flag == MetricsEnabledFlag || flag == DashboardEnabledFlag { 50 log.Info("Enabling metrics collection") 51 Enabled = true 52 } 53 } 54 } 55 56 // CollectProcessMetrics periodically collects various metrics about the running 57 // process. 58 func CollectProcessMetrics(refresh time.Duration) { 59 // Short circuit if the metrics system is disabled 60 if !Enabled { 61 return 62 } 63 // Create the various data collectors 64 memstats := make([]*runtime.MemStats, 2) 65 diskstats := make([]*DiskStats, 2) 66 for i := 0; i < len(memstats); i++ { 67 memstats[i] = new(runtime.MemStats) 68 diskstats[i] = new(DiskStats) 69 } 70 // Define the various metrics to collect 71 memAllocs := GetOrRegisterMeter("system/memory/allocs", DefaultRegistry) 72 memFrees := GetOrRegisterMeter("system/memory/frees", DefaultRegistry) 73 memInuse := GetOrRegisterMeter("system/memory/inuse", DefaultRegistry) 74 memPauses := GetOrRegisterMeter("system/memory/pauses", DefaultRegistry) 75 76 var diskReads, diskReadBytes, diskWrites, diskWriteBytes Meter 77 if err := ReadDiskStats(diskstats[0]); err == nil { 78 diskReads = GetOrRegisterMeter("system/disk/readcount", DefaultRegistry) 79 diskReadBytes = GetOrRegisterMeter("system/disk/readdata", DefaultRegistry) 80 diskWrites = GetOrRegisterMeter("system/disk/writecount", DefaultRegistry) 81 diskWriteBytes = GetOrRegisterMeter("system/disk/writedata", DefaultRegistry) 82 } else { 83 log.Debug("Failed to read disk metrics", "err", err) 84 } 85 // Iterate loading the different stats and updating the meters 86 for i := 1; ; i++ { 87 runtime.ReadMemStats(memstats[i%2]) 88 memAllocs.Mark(int64(memstats[i%2].Mallocs - memstats[(i-1)%2].Mallocs)) 89 memFrees.Mark(int64(memstats[i%2].Frees - memstats[(i-1)%2].Frees)) 90 memInuse.Mark(int64(memstats[i%2].Alloc - memstats[(i-1)%2].Alloc)) 91 memPauses.Mark(int64(memstats[i%2].PauseTotalNs - memstats[(i-1)%2].PauseTotalNs)) 92 93 if ReadDiskStats(diskstats[i%2]) == nil { 94 diskReads.Mark(diskstats[i%2].ReadCount - diskstats[(i-1)%2].ReadCount) 95 diskReadBytes.Mark(diskstats[i%2].ReadBytes - diskstats[(i-1)%2].ReadBytes) 96 diskWrites.Mark(diskstats[i%2].WriteCount - diskstats[(i-1)%2].WriteCount) 97 diskWriteBytes.Mark(diskstats[i%2].WriteBytes - diskstats[(i-1)%2].WriteBytes) 98 } 99 time.Sleep(refresh) 100 } 101 }