gitlab.com/aquachain/aquachain@v1.17.16-rc3.0.20221018032414-e3ddf1e1c055/common/metrics/writer.go (about)

     1  // Copyright 2018 The aquachain Authors
     2  // This file is part of the aquachain library.
     3  //
     4  // The aquachain library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The aquachain library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the aquachain library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package metrics
    18  
    19  import (
    20  	"fmt"
    21  	"io"
    22  	"sort"
    23  	"time"
    24  )
    25  
    26  // Write sorts writes each metric in the given registry periodically to the
    27  // given io.Writer.
    28  func Write(r Registry, d time.Duration, w io.Writer) {
    29  	for range time.Tick(d) {
    30  		WriteOnce(r, w)
    31  	}
    32  }
    33  
    34  // WriteOnce sorts and writes metrics in the given registry to the given
    35  // io.Writer.
    36  func WriteOnce(r Registry, w io.Writer) {
    37  	var namedMetrics namedMetricSlice
    38  	r.Each(func(name string, i interface{}) {
    39  		namedMetrics = append(namedMetrics, namedMetric{name, i})
    40  	})
    41  
    42  	sort.Sort(namedMetrics)
    43  	for _, namedMetric := range namedMetrics {
    44  		switch metric := namedMetric.m.(type) {
    45  		case Counter:
    46  			fmt.Fprintf(w, "counter %s\n", namedMetric.name)
    47  			fmt.Fprintf(w, "  count:       %9d\n", metric.Count())
    48  		case Gauge:
    49  			fmt.Fprintf(w, "gauge %s\n", namedMetric.name)
    50  			fmt.Fprintf(w, "  value:       %9d\n", metric.Value())
    51  		case GaugeFloat64:
    52  			fmt.Fprintf(w, "gauge %s\n", namedMetric.name)
    53  			fmt.Fprintf(w, "  value:       %f\n", metric.Value())
    54  		case Healthcheck:
    55  			metric.Check()
    56  			fmt.Fprintf(w, "healthcheck %s\n", namedMetric.name)
    57  			fmt.Fprintf(w, "  error:       %v\n", metric.Error())
    58  		case Histogram:
    59  			h := metric.Snapshot()
    60  			ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
    61  			fmt.Fprintf(w, "histogram %s\n", namedMetric.name)
    62  			fmt.Fprintf(w, "  count:       %9d\n", h.Count())
    63  			fmt.Fprintf(w, "  min:         %9d\n", h.Min())
    64  			fmt.Fprintf(w, "  max:         %9d\n", h.Max())
    65  			fmt.Fprintf(w, "  mean:        %12.2f\n", h.Mean())
    66  			fmt.Fprintf(w, "  stddev:      %12.2f\n", h.StdDev())
    67  			fmt.Fprintf(w, "  median:      %12.2f\n", ps[0])
    68  			fmt.Fprintf(w, "  75%%:         %12.2f\n", ps[1])
    69  			fmt.Fprintf(w, "  95%%:         %12.2f\n", ps[2])
    70  			fmt.Fprintf(w, "  99%%:         %12.2f\n", ps[3])
    71  			fmt.Fprintf(w, "  99.9%%:       %12.2f\n", ps[4])
    72  		case Meter:
    73  			m := metric.Snapshot()
    74  			fmt.Fprintf(w, "meter %s\n", namedMetric.name)
    75  			fmt.Fprintf(w, "  count:       %9d\n", m.Count())
    76  			fmt.Fprintf(w, "  1-min rate:  %12.2f\n", m.Rate1())
    77  			fmt.Fprintf(w, "  5-min rate:  %12.2f\n", m.Rate5())
    78  			fmt.Fprintf(w, "  15-min rate: %12.2f\n", m.Rate15())
    79  			fmt.Fprintf(w, "  mean rate:   %12.2f\n", m.RateMean())
    80  		case Timer:
    81  			t := metric.Snapshot()
    82  			ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
    83  			fmt.Fprintf(w, "timer %s\n", namedMetric.name)
    84  			fmt.Fprintf(w, "  count:       %9d\n", t.Count())
    85  			fmt.Fprintf(w, "  min:         %9d\n", t.Min())
    86  			fmt.Fprintf(w, "  max:         %9d\n", t.Max())
    87  			fmt.Fprintf(w, "  mean:        %12.2f\n", t.Mean())
    88  			fmt.Fprintf(w, "  stddev:      %12.2f\n", t.StdDev())
    89  			fmt.Fprintf(w, "  median:      %12.2f\n", ps[0])
    90  			fmt.Fprintf(w, "  75%%:         %12.2f\n", ps[1])
    91  			fmt.Fprintf(w, "  95%%:         %12.2f\n", ps[2])
    92  			fmt.Fprintf(w, "  99%%:         %12.2f\n", ps[3])
    93  			fmt.Fprintf(w, "  99.9%%:       %12.2f\n", ps[4])
    94  			fmt.Fprintf(w, "  1-min rate:  %12.2f\n", t.Rate1())
    95  			fmt.Fprintf(w, "  5-min rate:  %12.2f\n", t.Rate5())
    96  			fmt.Fprintf(w, "  15-min rate: %12.2f\n", t.Rate15())
    97  			fmt.Fprintf(w, "  mean rate:   %12.2f\n", t.RateMean())
    98  		}
    99  	}
   100  }
   101  
   102  type namedMetric struct {
   103  	name string
   104  	m    interface{}
   105  }
   106  
   107  // namedMetricSlice is a slice of namedMetrics that implements sort.Interface.
   108  type namedMetricSlice []namedMetric
   109  
   110  func (nms namedMetricSlice) Len() int { return len(nms) }
   111  
   112  func (nms namedMetricSlice) Swap(i, j int) { nms[i], nms[j] = nms[j], nms[i] }
   113  
   114  func (nms namedMetricSlice) Less(i, j int) bool {
   115  	return nms[i].name < nms[j].name
   116  }