vitess.io/vitess@v0.16.2/go/vt/vtgate/errorsanitizer/error_sanitizer.go (about) 1 /* 2 Copyright 2022 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package errorsanitizer 18 19 import ( 20 "regexp" 21 ) 22 23 const ( 24 // Truncate errors longer than this 25 maxErrorLength = 384 26 ) 27 28 var ( 29 // Remove any BindVars or Sql, and anything after it 30 reTruncateError = regexp.MustCompile(`[,:] BindVars:|[,:] Sql:`) 31 32 // Keep syntax error, but remove anything after it 33 reTruncateErrorAfterSyntaxError = regexp.MustCompile(`syntax error at position \d+`) 34 35 // Keep Duplicate entry, but replace '...' with '<val>' using reReplaceSingleQuotesWithinDuplicate regexp 36 reTruncateErrorAfterDuplicate = regexp.MustCompile(`Duplicate entry '(.*)' for key`) 37 38 // Keep Incorrect <type> value: '...' but replace '...' with '<val> 39 reRemoveIncorrectValue = regexp.MustCompile(`Incorrect [\S]+ value: '(.*)' for column`) 40 ) 41 42 /* Error messages often have PII in them. That can come from vttablet or from mysql, so by the time it gets to vtgate, 43 it's an opaque string. To avoid leaking PII into, we normalize error messages before sending them out. 44 We remove five different sorts of strings: 45 */ 46 47 // * [,:] BindVars: .*/ 48 // * [,:] Sql: '.*/' 49 // * Anything after /syntax error at position \d+/ 50 // * Anything after /Duplicate entry/ --> replace '...' with '<val>' 51 // * Anything with /Incorrect ... value: '...'/ replace '...' with '<val> 52 53 /* We also truncate the error message at a maximum length of 256 bytes, if it's somehow longer than that after normalizing.*/ 54 55 func NormalizeError(str string) string { 56 if idx := reTruncateError.FindStringIndex(str); idx != nil { 57 str = str[0:idx[0]] 58 } 59 if idx := reTruncateErrorAfterSyntaxError.FindStringIndex(str); idx != nil { 60 str = str[0:idx[1]] 61 } 62 if idx := reTruncateErrorAfterDuplicate.FindStringSubmatchIndex(str); len(idx) >= 4 { 63 // replace string '...' with '<val>' to mask real values 64 str = str[0:idx[2]] + "<val>" + str[idx[3]:] 65 } 66 if idx := reRemoveIncorrectValue.FindStringSubmatchIndex(str); len(idx) >= 4 { 67 str = str[0:idx[2]] + "<val>" + str[idx[3]:] 68 } 69 70 if len(str) > maxErrorLength { 71 return str[0:maxErrorLength] 72 } 73 return str 74 }