Scott Baker | eee8dd8 | 2019-09-24 12:52:34 -0700 | [diff] [blame] | 1 | package metrics |
| 2 | |
| 3 | import ( |
| 4 | "fmt" |
| 5 | "io" |
| 6 | "sort" |
| 7 | "time" |
| 8 | ) |
| 9 | |
| 10 | // Write sorts writes each metric in the given registry periodically to the |
| 11 | // given io.Writer. |
| 12 | func Write(r Registry, d time.Duration, w io.Writer) { |
| 13 | for _ = range time.Tick(d) { |
| 14 | WriteOnce(r, w) |
| 15 | } |
| 16 | } |
| 17 | |
| 18 | // WriteOnce sorts and writes metrics in the given registry to the given |
| 19 | // io.Writer. |
| 20 | func WriteOnce(r Registry, w io.Writer) { |
| 21 | var namedMetrics namedMetricSlice |
| 22 | r.Each(func(name string, i interface{}) { |
| 23 | namedMetrics = append(namedMetrics, namedMetric{name, i}) |
| 24 | }) |
| 25 | |
| 26 | sort.Sort(namedMetrics) |
| 27 | for _, namedMetric := range namedMetrics { |
| 28 | switch metric := namedMetric.m.(type) { |
| 29 | case Counter: |
| 30 | fmt.Fprintf(w, "counter %s\n", namedMetric.name) |
| 31 | fmt.Fprintf(w, " count: %9d\n", metric.Count()) |
| 32 | case Gauge: |
| 33 | fmt.Fprintf(w, "gauge %s\n", namedMetric.name) |
| 34 | fmt.Fprintf(w, " value: %9d\n", metric.Value()) |
| 35 | case GaugeFloat64: |
| 36 | fmt.Fprintf(w, "gauge %s\n", namedMetric.name) |
| 37 | fmt.Fprintf(w, " value: %f\n", metric.Value()) |
| 38 | case Healthcheck: |
| 39 | metric.Check() |
| 40 | fmt.Fprintf(w, "healthcheck %s\n", namedMetric.name) |
| 41 | fmt.Fprintf(w, " error: %v\n", metric.Error()) |
| 42 | case Histogram: |
| 43 | h := metric.Snapshot() |
| 44 | ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) |
| 45 | fmt.Fprintf(w, "histogram %s\n", namedMetric.name) |
| 46 | fmt.Fprintf(w, " count: %9d\n", h.Count()) |
| 47 | fmt.Fprintf(w, " min: %9d\n", h.Min()) |
| 48 | fmt.Fprintf(w, " max: %9d\n", h.Max()) |
| 49 | fmt.Fprintf(w, " mean: %12.2f\n", h.Mean()) |
| 50 | fmt.Fprintf(w, " stddev: %12.2f\n", h.StdDev()) |
| 51 | fmt.Fprintf(w, " median: %12.2f\n", ps[0]) |
| 52 | fmt.Fprintf(w, " 75%%: %12.2f\n", ps[1]) |
| 53 | fmt.Fprintf(w, " 95%%: %12.2f\n", ps[2]) |
| 54 | fmt.Fprintf(w, " 99%%: %12.2f\n", ps[3]) |
| 55 | fmt.Fprintf(w, " 99.9%%: %12.2f\n", ps[4]) |
| 56 | case Meter: |
| 57 | m := metric.Snapshot() |
| 58 | fmt.Fprintf(w, "meter %s\n", namedMetric.name) |
| 59 | fmt.Fprintf(w, " count: %9d\n", m.Count()) |
| 60 | fmt.Fprintf(w, " 1-min rate: %12.2f\n", m.Rate1()) |
| 61 | fmt.Fprintf(w, " 5-min rate: %12.2f\n", m.Rate5()) |
| 62 | fmt.Fprintf(w, " 15-min rate: %12.2f\n", m.Rate15()) |
| 63 | fmt.Fprintf(w, " mean rate: %12.2f\n", m.RateMean()) |
| 64 | case Timer: |
| 65 | t := metric.Snapshot() |
| 66 | ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999}) |
| 67 | fmt.Fprintf(w, "timer %s\n", namedMetric.name) |
| 68 | fmt.Fprintf(w, " count: %9d\n", t.Count()) |
| 69 | fmt.Fprintf(w, " min: %9d\n", t.Min()) |
| 70 | fmt.Fprintf(w, " max: %9d\n", t.Max()) |
| 71 | fmt.Fprintf(w, " mean: %12.2f\n", t.Mean()) |
| 72 | fmt.Fprintf(w, " stddev: %12.2f\n", t.StdDev()) |
| 73 | fmt.Fprintf(w, " median: %12.2f\n", ps[0]) |
| 74 | fmt.Fprintf(w, " 75%%: %12.2f\n", ps[1]) |
| 75 | fmt.Fprintf(w, " 95%%: %12.2f\n", ps[2]) |
| 76 | fmt.Fprintf(w, " 99%%: %12.2f\n", ps[3]) |
| 77 | fmt.Fprintf(w, " 99.9%%: %12.2f\n", ps[4]) |
| 78 | fmt.Fprintf(w, " 1-min rate: %12.2f\n", t.Rate1()) |
| 79 | fmt.Fprintf(w, " 5-min rate: %12.2f\n", t.Rate5()) |
| 80 | fmt.Fprintf(w, " 15-min rate: %12.2f\n", t.Rate15()) |
| 81 | fmt.Fprintf(w, " mean rate: %12.2f\n", t.RateMean()) |
| 82 | } |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | type namedMetric struct { |
| 87 | name string |
| 88 | m interface{} |
| 89 | } |
| 90 | |
| 91 | // namedMetricSlice is a slice of namedMetrics that implements sort.Interface. |
| 92 | type namedMetricSlice []namedMetric |
| 93 | |
| 94 | func (nms namedMetricSlice) Len() int { return len(nms) } |
| 95 | |
| 96 | func (nms namedMetricSlice) Swap(i, j int) { nms[i], nms[j] = nms[j], nms[i] } |
| 97 | |
| 98 | func (nms namedMetricSlice) Less(i, j int) bool { |
| 99 | return nms[i].name < nms[j].name |
| 100 | } |