diff --git a/helpers/mysql/lib/opentelemetry/helpers/mysql.rb b/helpers/mysql/lib/opentelemetry/helpers/mysql.rb index 1260f8d149..b9103c4eb2 100644 --- a/helpers/mysql/lib/opentelemetry/helpers/mysql.rb +++ b/helpers/mysql/lib/opentelemetry/helpers/mysql.rb @@ -3,6 +3,7 @@ # Copyright The OpenTelemetry Authors # # SPDX-License-Identifier: Apache-2.0module OpenTelemetry +require 'opentelemetry-common' module OpenTelemetry module Helpers @@ -36,7 +37,7 @@ class MySQL 'create table' ].freeze - QUERY_NAME_REGEX = Regexp.new("(#{QUERY_NAMES.join('|')})", Regexp::IGNORECASE) + QUERY_NAME_REGEX = Regexp.new("\\b(#{QUERY_NAMES.join('|')})\\b", Regexp::IGNORECASE) # This is a span naming utility intended for use in MySQL database # adapter instrumentation. @@ -62,6 +63,8 @@ def self.database_span_name(sql, operation, database_name, config) # @api private def self.extract_statement_type(sql) + sql = OpenTelemetry::Common::Utilities.utf8_encode(sql, binary: true) + QUERY_NAME_REGEX.match(sql) { |match| match[1].downcase } unless sql.nil? rescue StandardError => e OpenTelemetry.handle_error(message: 'Error extracting SQL statement type', exception: e) diff --git a/helpers/mysql/opentelemetry-helpers-mysql.gemspec b/helpers/mysql/opentelemetry-helpers-mysql.gemspec index c1b5eab784..0c5ecf5516 100644 --- a/helpers/mysql/opentelemetry-helpers-mysql.gemspec +++ b/helpers/mysql/opentelemetry-helpers-mysql.gemspec @@ -26,6 +26,7 @@ Gem::Specification.new do |spec| spec.required_ruby_version = '>= 3.0' spec.add_dependency 'opentelemetry-api', '~> 1.0' + spec.add_dependency 'opentelemetry-common', '~> 0.20' spec.add_development_dependency 'bundler', '~> 2.4' spec.add_development_dependency 'minitest', '~> 5.0' diff --git a/helpers/mysql/test/helpers/mysql_test.rb b/helpers/mysql/test/helpers/mysql_test.rb index 7cba870b44..8f386b871c 100644 --- a/helpers/mysql/test/helpers/mysql_test.rb +++ b/helpers/mysql/test/helpers/mysql_test.rb @@ -93,6 +93,23 @@ end end + describe 'when sql contains invalid byte sequences' do + let(:sql) { "SELECT * from users where users.id = 1 and users.email = 'test@test.com\255'" } + + it 'extracts the statement' do + assert_equal('select', extract_statement_type) + end + end + + describe 'when sql contains unknown query statement' do + let(:sql) { 'DESELECT 1' } + + # nil sets the span name to 'mysql' + it 'returns nil' do + assert_nil(extract_statement_type) + end + end + describe 'when sql has marginalia-style prepended comments' do let(:sql) do '/*application:web,controller:blob,action:show,correlation_id:01EZVMR923313VV44ZJDJ7PMEZ,' \ diff --git a/instrumentation/mysql2/test/opentelemetry/instrumentation/mysql2/instrumentation_test.rb b/instrumentation/mysql2/test/opentelemetry/instrumentation/mysql2/instrumentation_test.rb index e363980c73..6e7ad74dd1 100644 --- a/instrumentation/mysql2/test/opentelemetry/instrumentation/mysql2/instrumentation_test.rb +++ b/instrumentation/mysql2/test/opentelemetry/instrumentation/mysql2/instrumentation_test.rb @@ -182,7 +182,7 @@ client.query(sql) end.must_raise Mysql2::Error - _(span.name).must_equal 'mysql' + _(span.name).must_equal 'select' _(span.attributes['db.statement']).must_equal obfuscated_sql end diff --git a/instrumentation/trilogy/test/opentelemetry/instrumentation/trilogy/instrumentation_test.rb b/instrumentation/trilogy/test/opentelemetry/instrumentation/trilogy/instrumentation_test.rb index 1e395f03f4..548c8bdd7d 100644 --- a/instrumentation/trilogy/test/opentelemetry/instrumentation/trilogy/instrumentation_test.rb +++ b/instrumentation/trilogy/test/opentelemetry/instrumentation/trilogy/instrumentation_test.rb @@ -285,7 +285,7 @@ client.query(sql) end.must_raise Trilogy::Error - _(span.name).must_equal 'mysql' + _(span.name).must_equal 'select' _(span.attributes[OpenTelemetry::SemanticConventions::Trace::DB_STATEMENT]).must_equal obfuscated_sql end