From 4b0c5e0506158b07af8661b23a424ffb8d8bfabb Mon Sep 17 00:00:00 2001 From: Gildas Cherruel Date: Wed, 8 May 2024 21:39:20 +0900 Subject: [PATCH 1/5] Issue #20: wrong append during logger.Child --- logger.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/logger.go b/logger.go index cbb4858..dc8821c 100644 --- a/logger.go +++ b/logger.go @@ -218,9 +218,9 @@ func (log *Logger) Child(topic, scope interface{}, params ...interface{}) *Logge for _, param := range params { switch actual := param.(type) { case *Redactor: - newlog.redactors = append(log.redactors, *actual) + newlog.redactors = append(newlog.redactors, *actual) case Redactor: - newlog.redactors = append(log.redactors, actual) + newlog.redactors = append(newlog.redactors, actual) case string: if len(key) == 0 { key = actual From bee9c1908967b791a266026d998a40f6c85d597c Mon Sep 17 00:00:00 2001 From: Gildas Cherruel Date: Wed, 8 May 2024 21:39:44 +0900 Subject: [PATCH 2/5] Better Redactors --- redact_test.go | 230 +++++++++++++++++++++++++++++++++++++++++++++---- redactor.go | 50 +++++++++-- 2 files changed, 253 insertions(+), 27 deletions(-) diff --git a/redact_test.go b/redact_test.go index e29f8e5..027e321 100644 --- a/redact_test.go +++ b/redact_test.go @@ -1,13 +1,29 @@ package logger_test import ( + "reflect" "strings" + "testing" "github.com/gildas/go-core" "github.com/gildas/go-logger" + "github.com/stretchr/testify/suite" ) -func (suite *LoggerSuite) TestCanRedactSensitiveStruct() { +type RedactSuite struct { + LoggerSuite + Name string +} + +func TestRedactSuite(t *testing.T) { + suite.Run(t, new(RedactSuite)) +} + +func (suite *RedactSuite) SetupSuite() { + suite.Name = strings.TrimSuffix(reflect.TypeOf(suite).Elem().Name(), "Suite") +} + +func (suite *RedactSuite) TestCanRedactSensitiveStruct() { customer := User{"12345678", "John Doe", nil} output := CaptureStdout(func() { log := logger.Create("test", &logger.StdoutStream{Unbuffered: true}) @@ -28,7 +44,7 @@ func (suite *LoggerSuite) TestCanRedactSensitiveStruct() { }) } -func (suite *LoggerSuite) TestCanRedactMessage() { +func (suite *RedactSuite) TestCanRedactMessage() { redactor := core.Must(logger.NewRedactor(`\+[0-9]{11}`)) suite.Require().NotEmpty(redactor.String()) output := CaptureStdout(func() { @@ -53,7 +69,7 @@ func (suite *LoggerSuite) TestCanRedactMessage() { }) } -func (suite *LoggerSuite) TestShouldNotRedactMessageWithNoMatch() { +func (suite *RedactSuite) TestShouldNotRedactMessageWithNoMatch() { redactor := core.Must(logger.NewRedactor(`\+[0-9]{23}`)) suite.Require().NotEmpty(redactor.String()) output := CaptureStdout(func() { @@ -78,7 +94,7 @@ func (suite *LoggerSuite) TestShouldNotRedactMessageWithNoMatch() { }) } -func (suite *LoggerSuite) TestCanRedactMessageWithSeveralRedactors() { +func (suite *RedactSuite) TestCanRedactMessageWithSeveralRedactors() { output := CaptureStdout(func() { log := logger.Create( "test", @@ -116,7 +132,7 @@ func (suite *LoggerSuite) TestCanRedactMessageWithSeveralRedactors() { }) } -func (suite *LoggerSuite) TestCanRedactAsString() { +func (suite *RedactSuite) TestCanRedactAsString() { suite.Assert().Equal("", logger.Redact(nil)) suite.Assert().Equal("", logger.Redact("")) redacted := logger.Redact("John Doe") @@ -128,67 +144,113 @@ func (suite *LoggerSuite) TestCanRedactAsString() { suite.Assert().Equal("Name-6cea57c2fb", logger.RedactWithPrefixedHash("Name", "John Doe")) } -func (suite *LoggerSuite) TestCanRedactCreditCardCard() { +func (suite *RedactSuite) TestCanRedactCreditCardCard() { redactor := logger.CreditCardRedactor redacted, ok := redactor.Redact("message with 30569309025904") suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 3700 000001 00018") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 4111 1111 1111 1111") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 3056 9309 0259 04") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 6011 0009 9013 9424") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 5105 1051 0510 5100") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 3569 9900 1009 5841") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) redacted, ok = redactor.Redact("message with nothing") suite.Assert().Falsef(ok, "Redactor %T should not have matched", redactor) suite.Assert().Equal("message with nothing", redacted) } -func (suite *LoggerSuite) TestCanRedactAMEXCard() { +func (suite *RedactSuite) TestCanRedactAMEXCard() { redactor := logger.AMEXRedactor redacted, ok := redactor.Redact("message with 370000000100018") suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 3700 000001 00018") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) redacted, ok = redactor.Redact("message with nothing") suite.Assert().Falsef(ok, "Redactor %T should not have matched", redactor) suite.Assert().Equal("message with nothing", redacted) } -func (suite *LoggerSuite) TestCanRedactVISACard() { +func (suite *RedactSuite) TestCanRedactVISACard() { redactor := logger.VISARedactor redacted, ok := redactor.Redact("message with 4111111111111111") suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 4111 1111 1111 1111") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) redacted, ok = redactor.Redact("message with nothing") suite.Assert().Falsef(ok, "Redactor %T should not have matched", redactor) suite.Assert().Equal("message with nothing", redacted) } -func (suite *LoggerSuite) TestCanRedactDinersClubCard() { +func (suite *RedactSuite) TestCanRedactDinersClubCard() { redactor := logger.DinersClubRedactor redacted, ok := redactor.Redact("message with 30569309025904") suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 3056 9309 0259 04") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) redacted, ok = redactor.Redact("message with nothing") suite.Assert().Falsef(ok, "Redactor %T should not have matched", redactor) suite.Assert().Equal("message with nothing", redacted) } -func (suite *LoggerSuite) TestCanRedactDiscoverCard() { +func (suite *RedactSuite) TestCanRedactDiscoverCard() { redactor := logger.DiscoverRedactor redacted, ok := redactor.Redact("message with 6011000990139424") suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 6011 0009 9013 9424") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) redacted, ok = redactor.Redact("message with nothing") suite.Assert().Falsef(ok, "Redactor %T should not have matched", redactor) suite.Assert().Equal("message with nothing", redacted) } -func (suite *LoggerSuite) TestCanRedactMasterCardCard() { +func (suite *RedactSuite) TestCanRedactMasterCardCard() { redactor := logger.MasterCardRedactor redacted, ok := redactor.Redact("message with 5105105105105100") suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 5105 1051 0510 5100") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with nothing") + suite.Assert().Falsef(ok, "Redactor %T should not have matched", redactor) + suite.Assert().Equal("message with nothing", redacted) +} + +func (suite *RedactSuite) TestCanRedactJCBCard() { + redactor := logger.JCBRedactor + redacted, ok := redactor.Redact("message with 3569990010095841") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 3569 9900 1009 5841") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) redacted, ok = redactor.Redact("message with nothing") suite.Assert().Falsef(ok, "Redactor %T should not have matched", redactor) suite.Assert().Equal("message with nothing", redacted) } -func (suite *LoggerSuite) TestCanRedactPhone() { +func (suite *RedactSuite) TestCanRedactPhone() { redactor := logger.PhoneRedactor redacted, ok := redactor.Redact("message with +13178723000") suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) @@ -201,7 +263,7 @@ func (suite *LoggerSuite) TestCanRedactPhone() { suite.Assert().Equal("message with nothing", redacted) } -func (suite *LoggerSuite) TestCanRedactEmail() { +func (suite *RedactSuite) TestCanRedactEmail() { redactor := logger.EmailRedactor redacted, ok := redactor.Redact("message with john.doe@acme.com") suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) @@ -211,7 +273,7 @@ func (suite *LoggerSuite) TestCanRedactEmail() { suite.Assert().Equal("message with nothing", redacted) } -func (suite *LoggerSuite) TestCanRedactIP() { +func (suite *RedactSuite) TestCanRedactIP() { redactor := logger.IPRedactor redacted, ok := redactor.Redact("message with 192.168.1.1") suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) @@ -224,7 +286,7 @@ func (suite *LoggerSuite) TestCanRedactIP() { suite.Assert().Equal("message with nothing", redacted) } -func (suite *LoggerSuite) TestCanRedactIPV4() { +func (suite *RedactSuite) TestCanRedactIPV4() { redactor := logger.IPV4Redactor redacted, ok := redactor.Redact("message with 192.168.1.1") suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) @@ -234,7 +296,7 @@ func (suite *LoggerSuite) TestCanRedactIPV4() { suite.Assert().Equal("message with nothing", redacted) } -func (suite *LoggerSuite) TestCanRedactIPV6() { +func (suite *RedactSuite) TestCanRedactIPV6() { redactor := logger.IPV6Redactor redacted, ok := redactor.Redact("message with 2600:::") suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) @@ -250,7 +312,7 @@ func (suite *LoggerSuite) TestCanRedactIPV6() { suite.Assert().Equal("message with nothing", redacted) } -func (suite *LoggerSuite) TestCanRedactMAC() { +func (suite *RedactSuite) TestCanRedactMAC() { redactor := logger.MACRedactor redacted, ok := redactor.Redact("message with 2C:54:91:88:C9:E3") suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) @@ -260,7 +322,139 @@ func (suite *LoggerSuite) TestCanRedactMAC() { suite.Assert().Equal("message with nothing", redacted) } -func (suite *LoggerSuite) TestCanRedactWithKeysToRedact() { +func (suite *RedactSuite) TestCanMergeEmpty() { + suite.Assert().Equal(logger.VISARedactor.String(), logger.VISARedactor.Merge().String()) +} + +func (suite *RedactSuite) TestCanMergeWithRedactor() { + expected := `3[47]\d{2}[- ]*\d{6}[- ]*\d{5}|4\d{3}[- ]*\d{4}[- ]*\d{4}[- ]*\d{4}` + redactor := logger.AMEXRedactor.Merge(logger.VISARedactor) + suite.Assert().Equal(expected, redactor.String()) + redacted, ok := redactor.Redact("message with 3700 000001 00018") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 4111 1111 1111 1111") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 5105 1051 0510 5100") + suite.Assert().Falsef(ok, "Redactor %T should not have matched", redactor) + suite.Assert().Equal("message with 5105 1051 0510 5100", redacted) + redacted, ok = redactor.Redact("message with nothing") + suite.Assert().Falsef(ok, "Redactor %T should not have matched", redactor) + suite.Assert().Equal("message with nothing", redacted) +} + +func (suite *RedactSuite) TestCanMergeWithRedactors() { + expected := `3[47]\d{2}[- ]*\d{6}[- ]*\d{5}|4\d{3}[- ]*\d{4}[- ]*\d{4}[- ]*\d{4}|(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[- ]*\d{4}[- ]*\d{4}[- ]*\d{4}` + redactor := logger.AMEXRedactor.Merge(logger.VISARedactor, logger.MasterCardRedactor) + suite.Assert().Equal(expected, redactor.String()) + redacted, ok := redactor.Redact("message with 3700 000001 00018") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 4111 1111 1111 1111") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 5105 1051 0510 5100") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with nothing") + suite.Assert().Falsef(ok, "Redactor %T should not have matched", redactor) + suite.Assert().Equal("message with nothing", redacted) +} + +func (suite *RedactSuite) TestCanMergeWithPipedRedactors() { + expected := `3[47]\d{2}[- ]*\d{6}[- ]*\d{5}|4\d{3}[- ]*\d{4}[- ]*\d{4}[- ]*\d{4}|(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[- ]*\d{4}[- ]*\d{4}[- ]*\d{4}` + redactor := logger.AMEXRedactor.Merge(logger.VISARedactor).Merge(logger.MasterCardRedactor) + suite.Assert().Equal(expected, redactor.String()) + redacted, ok := redactor.Redact("message with 3700 000001 00018") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 4111 1111 1111 1111") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 5105 1051 0510 5100") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with nothing") + suite.Assert().Falsef(ok, "Redactor %T should not have matched", redactor) + suite.Assert().Equal("message with nothing", redacted) +} + +func (suite *RedactSuite) TestCanMergeWithString() { + expected := `3[47]\d{2}[- ]*\d{6}[- ]*\d{5}|4\d{3}[- ]*\d{4}[- ]*\d{4}[- ]*\d{4}` + redactor := logger.AMEXRedactor.Merge(logger.VISARedactor.String()) + suite.Assert().Equal(expected, redactor.String()) + redacted, ok := redactor.Redact("message with 3700 000001 00018") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with 4111 1111 1111 1111") + suite.Assert().Truef(ok, "Redactor %T should have matched", redactor) + suite.Assert().Equal("message with REDACTED", redacted) + redacted, ok = redactor.Redact("message with nothing") + suite.Assert().Falsef(ok, "Redactor %T should not have matched", redactor) + suite.Assert().Equal("message with nothing", redacted) +} + + type stringer logger.Redactor + func (s stringer) String() string { + return logger.Redactor(s).String() + } + +func (suite *RedactSuite) TestCanMergeWithStringer() { + expected := `3[47]\d{2}[- ]*\d{6}[- ]*\d{5}|4\d{3}[- ]*\d{4}[- ]*\d{4}[- ]*\d{4}` + redactor := logger.AMEXRedactor.Merge(stringer(*logger.VISARedactor)) + suite.Assert().Equal(expected, redactor.String()) +} + +func (suite *RedactSuite) TestMergeShouldPanicWithWrongType() { + suite.Require().Panics(func() { + _ = logger.VISARedactor.Merge(42) + }) +} + +func (suite *RedactSuite) TestCanUseSeveralRedactors() { + output := CaptureStdout(func() { + mainLog := logger.Create( + "test", + &logger.StdoutStream{Unbuffered: true}, + ) + log := mainLog.Child( + nil, + nil, + logger.PhoneRedactor, + logger.EmailRedactor, + ) + log.Infof("message with sensitive (+13178723000) data") + log.Infof("message with sensitive (john.doe@acme.com) data") + }) + lines := strings.Split(output, "\n")[0:2] + suite.LogLineEqual(lines[0], map[string]string{ + "hostname": `[a-zA-Z_0-9\-\.]+`, + "level": "30", + "msg": `message with sensitive \(REDACTED\) data`, + "name": "test", + "pid": "[0-9]+", + "scope": "main", + "tid": "[0-9]+", + "time": `[0-9]+-[0-9]+-[0-9]+T[0-9]+:[0-9]+:[0-9]+Z`, + "topic": "main", + "v": "0", + }) + suite.LogLineEqual(lines[1], map[string]string{ + "hostname": `[a-zA-Z_0-9\-\.]+`, + "level": "30", + "msg": `message with sensitive \(REDACTED\) data`, + "name": "test", + "pid": "[0-9]+", + "scope": "main", + "tid": "[0-9]+", + "time": `[0-9]+-[0-9]+-[0-9]+T[0-9]+:[0-9]+:[0-9]+Z`, + "topic": "main", + "v": "0", + }) +} + +func (suite *RedactSuite) TestCanRedactWithKeysToRedact() { metadata := Metadata{"12345678", "Taro Yamamoto", "Tokyo"} output := CaptureStdout(func() { log := logger.Create("test", &logger.StdoutStream{Unbuffered: true}) diff --git a/redactor.go b/redactor.go index 7677caf..34c847c 100644 --- a/redactor.go +++ b/redactor.go @@ -1,7 +1,9 @@ package logger import ( + "fmt" "regexp" + "strings" "github.com/gildas/go-core" ) @@ -9,26 +11,26 @@ import ( type Redactor regexp.Regexp var ( - // CreditCardRedactor is a Redactor that will redact Credit Card Numbers - CreditCardRedactor = core.Must(NewRedactor(`(4[0-9]{12}(?:[0-9]{3})?)|((?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|(6(?:011|5[0-9]{2})[0-9]{12})|((?:2131|1800|35\d{3})\d{11})`)) - // AMEXRedactor is a Redactor that will redact AMEX Numbers - AMEXRedactor = core.Must(NewRedactor(`3[47][0-9]{13}`)) + AMEXRedactor = core.Must(NewRedactor(`3[47]\d{2}[- ]*\d{6}[- ]*\d{5}`)) // DinersClubRedactor is a Redactor that will redact Diners Club Numbers - DinersClubRedactor = core.Must(NewRedactor(`3(?:0[0-5]|[68][0-9])[0-9]{11}`)) + DinersClubRedactor = core.Must(NewRedactor(`3(?:0[0-5]|[68][0-9])\d[- ]*\d{4}[- ]*\d{4}[- ]*\d{2}`)) // DiscoverRedactor is a Redactor that will redact Discover Numbers - DiscoverRedactor = core.Must(NewRedactor(`6(?:011|5[0-9]{2})[0-9]{12}`)) + DiscoverRedactor = core.Must(NewRedactor(`6(?:011|5[0-9]{2})[- ]*\d{4}[- ]*\d{4}[- ]*\d{4}`)) // JCBRedactor is a Redactor that will redact JCB Numbers - JCBRedactor = core.Must(NewRedactor(`(?:2131|1800|35\d{3})\d{11}`)) + JCBRedactor = core.Must(NewRedactor(`(?:2131|1800|35\d{2})[- ]*\d{4}[- ]*\d{4}[- ]*\d{4}`)) // MasterCardRedactor is a Redactor that will redact MasterCard Numbers - MasterCardRedactor = core.Must(NewRedactor(`(5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}`)) + MasterCardRedactor = core.Must(NewRedactor(`(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[- ]*\d{4}[- ]*\d{4}[- ]*\d{4}`)) // VISARedactor is a Redactor that will redact VISA Credit Card Numbers - VISARedactor = core.Must(NewRedactor(`4[0-9]{12}(?:[0-9]{3})?`)) + VISARedactor = core.Must(NewRedactor(`4\d{3}[- ]*\d{4}[- ]*\d{4}[- ]*\d{4}`)) + + // CreditCardRedactor is a Redactor that will redact Credit Card Numbers + CreditCardRedactor = AMEXRedactor.Merge(DinersClubRedactor, DiscoverRedactor, JCBRedactor, MasterCardRedactor, VISARedactor) // PhoneRedactor is a Redactor that will redact Phone Numbers PhoneRedactor = core.Must(NewRedactor(`(\+?[0-9]{1,3}[-. ]?[0-9]{3}[-. ]?[0-9]{3}[-. ]?[0-9]{4})|(\+?[0-9]{1,3}[-. ]?[0-9.\-]+)`)) @@ -53,6 +55,36 @@ func NewRedactor(regex string) (*Redactor, error) { return (*Redactor)(r), err } +// Merge merges the Redactor with other Redactors +// +// The other Redactors can be strings, Redactor, *Redactor or fmt.Stringers +func (redactor Redactor) Merge(other ...any) Redactor { + if len(other) == 0 { + copy := redactor + return copy + } + var text strings.Builder + text.WriteString(redactor.String()) + for _, r := range other { + text.WriteString("|") + switch actual := r.(type) { + case *Redactor: + text.WriteString(actual.String()) + case Redactor: + text.WriteString(actual.String()) + case string: + text.WriteString(actual) + default: + if stringer, ok := actual.(fmt.Stringer); ok { + text.WriteString(stringer.String()) + } else { + panic("Invalid Redactor type") + } + } + } + return *core.Must(NewRedactor(text.String())) +} + func (redactor Redactor) Redact(value string) (string, bool) { // TODO: Find a way to not run the regex twice if (*regexp.Regexp)(&redactor).MatchString(value) { From 24c90cf8466081fc42bd512982e4acb13289f1ea Mon Sep 17 00:00:00 2001 From: Gildas Cherruel Date: Wed, 8 May 2024 21:50:14 +0900 Subject: [PATCH 3/5] Better Redactors --- common_test.go | 4 ++-- logger_internal_test.go | 3 +++ record_test.go | 2 +- redact_test.go | 9 +++++---- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/common_test.go b/common_test.go index 4f0b71a..6db3e44 100644 --- a/common_test.go +++ b/common_test.go @@ -99,8 +99,8 @@ func (user User) String() string { type Metadata struct { UserID string `json:"userId"` - Name string `json:"name"` - City string `json:"city"` + Name string `json:"name"` + City string `json:"city"` } func (metadata Metadata) Redact(keyToRedact ...string) interface{} { diff --git a/logger_internal_test.go b/logger_internal_test.go index 57b7d91..0aeafa2 100644 --- a/logger_internal_test.go +++ b/logger_internal_test.go @@ -340,13 +340,16 @@ func (suite *InternalLoggerSuite) TestIsHijacker() { } type hijackerResponse struct{} + func (*hijackerResponse) Header() http.Header { return nil } func (*hijackerResponse) Write([]byte) (int, error) { return 0, nil } func (*hijackerResponse) WriteHeader(statusCode int) {} func (*hijackerResponse) Hijack() (net.Conn, *bufio.ReadWriter, error) { return nil, nil, errors.NotImplemented.WithStack() } + type noopResponse struct{} + func (*noopResponse) Header() http.Header { return nil } func (*noopResponse) Write([]byte) (int, error) { return 0, nil } func (*noopResponse) WriteHeader(statusCode int) {} diff --git a/record_test.go b/record_test.go index df30220..d5ed7d7 100644 --- a/record_test.go +++ b/record_test.go @@ -316,4 +316,4 @@ func (suite *RecordSuite) TestCanAddKeysToRedact() { suite.Assert().Contains(record.KeysToRedact, "key2") suite.Assert().Contains(record.KeysToRedact, "key3") suite.Assert().NotContains(record.KeysToRedact, "key4") -} \ No newline at end of file +} diff --git a/redact_test.go b/redact_test.go index 027e321..dbb79c8 100644 --- a/redact_test.go +++ b/redact_test.go @@ -395,10 +395,11 @@ func (suite *RedactSuite) TestCanMergeWithString() { suite.Assert().Equal("message with nothing", redacted) } - type stringer logger.Redactor - func (s stringer) String() string { - return logger.Redactor(s).String() - } +type stringer logger.Redactor + +func (s stringer) String() string { + return logger.Redactor(s).String() +} func (suite *RedactSuite) TestCanMergeWithStringer() { expected := `3[47]\d{2}[- ]*\d{6}[- ]*\d{5}|4\d{3}[- ]*\d{4}[- ]*\d{4}[- ]*\d{4}` From b530f6a9a98ea278e38f2b6c319936f680fa8ce8 Mon Sep 17 00:00:00 2001 From: Gildas Cherruel Date: Wed, 8 May 2024 21:51:47 +0900 Subject: [PATCH 4/5] Bumped to version 1.7.1 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index fcf8211..663d35c 100644 --- a/version.go +++ b/version.go @@ -4,4 +4,4 @@ package logger var commit string // VERSION is the version of this application -var VERSION = "1.7.0" + commit +var VERSION = "1.7.1" + commit From cf6d909d7df50b4eda2fdbd70b5e1696478f38d5 Mon Sep 17 00:00:00 2001 From: Gildas Cherruel Date: Wed, 8 May 2024 21:54:49 +0900 Subject: [PATCH 5/5] Updated Go packages --- go.mod | 16 ++++++++-------- go.sum | 36 ++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index aa5ce76..225bdc3 100644 --- a/go.mod +++ b/go.mod @@ -11,12 +11,12 @@ require ( github.com/google/uuid v1.6.0 github.com/stretchr/testify v1.9.0 golang.org/x/sys v0.20.0 - google.golang.org/api v0.177.0 + google.golang.org/api v0.178.0 ) require ( cloud.google.com/go v0.112.2 // indirect - cloud.google.com/go/auth v0.3.0 // indirect + cloud.google.com/go/auth v0.4.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect cloud.google.com/go/compute/metadata v0.3.0 // indirect cloud.google.com/go/longrunning v0.5.7 // indirect @@ -37,16 +37,16 @@ require ( go.opentelemetry.io/otel v1.26.0 // indirect go.opentelemetry.io/otel/metric v1.26.0 // indirect go.opentelemetry.io/otel/trace v1.26.0 // indirect - golang.org/x/crypto v0.22.0 // indirect - golang.org/x/net v0.24.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/net v0.25.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect - google.golang.org/genproto v0.0.0-20240429193739-8cf5692501f6 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 // indirect + google.golang.org/genproto v0.0.0-20240506185236-b8a5c65736ae // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240506185236-b8a5c65736ae // indirect google.golang.org/grpc v1.63.2 // indirect - google.golang.org/protobuf v1.34.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 8d5db8a..c39dc06 100644 --- a/go.sum +++ b/go.sum @@ -1,14 +1,14 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.112.2 h1:ZaGT6LiG7dBzi6zNOvVZwacaXlmf3lRqnC4DQzqyRQw= cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbDms= -cloud.google.com/go/auth v0.3.0 h1:PRyzEpGfx/Z9e8+lHsbkoUVXD0gnu4MNmm7Gp8TQNIs= -cloud.google.com/go/auth v0.3.0/go.mod h1:lBv6NKTWp8E3LPzmO1TbiiRKc4drLOfHsgmlH9ogv5w= +cloud.google.com/go/auth v0.4.0 h1:vcJWEguhY8KuiHoSs/udg1JtIRYm3YAWPBE1moF1m3U= +cloud.google.com/go/auth v0.4.0/go.mod h1:tO/chJN3obc5AbRYFQDsuFbL4wW5y8LfbPtDCfgwOVE= cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4= cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/iam v1.1.7 h1:z4VHOhwKLF/+UYXAJDFwGtNF0b6gjsW1Pk9Ml0U/IoM= -cloud.google.com/go/iam v1.1.7/go.mod h1:J4PMPg8TtyurAUvSmPj8FF3EDgY1SPRZxcUGrn7WXGA= +cloud.google.com/go/iam v1.1.8 h1:r7umDwhj+BQyz0ScZMp4QrGXjSTI3ZINnpgU2nlB/K0= +cloud.google.com/go/iam v1.1.8/go.mod h1:GvE6lyMmfxXauzNq8NbgJbeVQNspG+tcdL/W8QO1+zE= cloud.google.com/go/logging v1.9.0 h1:iEIOXFO9EmSiTjDmfpbRjOxECO7R8C7b8IXUGOj7xZw= cloud.google.com/go/logging v1.9.0/go.mod h1:1Io0vnZv4onoUnsVUQY3HZ3Igb1nBchky0A0y7BBBhE= cloud.google.com/go/longrunning v0.5.7 h1:WLbHekDbjK1fVFD3ibpFFVoyizlLRl73I7YKuAKilhU= @@ -100,8 +100,8 @@ go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2L go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -112,8 +112,8 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= @@ -140,19 +140,19 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.177.0 h1:8a0p/BbPa65GlqGWtUKxot4p0TV8OGOfyTjtmkXNXmk= -google.golang.org/api v0.177.0/go.mod h1:srbhue4MLjkjbkux5p3dw/ocYOSZTaIEvf7bCOnFQDw= +google.golang.org/api v0.178.0 h1:yoW/QMI4bRVCHF+NWOTa4cL8MoWL3Jnuc7FlcFF91Ok= +google.golang.org/api v0.178.0/go.mod h1:84/k2v8DFpDRebpGcooklv/lais3MEfqpaBLA12gl2U= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20240429193739-8cf5692501f6 h1:MTmrc2F5TZKDKXigcZetYkH04YwqtOPEQJwh4PPOgfk= -google.golang.org/genproto v0.0.0-20240429193739-8cf5692501f6/go.mod h1:2ROWwqCIx97Y7CSyp11xB8fori0wzvD6+gbacaf5c8I= -google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6 h1:DTJM0R8LECCgFeUwApvcEJHz85HLagW8uRENYxHh1ww= -google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6/go.mod h1:10yRODfgim2/T8csjQsMPgZOMvtytXKTDRzH6HRGzRw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 h1:DujSIu+2tC9Ht0aPNA7jgj23Iq8Ewi5sgkQ++wdvonE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto v0.0.0-20240506185236-b8a5c65736ae h1:HjgkYCl6cWQEKSHkpUp4Q8VB74swzyBwTz1wtTzahm0= +google.golang.org/genproto v0.0.0-20240506185236-b8a5c65736ae/go.mod h1:i4np6Wrjp8EujFAUn0CM0SH+iZhY1EbrfzEIJbFkHFM= +google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae h1:AH34z6WAGVNkllnKs5raNq3yRq93VnjBG6rpfub/jYk= +google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae/go.mod h1:FfiGhwUm6CJviekPrc0oJ+7h29e+DmWU6UtjX0ZvI7Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240506185236-b8a5c65736ae h1:c55+MER4zkBS14uJhSZMGGmya0yJx5iHV4x/fpOSNRk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240506185236-b8a5c65736ae/go.mod h1:I7Y+G38R2bu5j1aLzfFmQfTcU/WnFuqDwLZAbvKTKpM= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -169,8 +169,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4= -google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=