From 140522df81e3940b6dc7233c9771ba45a44ba899 Mon Sep 17 00:00:00 2001 From: Sivachandran Paramasivam Date: Thu, 21 Sep 2023 19:34:08 +0530 Subject: [PATCH] error_map: canonicalise error --- error_map.go | 31 ++++++++++++++++++++++++++++++- error_map_test.go | 19 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/error_map.go b/error_map.go index 6bd178d..6f68781 100644 --- a/error_map.go +++ b/error_map.go @@ -1,12 +1,41 @@ package main import ( + "regexp" "sort" "strconv" "sync" "sync/atomic" ) +var ( + // capture 1 should capture the canonicalised error message + errMsgPatterns = []string{ + // read tcp 10.10.0.62:60682->63.35.24.107:443: read: connection reset by peer + `read tcp [\d.]+:\d+->[\d.]+:\d+: read: (.*)`, + } + + errMsgRegexes []*regexp.Regexp +) + +func init() { + for _, pattern := range errMsgPatterns { + errMsgRegexes = append(errMsgRegexes, regexp.MustCompile(pattern)) + } +} + +func canonicalizeError(err error) string { + msg := err.Error() + for _, errMsgRegex := range errMsgRegexes { + matches := errMsgRegex.FindStringSubmatch(msg) + if matches != nil { + return matches[1] + } + } + + return msg +} + type errorMap struct { mu sync.RWMutex m map[string]*uint64 @@ -19,7 +48,7 @@ func newErrorMap() *errorMap { } func (e *errorMap) add(err error) { - s := err.Error() + s := canonicalizeError(err) e.mu.RLock() c, ok := e.m[s] e.mu.RUnlock() diff --git a/error_map_test.go b/error_map_test.go index cad6fb2..0b37157 100644 --- a/error_map_test.go +++ b/error_map_test.go @@ -2,6 +2,7 @@ package main import ( "errors" + "fmt" "reflect" "testing" ) @@ -23,6 +24,24 @@ func TestErrorMapGet(t *testing.T) { } } +func TestCanonicalisedError(t *testing.T) { + m := newErrorMap() + for i := 0; i < 10; i++ { + m.add(fmt.Errorf("read tcp 10.10.0.62:%d->63.35.24.107:%d: read: connection reset by peer", 1000+i, 2000+i)) + } + m.add(errors.New("tls timeout")) + + e := errorsByFrequency{ + {"connection reset by peer", 10}, + {"tls timeout", 1}, + } + if a := m.byFrequency(); !reflect.DeepEqual(a, e) { + t.Logf("Expected: %+v", e) + t.Logf("Got: %+v", a) + t.Fail() + } +} + func TestByFrequency(t *testing.T) { m := newErrorMap() a := errors.New("A")