github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/metrics/writer.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // Copyright 2019 The go-aigar Authors 3 // This file is part of the go-aigar library. 4 // 5 // The go-aigar library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-aigar library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-aigar library. If not, see <http://www.gnu.org/licenses/>. 17 18 package metrics 19 20 import ( 21 "fmt" 22 "io" 23 "sort" 24 "time" 25 ) 26 27 // Write sorts writes each metric in the given registry periodically to the 28 // given io.Writer. 29 func Write(r Registry, d time.Duration, w io.Writer) { 30 for range time.Tick(d) { 31 WriteOnce(r, w) 32 } 33 } 34 35 // WriteOnce sorts and writes metrics in the given registry to the given 36 // io.Writer. 37 func WriteOnce(r Registry, w io.Writer) { 38 var namedMetrics namedMetricSlice 39 r.Each(func(name string, i interface{}) { 40 namedMetrics = append(namedMetrics, namedMetric{name, i}) 41 }) 42 43 sort.Sort(namedMetrics) 44 for _, namedMetric := range namedMetrics { 45 switch metric := namedMetric.m.(type) { 46 case Counter: 47 fmt.Fprintf(w, "counter %s\n", namedMetric.name) 48 fmt.Fprintf(w, " count: %9d\n", metric.Count()) 49 case Gauge: 50 fmt.Fprintf(w, "gauge %s\n", namedMetric.name) 51 fmt.Fprintf(w, " value: %9d\n", metric.Value()) 52 case GaugeFloat64: 53 fmt.Fprintf(w, "gauge %s\n", namedMetric.name) 54 fmt.Fprintf(w, " value: %f\n", metric.Value()) 55 case Healthcheck: 56 metric.Check() 57 fmt.Fprintf(w, "healthcheck %s\n", namedMetric.name) 58 fmt.Fprintf(w, " error: %v\n", metric.Error()) 59 case Histogram: 60 h := metric.Snapshot() 61 ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) 62 fmt.Fprintf(w, "histogram %s\n", namedMetric.name) 63 fmt.Fprintf(w, " count: %9d\n", h.Count()) 64 fmt.Fprintf(w, " min: %9d\n", h.Min()) 65 fmt.Fprintf(w, " max: %9d\n", h.Max()) 66 fmt.Fprintf(w, " mean: %12.2f\n", h.Mean()) 67 fmt.Fprintf(w, " stddev: %12.2f\n", h.StdDev()) 68 fmt.Fprintf(w, " median: %12.2f\n", ps[0]) 69 fmt.Fprintf(w, " 75%%: %12.2f\n", ps[1]) 70 fmt.Fprintf(w, " 95%%: %12.2f\n", ps[2]) 71 fmt.Fprintf(w, " 99%%: %12.2f\n", ps[3]) 72 fmt.Fprintf(w, " 99.9%%: %12.2f\n", ps[4]) 73 case Meter: 74 m := metric.Snapshot() 75 fmt.Fprintf(w, "meter %s\n", namedMetric.name) 76 fmt.Fprintf(w, " count: %9d\n", m.Count()) 77 fmt.Fprintf(w, " 1-min rate: %12.2f\n", m.Rate1()) 78 fmt.Fprintf(w, " 5-min rate: %12.2f\n", m.Rate5()) 79 fmt.Fprintf(w, " 15-min rate: %12.2f\n", m.Rate15()) 80 fmt.Fprintf(w, " mean rate: %12.2f\n", m.RateMean()) 81 case Timer: 82 t := metric.Snapshot() 83 ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) 84 fmt.Fprintf(w, "timer %s\n", namedMetric.name) 85 fmt.Fprintf(w, " count: %9d\n", t.Count()) 86 fmt.Fprintf(w, " min: %9d\n", t.Min()) 87 fmt.Fprintf(w, " max: %9d\n", t.Max()) 88 fmt.Fprintf(w, " mean: %12.2f\n", t.Mean()) 89 fmt.Fprintf(w, " stddev: %12.2f\n", t.StdDev()) 90 fmt.Fprintf(w, " median: %12.2f\n", ps[0]) 91 fmt.Fprintf(w, " 75%%: %12.2f\n", ps[1]) 92 fmt.Fprintf(w, " 95%%: %12.2f\n", ps[2]) 93 fmt.Fprintf(w, " 99%%: %12.2f\n", ps[3]) 94 fmt.Fprintf(w, " 99.9%%: %12.2f\n", ps[4]) 95 fmt.Fprintf(w, " 1-min rate: %12.2f\n", t.Rate1()) 96 fmt.Fprintf(w, " 5-min rate: %12.2f\n", t.Rate5()) 97 fmt.Fprintf(w, " 15-min rate: %12.2f\n", t.Rate15()) 98 fmt.Fprintf(w, " mean rate: %12.2f\n", t.RateMean()) 99 } 100 } 101 } 102 103 type namedMetric struct { 104 name string 105 m interface{} 106 } 107 108 // namedMetricSlice is a slice of namedMetrics that implements sort.Interface. 109 type namedMetricSlice []namedMetric 110 111 func (nms namedMetricSlice) Len() int { return len(nms) } 112 113 func (nms namedMetricSlice) Swap(i, j int) { nms[i], nms[j] = nms[j], nms[i] } 114 115 func (nms namedMetricSlice) Less(i, j int) bool { 116 return nms[i].name < nms[j].name 117 }