diff --git a/internal/logger/sanitize/sanitize.go b/internal/logger/sanitize/sanitize.go index 0e286637..d64877cc 100644 --- a/internal/logger/sanitize/sanitize.go +++ b/internal/logger/sanitize/sanitize.go @@ -49,6 +49,10 @@ var SecretPatterns = []*regexp.Regexp{ regexp.MustCompile(`(?i)"(token|password|passwd|pwd|apikey|api_key|api-key|secret|client_secret|api_secret|authorization|auth|key|private_key|public_key|credentials|credential|access_token|refresh_token|bearer_token)"\s*:\s*"[^"]{1,}"`), } +// keyValueSplitPattern splits a key=value or key:value match at the separator. +// Pre-compiled to avoid per-call regexp compilation inside SanitizeString. +var keyValueSplitPattern = regexp.MustCompile(`[=:]\s*`) + // SanitizeString replaces potential secrets in a string with [REDACTED] func SanitizeString(message string) string { result := message @@ -56,7 +60,7 @@ func SanitizeString(message string) string { result = pattern.ReplaceAllStringFunc(result, func(match string) string { // Keep the prefix (key name) but redact the value if strings.Contains(match, "=") || strings.Contains(match, ":") { - parts := regexp.MustCompile(`[=:]\s*`).Split(match, 2) + parts := keyValueSplitPattern.Split(match, 2) if len(parts) == 2 { return parts[0] + "=[REDACTED]" } diff --git a/internal/logger/sanitize/sanitize_test.go b/internal/logger/sanitize/sanitize_test.go index 4fdbbb1b..6902acaf 100644 --- a/internal/logger/sanitize/sanitize_test.go +++ b/internal/logger/sanitize/sanitize_test.go @@ -640,3 +640,22 @@ func TestSanitizeArgsDoesNotLeakSecrets(t *testing.T) { assert.Contains(t, resultStr, "GITHUB_TOKEN=ghp_...", "Truncated token should be present") assert.Contains(t, resultStr, "API_KEY=test...", "Truncated API key should be present") } + +// BenchmarkSanitizeString measures the per-call cost of SanitizeString across +// a clean message (no matches) and a message containing a secret token. +func BenchmarkSanitizeString(b *testing.B) { +clean := "Processing request for user 42 in repository owner/repo" +withSecret := "Authorization: ghp_aBcDeFgHiJkLmNoPqRsTuVwXyZ1234567890 is set" + +b.Run("no_secrets", func(b *testing.B) { +for i := 0; i < b.N; i++ { +_ = SanitizeString(clean) +} +}) + +b.Run("with_secret", func(b *testing.B) { +for i := 0; i < b.N; i++ { +_ = SanitizeString(withSecret) +} +}) +}