From 53ad91c63c2788a83d0e80985ffa89ce7cdf203f Mon Sep 17 00:00:00 2001 From: Rasmus Dahlberg Date: Wed, 4 Nov 2020 23:09:42 +0100 Subject: added prometheus metrics --- handler.go | 14 +++++++++++++- instance.go | 5 +++++ metric.go | 28 ++++++++++++++++++++++++++++ server/main.go | 4 ++++ 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 metric.go diff --git a/handler.go b/handler.go index 735d798..e45a78f 100644 --- a/handler.go +++ b/handler.go @@ -21,7 +21,16 @@ type appHandler struct { } func (a appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - ctx, cancel := context.WithDeadline(r.Context(), time.Now().Add(a.instance.Deadline)) + // export prometheus metrics + var now time.Time = time.Now() + var statusCode int + defer func() { + rspcnt.Inc(a.instance.LogParameters.id(), a.endpoint, fmt.Sprintf("%d", statusCode)) + latency.Observe(time.Now().Sub(now).Seconds(), a.instance.LogParameters.id(), a.endpoint, fmt.Sprintf("%d", statusCode)) + }() + reqcnt.Inc(a.instance.LogParameters.id(), a.endpoint) + + ctx, cancel := context.WithDeadline(r.Context(), now.Add(a.instance.Deadline)) defer cancel() if r.Method != a.method { @@ -71,6 +80,7 @@ func addEntry(ctx context.Context, i *Instance, w http.ResponseWriter, r *http.R if err != nil { return http.StatusInternalServerError, err } + lastSdiTimestamp.Set(float64(time.Now().Unix()), i.LogParameters.id()) if err := WriteJsonResponse(rsp, w); err != nil { return http.StatusInternalServerError, err } @@ -207,6 +217,8 @@ func getSth(ctx context.Context, i *Instance, w http.ResponseWriter, _ *http.Req if err != nil { return http.StatusInternalServerError, err } + lastSthTimestamp.Set(float64(time.Now().Unix()), i.LogParameters.id()) + lastSthSize.Set(float64(sth.SignedTreeHeadV1.TreeHead.TreeSize), i.LogParameters.id()) if err := WriteJsonResponse(rsp, w); err != nil { return http.StatusInternalServerError, err } diff --git a/instance.go b/instance.go index 843e9f8..65ebcb3 100644 --- a/instance.go +++ b/instance.go @@ -43,6 +43,10 @@ func (p LogParameters) String() string { return fmt.Sprintf("LogId(%s) TreeId(%d) Prefix(%s) NumAnchors(%d)", base64.StdEncoding.EncodeToString(p.LogId), p.TreeId, p.Prefix, len(p.AnchorList)) } +func (i *LogParameters) id() string { + return base64.StdEncoding.EncodeToString(i.LogId) +} + // NewInstance returns a new STFE Instance func NewInstance(lp *LogParameters, client trillian.TrillianLogClient, deadline time.Duration, mux *http.ServeMux) (*Instance, error) { i := &Instance{ @@ -51,6 +55,7 @@ func NewInstance(lp *LogParameters, client trillian.TrillianLogClient, deadline Deadline: deadline, } i.registerHandlers(mux) + once.Do(metricSetup) return i, nil } diff --git a/metric.go b/metric.go new file mode 100644 index 0000000..7179458 --- /dev/null +++ b/metric.go @@ -0,0 +1,28 @@ +package stfe + +import ( + "sync" + + "github.com/google/trillian/monitoring" + "github.com/google/trillian/monitoring/prometheus" +) + +var ( + once sync.Once + reqcnt monitoring.Counter // number of incoming http requests + rspcnt monitoring.Counter // number of valid http responses + latency monitoring.Histogram // request-response latency + lastSdiTimestamp monitoring.Gauge // unix timestamp from the most recent sdi + lastSthTimestamp monitoring.Gauge // unix timestamp from the most recent sth + lastSthSize monitoring.Gauge // tree size of most recent sth +) + +func metricSetup() { + mf := prometheus.MetricFactory{} + reqcnt = mf.NewCounter("http_req", "number of http requests", "logid", "endpoint") + rspcnt = mf.NewCounter("http_rsp", "number of http requests", "logid", "endpoint", "status") + latency = mf.NewHistogram("http_latency", "http request-response latency", "logid", "endpoint", "status") + lastSthTimestamp = mf.NewGauge("last_sth_timestamp", "unix timestamp while handling the most recent sth", "logid") + lastSdiTimestamp = mf.NewGauge("last_sdi_timestamp", "unix timestamp while handling the most recent sdi", "logid") + lastSthSize = mf.NewGauge("last_sth_size", "most recent sth tree size", "logid") +} diff --git a/server/main.go b/server/main.go index aea2239..7cf9ccf 100644 --- a/server/main.go +++ b/server/main.go @@ -9,6 +9,7 @@ import ( "github.com/golang/glog" "github.com/google/trillian" + "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/system-transparency/stfe" "google.golang.org/grpc" ) @@ -40,6 +41,9 @@ func main() { mux := http.NewServeMux() http.Handle("/", mux) + glog.Info("Adding prometheus handler on path: /metrics") + http.Handle("/metrics", promhttp.Handler()) + lp, err := stfe.NewLogParameters(*trillianID, *prefix, *anchorPath, *keyPath, *maxRange, *maxChain) if err != nil { glog.Fatalf("failed setting up log parameters: %v", err) -- cgit v1.2.3