From f46aa7c1454504065e2b697ddac72d1d1c83d70c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matthias=20K=C3=A4ppler?= <mkaeppler@gitlab.com>
Date: Mon, 28 Sep 2020 16:17:59 +0000
Subject: [PATCH] Add image scaler duration Prometheus metric

---
 ...k-more-image-scaler-prometheus-metrics.yml |  5 ++
 internal/imageresizer/image_resizer.go        | 51 +++++++++++++++----
 2 files changed, 47 insertions(+), 9 deletions(-)
 create mode 100644 changelogs/unreleased/mk-more-image-scaler-prometheus-metrics.yml

diff --git a/changelogs/unreleased/mk-more-image-scaler-prometheus-metrics.yml b/changelogs/unreleased/mk-more-image-scaler-prometheus-metrics.yml
new file mode 100644
index 0000000000000..229933e6be200
--- /dev/null
+++ b/changelogs/unreleased/mk-more-image-scaler-prometheus-metrics.yml
@@ -0,0 +1,5 @@
+---
+title: Add image scaler duration histogram
+merge_request: 614
+author:
+type: other
diff --git a/internal/imageresizer/image_resizer.go b/internal/imageresizer/image_resizer.go
index 545fc8c8c8c3b..aa9df89cf34e3 100644
--- a/internal/imageresizer/image_resizer.go
+++ b/internal/imageresizer/image_resizer.go
@@ -65,24 +65,52 @@ var httpClient = &http.Client{
 	Transport: httpTransport,
 }
 
+const (
+	namespace = "gitlab_workhorse"
+	subsystem = "image_resize"
+)
+
 var (
 	imageResizeConcurrencyLimitExceeds = prometheus.NewCounter(
 		prometheus.CounterOpts{
-			Name: "gitlab_workhorse_image_resize_concurrency_limit_exceeds_total",
-			Help: "Amount of image resizing requests that exceeded the maximum allowed scaler processes",
+			Namespace: namespace,
+			Subsystem: subsystem,
+			Name:      "concurrency_limit_exceeds_total",
+			Help:      "Amount of image resizing requests that exceeded the maximum allowed scaler processes",
 		},
 	)
 	imageResizeProcesses = prometheus.NewGauge(
 		prometheus.GaugeOpts{
-			Name: "gitlab_workhorse_image_resize_processes",
-			Help: "Amount of image resizing scaler processes working now",
+			Namespace: namespace,
+			Subsystem: subsystem,
+			Name:      "processes",
+			Help:      "Amount of image resizing scaler processes working now",
 		},
 	)
 	imageResizeCompleted = prometheus.NewCounter(
 		prometheus.CounterOpts{
-			Name: "gitlab_workhorse_image_resize_completed_total",
-			Help: "Amount of image resizing processes successfully completed",
+			Namespace: namespace,
+			Subsystem: subsystem,
+			Name:      "completed_total",
+			Help:      "Amount of image resizing processes sucessfully completed",
+		},
+	)
+	imageResizeDurations = prometheus.NewHistogramVec(
+		prometheus.HistogramOpts{
+			Namespace: namespace,
+			Subsystem: subsystem,
+			Name:      "duration_seconds",
+			Help:      "Total seconds spent serving image resizing requests",
+			Buckets: []float64{
+				0.050, /* 50ms */
+				0.1,   /* 100ms */
+				0.2,   /* 200ms */
+				0.4,   /* 400ms */
+				0.8,   /* 800ms */
+				1.6,   /* 1600ms */
+			},
 		},
+		[]string{"content_type", "width"},
 	)
 )
 
@@ -90,6 +118,7 @@ func init() {
 	prometheus.MustRegister(imageResizeConcurrencyLimitExceeds)
 	prometheus.MustRegister(imageResizeProcesses)
 	prometheus.MustRegister(imageResizeCompleted)
+	prometheus.MustRegister(imageResizeDurations)
 }
 
 // This Injecter forks into a dedicated scaler process to resize an image identified by path or URL
@@ -135,11 +164,17 @@ func (r *resizer) Inject(w http.ResponseWriter, req *http.Request, paramsData st
 
 	w.Header().Del("Content-Length")
 	bytesWritten, err := serveImage(imageReader, w, resizeCmd)
+
 	if err != nil {
 		handleFailedCommand(w, req, bytesWritten, err, logFields(bytesWritten))
 		return
 	}
 
+	if resizeCmd != nil {
+		widthLabelVal := strconv.Itoa(int(params.Width))
+		imageResizeDurations.WithLabelValues(params.ContentType, widthLabelVal).Observe(time.Since(start).Seconds())
+	}
+
 	logger.WithFields(*logFields(bytesWritten)).Printf("ImageResizer: Success")
 }
 
@@ -153,9 +188,7 @@ func serveImage(r io.Reader, w io.Writer, resizeCmd *exec.Cmd) (int64, error) {
 	}
 
 	if resizeCmd != nil {
-		if err = resizeCmd.Wait(); err != nil {
-			return bytesWritten, err
-		}
+		return bytesWritten, resizeCmd.Wait()
 	}
 
 	return bytesWritten, nil
-- 
GitLab