github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/metrics/registry.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:40</date> 10 //</624450099665178624> 11 12 package metrics 13 14 import ( 15 "fmt" 16 "reflect" 17 "strings" 18 "sync" 19 ) 20 21 //Duplicatemetric是注册表返回的错误。当度量 22 //已经存在。如果要注册该度量,必须首先 23 //注销现有度量。 24 type DuplicateMetric string 25 26 func (err DuplicateMetric) Error() string { 27 return fmt.Sprintf("duplicate metric: %s", string(err)) 28 } 29 30 //注册表按名称保存对一组度量的引用,并且可以迭代 31 //通过它们,调用用户提供的回调函数。 32 // 33 //这是一个接口,以鼓励其他结构实现 34 //注册表API(视情况而定)。 35 type Registry interface { 36 37 //为每个注册的度量调用给定的函数。 38 Each(func(string, interface{})) 39 40 //按给定的名称获取度量,如果未注册,则为零。 41 Get(string) interface{} 42 43 //获取注册表中的所有指标。 44 GetAll() map[string]map[string]interface{} 45 46 //获取现有度量或注册给定的度量。 47 //如果在注册表中找不到接口,则该接口可以是要注册的度量。 48 //或者返回延迟实例化度量的函数。 49 GetOrRegister(string, interface{}) interface{} 50 51 //在给定的名称下注册给定的度量。 52 Register(string, interface{}) error 53 54 //运行所有已注册的运行状况检查。 55 RunHealthchecks() 56 57 //用给定的名称注销度量。 58 Unregister(string) 59 60 //注销所有度量。(主要用于测试。) 61 UnregisterAll() 62 } 63 64 //注册表的标准实现是一个互斥保护映射 65 //从名称到度量。 66 type StandardRegistry struct { 67 metrics map[string]interface{} 68 mutex sync.Mutex 69 } 70 71 //创建新注册表。 72 func NewRegistry() Registry { 73 return &StandardRegistry{metrics: make(map[string]interface{})} 74 } 75 76 //为每个注册的度量调用给定的函数。 77 func (r *StandardRegistry) Each(f func(string, interface{})) { 78 for name, i := range r.registered() { 79 f(name, i) 80 } 81 } 82 83 //按给定的名称获取度量,如果未注册,则为零。 84 func (r *StandardRegistry) Get(name string) interface{} { 85 r.mutex.Lock() 86 defer r.mutex.Unlock() 87 return r.metrics[name] 88 } 89 90 //获取现有度量或创建并注册新度量。线程安全的 91 //在失败时调用get和register的替代方法。 92 //如果在注册表中找不到接口,则该接口可以是要注册的度量。 93 //或者返回延迟实例化度量的函数。 94 func (r *StandardRegistry) GetOrRegister(name string, i interface{}) interface{} { 95 r.mutex.Lock() 96 defer r.mutex.Unlock() 97 if metric, ok := r.metrics[name]; ok { 98 return metric 99 } 100 if v := reflect.ValueOf(i); v.Kind() == reflect.Func { 101 i = v.Call(nil)[0].Interface() 102 } 103 r.register(name, i) 104 return i 105 } 106 107 //在给定的名称下注册给定的度量。返回重复度量值 108 //如果已注册给定名称的度量值。 109 func (r *StandardRegistry) Register(name string, i interface{}) error { 110 r.mutex.Lock() 111 defer r.mutex.Unlock() 112 return r.register(name, i) 113 } 114 115 //运行所有已注册的运行状况检查。 116 func (r *StandardRegistry) RunHealthchecks() { 117 r.mutex.Lock() 118 defer r.mutex.Unlock() 119 for _, i := range r.metrics { 120 if h, ok := i.(Healthcheck); ok { 121 h.Check() 122 } 123 } 124 } 125 126 //获取注册表中的所有指标 127 func (r *StandardRegistry) GetAll() map[string]map[string]interface{} { 128 data := make(map[string]map[string]interface{}) 129 r.Each(func(name string, i interface{}) { 130 values := make(map[string]interface{}) 131 switch metric := i.(type) { 132 case Counter: 133 values["count"] = metric.Count() 134 case Gauge: 135 values["value"] = metric.Value() 136 case GaugeFloat64: 137 values["value"] = metric.Value() 138 case Healthcheck: 139 values["error"] = nil 140 metric.Check() 141 if err := metric.Error(); nil != err { 142 values["error"] = metric.Error().Error() 143 } 144 case Histogram: 145 h := metric.Snapshot() 146 ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) 147 values["count"] = h.Count() 148 values["min"] = h.Min() 149 values["max"] = h.Max() 150 values["mean"] = h.Mean() 151 values["stddev"] = h.StdDev() 152 values["median"] = ps[0] 153 values["75%"] = ps[1] 154 values["95%"] = ps[2] 155 values["99%"] = ps[3] 156 values["99.9%"] = ps[4] 157 case Meter: 158 m := metric.Snapshot() 159 values["count"] = m.Count() 160 values["1m.rate"] = m.Rate1() 161 values["5m.rate"] = m.Rate5() 162 values["15m.rate"] = m.Rate15() 163 values["mean.rate"] = m.RateMean() 164 case Timer: 165 t := metric.Snapshot() 166 ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) 167 values["count"] = t.Count() 168 values["min"] = t.Min() 169 values["max"] = t.Max() 170 values["mean"] = t.Mean() 171 values["stddev"] = t.StdDev() 172 values["median"] = ps[0] 173 values["75%"] = ps[1] 174 values["95%"] = ps[2] 175 values["99%"] = ps[3] 176 values["99.9%"] = ps[4] 177 values["1m.rate"] = t.Rate1() 178 values["5m.rate"] = t.Rate5() 179 values["15m.rate"] = t.Rate15() 180 values["mean.rate"] = t.RateMean() 181 } 182 data[name] = values 183 }) 184 return data 185 } 186 187 //用给定的名称注销度量。 188 func (r *StandardRegistry) Unregister(name string) { 189 r.mutex.Lock() 190 defer r.mutex.Unlock() 191 r.stop(name) 192 delete(r.metrics, name) 193 } 194 195 //注销所有度量。(主要用于测试。) 196 func (r *StandardRegistry) UnregisterAll() { 197 r.mutex.Lock() 198 defer r.mutex.Unlock() 199 for name := range r.metrics { 200 r.stop(name) 201 delete(r.metrics, name) 202 } 203 } 204 205 func (r *StandardRegistry) register(name string, i interface{}) error { 206 if _, ok := r.metrics[name]; ok { 207 return DuplicateMetric(name) 208 } 209 switch i.(type) { 210 case Counter, Gauge, GaugeFloat64, Healthcheck, Histogram, Meter, Timer, ResettingTimer: 211 r.metrics[name] = i 212 } 213 return nil 214 } 215 216 func (r *StandardRegistry) registered() map[string]interface{} { 217 r.mutex.Lock() 218 defer r.mutex.Unlock() 219 metrics := make(map[string]interface{}, len(r.metrics)) 220 for name, i := range r.metrics { 221 metrics[name] = i 222 } 223 return metrics 224 } 225 226 func (r *StandardRegistry) stop(name string) { 227 if i, ok := r.metrics[name]; ok { 228 if s, ok := i.(Stoppable); ok { 229 s.Stop() 230 } 231 } 232 } 233 234 //stoppable定义必须停止的度量。 235 type Stoppable interface { 236 Stop() 237 } 238 239 type PrefixedRegistry struct { 240 underlying Registry 241 prefix string 242 } 243 244 func NewPrefixedRegistry(prefix string) Registry { 245 return &PrefixedRegistry{ 246 underlying: NewRegistry(), 247 prefix: prefix, 248 } 249 } 250 251 func NewPrefixedChildRegistry(parent Registry, prefix string) Registry { 252 return &PrefixedRegistry{ 253 underlying: parent, 254 prefix: prefix, 255 } 256 } 257 258 //为每个注册的度量调用给定的函数。 259 func (r *PrefixedRegistry) Each(fn func(string, interface{})) { 260 wrappedFn := func(prefix string) func(string, interface{}) { 261 return func(name string, iface interface{}) { 262 if strings.HasPrefix(name, prefix) { 263 fn(name, iface) 264 } else { 265 return 266 } 267 } 268 } 269 270 baseRegistry, prefix := findPrefix(r, "") 271 baseRegistry.Each(wrappedFn(prefix)) 272 } 273 274 func findPrefix(registry Registry, prefix string) (Registry, string) { 275 switch r := registry.(type) { 276 case *PrefixedRegistry: 277 return findPrefix(r.underlying, r.prefix+prefix) 278 case *StandardRegistry: 279 return r, prefix 280 } 281 return nil, "" 282 } 283 284 //按给定的名称获取度量,如果未注册,则为零。 285 func (r *PrefixedRegistry) Get(name string) interface{} { 286 realName := r.prefix + name 287 return r.underlying.Get(realName) 288 } 289 290 //获取现有度量或注册给定的度量。 291 //如果在注册表中找不到接口,则该接口可以是要注册的度量。 292 //或者返回延迟实例化度量的函数。 293 func (r *PrefixedRegistry) GetOrRegister(name string, metric interface{}) interface{} { 294 realName := r.prefix + name 295 return r.underlying.GetOrRegister(realName, metric) 296 } 297 298 //在给定的名称下注册给定的度量。名称将以前缀形式出现。 299 func (r *PrefixedRegistry) Register(name string, metric interface{}) error { 300 realName := r.prefix + name 301 return r.underlying.Register(realName, metric) 302 } 303 304 //运行所有已注册的运行状况检查。 305 func (r *PrefixedRegistry) RunHealthchecks() { 306 r.underlying.RunHealthchecks() 307 } 308 309 //获取注册表中的所有指标 310 func (r *PrefixedRegistry) GetAll() map[string]map[string]interface{} { 311 return r.underlying.GetAll() 312 } 313 314 //用给定的名称注销度量。名称将以前缀形式出现。 315 func (r *PrefixedRegistry) Unregister(name string) { 316 realName := r.prefix + name 317 r.underlying.Unregister(realName) 318 } 319 320 //注销所有度量。(主要用于测试。) 321 func (r *PrefixedRegistry) UnregisterAll() { 322 r.underlying.UnregisterAll() 323 } 324 325 var ( 326 DefaultRegistry = NewRegistry() 327 EphemeralRegistry = NewRegistry() 328 ) 329 330 //为每个注册的度量调用给定的函数。 331 func Each(f func(string, interface{})) { 332 DefaultRegistry.Each(f) 333 } 334 335 //按给定的名称获取度量,如果未注册,则为零。 336 func Get(name string) interface{} { 337 return DefaultRegistry.Get(name) 338 } 339 340 //获取现有度量或创建并注册新度量。线程安全的 341 //在失败时调用get和register的替代方法。 342 func GetOrRegister(name string, i interface{}) interface{} { 343 return DefaultRegistry.GetOrRegister(name, i) 344 } 345 346 //在给定的名称下注册给定的度量。返回重复度量值 347 //如果已注册给定名称的度量值。 348 func Register(name string, i interface{}) error { 349 return DefaultRegistry.Register(name, i) 350 } 351 352 //在给定的名称下注册给定的度量。如果一个度量由 353 //给定的名称已注册。 354 func MustRegister(name string, i interface{}) { 355 if err := Register(name, i); err != nil { 356 panic(err) 357 } 358 } 359 360 //运行所有已注册的运行状况检查。 361 func RunHealthchecks() { 362 DefaultRegistry.RunHealthchecks() 363 } 364 365 //用给定的名称注销度量。 366 func Unregister(name string) { 367 DefaultRegistry.Unregister(name) 368 } 369