Skip to content

Commit

Permalink
use apiMiddleware for better metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
fsrv-xyz committed Dec 31, 2021
1 parent 51b0649 commit 23cc7bf
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 11 deletions.
11 changes: 3 additions & 8 deletions handler.go
Expand Up @@ -9,10 +9,11 @@ import (
"net/http"
"net/url"

"github.com/prometheus/client_golang/prometheus"

"github.com/google/uuid"
"github.com/gorilla/mux"
"github.com/minio/minio-go/v7"
"github.com/prometheus/client_golang/prometheus"
)

func (c *Config) HealthCheckHandler(w http.ResponseWriter, _ *http.Request) {
Expand Down Expand Up @@ -50,9 +51,7 @@ func (c *Config) DownloadHandler(w http.ResponseWriter, r *http.Request) {

// only return checksum when called in sum mode
if sumMode {
traceLog(c.logger, "sum "+object.Key)
metricObjectAction.With(prometheus.Labels{"action": "sum"}).Inc()

_, httpResponseError := fmt.Fprintf(w, "%s %s\n", object.UserMetadata[ChecksumMetadataFieldName], filename)
if httpResponseError != nil {
w.WriteHeader(http.StatusInternalServerError)
Expand All @@ -70,7 +69,6 @@ func (c *Config) DownloadHandler(w http.ResponseWriter, r *http.Request) {
return
}

traceLog(c.logger, "download "+object.Key)
metricObjectAction.With(prometheus.Labels{"action": "download"}).Inc()

if _, copyError := io.Copy(w, reader); err != nil {
Expand All @@ -81,7 +79,6 @@ func (c *Config) DownloadHandler(w http.ResponseWriter, r *http.Request) {
}

func (c *Config) UploadHandler(w http.ResponseWriter, r *http.Request) {
fmt.Printf("%#v\n", r.Header)
vars := mux.Vars(r)
filename, ok := vars["filename"]
filename = url.QueryEscape(filename)
Expand Down Expand Up @@ -114,7 +111,7 @@ func (c *Config) UploadHandler(w http.ResponseWriter, r *http.Request) {
metadata[ChecksumMetadataFieldName] = hex.EncodeToString(sha512SumGenerator.Sum(nil))

id := uuid.New()
object, err := c.minioClient.PutObject(r.Context(), p.S3BucketName, id.String()+"/"+filename, buf, r.ContentLength, minio.PutObjectOptions{
_, err = c.minioClient.PutObject(r.Context(), p.S3BucketName, id.String()+"/"+filename, buf, r.ContentLength, minio.PutObjectOptions{
ContentType: selectContentType(filename),
UserMetadata: metadata,
})
Expand All @@ -126,8 +123,6 @@ func (c *Config) UploadHandler(w http.ResponseWriter, r *http.Request) {
}

metricObjectSize.Observe(float64(r.ContentLength))

traceLog(c.logger, "upload "+object.Key)
metricObjectAction.With(prometheus.Labels{"action": "upload"}).Inc()

// generate download link
Expand Down
22 changes: 22 additions & 0 deletions helper.go
Expand Up @@ -6,8 +6,30 @@ import (
"net/http"
"path"
"runtime"
"time"

"github.com/prometheus/client_golang/prometheus"
)

// apiMiddleware - logging and metrics for api endpoints
func apiMiddleware(handler http.HandlerFunc, logger *log.Logger, endpointName string) http.HandlerFunc {
if logger == nil {
logger = log.Default()
}
fn := func(w http.ResponseWriter, r *http.Request) {
metricEndpointRequests.With(prometheus.Labels{"endpoint": endpointName}).Inc()
start := time.Now()

// serve http request
handler.ServeHTTP(w, r)
duration := time.Since(start)
metricOperationDuration.With(prometheus.Labels{"endpoint": endpointName}).Observe(duration.Seconds())

logger.Printf("%v %v %v", r.Method, r.RequestURI, duration)
}
return fn
}

// selectContentType - parse file extension and determine content type
func selectContentType(filename string) string {
extension := path.Ext(filename)
Expand Down
19 changes: 16 additions & 3 deletions main.go
Expand Up @@ -45,13 +45,26 @@ var (
Help: "Actions applied to objects",
}, []string{"action"})

metricEndpointRequests = promauto.NewGaugeVec(prometheus.GaugeOpts{
Namespace: "transfer",
Name: "endpoint_requests",
Help: "HTTP endpoint requests",
}, []string{"endpoint"})

metricObjectSize = promauto.NewHistogram(prometheus.HistogramOpts{
Namespace: "transfer",
Name: "object_size_bytes",
Help: "Uploaded objects by size",
Buckets: []float64{1 * KB, 10 * KB, 100 * KB, 1 * MB, 10 * MB, 100 * MB, 300 * MB, 600 * MB, 900 * MB},
})

metricOperationDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
Namespace: "transfer",
Name: "operation_duration",
Help: "duration per endpoint",
Buckets: []float64{0.01, 0.05, 0.1, 0.2, 0.4, 1, 2, 4, 8, 10, 20},
}, []string{"endpoint"})

// declare initial state as unhealthy
backendState = StateUnhealthy
)
Expand Down Expand Up @@ -151,9 +164,9 @@ func main() {
}

applicationRouter := mux.NewRouter()
applicationRouter.HandleFunc("/{id}/{filename}", c.DownloadHandler).Methods(http.MethodGet)
applicationRouter.HandleFunc("/{id}/{filename}/{sum:sum}", c.DownloadHandler).Methods(http.MethodGet)
applicationRouter.HandleFunc("/{filename}", c.UploadHandler).Methods(http.MethodPut)
applicationRouter.HandleFunc("/{filename}", apiMiddleware(c.UploadHandler, c.logger, "upload")).Methods(http.MethodPut)
applicationRouter.HandleFunc("/{id}/{filename}", apiMiddleware(c.DownloadHandler, c.logger, "download")).Methods(http.MethodGet)
applicationRouter.HandleFunc("/{id}/{filename}/{sum:sum}", apiMiddleware(c.DownloadHandler, c.logger, "sum")).Methods(http.MethodGet)

metricsRouter := mux.NewRouter()
metricsRouter.Handle("/metrics", promhttp.Handler()).Methods(http.MethodGet)
Expand Down

0 comments on commit 23cc7bf

Please sign in to comment.