diff --git a/redactrus.go b/redactrus.go index be2fb0d..ad4fdf3 100644 --- a/redactrus.go +++ b/redactrus.go @@ -1,6 +1,7 @@ package redactrus import ( + "fmt" "reflect" "regexp" @@ -56,9 +57,20 @@ func (h *Hook) Fire(e *logrus.Entry) error { } // Redact based on value matching in Data fields + // Handle fmt.Stringer type + if vv, ok := v.(fmt.Stringer); ok { + e.Data[k] = re.ReplaceAllString(vv.String(), "$1[REDACTED]$2") + continue + } + switch reflect.TypeOf(v).Kind() { case reflect.String: - e.Data[k] = re.ReplaceAllString(v.(string), "$1[REDACTED]$2") + switch vv := v.(type) { + case string: + e.Data[k] = re.ReplaceAllString(vv, "$1[REDACTED]$2") + default: + e.Data[k] = re.ReplaceAllString(fmt.Sprint(v), "$1[REDACTED]$2") + } continue } } diff --git a/redactrus_test.go b/redactrus_test.go index 574bd9b..2b20bf4 100644 --- a/redactrus_test.go +++ b/redactrus_test.go @@ -151,3 +151,36 @@ func TestNilField(t *testing.T) { assert.Nil(t, err) assert.Equal(t, logrus.Fields{"Nil": nil}, logEntry.Data) } + +type stringerValue struct { + value string +} + +func (v stringerValue) String() string { + return v.value +} + +func TestStringer(t *testing.T) { + logEntry := &logrus.Entry{ + Data: logrus.Fields{"Stringer": stringerValue{"kind is fmt.Stringer"}}, + } + h = &Hook{RedactionList: []string{"kind"}} + err := h.Fire(logEntry) + + assert.Nil(t, err) + assert.Equal(t, logrus.Fields{"Stringer": "[REDACTED] is fmt.Stringer"}, logEntry.Data) +} + +type TypedString string + +// Logrus fields can have re-typed strings so test we handle this edge case +func TestTypedStringValue(t *testing.T) { + logEntry := &logrus.Entry{ + Data: logrus.Fields{"TypedString": TypedString("kind is string")}, + } + h = &Hook{RedactionList: []string{"kind"}} + err := h.Fire(logEntry) + + assert.Nil(t, err) + assert.Equal(t, logrus.Fields{"TypedString": "[REDACTED] is string"}, logEntry.Data) +}