DataDog/dd-trace-rb

Support tracing of Mysql2 gem prepared statements

Opened this issue · 2 comments

Current behaviour

We have a Ruby application that uses the mysql2 gem to communicate directly with a MySQL cluster. No Active Record; these are native MySQL clients. Our clients issue some calls with .execute and other calls with .prepare through prepared statements. We have configured the MySQL integration config as called out in the documentation.

The existing dd-trace-rb gem we are using (version: 1.23.0), appears to only trace the .execute calls and none of the prepared statement I/O via the mysql2 gem. We can see in our APM traces only the .execute calls to the MySQL and none of our prepared statement I/O. For us this produces APM flame graphs of 3 rapid-fire queries and then blank space where we know our application code is issuing prepared statements and streaming results back to our app.

Example redacted flame graph:

RedactedFlameGraph

Expected behaviour

We would expect the tracing to show the SQL of prepared statements and the calls to retrieve the record sets from the prepared statements.

It looks like the dd-trace-js code added this support in 2019.

Steps to reproduce

  • Have DataDog integrated with your Ruby app.
  • Add mysql2 tracing, as documented.
  • Declare a prepared statement and retrieve a result set via that prepared statement.
  • Observe your APM traces and flame graphs for details.

How does datadog help you?

I generally love DataDog. This was a surprising blind spot.

Environment

  • datadog version:

  • Whatever is current in SaaS as of June 20, 2024.

  • Configuration block (Datadog.configure ...):

Datadog.configure do |c|
  service_name = "acme_service"

  c.tracing.instrument :mongo, {service_name: "#{service_name}-mongodb"}
  c.tracing.instrument :active_model_serializers, {service_name: "#{service_name}-serializers"}
  c.tracing.instrument :mysql2, {service_name: "#{service_name}-mysql}"}

  # This uses the correct class name, no longer: Datadog::Tracing::SpanFilter
  Datadog::Tracing::Pipeline.before_flush(
    Datadog::Tracing::Pipeline::SpanFilter.new { |span| span.resource =~ /HealthCheck/ }
  )

  # Setup trace headers for propagation - be sure this is the same across the board.
  c.tracing.distributed_tracing.propagation_inject_style = [Datadog::Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_DATADOG]
  c.tracing.distributed_tracing.propagation_extract_style = [Datadog::Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_DATADOG]
end
  • Ruby version:

  • 3.3.1

  • Operating system:

  • Consistent behavior on all of: Red Hat UBI, Amazon Linux, and Ubuntu 2022 LTS

  • Relevant library versions:

    ddtrace (1.23.0)
      datadog-ci (~> 0.8.1)
      debase-ruby_core_source (= 3.3.1)
      libdatadog (~> 7.0.0.1.0)
      libddwaf (~> 1.14.0.0.0)
      msgpack

👋 @adam-hampton-sp , Thanks for the feedback. Indeed our mysql2 instrumentation has yet to support prepared_statement. I have labelled this issue as feature requested.

Thank you for applying the label.