Skip to content
Merged
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## [Unreleased]

### Added

- Added `IgnoredPaths` option to ignore measuring specific exact paths.


## [0.12.0] - 2024-04-19

### Changed
Expand Down
44 changes: 31 additions & 13 deletions middleware/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type Config struct {
DisableMeasureInflight bool
// 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 map[string]struct{}
IgnoredPaths []string
}

func (c *Config) defaults() {
Expand All @@ -51,14 +51,31 @@ func (c *Config) defaults() {
// receive a `Reporter` that knows how to get the data the Middleware service needs
// to measure.
type Middleware struct {
cfg Config
recorder metrics.Recorder
service string
groupedStatus bool
disableMeasureSize bool
disableMeasureInflight bool
ignoredPaths map[string]struct{}
}

// New returns the a Middleware service.
func New(cfg Config) Middleware {
cfg.defaults()

m := Middleware{cfg: cfg}
ignPaths := map[string]struct{}{}
for _, path := range cfg.IgnoredPaths {
ignPaths[path] = struct{}{}
}

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

return m
}
Expand All @@ -78,19 +95,20 @@ func (m Middleware) Measure(handlerID string, reporter Reporter, next func()) {
}

// Measure inflights if required.
if !m.cfg.DisableMeasureInflight {
if !m.disableMeasureInflight {
props := metrics.HTTPProperties{
Service: m.cfg.Service,
Service: m.service,
ID: hid,
}
m.cfg.Recorder.AddInflightRequests(ctx, props, 1)
defer m.cfg.Recorder.AddInflightRequests(ctx, props, -1)
m.recorder.AddInflightRequests(ctx, props, 1)
defer m.recorder.AddInflightRequests(ctx, props, -1)
}

// Start the timer and when finishing measure the duration.
start := time.Now()
defer func() {
if _, isPathIgnored := m.cfg.IgnoredPaths[reporter.URLPath()]; isPathIgnored {
_, shouldIgnore := m.ignoredPaths[reporter.URLPath()]
if shouldIgnore {
return
}

Expand All @@ -100,23 +118,23 @@ func (m Middleware) Measure(handlerID string, reporter Reporter, next func()) {
// first number of the status code because is the least
// required identification way.
var code string
if m.cfg.GroupedStatus {
if m.groupedStatus {
code = fmt.Sprintf("%dxx", reporter.StatusCode()/100)
} else {
code = strconv.Itoa(reporter.StatusCode())
}

props := metrics.HTTPReqProperties{
Service: m.cfg.Service,
Service: m.service,
ID: hid,
Method: reporter.Method(),
Code: code,
}
m.cfg.Recorder.ObserveHTTPRequestDuration(ctx, props, duration)
m.recorder.ObserveHTTPRequestDuration(ctx, props, duration)

// Measure size of response if required.
if !m.cfg.DisableMeasureSize {
m.cfg.Recorder.ObserveHTTPResponseSize(ctx, props, reporter.BytesWritten())
if !m.disableMeasureSize {
m.recorder.ObserveHTTPResponseSize(ctx, props, reporter.BytesWritten())
}
}()

Expand Down
6 changes: 2 additions & 4 deletions middleware/middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,8 @@ func TestMiddlewareMeasure(t *testing.T) {
handlerID: "test01",
config: func() middleware.Config {
return middleware.Config{
Service: "svc1",
IgnoredPaths: map[string]struct{}{
"/ignored": {},
},
Service: "svc1",
IgnoredPaths: []string{"/ignored"},
}
},
mock: func(mrec *mockmetrics.Recorder, mrep *mockmiddleware.Reporter) {
Expand Down