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