diff --git a/instrumentation/opentelemetry_ecto/lib/opentelemetry_ecto.ex b/instrumentation/opentelemetry_ecto/lib/opentelemetry_ecto.ex index 28f2321a..f824cfac 100644 --- a/instrumentation/opentelemetry_ecto/lib/opentelemetry_ecto.ex +++ b/instrumentation/opentelemetry_ecto/lib/opentelemetry_ecto.ex @@ -19,6 +19,7 @@ defmodule OpentelemetryEcto do """ require OpenTelemetry.Tracer + require OpenTelemetry.SemanticConventions.Trace, as: Trace @typedoc """ Option that you can pass to `setup/2`. @@ -82,7 +83,7 @@ defmodule OpentelemetryEcto do def handle_event( event, measurements, - %{query: query, source: source, result: query_result, repo: repo, type: type}, + %{query: query, source: source, result: query_result, repo: repo, type: type, options: options}, config ) do # Doing all this even if the span isn't sampled so the sampler @@ -134,11 +135,14 @@ defmodule OpentelemetryEcto do db_statement_config = Keyword.get(config, :db_statement, :disabled) + db_operation = Keyword.get(options, Trace.db_operation()) + attributes = base_attributes |> add_measurements(measurements, time_unit) |> maybe_add_db_statement(db_statement_config, query) |> maybe_add_db_system(repo.__adapter__()) + |> maybe_add_db_operation(db_operation) |> add_additional_attributes(additional_attributes) parent_context = @@ -201,6 +205,14 @@ defmodule OpentelemetryEcto do end) end + defp maybe_add_db_operation(attributes, nil) do + attributes + end + + defp maybe_add_db_operation(attributes, db_operation) do + Map.put(attributes, Trace.db_operation(), db_operation) + end + defp maybe_add_db_statement(attributes, :enabled, query) do Map.put(attributes, :"db.statement", query) end diff --git a/instrumentation/opentelemetry_ecto/mix.exs b/instrumentation/opentelemetry_ecto/mix.exs index d7d85745..337c1182 100644 --- a/instrumentation/opentelemetry_ecto/mix.exs +++ b/instrumentation/opentelemetry_ecto/mix.exs @@ -64,7 +64,8 @@ defmodule OpentelemetryEcto.MixProject do {:ecto_sql, ">= 3.0.0", only: [:dev, :test]}, {:postgrex, ">= 0.15.0", only: [:dev, :test]}, {:dialyxir, "~> 1.1", only: [:dev, :test], runtime: false}, - {:opentelemetry_process_propagator, "~> 0.3"} + {:opentelemetry_process_propagator, "~> 0.3"}, + {:opentelemetry_semantic_conventions, "~> 0.2"} ] end end diff --git a/instrumentation/opentelemetry_ecto/test/opentelemetry_ecto_test.exs b/instrumentation/opentelemetry_ecto/test/opentelemetry_ecto_test.exs index 14555909..3c8ed4b3 100644 --- a/instrumentation/opentelemetry_ecto/test/opentelemetry_ecto_test.exs +++ b/instrumentation/opentelemetry_ecto/test/opentelemetry_ecto_test.exs @@ -2,6 +2,7 @@ defmodule OpentelemetryEctoTest do use ExUnit.Case import Ecto.Query require OpenTelemetry.Tracer + require OpenTelemetry.SemanticConventions.Trace, as: Trace alias OpentelemetryEcto.TestRepo, as: Repo alias OpentelemetryEcto.TestModels.{Comment, User, Post} @@ -61,6 +62,21 @@ defmodule OpentelemetryEctoTest do } = :otel_attributes.map(attributes) end + test "reads the db.operation.name" do + attach_handler() + + Repo.all(User, telemetry_options: [{Trace.db_operation(), "read_all_users"}]) + + assert_receive {:span, + span( + name: "opentelemetry_ecto.test_repo.query:users", + attributes: attributes, + kind: :client + )} + + assert %{"db.operation": "read_all_users"} = :otel_attributes.map(attributes) + end + test "exclude unsantized query" do attach_handler() Repo.all(User)