diff --git a/instrumentation/mysql2/lib/opentelemetry/instrumentation/mysql2/patches/client.rb b/instrumentation/mysql2/lib/opentelemetry/instrumentation/mysql2/patches/client.rb index 37a0beb569..ea66e33622 100644 --- a/instrumentation/mysql2/lib/opentelemetry/instrumentation/mysql2/patches/client.rb +++ b/instrumentation/mysql2/lib/opentelemetry/instrumentation/mysql2/patches/client.rb @@ -9,7 +9,7 @@ module Instrumentation module Mysql2 module Patches # Module to prepend to Mysql2::Client for instrumentation - module Client + module Client # rubocop:disable Metrics/ModuleLength QUERY_NAMES = [ 'set names', 'select', @@ -73,10 +73,13 @@ def obfuscate_sql(sql) if sql.size > 2000 'SQL query too large to remove sensitive data ...' else - obfuscated = sql.gsub(generated_mysql_regex, '?') + obfuscated = OpenTelemetry::Common::Utilities.utf8_encode(sql, binary: true) + obfuscated = obfuscated.gsub(generated_mysql_regex, '?') obfuscated = 'Failed to obfuscate SQL query - quote characters remained after obfuscation' if detect_unmatched_pairs(obfuscated) obfuscated end + rescue StandardError + 'OpenTelemetry error: failed to obfuscate sql' end def generated_mysql_regex @@ -142,6 +145,7 @@ def extract_statement_type(sql) QUERY_NAME_RE.match(sql) { |match| match[1].downcase } unless sql.nil? rescue StandardError => e OpenTelemetry.logger.debug("Error extracting sql statement type: #{e.message}") + nil end end end diff --git a/instrumentation/mysql2/test/opentelemetry/instrumentation/mysql2/instrumentation_test.rb b/instrumentation/mysql2/test/opentelemetry/instrumentation/mysql2/instrumentation_test.rb index 0735e6ac0d..b27bae086f 100644 --- a/instrumentation/mysql2/test/opentelemetry/instrumentation/mysql2/instrumentation_test.rb +++ b/instrumentation/mysql2/test/opentelemetry/instrumentation/mysql2/instrumentation_test.rb @@ -209,6 +209,19 @@ _(span.attributes['net.peer.name']).must_equal host.to_s _(span.attributes['net.peer.port']).must_equal port.to_s end + + it 'encodes invalid byte sequences for db.statement' do + # \255 is off-limits https://en.wikipedia.org/wiki/UTF-8#Codepage_layout + sql = "SELECT * from users where users.id = 1 and users.email = 'test@test.com\255'" + obfuscated_sql = 'SELECT * from users where users.id = ? and users.email = ?' + + expect do + client.query(sql) + end.must_raise Mysql2::Error + + _(span.name).must_equal 'mysql.mysql' + _(span.attributes['db.statement']).must_equal obfuscated_sql + end end describe 'when enable_sql_obfuscation is enabled with db_statement set' do