From 6bfc5d31d5e6582817718e54b0d7667cd6c74ef4 Mon Sep 17 00:00:00 2001 From: Hartley McGuire Date: Thu, 5 Dec 2024 17:15:24 -0500 Subject: [PATCH] Add row count and affected rows to Trilogy spans Identifying queries that return/update many rows is very useful for improving database performance. Queries that return many rows can cause applications to use excess memory (or in some cases like Vitess) could be blocked altogether. Queries that update many rows can cause replication lag and generally put more pressure on a database. This commit adds both of these values (row_count and affected_rows) to spans created from Trilogy#query to help identify these problematic queries. Trilogy::Result#count will always return a value (0 for mutations), but #affected_rows only returns values for mutations (nil for SELECTs). --- .../instrumentation/trilogy/patches/client.rb | 11 ++++++++-- .../trilogy/instrumentation_test.rb | 20 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/instrumentation/trilogy/lib/opentelemetry/instrumentation/trilogy/patches/client.rb b/instrumentation/trilogy/lib/opentelemetry/instrumentation/trilogy/patches/client.rb index 8f15dd89d8..76e287577c 100644 --- a/instrumentation/trilogy/lib/opentelemetry/instrumentation/trilogy/patches/client.rb +++ b/instrumentation/trilogy/lib/opentelemetry/instrumentation/trilogy/patches/client.rb @@ -49,7 +49,7 @@ def query(sql) OpenTelemetry::Instrumentation::Trilogy.attributes ), kind: :client - ) do |_span, context| + ) do |span, context| if propagator && sql.frozen? sql = +sql propagator.inject(sql, context: context) @@ -58,7 +58,14 @@ def query(sql) propagator.inject(sql, context: context) end - super + result = super + + attributes = { 'db.response.returned_rows' => result.count } + attributes['db.response.affected_rows'] = result.affected_rows unless result.affected_rows.nil? + + span.add_attributes(attributes) + + result end end diff --git a/instrumentation/trilogy/test/opentelemetry/instrumentation/trilogy/instrumentation_test.rb b/instrumentation/trilogy/test/opentelemetry/instrumentation/trilogy/instrumentation_test.rb index 350ee5f834..e470daadf4 100644 --- a/instrumentation/trilogy/test/opentelemetry/instrumentation/trilogy/instrumentation_test.rb +++ b/instrumentation/trilogy/test/opentelemetry/instrumentation/trilogy/instrumentation_test.rb @@ -164,6 +164,26 @@ _(span.attributes[OpenTelemetry::SemanticConventions::Trace::DB_SYSTEM]).must_equal 'mysql' _(span.attributes[OpenTelemetry::SemanticConventions::Trace::DB_STATEMENT]).must_equal 'DESELECT ?' end + + it 'includes row count' do + client.query('SELECT 1') + + _(span.attributes['db.response.returned_rows']).must_equal(1) + end + + it 'includes affected rows' do + client.query(<<~SQL) + CREATE TABLE products ( + product_id int + ) + SQL + + client.query('INSERT INTO products (product_id) VALUES (1), (2), (3)') + + _(exporter.finished_spans.last.attributes['db.response.affected_rows']).must_equal(3) + ensure + client.query('DROP TABLE IF EXISTS products') + end end describe 'when connecting' do