github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/metrics/librato/librato.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 package librato 10 11 import ( 12 "fmt" 13 "log" 14 "math" 15 "regexp" 16 "time" 17 18 "github.com/ethereum/go-ethereum/metrics" 19 ) 20 21 //用于从time.duration.string提取单位的regexp 22 var unitRegexp = regexp.MustCompile(`[^\\d]+$`) 23 24 //将时间.duration转换为库的帮助程序,用于显示计时器度量的属性 25 func translateTimerAttributes(d time.Duration) (attrs map[string]interface{}) { 26 attrs = make(map[string]interface{}) 27 attrs[DisplayTransform] = fmt.Sprintf("x/%d", int64(d)) 28 attrs[DisplayUnitsShort] = string(unitRegexp.Find([]byte(d.String()))) 29 return 30 } 31 32 type Reporter struct { 33 Email, Token string 34 Namespace string 35 Source string 36 Interval time.Duration 37 Registry metrics.Registry 38 Percentiles []float64 //要报告的柱状图指标百分比 39 TimerAttributes map[string]interface{} //显示计时器的单位 40 intervalSec int64 41 } 42 43 func NewReporter(r metrics.Registry, d time.Duration, e string, t string, s string, p []float64, u time.Duration) *Reporter { 44 return &Reporter{e, t, "", s, d, r, p, translateTimerAttributes(u), int64(d / time.Second)} 45 } 46 47 func Librato(r metrics.Registry, d time.Duration, e string, t string, s string, p []float64, u time.Duration) { 48 NewReporter(r, d, e, t, s, p, u).Run() 49 } 50 51 func (rep *Reporter) Run() { 52 log.Printf("WARNING: This client has been DEPRECATED! It has been moved to https://github.com/mihasya/go-metrics-libarto,将于2015年8月5日从rcrowley/go metrics中删除) 53 ticker := time.Tick(rep.Interval) 54 metricsApi := &LibratoClient{rep.Email, rep.Token} 55 for now := range ticker { 56 var metrics Batch 57 var err error 58 if metrics, err = rep.BuildRequest(now, rep.Registry); err != nil { 59 log.Printf("ERROR constructing librato request body %s", err) 60 continue 61 } 62 if err := metricsApi.PostMetrics(metrics); err != nil { 63 log.Printf("ERROR sending metrics to librato %s", err) 64 continue 65 } 66 } 67 } 68 69 //根据度量提供的数据计算平方和。柱状图 70 //参见http://en.wikipedia.org/wiki/standard_deviation rapid_calculation_methods 71 func sumSquares(s metrics.Sample) float64 { 72 count := float64(s.Count()) 73 sumSquared := math.Pow(count*s.Mean(), 2) 74 sumSquares := math.Pow(count*s.StdDev(), 2) + sumSquared/count 75 if math.IsNaN(sumSquares) { 76 return 0.0 77 } 78 return sumSquares 79 } 80 func sumSquaresTimer(t metrics.Timer) float64 { 81 count := float64(t.Count()) 82 sumSquared := math.Pow(count*t.Mean(), 2) 83 sumSquares := math.Pow(count*t.StdDev(), 2) + sumSquared/count 84 if math.IsNaN(sumSquares) { 85 return 0.0 86 } 87 return sumSquares 88 } 89 90 func (rep *Reporter) BuildRequest(now time.Time, r metrics.Registry) (snapshot Batch, err error) { 91 snapshot = Batch{ 92 //将时间戳强制为单步执行fn,以便它们在天秤座图中对齐 93 MeasureTime: (now.Unix() / rep.intervalSec) * rep.intervalSec, 94 Source: rep.Source, 95 } 96 snapshot.Gauges = make([]Measurement, 0) 97 snapshot.Counters = make([]Measurement, 0) 98 histogramGaugeCount := 1 + len(rep.Percentiles) 99 r.Each(func(name string, metric interface{}) { 100 if rep.Namespace != "" { 101 name = fmt.Sprintf("%s.%s", rep.Namespace, name) 102 } 103 measurement := Measurement{} 104 measurement[Period] = rep.Interval.Seconds() 105 switch m := metric.(type) { 106 case metrics.Counter: 107 if m.Count() > 0 { 108 measurement[Name] = fmt.Sprintf("%s.%s", name, "count") 109 measurement[Value] = float64(m.Count()) 110 measurement[Attributes] = map[string]interface{}{ 111 DisplayUnitsLong: Operations, 112 DisplayUnitsShort: OperationsShort, 113 DisplayMin: "0", 114 } 115 snapshot.Counters = append(snapshot.Counters, measurement) 116 } 117 case metrics.Gauge: 118 measurement[Name] = name 119 measurement[Value] = float64(m.Value()) 120 snapshot.Gauges = append(snapshot.Gauges, measurement) 121 case metrics.GaugeFloat64: 122 measurement[Name] = name 123 measurement[Value] = m.Value() 124 snapshot.Gauges = append(snapshot.Gauges, measurement) 125 case metrics.Histogram: 126 if m.Count() > 0 { 127 gauges := make([]Measurement, histogramGaugeCount) 128 s := m.Sample() 129 measurement[Name] = fmt.Sprintf("%s.%s", name, "hist") 130 measurement[Count] = uint64(s.Count()) 131 measurement[Max] = float64(s.Max()) 132 measurement[Min] = float64(s.Min()) 133 measurement[Sum] = float64(s.Sum()) 134 measurement[SumSquares] = sumSquares(s) 135 gauges[0] = measurement 136 for i, p := range rep.Percentiles { 137 gauges[i+1] = Measurement{ 138 Name: fmt.Sprintf("%s.%.2f", measurement[Name], p), 139 Value: s.Percentile(p), 140 Period: measurement[Period], 141 } 142 } 143 snapshot.Gauges = append(snapshot.Gauges, gauges...) 144 } 145 case metrics.Meter: 146 measurement[Name] = name 147 measurement[Value] = float64(m.Count()) 148 snapshot.Counters = append(snapshot.Counters, measurement) 149 snapshot.Gauges = append(snapshot.Gauges, 150 Measurement{ 151 Name: fmt.Sprintf("%s.%s", name, "1min"), 152 Value: m.Rate1(), 153 Period: int64(rep.Interval.Seconds()), 154 Attributes: map[string]interface{}{ 155 DisplayUnitsLong: Operations, 156 DisplayUnitsShort: OperationsShort, 157 DisplayMin: "0", 158 }, 159 }, 160 Measurement{ 161 Name: fmt.Sprintf("%s.%s", name, "5min"), 162 Value: m.Rate5(), 163 Period: int64(rep.Interval.Seconds()), 164 Attributes: map[string]interface{}{ 165 DisplayUnitsLong: Operations, 166 DisplayUnitsShort: OperationsShort, 167 DisplayMin: "0", 168 }, 169 }, 170 Measurement{ 171 Name: fmt.Sprintf("%s.%s", name, "15min"), 172 Value: m.Rate15(), 173 Period: int64(rep.Interval.Seconds()), 174 Attributes: map[string]interface{}{ 175 DisplayUnitsLong: Operations, 176 DisplayUnitsShort: OperationsShort, 177 DisplayMin: "0", 178 }, 179 }, 180 ) 181 case metrics.Timer: 182 measurement[Name] = name 183 measurement[Value] = float64(m.Count()) 184 snapshot.Counters = append(snapshot.Counters, measurement) 185 if m.Count() > 0 { 186 libratoName := fmt.Sprintf("%s.%s", name, "timer.mean") 187 gauges := make([]Measurement, histogramGaugeCount) 188 gauges[0] = Measurement{ 189 Name: libratoName, 190 Count: uint64(m.Count()), 191 Sum: m.Mean() * float64(m.Count()), 192 Max: float64(m.Max()), 193 Min: float64(m.Min()), 194 SumSquares: sumSquaresTimer(m), 195 Period: int64(rep.Interval.Seconds()), 196 Attributes: rep.TimerAttributes, 197 } 198 for i, p := range rep.Percentiles { 199 gauges[i+1] = Measurement{ 200 Name: fmt.Sprintf("%s.timer.%2.0f", name, p*100), 201 Value: m.Percentile(p), 202 Period: int64(rep.Interval.Seconds()), 203 Attributes: rep.TimerAttributes, 204 } 205 } 206 snapshot.Gauges = append(snapshot.Gauges, gauges...) 207 snapshot.Gauges = append(snapshot.Gauges, 208 Measurement{ 209 Name: fmt.Sprintf("%s.%s", name, "rate.1min"), 210 Value: m.Rate1(), 211 Period: int64(rep.Interval.Seconds()), 212 Attributes: map[string]interface{}{ 213 DisplayUnitsLong: Operations, 214 DisplayUnitsShort: OperationsShort, 215 DisplayMin: "0", 216 }, 217 }, 218 Measurement{ 219 Name: fmt.Sprintf("%s.%s", name, "rate.5min"), 220 Value: m.Rate5(), 221 Period: int64(rep.Interval.Seconds()), 222 Attributes: map[string]interface{}{ 223 DisplayUnitsLong: Operations, 224 DisplayUnitsShort: OperationsShort, 225 DisplayMin: "0", 226 }, 227 }, 228 Measurement{ 229 Name: fmt.Sprintf("%s.%s", name, "rate.15min"), 230 Value: m.Rate15(), 231 Period: int64(rep.Interval.Seconds()), 232 Attributes: map[string]interface{}{ 233 DisplayUnitsLong: Operations, 234 DisplayUnitsShort: OperationsShort, 235 DisplayMin: "0", 236 }, 237 }, 238 ) 239 } 240 } 241 }) 242 return 243 }