Skip to content

Commit

Permalink
Merge pull request #173 from harness/0.17.0-debug-log-metrics
Browse files Browse the repository at this point in the history
FFM-8719 Log out raw metrics requests
  • Loading branch information
jcox250 authored Aug 17, 2023
2 parents e1bdd24 + e1a5f21 commit 0a1f94a
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 14 deletions.
1 change: 1 addition & 0 deletions cmd/ff-proxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,7 @@ func main() {
middleware.NewEchoLoggingMiddleware(),
middleware.NewEchoAuthMiddleware([]byte(authSecret), bypassAuth),
middleware.NewPrometheusMiddleware(promReg),
middleware.NewMetricsLoggingMiddleware(logger),
)

go func() {
Expand Down
13 changes: 11 additions & 2 deletions log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ package log
import (
"context"

"github.com/harness/ff-proxy/middleware"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)

type contextKey string

const RequestIDKey contextKey = "requestID"

// Logger defines a logger with multiple logging levels. When using the logger
// calls to its methods should include a brief message describing what happened
// and then key value pairs that contain additional info e.g.
Expand Down Expand Up @@ -221,11 +224,17 @@ func (s StructuredLogger) With(keyvals ...interface{}) Logger {
// returns them as a slice of strings
func ExtractRequestValuesFromContext(ctx context.Context) []interface{} {
values := []interface{}{}
reqID := middleware.GetRequestID(ctx)
reqID := GetRequestID(ctx)
if reqID != "" {
values = append(values, "reqID")
values = append(values, reqID)
}

return values
}

// GetRequestID extracts the requestID value from the context if it exists.
func GetRequestID(ctx context.Context) string {
requestID, _ := ctx.Value(RequestIDKey).(string)
return requestID
}
39 changes: 28 additions & 11 deletions middleware/middleware.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package middleware

import (
"bytes"
"context"
"errors"
"fmt"
"github.com/harness/ff-proxy/log"
"io"
"net/http"
"strconv"
"strings"
Expand Down Expand Up @@ -63,10 +67,6 @@ func NewEchoAuthMiddleware(secret []byte, bypassAuth bool) echo.MiddlewareFunc {
})
}

type contextKey string

const requestIDKey contextKey = "requestID"

// NewEchoRequestIDMiddleware returns an echo middleware that either uses a
// provided requestID from the header or generates one and adds it to the request
// context.
Expand All @@ -82,7 +82,7 @@ func NewEchoRequestIDMiddleware() echo.MiddlewareFunc {
reqID = requestUUID.String()
}

req = req.WithContext(context.WithValue(req.Context(), requestIDKey, reqID))
req = req.WithContext(context.WithValue(req.Context(), log.RequestIDKey, reqID))
c.SetRequest(req)

resp.Header().Set(echo.HeaderXRequestID, reqID)
Expand All @@ -91,12 +91,6 @@ func NewEchoRequestIDMiddleware() echo.MiddlewareFunc {
}
}

// GetRequestID extracts the requestID value from the context if it exists.
func GetRequestID(ctx context.Context) string {
requestID, _ := ctx.Value(requestIDKey).(string)
return requestID
}

type prometheusMiddleware struct {
requestCount *prometheus.CounterVec
requestDuration *prometheus.HistogramVec
Expand Down Expand Up @@ -185,3 +179,26 @@ func NewPrometheusMiddleware(reg prometheus.Registerer) echo.MiddlewareFunc {
}
}
}

// NewMetricsLoggingMiddleware creates a middleware that logs the raw request body coming in to the /metrics endpoint
func NewMetricsLoggingMiddleware(logger log.Logger) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
if c.Path() != "/metrics/:environment_uuid" {
return next(c)
}
defer c.Request().Body.Close()

buf := bytes.NewBuffer([]byte{})
if _, err := io.Copy(buf, c.Request().Body); err != nil {
return fmt.Errorf("failed to read body in metrics logging middleware: %s")
}

logger.Info("raw metrics payload", "component", "MetricsLoggingMiddleware", "payload", buf.String())

// Need to reset the request body so it can be read by our handler.
c.Request().Body = io.NopCloser(buf)
return next(c)
}
}
}
18 changes: 17 additions & 1 deletion services/metric_service.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package services

import (
"bytes"
"context"
"fmt"
"io"
"net/http"
"sync"

Expand Down Expand Up @@ -150,11 +152,25 @@ func (m MetricService) sendMetrics(ctx context.Context, envID string, metric dom
return nil
}

logPayloadFn := func(ctx context.Context, req *http.Request) error {
buf := bytes.NewBuffer([]byte{})
if _, err := io.Copy(buf, req.Body); err != nil {
return err
}

req.Body = io.NopCloser(buf)
m.log.Info("posting metrics to saas", "payload", buf.String())
return nil
}

ctx = context.WithValue(ctx, tokenKey, token)
res, err := m.client.PostMetricsWithResponse(ctx, envID, &clientgen.PostMetricsParams{Cluster: &clusterIdentifier}, clientgen.PostMetricsJSONRequestBody{
MetricsData: metric.MetricsData,
TargetData: metric.TargetData,
}, addAuthToken)
},
addAuthToken,
logPayloadFn,
)
if err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions transport/http_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ func setupHTTPServer(t *testing.T, bypassAuth bool, opts ...setupOpts) *HTTPServ
middleware.NewEchoLoggingMiddleware(),
middleware.NewEchoAuthMiddleware([]byte(`secret`), bypassAuth),
middleware.NewPrometheusMiddleware(prometheus.NewRegistry()),
middleware.NewMetricsLoggingMiddleware(logger),
)
return server
}
Expand Down

0 comments on commit 0a1f94a

Please sign in to comment.