Skip to content

Support tracing of Mysql2 gem prepared statements #3771

Open

Description

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    communityWas opened by a community memberfeature-requestA request for a new feature or change to an existing one

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions