From d6b83167c839e47b26729234b72f3b6a796e462e Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Sun, 29 Jul 2018 16:07:58 +0200 Subject: [PATCH] exp: export healthcheck status This will trigger the check immediately, then export its status as ".status" with value of 1 if the healthcheck is OK and 0 otherwise. If the status is 0, the error is stored in ".error", otherwise an empty string is used. Fix #213 --- cmd/metrics-example/metrics-example.go | 22 ++++++++++++++++++++- exp/exp.go | 27 ++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/cmd/metrics-example/metrics-example.go b/cmd/metrics-example/metrics-example.go index 66f42c0..1fb24a4 100644 --- a/cmd/metrics-example/metrics-example.go +++ b/cmd/metrics-example/metrics-example.go @@ -2,8 +2,12 @@ package main import ( "errors" + // "fmt" "github.com/rcrowley/go-metrics" + // "github.com/rcrowley/go-metrics/exp" // "github.com/rcrowley/go-metrics/stathat" + // "net" + // "net/http" "log" "math/rand" "os" @@ -69,7 +73,7 @@ func main() { } hc := metrics.NewHealthcheck(func(h metrics.Healthcheck) { - if 0 < rand.Intn(2) { + if 0 == rand.Intn(2) { h.Healthy() } else { h.Unhealthy(errors.New("baz")) @@ -136,6 +140,22 @@ func main() { metrics.Log(r, 60e9, log.New(os.Stderr, "metrics: ", log.Lmicroseconds)) + /* + mux := http.NewServeMux() + mux.Handle("/", exp.ExpHandler(r)) + server := &http.Server{Handler: mux} + addr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:0") + if err != nil { + panic(err) + } + listener, err := net.ListenTCP("tcp", addr) + if err != nil { + panic(err) + } + fmt.Printf("Listening on %s\n", listener.Addr()) + server.Serve(listener) + */ + /* w, err := syslog.Dial("unixgram", "/dev/log", syslog.LOG_INFO, "metrics") if nil != err { log.Fatalln(err) } diff --git a/exp/exp.go b/exp/exp.go index 11dd3f8..858b658 100644 --- a/exp/exp.go +++ b/exp/exp.go @@ -78,6 +78,20 @@ func (exp *exp) getFloat(name string) *expvar.Float { return v } +func (exp *exp) getString(name string) *expvar.String { + var v *expvar.String + exp.expvarLock.Lock() + p := expvar.Get(name) + if p != nil { + v = p.(*expvar.String) + } else { + v = new(expvar.String) + expvar.Publish(name, v) + } + exp.expvarLock.Unlock() + return v +} + func (exp *exp) publishCounter(name string, metric metrics.Counter) { v := exp.getInt(name) v.Set(metric.Count()) @@ -134,6 +148,17 @@ func (exp *exp) publishTimer(name string, metric metrics.Timer) { exp.getFloat(name + ".mean-rate").Set(float64(t.RateMean())) } +func (exp *exp) publishHealthcheck(name string, metric metrics.Healthcheck) { + metric.Check() + if err := metric.Error(); err == nil { + exp.getInt(name + ".status").Set(1) + exp.getString(name + ".error").Set("") + } else { + exp.getInt(name + ".status").Set(0) + exp.getString(name + ".error").Set(err.Error()) + } +} + func (exp *exp) syncToExpvar() { exp.registry.Each(func(name string, i interface{}) { switch i.(type) { @@ -149,6 +174,8 @@ func (exp *exp) syncToExpvar() { exp.publishMeter(name, i.(metrics.Meter)) case metrics.Timer: exp.publishTimer(name, i.(metrics.Timer)) + case metrics.Healthcheck: + exp.publishHealthcheck(name, i.(metrics.Healthcheck)) default: panic(fmt.Sprintf("unsupported type for '%s': %T", name, i)) }