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  }