Add Dataloader instrumentation library (#137)
* Add Dataloader instrumentation library * Move call to set context to @run_start event --------- Co-authored-by: Tristan Sloughter <t@crashfast.com>
This commit is contained in:
parent
de17c31194
commit
1de26cce1a
|
@ -344,7 +344,52 @@ jobs:
|
||||||
run: mix format --check-formatted
|
run: mix format --check-formatted
|
||||||
- name: Test
|
- name: Test
|
||||||
run: mix test
|
run: mix test
|
||||||
|
opentelemetry-dataloader:
|
||||||
|
needs: [test-matrix]
|
||||||
|
if: (contains(github.event.pull_request.labels.*.name, 'elixir') && contains(github.event.pull_request.labels.*.name, 'opentelemetry_dataloader'))
|
||||||
|
env:
|
||||||
|
app: 'opentelemetry_dataloader'
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: instrumentation/${{ env.app }}
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
name: Opentelemetry Dataloader test on Elixir ${{ matrix.elixir_version }} (OTP ${{ matrix.otp_version }})
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix: ${{ fromJson(needs.test-matrix.outputs.matrix) }}
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: circleci/postgres:13.3-ram
|
||||||
|
ports: ['5432:5432']
|
||||||
|
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
|
||||||
|
env:
|
||||||
|
POSTGRES_USER: postgres
|
||||||
|
POSTGRES_PASSWORD: postgres
|
||||||
|
POSTGRES_DB: opentelemetry_dataloader_test
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: erlef/setup-beam@v1
|
||||||
|
with:
|
||||||
|
otp-version: ${{ matrix.otp_version }}
|
||||||
|
elixir-version: ${{ matrix.elixir_version }}
|
||||||
|
rebar3-version: ${{ matrix.rebar3_version }}
|
||||||
|
- name: Cache
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/deps
|
||||||
|
~/_build
|
||||||
|
key: ${{ runner.os }}-build-${{ matrix.otp_version }}-${{ matrix.elixir_version }}-v3-${{ hashFiles('**/mix.lock') }}
|
||||||
|
- name: Fetch deps
|
||||||
|
if: steps.deps-cache.outputs.cache-hit != 'true'
|
||||||
|
run: mix deps.get
|
||||||
|
- name: Compile project
|
||||||
|
run: mix compile --warnings-as-errors
|
||||||
|
- name: Check formatting
|
||||||
|
run: mix format --check-formatted
|
||||||
|
- name: Test
|
||||||
|
run: mix test
|
||||||
opentelemetry-process-propagator:
|
opentelemetry-process-propagator:
|
||||||
needs: [test-matrix]
|
needs: [test-matrix]
|
||||||
if: (contains(github.event.pull_request.labels.*.name, 'elixir') && contains(github.event.pull_request.labels.*.name, 'opentelemetry_process_propagator'))
|
if: (contains(github.event.pull_request.labels.*.name, 'elixir') && contains(github.event.pull_request.labels.*.name, 'opentelemetry_process_propagator'))
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
# Used by "mix format"
|
||||||
|
[
|
||||||
|
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||||
|
]
|
|
@ -0,0 +1,26 @@
|
||||||
|
# The directory Mix will write compiled artifacts to.
|
||||||
|
/_build/
|
||||||
|
|
||||||
|
# If you run "mix test --cover", coverage assets end up here.
|
||||||
|
/cover/
|
||||||
|
|
||||||
|
# The directory Mix downloads your dependencies sources to.
|
||||||
|
/deps/
|
||||||
|
|
||||||
|
# Where third-party dependencies like ExDoc output generated docs.
|
||||||
|
/doc/
|
||||||
|
|
||||||
|
# Ignore .fetch files in case you like to edit your project deps locally.
|
||||||
|
/.fetch
|
||||||
|
|
||||||
|
# If the VM crashes, it generates a dump, let's ignore it too.
|
||||||
|
erl_crash.dump
|
||||||
|
|
||||||
|
# Also ignore archive artifacts (built via "mix archive.build").
|
||||||
|
*.ez
|
||||||
|
|
||||||
|
# Ignore package tarball (built via "mix hex.build").
|
||||||
|
opentelemetry_dataloader-*.tar
|
||||||
|
|
||||||
|
# Temporary files, for example, from tests.
|
||||||
|
/tmp/
|
|
@ -0,0 +1,27 @@
|
||||||
|
# OpentelemetryDataloader
|
||||||
|
|
||||||
|
Telemetry handler that creates Opentelemetry spans from Dataloader events.
|
||||||
|
|
||||||
|
After installing, setup the handler in your application behaviour before your
|
||||||
|
top-level supervisor starts.
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
OpentelemetryDataloader.setup()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
|
||||||
|
by adding `opentelemetry_dataloader` to your list of dependencies in `mix.exs`:
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
def deps do
|
||||||
|
[
|
||||||
|
{:opentelemetry_dataloader, "~> 1.0.0"}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
|
||||||
|
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
|
||||||
|
be found at <https://hexdocs.pm/opentelemetry_dataloader>.
|
|
@ -0,0 +1,34 @@
|
||||||
|
# This file is responsible for configuring your application
|
||||||
|
# and its dependencies with the aid of the Mix.Config module.
|
||||||
|
import Config
|
||||||
|
|
||||||
|
# This configuration is loaded before any dependency and is restricted
|
||||||
|
# to this project. If another project depends on this project, this
|
||||||
|
# file won't be loaded nor affect the parent project. For this reason,
|
||||||
|
# if you want to provide default values for your application for
|
||||||
|
# third-party users, it should be done in your "mix.exs" file.
|
||||||
|
|
||||||
|
# You can configure your application as:
|
||||||
|
#
|
||||||
|
# config :opentelemetry_ecto, key: :value
|
||||||
|
#
|
||||||
|
# and access this configuration in your application as:
|
||||||
|
#
|
||||||
|
# Application.get_env(:opentelemetry_ecto, :key)
|
||||||
|
#
|
||||||
|
# You can also configure a third-party app:
|
||||||
|
#
|
||||||
|
# config :logger, level: :info
|
||||||
|
#
|
||||||
|
|
||||||
|
# It is also possible to import configuration files, relative to this
|
||||||
|
# directory. For example, you can emulate configuration per environment
|
||||||
|
# by uncommenting the line below and defining dev.exs, test.exs and such.
|
||||||
|
# Configuration from the imported file will override the ones defined
|
||||||
|
# here (which is why it is important to import them last).
|
||||||
|
#
|
||||||
|
try do
|
||||||
|
import_config "#{Mix.env()}.exs"
|
||||||
|
rescue
|
||||||
|
_ -> :ok
|
||||||
|
end
|
|
@ -0,0 +1,14 @@
|
||||||
|
import Config
|
||||||
|
|
||||||
|
config :opentelemetry_dataloader,
|
||||||
|
ecto_repos: [OpentelemetryDataloader.TestRepo]
|
||||||
|
|
||||||
|
config :opentelemetry_dataloader, OpentelemetryDataloader.TestRepo,
|
||||||
|
hostname: "localhost",
|
||||||
|
username: "postgres",
|
||||||
|
password: "postgres",
|
||||||
|
database: "opentelemetry_dataloader_test",
|
||||||
|
pool: Ecto.Adapters.SQL.Sandbox
|
||||||
|
|
||||||
|
config :opentelemetry,
|
||||||
|
processors: [{:otel_simple_processor, %{}}]
|
|
@ -0,0 +1,11 @@
|
||||||
|
version: "3.7"
|
||||||
|
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:13.3
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=postgres
|
||||||
|
- POSTGRES_PASSWORD=postgres
|
||||||
|
- POSTGRES_DB=opentelemetry_dataloader_test
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
|
@ -0,0 +1,99 @@
|
||||||
|
defmodule OpentelemetryDataloader do
|
||||||
|
@moduledoc """
|
||||||
|
Module for automatic instrumentation of Dataloader.
|
||||||
|
|
||||||
|
It works by listening to `[:dataloader, :source, :run/:batch, :start/:stop]` telemetry events.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@tracer_id __MODULE__
|
||||||
|
|
||||||
|
@run_start [:dataloader, :source, :run, :start]
|
||||||
|
@run_stop [:dataloader, :source, :run, :stop]
|
||||||
|
|
||||||
|
@batch_start [:dataloader, :source, :batch, :run, :start]
|
||||||
|
@batch_stop [:dataloader, :source, :batch, :run, :stop]
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Initializes and configures the telemetry handlers.
|
||||||
|
"""
|
||||||
|
def setup(_opts \\ []) do
|
||||||
|
config = %{
|
||||||
|
tracer_id: @tracer_id
|
||||||
|
}
|
||||||
|
|
||||||
|
:telemetry.attach_many(
|
||||||
|
{__MODULE__, :run},
|
||||||
|
[
|
||||||
|
@run_start,
|
||||||
|
@run_stop
|
||||||
|
],
|
||||||
|
&__MODULE__.handle_event/4,
|
||||||
|
config
|
||||||
|
)
|
||||||
|
|
||||||
|
:telemetry.attach_many(
|
||||||
|
{__MODULE__, :batch},
|
||||||
|
[
|
||||||
|
@batch_start,
|
||||||
|
@batch_stop
|
||||||
|
],
|
||||||
|
&__MODULE__.handle_event/4,
|
||||||
|
config
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event(event, measurements, metadata, config)
|
||||||
|
|
||||||
|
def handle_event(@run_start, _measurements, metadata, config) do
|
||||||
|
parent_ctx = OpentelemetryProcessPropagator.fetch_parent_ctx(4, :"$callers")
|
||||||
|
|
||||||
|
if parent_ctx != :undefined do
|
||||||
|
OpenTelemetry.Ctx.attach(parent_ctx)
|
||||||
|
end
|
||||||
|
|
||||||
|
OpentelemetryTelemetry.start_telemetry_span(
|
||||||
|
config.tracer_id,
|
||||||
|
"dataloader.run",
|
||||||
|
metadata,
|
||||||
|
%{
|
||||||
|
kind: :client
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event(@run_stop, _measurements, metadata, config) do
|
||||||
|
OpentelemetryTelemetry.set_current_telemetry_span(config.tracer_id, metadata)
|
||||||
|
|
||||||
|
OpentelemetryTelemetry.end_telemetry_span(config.tracer_id, metadata)
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event(@batch_start, _measurements, metadata, config) do
|
||||||
|
parent_ctx = OpentelemetryProcessPropagator.fetch_parent_ctx(4, :"$callers")
|
||||||
|
|
||||||
|
if parent_ctx != :undefined do
|
||||||
|
OpenTelemetry.Ctx.attach(parent_ctx)
|
||||||
|
end
|
||||||
|
|
||||||
|
{batch_name, _batch_args} = metadata.batch
|
||||||
|
|
||||||
|
attributes = %{
|
||||||
|
"dataloader.batch_key" => inspect(batch_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
OpentelemetryTelemetry.start_telemetry_span(
|
||||||
|
config.tracer_id,
|
||||||
|
"dataloader.batch",
|
||||||
|
metadata,
|
||||||
|
%{
|
||||||
|
kind: :client,
|
||||||
|
attributes: attributes
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event(@batch_stop, _measurements, metadata, config) do
|
||||||
|
OpentelemetryTelemetry.set_current_telemetry_span(config.tracer_id, metadata)
|
||||||
|
|
||||||
|
OpentelemetryTelemetry.end_telemetry_span(config.tracer_id, metadata)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,62 @@
|
||||||
|
defmodule OpentelemetryDataloader.MixProject do
|
||||||
|
use Mix.Project
|
||||||
|
|
||||||
|
def project do
|
||||||
|
[
|
||||||
|
app: :opentelemetry_dataloader,
|
||||||
|
description: "Trace Dataloader with OpenTelemetry.",
|
||||||
|
version: "1.0.0",
|
||||||
|
elixir: "~> 1.14",
|
||||||
|
start_permanent: Mix.env() == :prod,
|
||||||
|
deps: deps(),
|
||||||
|
aliases: aliases(),
|
||||||
|
elixirc_paths: elixirc_paths(Mix.env()),
|
||||||
|
package: package(),
|
||||||
|
source_url:
|
||||||
|
"https://github.com/open-telemetry/opentelemetry-erlang-contrib/tree/main/instrumentation/opentelemetry_dataloader"
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp package do
|
||||||
|
[
|
||||||
|
files: ~w(lib .formatter.exs mix.exs README* LICENSE* CHANGELOG*),
|
||||||
|
licenses: ["Apache-2.0"],
|
||||||
|
links: %{
|
||||||
|
"GitHub" =>
|
||||||
|
"https://github.com/open-telemetry/opentelemetry-erlang-contrib/tree/main/instrumentation/opentelemetry_dataloader",
|
||||||
|
"OpenTelemetry Erlang" => "https://github.com/open-telemetry/opentelemetry-erlang",
|
||||||
|
"OpenTelemetry Erlang Contrib" =>
|
||||||
|
"https://github.com/open-telemetry/opentelemetry-erlang-contrib",
|
||||||
|
"OpenTelemetry.io" => "https://opentelemetry.io"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
def application do
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp elixirc_paths(:test), do: ["lib", "test/support"]
|
||||||
|
defp elixirc_paths(_), do: ["lib"]
|
||||||
|
|
||||||
|
defp aliases() do
|
||||||
|
[test: ["ecto.drop -q", "ecto.create -q", "ecto.migrate --quiet", "test"]]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Run "mix help deps" to learn about dependencies.
|
||||||
|
defp deps do
|
||||||
|
[
|
||||||
|
{:telemetry, "~> 0.4 or ~> 1.0"},
|
||||||
|
{:opentelemetry_api, "~> 1.0"},
|
||||||
|
{:opentelemetry_telemetry, "~> 1.0"},
|
||||||
|
{:dataloader, "~> 1.0.8"},
|
||||||
|
{:opentelemetry_exporter, "~> 1.0", only: [:dev, :test]},
|
||||||
|
{:opentelemetry, "~> 1.0", only: [:dev, :test]},
|
||||||
|
{:ex_doc, "~> 0.29", 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},
|
||||||
|
{:opentelemetry_process_propagator, "~> 0.2"}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,32 @@
|
||||||
|
%{
|
||||||
|
"acceptor_pool": {:hex, :acceptor_pool, "1.0.0", "43c20d2acae35f0c2bcd64f9d2bde267e459f0f3fd23dab26485bf518c281b21", [:rebar3], [], "hexpm", "0cbcd83fdc8b9ad2eee2067ef8b91a14858a5883cb7cd800e6fcd5803e158788"},
|
||||||
|
"chatterbox": {:hex, :ts_chatterbox, "0.13.0", "6f059d97bcaa758b8ea6fffe2b3b81362bd06b639d3ea2bb088335511d691ebf", [:rebar3], [{:hpack, "~> 0.2.3", [hex: :hpack_erl, repo: "hexpm", optional: false]}], "hexpm", "b93d19104d86af0b3f2566c4cba2a57d2e06d103728246ba1ac6c3c0ff010aa7"},
|
||||||
|
"connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
|
||||||
|
"ctx": {:hex, :ctx, "0.6.0", "8ff88b70e6400c4df90142e7f130625b82086077a45364a78d208ed3ed53c7fe", [:rebar3], [], "hexpm", "a14ed2d1b67723dbebbe423b28d7615eb0bdcba6ff28f2d1f1b0a7e1d4aa5fc2"},
|
||||||
|
"dataloader": {:hex, :dataloader, "1.0.10", "a42f07641b1a0572e0b21a2a5ae1be11da486a6790f3d0d14512d96ff3e3bbe9", [:mix], [{:ecto, ">= 3.4.3 and < 4.0.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "54cd70cec09addf4b2ace14cc186a283a149fd4d3ec5475b155951bf33cd963f"},
|
||||||
|
"db_connection": {:hex, :db_connection, "2.4.3", "3b9aac9f27347ec65b271847e6baeb4443d8474289bd18c1d6f4de655b70c94d", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c127c15b0fa6cfb32eed07465e05da6c815b032508d4ed7c116122871df73c12"},
|
||||||
|
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
|
||||||
|
"dialyxir": {:hex, :dialyxir, "1.2.0", "58344b3e87c2e7095304c81a9ae65cb68b613e28340690dfe1a5597fd08dec37", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "61072136427a851674cab81762be4dbeae7679f85b1272b6d25c3a839aff8463"},
|
||||||
|
"earmark_parser": {:hex, :earmark_parser, "1.4.29", "149d50dcb3a93d9f3d6f3ecf18c918fb5a2d3c001b5d3305c926cddfbd33355b", [:mix], [], "hexpm", "4902af1b3eb139016aed210888748db8070b8125c2342ce3dcae4f38dcc63503"},
|
||||||
|
"ecto": {:hex, :ecto, "3.9.2", "017db3bc786ff64271108522c01a5d3f6ba0aea5c84912cfb0dd73bf13684108", [: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", "21466d5177e09e55289ac7eade579a642578242c7a3a9f91ad5c6583337a9d15"},
|
||||||
|
"ecto_sql": {:hex, :ecto_sql, "3.9.1", "9bd5894eecc53d5b39d0c95180d4466aff00e10679e13a5cfa725f6f85c03c22", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 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", "5fd470a4fff2e829bbf9dcceb7f3f9f6d1e49b4241e802f614de6b8b67c51118"},
|
||||||
|
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
|
||||||
|
"ex_doc": {:hex, :ex_doc, "0.29.1", "b1c652fa5f92ee9cf15c75271168027f92039b3877094290a75abcaac82a9f77", [:mix], [{:earmark_parser, "~> 1.4.19", [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", "b7745fa6374a36daf484e2a2012274950e084815b936b1319aeebcf7809574f6"},
|
||||||
|
"gproc": {:hex, :gproc, "0.8.0", "cea02c578589c61e5341fce149ea36ccef236cc2ecac8691fba408e7ea77ec2f", [:rebar3], [], "hexpm", "580adafa56463b75263ef5a5df4c86af321f68694e7786cb057fd805d1e2a7de"},
|
||||||
|
"grpcbox": {:hex, :grpcbox, "0.16.0", "b83f37c62d6eeca347b77f9b1ec7e9f62231690cdfeb3a31be07cd4002ba9c82", [:rebar3], [{:acceptor_pool, "~> 1.0.0", [hex: :acceptor_pool, repo: "hexpm", optional: false]}, {:chatterbox, "~> 0.13.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", "294df743ae20a7e030889f00644001370a4f7ce0121f3bbdaf13cf3169c62913"},
|
||||||
|
"hpack": {:hex, :hpack_erl, "0.2.3", "17670f83ff984ae6cd74b1c456edde906d27ff013740ee4d9efaa4f1bf999633", [:rebar3], [], "hexpm", "06f580167c4b8b8a6429040df36cc93bba6d571faeaec1b28816523379cbb23a"},
|
||||||
|
"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.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"},
|
||||||
|
"opentelemetry": {:hex, :opentelemetry, "1.1.2", "77ba2fd2fee67bebde590851a4afeda45b3f298310aa410a2a3804b364cb598a", [:rebar3], [{:opentelemetry_api, "~> 1.1", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}], "hexpm", "5c60be189d6aed64a9fd17055f72c93eab144be441e625276c3c95533e6bb4c7"},
|
||||||
|
"opentelemetry_api": {:hex, :opentelemetry_api, "1.1.1", "3b43877c456c8a7f5448a95d9bf4fb4bb8cc2abbbea2c62d5f8e8c538b4af14f", [:mix, :rebar3], [], "hexpm", "a9554b3208b60a70043318d051ea78fbbc7a1b8f4c418ebc16ccb40015995675"},
|
||||||
|
"opentelemetry_exporter": {:hex, :opentelemetry_exporter, "1.2.2", "3966c56656627ef7db6c34c4ce28d44ac8629dcd065a310d7c33712fc2a1cfe3", [:rebar3], [{:grpcbox, ">= 0.0.0", [hex: :grpcbox, repo: "hexpm", optional: false]}, {:opentelemetry, "~> 1.1", [hex: :opentelemetry, repo: "hexpm", optional: false]}, {:opentelemetry_api, "~> 1.1", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}, {:tls_certificate_check, "~> 1.11", [hex: :tls_certificate_check, repo: "hexpm", optional: false]}], "hexpm", "5c11adeda19e0d203a04efe92cdd7a183da4b09ae8acaba7608e9303fa258e74"},
|
||||||
|
"opentelemetry_process_propagator": {:hex, :opentelemetry_process_propagator, "0.2.1", "20ac37648faf7175cade16fda8d58e6f1ff1b7f2a50a8ef9d70a032c41aba315", [:mix, :rebar3], [{:opentelemetry_api, "~> 1.0", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}], "hexpm", "f317237e39636d4f6140afa5d419e85ed3dc9e9a57072e7cd442df42af7b8aac"},
|
||||||
|
"opentelemetry_telemetry": {:hex, :opentelemetry_telemetry, "1.0.0", "d5982a319e725fcd2305b306b65c18a86afdcf7d96821473cf0649ff88877615", [:mix, :rebar3], [{:opentelemetry_api, "~> 1.0", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_registry, "~> 0.3.0", [hex: :telemetry_registry, repo: "hexpm", optional: false]}], "hexpm", "3401d13a1d4b7aa941a77e6b3ec074f0ae77f83b5b2206766ce630123a9291a9"},
|
||||||
|
"postgrex": {:hex, :postgrex, "0.16.5", "fcc4035cc90e23933c5d69a9cd686e329469446ef7abba2cf70f08e2c4b69810", [: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]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "edead639dc6e882618c01d8fc891214c481ab9a3788dfe38dd5e37fd1d5fb2e8"},
|
||||||
|
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
|
||||||
|
"telemetry": {:hex, :telemetry, "1.1.0", "a589817034a27eab11144ad24d5c0f9fab1f58173274b1e9bae7074af9cbee51", [:rebar3], [], "hexpm", "b727b2a1f75614774cff2d7565b64d0dfa5bd52ba517f16543e6fc7efcc0df48"},
|
||||||
|
"telemetry_registry": {:hex, :telemetry_registry, "0.3.0", "6768f151ea53fc0fbca70dbff5b20a8d663ee4e0c0b2ae589590e08658e76f1e", [:mix, :rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "492e2adbc609f3e79ece7f29fec363a97a2c484ac78a83098535d6564781e917"},
|
||||||
|
"tls_certificate_check": {:hex, :tls_certificate_check, "1.16.0", "45b05e3b993dbace2e4ebccb666eadbd038f1da8f4db9691f4f34a274dfb0bd7", [:rebar3], [{:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3dc0508c749619b8d6a5e21aca4d719c184f065541795b0556398c8e574a3064"},
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
defmodule OpentelemetryDataloader.TestRepo.Migrations.SetupTables do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
create table(:posts) do
|
||||||
|
add(:body, :text)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,69 @@
|
||||||
|
defmodule OpentelemetryDataloaderTest do
|
||||||
|
use ExUnit.Case
|
||||||
|
|
||||||
|
require OpenTelemetry.Tracer
|
||||||
|
|
||||||
|
alias OpentelemetryDataloader.TestRepo, as: Repo
|
||||||
|
alias OpentelemetryDataloader.TestModels.Post
|
||||||
|
|
||||||
|
require Record
|
||||||
|
|
||||||
|
for {name, spec} <- Record.extract_all(from_lib: "opentelemetry/include/otel_span.hrl") do
|
||||||
|
Record.defrecord(name, spec)
|
||||||
|
end
|
||||||
|
|
||||||
|
setup do
|
||||||
|
: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")
|
||||||
|
|
||||||
|
on_exit(fn ->
|
||||||
|
OpenTelemetry.Tracer.end_span()
|
||||||
|
:telemetry.detach({__MODULE__, :batch})
|
||||||
|
:telemetry.detach({__MODULE__, :run})
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "captures dataloader ecto source events" do
|
||||||
|
OpentelemetryDataloader.setup()
|
||||||
|
|
||||||
|
source = Dataloader.Ecto.new(Repo)
|
||||||
|
|
||||||
|
loader = Dataloader.new() |> Dataloader.add_source(:db, source)
|
||||||
|
|
||||||
|
loader =
|
||||||
|
loader
|
||||||
|
|> Dataloader.load(:db, Post, 1)
|
||||||
|
|> Dataloader.load_many(:db, Post, [4, 9])
|
||||||
|
|
||||||
|
Dataloader.run(loader)
|
||||||
|
|
||||||
|
assert_receive {:span,
|
||||||
|
span(
|
||||||
|
name: "dataloader.run",
|
||||||
|
attributes: attributes,
|
||||||
|
kind: :client
|
||||||
|
)}
|
||||||
|
|
||||||
|
assert %{} = :otel_attributes.map(attributes)
|
||||||
|
|
||||||
|
assert_receive {:span,
|
||||||
|
span(
|
||||||
|
name: "dataloader.batch",
|
||||||
|
attributes: attributes,
|
||||||
|
kind: :client
|
||||||
|
)}
|
||||||
|
|
||||||
|
assert %{"dataloader.batch_key" => key} = :otel_attributes.map(attributes)
|
||||||
|
assert key =~ ~r/OpentelemetryDataloader.TestModels.Post/
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
defmodule OpentelemetryDataloader.TestModels.Post do
|
||||||
|
use Ecto.Schema
|
||||||
|
|
||||||
|
schema "posts" do
|
||||||
|
field(:body, :string)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
defmodule OpentelemetryDataloader.TestRepo do
|
||||||
|
use Ecto.Repo,
|
||||||
|
otp_app: :opentelemetry_dataloader,
|
||||||
|
adapter: Ecto.Adapters.Postgres
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
OpentelemetryDataloader.TestRepo.start_link()
|
||||||
|
|
||||||
|
ExUnit.start(capture_log: true)
|
||||||
|
|
||||||
|
Ecto.Adapters.SQL.Sandbox.mode(OpentelemetryDataloader.TestRepo, {:shared, self()})
|
Loading…
Reference in New Issue