Skip to content

Added IgnoredPathRegexps option #256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ This settings will disable measuring the number of requests being handled concur

This setting is a list of paths that will not be measured for the request duration and the response size. They will still be counted in the RequestsInflight metric.

#### IgnoredPathRegexps
This setting is a list of regular expression path patterns that will not be measured for the request duration and the response size. They will still be counted in the RequestsInflight metric.

#### Custom handler ID

One of the options that you need to pass when wrapping the handler with the middleware is `handlerID`, this has 2 working ways.
Expand Down
23 changes: 21 additions & 2 deletions middleware/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package middleware
import (
"context"
"fmt"
"regexp"
"strconv"
"time"

Expand Down Expand Up @@ -35,6 +36,10 @@ type Config struct {
// IgnoredPaths is a list of paths that will not be measured for the request duration
// and the response size. They will still be counted in the RequestsInflight metric.
IgnoredPaths []string
// IgnoredPathRegexps is a list of regular expression path patterns that will not be
// measured for the request duration and the response size. They will still be counted
// in the RequestsInflight metric.
IgnoredPathRegexps []string
}

func (c *Config) defaults() {
Expand All @@ -57,6 +62,7 @@ type Middleware struct {
disableMeasureSize bool
disableMeasureInflight bool
ignoredPaths map[string]struct{}
ignoredPathRegexps []*regexp.Regexp
}

// New returns the a Middleware service.
Expand All @@ -68,13 +74,19 @@ func New(cfg Config) Middleware {
ignPaths[path] = struct{}{}
}

ignPathRegexps := make([]*regexp.Regexp, len(cfg.IgnoredPathRegexps))
for i, pathRegexp := range cfg.IgnoredPathRegexps {
ignPathRegexps[i] = regexp.MustCompile(pathRegexp)
}

m := Middleware{
recorder: cfg.Recorder,
service: cfg.Service,
groupedStatus: cfg.GroupedStatus,
disableMeasureSize: cfg.DisableMeasureSize,
disableMeasureInflight: cfg.DisableMeasureInflight,
ignoredPaths: ignPaths,
ignoredPathRegexps: ignPathRegexps,
}

return m
Expand Down Expand Up @@ -107,11 +119,18 @@ func (m Middleware) Measure(handlerID string, reporter Reporter, next func()) {
// Start the timer and when finishing measure the duration.
start := time.Now()
defer func() {
_, shouldIgnore := m.ignoredPaths[reporter.URLPath()]
if shouldIgnore {
path := reporter.URLPath()

if _, shouldIgnore := m.ignoredPaths[path]; shouldIgnore {
return
}

for _, ignorePathRegexp := range m.ignoredPathRegexps {
if ignorePathRegexp.MatchString(path) {
return
}
}

duration := time.Since(start)

// If we need to group the status code, it uses the
Expand Down
27 changes: 27 additions & 0 deletions middleware/middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,33 @@ func TestMiddlewareMeasure(t *testing.T) {
mrec.On("ObserveHTTPRequestDuration", mock.Anything, expRepProps, mock.Anything).Once()
},
},

"Having an ignored path regexp in the config, it should not measure the metrics for the ignored path.": {
handlerID: "test01",
config: func() middleware.Config {
return middleware.Config{
Service: "svc1",
IgnoredPathRegexps: []string{"/ignored/*"},
}
},
mock: func(mrec *mockmetrics.Recorder, mrep *mockmiddleware.Reporter) {
// Reporter mocks.
mrep.On("Context").Once().Return(context.TODO())
mrep.AssertNotCalled(t, "StatusCode")
mrep.AssertNotCalled(t, "Method")
mrep.AssertNotCalled(t, "BytesWritten")
mrep.On("URLPath").Once().Return("/ignored/path")

// Recorder mocks.
expProps := metrics.HTTPProperties{Service: "svc1", ID: "test01"}
expRepProps := metrics.HTTPReqProperties{Service: "svc1", ID: "test01", Method: "PATCH", Code: "418"}

mrec.On("AddInflightRequests", mock.Anything, expProps, 1).Once()
mrec.On("AddInflightRequests", mock.Anything, expProps, -1).Once()
mrec.AssertNotCalled(t, "ObserveHTTPRequestDuration", mock.Anything, expRepProps, mock.Anything)
mrec.AssertNotCalled(t, "ObserveHTTPResponseSize", mock.Anything, expRepProps, int64(42))
},
},
}

for name, test := range tests {
Expand Down