Skip to content

Commit eff5280

Browse files
authored
Make SetGroupingKey's hash configurable (#423)
1 parent d912d11 commit eff5280

File tree

2 files changed

+34
-17
lines changed

2 files changed

+34
-17
lines changed

model/modelprocessor/groupingkey.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package modelprocessor
1919

2020
import (
2121
"context"
22-
"crypto/md5"
2322
"encoding/hex"
2423
"hash"
2524
"io"
@@ -29,7 +28,9 @@ import (
2928

3029
// SetGroupingKey is a modelpb.BatchProcessor that sets the grouping key for errors
3130
// by hashing their stack frames.
32-
type SetGroupingKey struct{}
31+
type SetGroupingKey struct {
32+
NewHash func() hash.Hash
33+
}
3334

3435
// ProcessBatch sets the grouping key for errors.
3536
func (s SetGroupingKey) ProcessBatch(ctx context.Context, b *modelpb.Batch) error {
@@ -42,7 +43,7 @@ func (s SetGroupingKey) ProcessBatch(ctx context.Context, b *modelpb.Batch) erro
4243
}
4344

4445
func (s SetGroupingKey) processError(ctx context.Context, event *modelpb.Error) {
45-
hash := md5.New()
46+
hash := s.NewHash()
4647
var updated bool
4748
if event.Exception != nil {
4849
if s.hashExceptionTree(event.Exception, hash, s.hashExceptionType) {

model/modelprocessor/groupingkey_test.go

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818
package modelprocessor_test
1919

2020
import (
21+
"bytes"
2122
"context"
22-
"crypto/md5"
2323
"encoding/hex"
24+
"hash"
25+
"strings"
2426
"testing"
2527

2628
"github.com/stretchr/testify/assert"
@@ -36,7 +38,7 @@ func TestSetGroupingKey(t *testing.T) {
3638
}{
3739
"empty": {
3840
input: &modelpb.Error{},
39-
groupingKey: hashStrings( /*empty*/ ),
41+
groupingKey: "",
4042
},
4143
"exception_type_log_parammessage": {
4244
input: &modelpb.Error{
@@ -47,7 +49,7 @@ func TestSetGroupingKey(t *testing.T) {
4749
ParamMessage: "log_parammessage",
4850
},
4951
},
50-
groupingKey: hashStrings("exception_type", "log_parammessage"),
52+
groupingKey: hexifyStrings("exception_type", "log_parammessage"),
5153
},
5254
"exception_stacktrace": {
5355
input: &modelpb.Error{
@@ -74,7 +76,7 @@ func TestSetGroupingKey(t *testing.T) {
7476
},
7577
Log: &modelpb.ErrorLog{Stacktrace: []*modelpb.StacktraceFrame{{Filename: "abc"}}}, // ignored
7678
},
77-
groupingKey: hashStrings(
79+
groupingKey: hexifyStrings(
7880
"module", "func_1", "filename", "func_2", "classname", "func_4", "func_5", "func_6",
7981
),
8082
},
@@ -84,7 +86,7 @@ func TestSetGroupingKey(t *testing.T) {
8486
Stacktrace: []*modelpb.StacktraceFrame{{Function: "function"}},
8587
},
8688
},
87-
groupingKey: hashStrings("function"),
89+
groupingKey: hexifyStrings("function"),
8890
},
8991
"exception_message": {
9092
input: &modelpb.Error{
@@ -101,13 +103,13 @@ func TestSetGroupingKey(t *testing.T) {
101103
},
102104
Log: &modelpb.ErrorLog{Message: "log_message"}, // ignored
103105
},
104-
groupingKey: hashStrings("message_1", "message_2", "message_3", "message_4"),
106+
groupingKey: hexifyStrings("message_1", "message_2", "message_3", "message_4"),
105107
},
106108
"log_message": {
107109
input: &modelpb.Error{
108110
Log: &modelpb.ErrorLog{Message: "log_message"}, // ignored
109111
},
110-
groupingKey: hashStrings("log_message"),
112+
groupingKey: hexifyStrings("log_message"),
111113
},
112114
}
113115

@@ -116,7 +118,7 @@ func TestSetGroupingKey(t *testing.T) {
116118
batch := modelpb.Batch{{
117119
Error: test.input,
118120
}}
119-
processor := modelprocessor.SetGroupingKey{}
121+
processor := modelprocessor.SetGroupingKey{NewHash: func() hash.Hash { return &fakeHash{} }}
120122
err := processor.ProcessBatch(context.Background(), &batch)
121123
assert.NoError(t, err)
122124
assert.Equal(t, test.groupingKey, batch[0].Error.GroupingKey)
@@ -125,10 +127,24 @@ func TestSetGroupingKey(t *testing.T) {
125127

126128
}
127129

128-
func hashStrings(s ...string) string {
129-
md5 := md5.New()
130-
for _, s := range s {
131-
md5.Write([]byte(s))
132-
}
133-
return hex.EncodeToString(md5.Sum(nil))
130+
// fakeHash is a hash.Hash that just accumulates the written data
131+
// to a buffer, and returns it exactly as written.
132+
type fakeHash struct {
133+
bytes.Buffer
134+
}
135+
136+
func (f *fakeHash) Sum(b []byte) []byte {
137+
return append(b, f.Buffer.Bytes()...)
138+
}
139+
140+
func (f *fakeHash) Size() int {
141+
return f.Buffer.Len()
142+
}
143+
144+
func (f *fakeHash) BlockSize() int {
145+
return 1
146+
}
147+
148+
func hexifyStrings(s ...string) string {
149+
return hex.EncodeToString([]byte(strings.Join(s, "")))
134150
}

0 commit comments

Comments
 (0)