Make Ecto spans of preloads children of the parent span (#49)

🎉
This commit is contained in:
Damir Vandic 2022-03-24 21:19:24 +01:00 committed by GitHub
parent 3faa246d02
commit 0f137525b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 129 additions and 17 deletions

View File

@ -11,4 +11,4 @@ config :opentelemetry_ecto, OpentelemetryEcto.TestRepo,
pool: Ecto.Adapters.SQL.Sandbox
config :opentelemetry,
processors: [{:otel_simple_processor, %{}}]
processors: [{:otel_batch_processor, %{scheduled_delay_ms: 1}}]

View File

@ -1,6 +1,20 @@
defmodule OpentelemetryEcto do
@moduledoc """
Telemetry handler for creating OpenTelemetry Spans from Ecto query events.
Telemetry handler for creating OpenTelemetry Spans from Ecto query events. Any
relation preloads, which are executed in parallel in separate tasks, will be
linked to the span of the process that initiated the call. For example:
Tracer.with_span "parent span" do
Repo.all(Query.from(User, preload: [:posts, :comments]))
end
this will create a span called "parent span" with three child spans for each
query: users, posts, and comments.
> #### Note {: .neutral}
>
> Due to limitations with how Ecto emits its telemetry, nested preloads are not
> represented as nested spans within a trace.
"""
require OpenTelemetry.Tracer
@ -88,6 +102,12 @@ defmodule OpentelemetryEcto do
acc
end)
parent_context = OpentelemetryProcessPropagator.fetch_parent_ctx(1, :"$callers")
if parent_context != :undefined do
OpenTelemetry.Ctx.attach(parent_context)
end
s =
OpenTelemetry.Tracer.start_span(span_name, %{
start_time: start_time,
@ -104,6 +124,10 @@ defmodule OpentelemetryEcto do
end
OpenTelemetry.Span.end_span(s)
if parent_context != :undefined do
OpenTelemetry.Ctx.detach(parent_context)
end
end
defp format_error(%{__exception__: true} = exception) do

View File

@ -55,7 +55,8 @@ defmodule OpentelemetryEcto.MixProject do
{:ex_doc, "~> 0.26.0", only: [:dev], runtime: false},
{:ecto_sql, ">= 3.0.0", only: [:dev, :test]},
{:postgrex, ">= 0.15.0", only: [:dev, :test]},
{:dialyxir, "~> 1.1", only: [:dev, :test], runtime: false}
{:dialyxir, "~> 1.1", only: [:dev, :test], runtime: false},
{:opentelemetry_process_propagator, "~> 0.1.0"}
]
end
end

View File

@ -3,27 +3,29 @@
"chatterbox": {:hex, :ts_chatterbox, "0.11.0", "b8f372c706023eb0de5bf2976764edb27c70fe67052c88c1f6a66b3a5626847f", [:rebar3], [{:hpack, "~>0.2.3", [hex: :hpack_erl, repo: "hexpm", optional: false]}], "hexpm", "722fe2bad52913ab7e87d849fc6370375f0c961ffb2f0b5e6d647c9170c382a6"},
"connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
"ctx": {:hex, :ctx, "0.6.0", "8ff88b70e6400c4df90142e7f130625b82086077a45364a78d208ed3ed53c7fe", [:rebar3], [], "hexpm", "a14ed2d1b67723dbebbe423b28d7615eb0bdcba6ff28f2d1f1b0a7e1d4aa5fc2"},
"db_connection": {:hex, :db_connection, "2.4.1", "6411f6e23f1a8b68a82fa3a36366d4881f21f47fc79a9efb8c615e62050219da", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ea36d226ec5999781a9a8ad64e5d8c4454ecedc7a4d643e4832bf08efca01f00"},
"db_connection": {:hex, :db_connection, "2.4.2", "f92e79aff2375299a16bcb069a14ee8615c3414863a6fef93156aee8e86c2ff3", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4fe53ca91b99f55ea249693a0229356a08f4d1a7931d8ffa79289b145fe83668"},
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
"dialyxir": {:hex, :dialyxir, "1.1.0", "c5aab0d6e71e5522e77beff7ba9e08f8e02bad90dfbeffae60eaf0cb47e29488", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "07ea8e49c45f15264ebe6d5b93799d4dd56a44036cf42d0ad9c960bc266c0b9a"},
"earmark": {:hex, :earmark, "1.4.15", "2c7f924bf495ec1f65bd144b355d0949a05a254d0ec561740308a54946a67888", [:mix], [{:earmark_parser, ">= 1.4.13", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "3b1209b85bc9f3586f370f7c363f6533788fb4e51db23aa79565875e7f9999ee"},
"earmark_parser": {:hex, :earmark_parser, "1.4.18", "e1b2be73eb08a49fb032a0208bf647380682374a725dfb5b9e510def8397f6f2", [:mix], [], "hexpm", "114a0e85ec3cf9e04b811009e73c206394ffecfcc313e0b346de0d557774ee97"},
"ecto": {:hex, :ecto, "3.7.1", "a20598862351b29f80f285b21ec5297da1181c0442687f9b8329f0445d228892", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d36e5b39fc479e654cffd4dbe1865d9716e4a9b6311faff799b6f90ab81b8638"},
"ecto_sql": {:hex, :ecto_sql, "3.7.1", "8de624ef50b2a8540252d8c60506379fbbc2707be1606853df371cf53df5d053", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.4.0 or ~> 0.5.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2b42a32e2ce92f64aba5c88617891ab3b0ba34f3f3a503fa20009eae1a401c81"},
"earmark_parser": {:hex, :earmark_parser, "1.4.23", "1d5f22a2802160fd454404fbf5e8f5d14cd8eb727c63701397b72d8c35267e69", [:mix], [], "hexpm", "2ec13bf14b2f4bbb4a15480970e295eede8bb01087fad6ceca27b724ab8e9d18"},
"ecto": {:hex, :ecto, "3.7.2", "44c034f88e1980754983cc4400585970b4206841f6f3780967a65a9150ef09a8", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a600da5772d1c31abbf06f3e4a1ffb150e74ed3e2aa92ff3cee95901657a874e"},
"ecto_sql": {:hex, :ecto_sql, "3.7.2", "55c60aa3a06168912abf145c6df38b0295c34118c3624cf7a6977cd6ce043081", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.4.0 or ~> 0.5.0 or ~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0 or ~> 0.16.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3c218ea62f305dcaef0b915fb56583195e7b91c91dcfb006ba1f669bfacbff2a"},
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
"ex_doc": {:hex, :ex_doc, "0.26.0", "1922164bac0b18b02f84d6f69cab1b93bc3e870e2ad18d5dacb50a9e06b542a3", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "2775d66e494a9a48355db7867478ffd997864c61c65a47d31c4949459281c78d"},
"gproc": {:hex, :gproc, "0.8.0", "cea02c578589c61e5341fce149ea36ccef236cc2ecac8691fba408e7ea77ec2f", [:rebar3], [], "hexpm", "580adafa56463b75263ef5a5df4c86af321f68694e7786cb057fd805d1e2a7de"},
"grpcbox": {:hex, :grpcbox, "0.14.0", "3eb321bcd2275baf8b54cf381feb7b0559a50c02544de28fda039c7f2f9d1a7a", [:rebar3], [{:acceptor_pool, "~>1.0.0", [hex: :acceptor_pool, repo: "hexpm", optional: false]}, {:chatterbox, "~>0.11.0", [hex: :ts_chatterbox, repo: "hexpm", optional: false]}, {:ctx, "~>0.6.0", [hex: :ctx, repo: "hexpm", optional: false]}, {:gproc, "~>0.8.0", [hex: :gproc, repo: "hexpm", optional: false]}], "hexpm", "e24159b7b6d3f9869bbe528845c0125fed2259366ba908fd04a1f45fe81d0660"},
"hpack": {:hex, :hpack_erl, "0.2.3", "17670f83ff984ae6cd74b1c456edde906d27ff013740ee4d9efaa4f1bf999633", [:rebar3], [], "hexpm", "06f580167c4b8b8a6429040df36cc93bba6d571faeaec1b28816523379cbb23a"},
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
"makeup_elixir": {:hex, :makeup_elixir, "0.15.2", "dc72dfe17eb240552857465cc00cce390960d9a0c055c4ccd38b70629227e97c", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "fd23ae48d09b32eff49d4ced2b43c9f086d402ee4fd4fcb2d7fad97fa8823e75"},
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"},
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
"nimble_parsec": {:hex, :nimble_parsec, "1.2.0", "b44d75e2a6542dcb6acf5d71c32c74ca88960421b6874777f79153bbbbd7dccc", [:mix], [], "hexpm", "52b2871a7515a5ac49b00f214e4165a40724cf99798d8e4a65e4fd64ebd002c1"},
"opentelemetry": {:hex, :opentelemetry, "1.0.0", "6e98f4a9230681b2e4c88d45783ce1c02d671ffc0b5ac0cba69a34a3f5ada8d8", [:rebar3], [{:opentelemetry_api, "~> 1.0.0", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}], "hexpm", "08d8697740f70594d05067cb62a0a8845ff568b2d47e1f8c78c46708ab58a74f"},
"opentelemetry_api": {:hex, :opentelemetry_api, "1.0.0", "6e501f750ead189f35aed07eb8023fa6655fca12f913a196102f67db4ed5172c", [:mix, :rebar3], [], "hexpm", "ac51520bde21fdea7f82cea9236ce4e88a21281c22bc23b0f1fa3b28b4352fcf"},
"opentelemetry_exporter": {:hex, :opentelemetry_exporter, "1.0.0", "12fd928e72dec8108d40214a667e7a90026827d6268db678617c9e40ec3dc931", [:rebar3], [{:grpcbox, ">= 0.0.0", [hex: :grpcbox, repo: "hexpm", optional: false]}, {:opentelemetry, "~> 1.0", [hex: :opentelemetry, repo: "hexpm", optional: false]}, {:opentelemetry_api, "~> 1.0", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}, {:tls_certificate_check, "~> 1.11", [hex: :tls_certificate_check, repo: "hexpm", optional: false]}], "hexpm", "e2d2377abfb823cc99c1b68b4ce31df1ff1ce63e0c7bdbee7a7527e2d825168d"},
"postgrex": {:hex, :postgrex, "0.15.13", "7794e697481799aee8982688c261901de493eb64451feee6ea58207d7266d54a", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "3ffb76e1a97cfefe5c6a95632a27ffb67f28871c9741fb585f9d1c3cd2af70f1"},
"nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"},
"opentelemetry": {:hex, :opentelemetry, "1.0.2", "9ffa9ddcbec9356154681bc9d0a54bb20f0de0e8c6696ccc298b49633308782b", [:rebar3], [{:opentelemetry_api, "~> 1.0", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}], "hexpm", "e774506333c8afd9133fee4ba69d06e6413ccad6ee76f10e59c3ec624009af23"},
"opentelemetry_api": {:hex, :opentelemetry_api, "1.0.2", "91353ee40583b1d4f07d7b13ed62642abfec6aaa0d8a2114f07edafb2df781c5", [:mix, :rebar3], [], "hexpm", "2a8247f85c44216b883900067478d59955d11e58e5cfca7c884cd4f203ace3ac"},
"opentelemetry_ecto": {:git, "https://github.com/bryannaegele/opentelemetry-erlang-contrib.git", "9730da9300cdd08138d3455deb270b06f3a440fa", [sparse: "propagators/opentelemetry_process_propagator", branch: "otel-process-walker"]},
"opentelemetry_exporter": {:hex, :opentelemetry_exporter, "1.0.2", "19a102d1f04776399a915be27121852468318c27146e553faf28008e3e474972", [:rebar3], [{:grpcbox, ">= 0.0.0", [hex: :grpcbox, repo: "hexpm", optional: false]}, {:opentelemetry, "~> 1.0", [hex: :opentelemetry, repo: "hexpm", optional: false]}, {:opentelemetry_api, "~> 1.0", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}, {:tls_certificate_check, "~> 1.11", [hex: :tls_certificate_check, repo: "hexpm", optional: false]}], "hexpm", "43de904dd7f482009bf1a40d591ab5ed25f603f1072a04a162e87f7f8c08dbb5"},
"opentelemetry_process_propagator": {:hex, :opentelemetry_process_propagator, "0.1.1", "81ec6825971903486ee73be23230d06764df39ee11011e520f601aa2bb21c893", [:mix, :rebar3], [{:opentelemetry_api, "~> 1.0", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}], "hexpm", "0572f26066bbb0457e22e169f966c0140a8f95237716c9c6ba4458d6dbaa724b"},
"postgrex": {:hex, :postgrex, "0.16.2", "0f83198d0e73a36e8d716b90f45f3bde75b5eebf4ade4f43fa1f88c90a812f74", [:mix], [{:connection, "~> 1.1", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "a9ea589754d9d4d076121090662b7afe155b374897a6550eb288f11d755acfa0"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"telemetry": {:hex, :telemetry, "1.0.0", "0f453a102cdf13d506b7c0ab158324c337c41f1cc7548f0bc0e130bbf0ae9452", [:rebar3], [], "hexpm", "73bc09fa59b4a0284efb4624335583c528e07ec9ae76aca96ea0673850aec57a"},
"tls_certificate_check": {:hex, :tls_certificate_check, "1.11.0", "609dcd503f31170f0799dac380eb0e086388cf918fc769aaa60ddd6bbf575218", [:rebar3], [{:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "4ab962212ef7c87482619cb298e1fe06e047b57f0bd58cc417b3b299eb8d036e"},
"tls_certificate_check": {:hex, :tls_certificate_check, "1.12.0", "417124799daad41d5ed13d5efc15becec5b7bb9854397f92492b2e25be7b41f6", [:rebar3], [{:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "f65b090606f2503364727013ef9f70a1535a7f00a78a850b2e7ab238dda4adcb"},
}

View File

@ -10,5 +10,10 @@ defmodule OpentelemetryEcto.TestRepo.Migrations.SetupTables do
add :body, :text
add :user_id, references(:users)
end
create table(:comments) do
add :body, :text
add :user_id, references(:users)
end
end
end

View File

@ -4,7 +4,10 @@ defmodule OpentelemetryEctoTest do
require OpenTelemetry.Tracer
alias OpentelemetryEcto.TestRepo, as: Repo
alias OpentelemetryEcto.TestModels.{User, Post}
alias OpentelemetryEcto.TestModels.{Comment, User, Post}
require Ecto.Query, as: Query
require OpenTelemetry.Tracer, as: Tracer
@event_name [:opentelemetry_ecto, :test_repo]
@ -15,7 +18,16 @@ defmodule OpentelemetryEctoTest do
end
setup do
:otel_simple_processor.set_exporter(:otel_exporter_pid, self())
:application.stop(:opentelemetry)
:application.set_env(:opentelemetry, :tracer, :otel_tracer_default)
:application.set_env(:opentelemetry, :processors, [
{:otel_batch_processor, %{scheduled_delay_ms: 1}}
])
:application.start(:opentelemetry)
:otel_batch_processor.set_exporter(:otel_exporter_pid, self())
OpenTelemetry.Tracer.start_span("test")
@ -113,6 +125,65 @@ defmodule OpentelemetryEctoTest do
assert message =~ "non_existant_field does not exist"
end
test "preloads in sequence are tied to the parent span" do
user = Repo.insert!(%User{email: "opentelemetry@erlang.org"})
Repo.insert!(%Post{body: "We got traced!", user: user})
Repo.insert!(%Comment{body: "We got traced!", user: user})
attach_handler()
Tracer.with_span "parent span" do
Repo.all(Query.from(User, preload: [:posts, :comments]), in_parallel: false)
end
assert_receive {:span, span(span_id: root_span_id, name: "parent span")}
assert_receive {:span, span(parent_span_id: ^root_span_id, name: "opentelemetry_ecto.test_repo.query:users")}
assert_receive {:span, span(parent_span_id: ^root_span_id, name: "opentelemetry_ecto.test_repo.query:posts")}
assert_receive {:span, span(parent_span_id: ^root_span_id, name: "opentelemetry_ecto.test_repo.query:comments")}
end
test "preloads in parallel are tied to the parent span" do
user = Repo.insert!(%User{email: "opentelemetry@erlang.org"})
Repo.insert!(%Post{body: "We got traced!", user: user})
Repo.insert!(%Comment{body: "We got traced!", user: user})
attach_handler()
Tracer.with_span "parent span" do
Repo.all(Query.from(User, preload: [:posts, :comments]))
end
assert_receive {:span, span(span_id: root_span_id, name: "parent span")}
assert_receive {:span, span(parent_span_id: ^root_span_id, name: "opentelemetry_ecto.test_repo.query:users")}
assert_receive {:span, span(parent_span_id: ^root_span_id, name: "opentelemetry_ecto.test_repo.query:posts")}
assert_receive {:span, span(parent_span_id: ^root_span_id, name: "opentelemetry_ecto.test_repo.query:comments")}
end
test "nested query preloads are tied to the parent span" do
user = Repo.insert!(%User{email: "opentelemetry@erlang.org"})
Repo.insert!(%Post{body: "We got traced!", user: user})
Repo.insert!(%Comment{body: "We got traced!", user: user})
attach_handler()
Tracer.with_span "parent span" do
users_query = from u in User, preload: [:posts, :comments]
comments_query = from c in Comment, preload: [user: ^users_query]
Repo.all(Query.from(User, preload: [:posts, comments: ^comments_query]))
end
assert_receive {:span, span(span_id: root_span_id, name: "parent span")}
# root query
assert_receive {:span, span(parent_span_id: ^root_span_id, name: "opentelemetry_ecto.test_repo.query:users")}
# comments preload
assert_receive {:span, span(parent_span_id: ^root_span_id, name: "opentelemetry_ecto.test_repo.query:comments")}
# users preload
assert_receive {:span, span(parent_span_id: ^root_span_id, name: "opentelemetry_ecto.test_repo.query:users")}
# preloads of user
assert_receive {:span, span(parent_span_id: ^root_span_id, name: "opentelemetry_ecto.test_repo.query:posts")}
assert_receive {:span, span(parent_span_id: ^root_span_id, name: "opentelemetry_ecto.test_repo.query:comments")}
end
def attach_handler(config \\ []) do
# For now setup the handler manually in each test
handler = {__MODULE__, self()}

View File

@ -0,0 +1,8 @@
defmodule OpentelemetryEcto.TestModels.Comment do
use Ecto.Schema
schema "comments" do
field(:body, :string)
belongs_to(:user, OpentelemetryEcto.TestModels.User)
end
end

View File

@ -5,5 +5,6 @@ defmodule OpentelemetryEcto.TestModels.User do
field(:email, :string)
has_many(:posts, OpentelemetryEcto.TestModels.Post)
has_many(:comments, OpentelemetryEcto.TestModels.Comment)
end
end