/
filtering.go
105 lines (93 loc) · 2.98 KB
/
filtering.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
package logging
import (
"fmt"
"strings"
"github.com/hashicorp/terraform-plugin-log/internal/hclogutils"
)
const logMaskingReplacementString = "***"
// ShouldOmit takes a log's *string message and slices of arguments,
// and determines, based on the LoggerOpts configuration, if the
// log should be omitted (i.e. prevent it to be printed on the final writer).
func (lo LoggerOpts) ShouldOmit(msg *string, hclogArgSlices ...[]interface{}) bool {
// Omit log if any of the configured keys is found
// either in the logger implied arguments,
// or in the additional arguments
if len(lo.OmitLogWithFieldKeys) > 0 {
for _, args := range hclogArgSlices {
argKeys := hclogutils.ArgsToKeys(args)
if argKeysContain(argKeys, lo.OmitLogWithFieldKeys) {
return true
}
}
}
// Omit log if any of the configured regexp matches the log message
if len(lo.OmitLogWithMessageRegexes) > 0 {
for _, r := range lo.OmitLogWithMessageRegexes {
if r.MatchString(*msg) {
return true
}
}
}
// Omit log if any of the configured strings is contained in the log message
if len(lo.OmitLogWithMessageStrings) > 0 {
for _, s := range lo.OmitLogWithMessageStrings {
if strings.Contains(*msg, s) {
return true
}
}
}
return false
}
// ApplyMask takes a log's *string message and slices of arguments,
// and applies masking of keys' values and/or message,
// based on the LoggerOpts configuration.
//
// Note that the given input is changed-in-place by this method.
func (lo LoggerOpts) ApplyMask(msg *string, hclogArgSlices ...[]interface{}) {
if len(lo.MaskFieldValuesWithFieldKeys) > 0 {
for _, k := range lo.MaskFieldValuesWithFieldKeys {
for _, args := range hclogArgSlices {
// Here we loop `i` with steps of 2, starting from position 1 (i.e. `1, 3, 5, 7...`).
// We then look up the key for each argument, by looking at `i-1`.
// This ensures that in case of malformed arg slices that don't have
// an even number of elements, we simply skip the last k/v pair.
for i := 1; i < len(args); i += 2 {
switch argK := args[i-1].(type) {
case string:
if k == argK {
args[i] = logMaskingReplacementString
}
default:
if k == fmt.Sprintf("%s", argK) {
args[i] = logMaskingReplacementString
}
}
}
}
}
}
// Replace any part of the log message matching any of the configured regexp,
// with a masking replacement string
if len(lo.MaskMessageRegexes) > 0 {
for _, r := range lo.MaskMessageRegexes {
*msg = r.ReplaceAllString(*msg, logMaskingReplacementString)
}
}
// Replace any part of the log message equal to any of the configured strings,
// with a masking replacement string
if len(lo.MaskMessageStrings) > 0 {
for _, s := range lo.MaskMessageStrings {
*msg = strings.ReplaceAll(*msg, s, logMaskingReplacementString)
}
}
}
func argKeysContain(haystack []string, needles []string) bool {
for _, h := range haystack {
for _, n := range needles {
if n == h {
return true
}
}
}
return false
}