github.com/moov-io/imagecashletter@v0.10.1/internal/metrics/http.go (about)

     1  // Copyright 2020 The Moov Authors
     2  // Use of this source code is governed by an Apache License
     3  // license that can be found in the LICENSE file.
     4  
     5  package metrics
     6  
     7  import (
     8  	"fmt"
     9  	"net/http"
    10  	"regexp"
    11  	"strconv"
    12  	"strings"
    13  
    14  	moovhttp "github.com/moov-io/base/http"
    15  	"github.com/moov-io/base/log"
    16  
    17  	"github.com/go-kit/kit/metrics/prometheus"
    18  	stdprometheus "github.com/prometheus/client_golang/prometheus"
    19  )
    20  
    21  var (
    22  	routeHistogram = prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{
    23  		Name: "http_response_duration_seconds",
    24  		Help: "Histogram representing the http response durations",
    25  	}, []string{"route"})
    26  )
    27  
    28  func WrapResponseWriter(logger log.Logger, w http.ResponseWriter, r *http.Request) http.ResponseWriter {
    29  	route := fmt.Sprintf("%s-%s", strings.ToLower(r.Method), cleanMetricsPath(r.URL.Path))
    30  	return moovhttp.Wrap(logger, routeHistogram.With("route", route), w, r)
    31  }
    32  
    33  var baseIdRegex = regexp.MustCompile(`([a-f0-9]{40})`)
    34  
    35  // cleanMetricsPath takes a URL path and formats it for Prometheus metrics
    36  //
    37  // This method replaces /'s with -'s and clean out ID's (which are numeric).
    38  // This method also strips out moov/base.ID() values from URL path slugs.
    39  func cleanMetricsPath(path string) string {
    40  	parts := strings.Split(path, "/")
    41  	var out []string
    42  	for i := range parts {
    43  		if n, _ := strconv.Atoi(parts[i]); n > 0 || parts[i] == "" {
    44  			continue // numeric ID
    45  		}
    46  		if baseIdRegex.MatchString(parts[i]) {
    47  			continue // assume it's a moov/base.ID() value
    48  		}
    49  		out = append(out, parts[i])
    50  	}
    51  	return strings.Join(out, "-")
    52  }