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  }