-
Notifications
You must be signed in to change notification settings - Fork 64
/
enhancers_common.go
130 lines (109 loc) · 3.65 KB
/
enhancers_common.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package main
import (
"context"
"regexp"
"strings"
"github.com/getsentry/sentry-go"
"github.com/rs/zerolog"
globalLogger "github.com/rs/zerolog/log"
)
type commonMsgPattern struct {
regex *regexp.Regexp
fingerprintKeys []string
}
// Common message patterns that should be grouped better
var patternsAll = []*commonMsgPattern{
{
regex: regexp.MustCompile(`^Memory cgroup out of memory: Killed process (?P<process_id>\d+) \((?P<process_name>[^)]+)\).*`),
fingerprintKeys: []string{"process_name"},
},
{
regex: regexp.MustCompile(`^Readiness probe failed:.*`),
fingerprintKeys: []string{},
},
{
regex: regexp.MustCompile(`^0\/\d+ nodes are available:.*`),
fingerprintKeys: []string{},
},
{
regex: regexp.MustCompile(`^Liveness probe failed:.*`),
fingerprintKeys: []string{},
},
{
regex: regexp.MustCompile(`(?i)^Exec lifecycle hook .* for Container "(?P<container_name>[^"]+)".*`),
fingerprintKeys: []string{"container_name"},
},
}
func checkCommonEnhancerPatterns() {
globalLogger.Debug().Msgf("Checking common enhancer patterns: making sure that they are correct")
for _, pat := range patternsAll {
regex := pat.regex
captureGroups := regex.SubexpNames()
captureGroupMap := make(map[string]struct{}, len(captureGroups))
// Build a set of capture group names
for _, groupName := range captureGroups {
captureGroupMap[groupName] = struct{}{}
}
// Check that the fingerprint keys exist in capture group
for _, key := range pat.fingerprintKeys {
_, found := captureGroupMap[key]
if !found {
globalLogger.Panic().Msgf("Invalid pattern: cannot find %s in pattern %q", key, regex.String())
}
}
}
}
func matchSinglePattern(message string, pattern *commonMsgPattern) (fingerprint []string, matched bool) {
pat := pattern.regex
match := pat.FindStringSubmatch(message)
if match == nil {
// No match
return nil, false
}
subMatchMap := make(map[string]string)
// Build the mapping: group name -> match
for i, name := range pat.SubexpNames() {
if i == 0 {
continue
}
subMatchMap[name] = match[i]
}
fingerprint = []string{pat.String()}
for _, value := range pattern.fingerprintKeys {
fingerprint = append(fingerprint, subMatchMap[value])
}
return fingerprint, true
}
func matchCommonPatterns(ctx context.Context, sentryEvent *sentry.Event) error {
logger := zerolog.Ctx(ctx)
message := sentryEvent.Message
logger.Trace().Msgf("Matching against message: %q", message)
for _, pattern := range patternsAll {
fingerprint, matched := matchSinglePattern(message, pattern)
if matched {
logger.Trace().Msgf("Pattern match: %v, fingerprint: %v", pattern, fingerprint)
// Ideally we should set the fingerprint on Scope, but there's no easy way right now to get
// fingerprint from the Scope, which is currently needed in theh pod enhancer.
sentryEvent.Fingerprint = fingerprint
return nil
}
}
return nil
}
func runCommonEnhancer(ctx context.Context, scope *sentry.Scope, sentryEvent *sentry.Event) error {
logger := zerolog.Ctx(ctx)
logger.Debug().Msgf("Running the common enhancer, event message: %q", sentryEvent.Message)
// Remove the "combined from similar events" prefix
combinedFromSimilarEventsPrefix := "(combined from similar events):"
if strings.HasPrefix(sentryEvent.Message, combinedFromSimilarEventsPrefix) {
newMessage := strings.TrimPrefix(sentryEvent.Message, combinedFromSimilarEventsPrefix)
sentryEvent.Message = strings.TrimSpace(newMessage)
scope.SetTag("combined_from_similar", "true")
}
// Match common message patterns
err := matchCommonPatterns(ctx, sentryEvent)
if err != nil {
return err
}
return nil
}