Skip to content

Commit

Permalink
feat(HMS-4757): measure header and body request sizes
Browse files Browse the repository at this point in the history
This change add metrics to retrieve the size for header and
body requests, by adding the necessary changes to metrics
structure, and the behavior to store the metrics at the
metrics middleware.

https://issues.redhat.com/browse/HMS-4757

Signed-off-by: Alejandro Visiedo <[email protected]>
  • Loading branch information
avisiedo committed Sep 26, 2024
1 parent 7a68d7d commit 3713b2a
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
24 changes: 24 additions & 0 deletions internal/infrastructure/middleware/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package middleware

import (
"errors"
"log/slog"
"strconv"
"strings"
"time"

"github.com/labstack/echo/v4"
echo_middleware "github.com/labstack/echo/v4/middleware"
"github.com/podengo-project/idmsvc-backend/internal/infrastructure/context"
"github.com/podengo-project/idmsvc-backend/internal/metrics"
"github.com/prometheus/client_golang/prometheus"
)
Expand Down Expand Up @@ -40,6 +43,8 @@ func MetricsMiddlewareWithConfig(config *MetricsConfig) echo.MiddlewareFunc {

err := next(ctx)

logger := context.LogFromCtx(ctx.Request().Context())

method := ctx.Request().Method
path := MatchedRoute(ctx)
status := ctx.Response().Status
Expand All @@ -50,6 +55,25 @@ func MetricsMiddlewareWithConfig(config *MetricsConfig) echo.MiddlewareFunc {
status = httpErr.Code
}
statusStr := strconv.Itoa(status)
headerBuf := strings.Builder{}
headerSize := 0.0
if errHeaderBuf := ctx.Request().Header.Write(&headerBuf); errHeaderBuf == nil {
headerSize = float64(len(headerBuf.String()))
config.Metrics.HTTPRequestHeaderSize.WithLabelValues(statusStr, method, path).Observe(headerSize)
} else {
logger.Warn("writing headers in string buffer",
slog.String("err", errHeaderBuf.Error()),
)
}
bodySize := float64(ctx.Request().ContentLength)
config.Metrics.HTTPRequestBodySize.WithLabelValues(statusStr, method, path).Observe(bodySize)
logger.Debug("measured request size",
slog.String("status", statusStr),
slog.String("method", method),
slog.String("path", path),
slog.Float64("header_size", headerSize),
slog.Float64("body_size", bodySize),
)

config.Metrics.HTTPRequestDuration.WithLabelValues(statusStr, method, path).Observe(time.Since(start).Seconds())

Expand Down
1 change: 1 addition & 0 deletions internal/infrastructure/middleware/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ func TestMetricsMiddlewareWithConfigCreation(t *testing.T) {
}

e := echo.New()
e.Use(ContextLogConfig(&LogConfig{}))
m := MetricsMiddlewareWithConfig(config)
e.Use(m)
path := "/api/idmsvc/v1/domains"
Expand Down
20 changes: 19 additions & 1 deletion internal/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ const (

// Metrics holds all the Prometheus metrics for the application
type Metrics struct {
// HTTPRequestDuration is a histogram that measures the duration of HTTP requests
// HTTPRequestDuration is a histogram that measures the duration of the HTTP requests
HTTPRequestDuration *prometheus.HistogramVec
// HTTPRequestHeaderSize is a histogram that measures the size of the HTTP request headers.
HTTPRequestHeaderSize *prometheus.HistogramVec
// HTTPRequestBodySize is a histogram that measures the size of the HTTP request bodys.
HTTPRequestBodySize *prometheus.HistogramVec

reg *prometheus.Registry
}
Expand All @@ -37,6 +41,20 @@ func NewMetrics(reg *prometheus.Registry) *Metrics {
Help: "Duration of HTTP requests",
Buckets: prometheus.ExponentialBuckets(0.0005, 2, 20),
}, []string{"status", "method", "path"}),
HTTPRequestHeaderSize: promauto.With(reg).NewHistogramVec(prometheus.HistogramOpts{
Namespace: NameSpace,
Name: "http_request_header_size",
Help: "Size of the HTTP request headers",
// Bucket limited to 32KB
Buckets: []float64{1024, 2 * 1024, 4 * 1024, 8 * 1024, 16 * 1024, 32 * 1024},
}, []string{"status", "method", "path"}),
HTTPRequestBodySize: promauto.With(reg).NewHistogramVec(prometheus.HistogramOpts{
Namespace: NameSpace,
Name: "http_request_body_size",
Help: "Size of the HTTP request bodies",
// Bucket limited to 128KB
Buckets: []float64{1024, 2 * 1024, 4 * 1024, 8 * 1024, 16 * 1024, 32 * 1024, 64 * 1024, 128 * 1024},
}, []string{"status", "method", "path"}),
}

reg.MustRegister(collectors.NewBuildInfoCollector())
Expand Down

0 comments on commit 3713b2a

Please sign in to comment.