From 70fe943502d95606c80134615789320772890d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20van=20Diemen?= Date: Wed, 12 Jun 2024 13:52:16 +0200 Subject: [PATCH] Move OpenTelemetryMonitor to Tracing.Monitor OpenTelemetryMonitor used to be a fork with a new module named OpenTelemetryMonitor. This module was proposed as a PR but was not merged. Dissolving the monitor into Tracing opens the way to be published. --- README.md | 4 +-- lib/tracing.ex | 2 +- lib/tracing/monitor.ex | 56 +++++++++++++++++++++++++++++++++++ lib/tracing/oban_telemetry.ex | 2 +- mix.exs | 10 +------ mix.lock | 2 -- test/tracing/monitor_test.exs | 4 +++ 7 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 lib/tracing/monitor.ex create mode 100644 test/tracing/monitor_test.exs diff --git a/README.md b/README.md index 0d2f251..0be1433 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_do ## Setup -Tracing relies on `OpentelemetryMonitor` that should be added to the children list in your `Application.start/2`. +Tracing relies on `Tracing.Monitor` that should be added to the children list in your `Application.start/2`. Add `Tracing.setup/1` to `Application.start/2` too with the modules you want to enable telemetry for. @@ -31,7 +31,7 @@ defmodule MyApp.Application do def start(_type, _args) do children = [ - OpentelemetryMonitor, + Tracing.Monitor, Tracing.Telemetry, # or {Tracing.Telemetry, measurements: [], period: 15_000}, diff --git a/lib/tracing.ex b/lib/tracing.ex index 461ccbe..97625a0 100644 --- a/lib/tracing.ex +++ b/lib/tracing.ex @@ -154,7 +154,7 @@ defmodule Tracing do parent_span = OpenTelemetry.Tracer.current_span_ctx() if unquote(opts)[:monitor] do - OpentelemetryMonitor.monitor(parent_span) + Tracing.monitor(parent_span) end fn unquote_splicing(fun_args) -> diff --git a/lib/tracing/monitor.ex b/lib/tracing/monitor.ex new file mode 100644 index 0000000..0fa91ea --- /dev/null +++ b/lib/tracing/monitor.ex @@ -0,0 +1,56 @@ +defmodule Tracing.Monitor do + use GenServer + + def start_link(_arg) do + GenServer.start_link(__MODULE__, nil, name: __MODULE__) + end + + def init(nil) do + _table_id = :ets.new(__MODULE__, [:bag, :public, {:write_concurrency, true}, :named_table]) + {:ok, nil} + end + + def handle_call({:monitor, pid}, _from, state) do + Process.monitor(pid) + {:reply, :ok, state} + end + + def handle_info({:DOWN, _ref, :process, pid, :normal}, state) do + :ets.take(__MODULE__, pid) + |> Enum.each(fn {_pid, ctx} -> + _span_ctx = OpenTelemetry.Tracer.set_current_span(ctx) + _ = OpenTelemetry.Tracer.end_span() + end) + + {:noreply, state} + end + + def handle_info({:DOWN, _ref, :process, pid, {:shutdown, _}}, state) do + :ets.take(__MODULE__, pid) + |> Enum.each(fn {_pid, ctx} -> + _span_ctx = OpenTelemetry.Tracer.set_current_span(ctx) + _ = OpenTelemetry.Tracer.end_span() + end) + + {:noreply, state} + end + + def handle_info({:DOWN, _ref, :process, pid, reason}, state) do + :ets.take(__MODULE__, pid) + |> Enum.each(fn {_pid, ctx} -> + _span_ctx = OpenTelemetry.Tracer.set_current_span(ctx) + _ = OpenTelemetry.Tracer.add_event("Process died", [{"reason", inspect(reason)}]) + _ = OpenTelemetry.Tracer.end_span() + end) + + {:noreply, state} + end + + def monitor(span_ctx) do + if Application.fetch_env!(:opentelemetry, :processors) != [] do + # monitor first, because the monitor is necessary to clean the ets table. + :ok = GenServer.call(__MODULE__, {:monitor, self()}) + true = :ets.insert(__MODULE__, {self(), span_ctx}) + end + end +end diff --git a/lib/tracing/oban_telemetry.ex b/lib/tracing/oban_telemetry.ex index b8eae70..dbcf883 100644 --- a/lib/tracing/oban_telemetry.ex +++ b/lib/tracing/oban_telemetry.ex @@ -69,7 +69,7 @@ defmodule Tracing.ObanTelemetry do }) |> Span.set_attributes(attributes) - OpentelemetryMonitor.monitor(OpenTelemetry.Tracer.current_span_ctx()) + Tracing.Monitor.monitor(OpenTelemetry.Tracer.current_span_ctx()) end def handle_event([:oban, :job, :stop], _, meta, _) do diff --git a/mix.exs b/mix.exs index 82ba663..18e8a46 100644 --- a/mix.exs +++ b/mix.exs @@ -40,14 +40,6 @@ defmodule Tracing.MixProject do {:opentelemetry_ecto, "~> 1.1"}, {:opentelemetry_exporter, "~> 1.6"}, {:opentelemetry_phoenix, "~> 1.2"}, - {:opentelemetry_phoenix_live_view, "~> 0.1", - github: "wuunder/opentelemetry-erlang-contrib", - branch: "opentelemetry_phoenix_live_view", - sparse: "instrumentation/opentelemetry_phoenix_live_view"}, - {:opentelemetry_monitor, "~> 0.1", - github: "wuunder/opentelemetry-erlang-contrib", - branch: "opentelemetry_monitor", - sparse: "instrumentation/opentelemetry_monitor"}, {:opentelemetry_telemetry, "~> 1.0.0"}, {:telemetry, "~> 1.0"}, {:telemetry_metrics, "~> 0.4"}, @@ -57,7 +49,7 @@ defmodule Tracing.MixProject do defp description() do """ - Standardized library for using OpenTelemetry / :telemetry in Elixir applications. + Standardized library for using OpenTelemetry / :telemetry in Elixir applications. Provides telemetry modules for Phoenix, LiveView, ChromicPDF and Oban. Also contains a Monitor and Telemetry module." """ end diff --git a/mix.lock b/mix.lock index 7d2a636..3c6caba 100644 --- a/mix.lock +++ b/mix.lock @@ -18,9 +18,7 @@ "opentelemetry_api": {:hex, :opentelemetry_api, "1.2.2", "693f47b0d8c76da2095fe858204cfd6350c27fe85d00e4b763deecc9588cf27a", [:mix, :rebar3], [{:opentelemetry_semantic_conventions, "~> 0.2", [hex: :opentelemetry_semantic_conventions, repo: "hexpm", optional: false]}], "hexpm", "dc77b9a00f137a858e60a852f14007bb66eda1ffbeb6c05d5fe6c9e678b05e9d"}, "opentelemetry_ecto": {:hex, :opentelemetry_ecto, "1.2.0", "2382cb47ddc231f953d3b8263ed029d87fbf217915a1da82f49159d122b64865", [:mix], [{:opentelemetry_api, "~> 1.0", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}, {:opentelemetry_process_propagator, "~> 0.2", [hex: :opentelemetry_process_propagator, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "70dfa2e79932e86f209df00e36c980b17a32f82d175f0068bf7ef9a96cf080cf"}, "opentelemetry_exporter": {:hex, :opentelemetry_exporter, "1.6.0", "f4fbf69aa9f1541b253813221b82b48a9863bc1570d8ecc517bc510c0d1d3d8c", [:rebar3], [{:grpcbox, ">= 0.0.0", [hex: :grpcbox, repo: "hexpm", optional: false]}, {:opentelemetry, "~> 1.3", [hex: :opentelemetry, repo: "hexpm", optional: false]}, {:opentelemetry_api, "~> 1.2", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}, {:tls_certificate_check, "~> 1.18", [hex: :tls_certificate_check, repo: "hexpm", optional: false]}], "hexpm", "1802d1dca297e46f21e5832ecf843c451121e875f73f04db87355a6cb2ba1710"}, - "opentelemetry_monitor": {:git, "https://github.com/wuunder/opentelemetry-erlang-contrib.git", "31fb6f51bc0423b40ea777d0029e1d5754b7bf80", [branch: "opentelemetry_monitor", sparse: "instrumentation/opentelemetry_monitor"]}, "opentelemetry_phoenix": {:hex, :opentelemetry_phoenix, "1.2.0", "b8a53ee595b24970571a7d2fcaef3e4e1a021c68e97cac163ca5d9875fad5e9f", [:mix], [{:nimble_options, "~> 0.5 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:opentelemetry_api, "~> 1.0", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}, {:opentelemetry_process_propagator, "~> 0.2", [hex: :opentelemetry_process_propagator, repo: "hexpm", optional: false]}, {:opentelemetry_semantic_conventions, "~> 0.2", [hex: :opentelemetry_semantic_conventions, repo: "hexpm", optional: false]}, {:opentelemetry_telemetry, "~> 1.0", [hex: :opentelemetry_telemetry, repo: "hexpm", optional: false]}, {:plug, ">= 1.11.0", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "acab991d14ed3efc3f780c5a20cabba27149cf731005b1cc6454c160859debe5"}, - "opentelemetry_phoenix_live_view": {:git, "https://github.com/wuunder/opentelemetry-erlang-contrib.git", "0bfa1850147d80cdca686bdfc3f1b23cdbf68723", [branch: "opentelemetry_phoenix_live_view", sparse: "instrumentation/opentelemetry_phoenix_live_view"]}, "opentelemetry_process_propagator": {:hex, :opentelemetry_process_propagator, "0.3.0", "ef5b2059403a1e2b2d2c65914e6962e56371570b8c3ab5323d7a8d3444fb7f84", [:mix, :rebar3], [{:opentelemetry_api, "~> 1.0", [hex: :opentelemetry_api, repo: "hexpm", optional: false]}], "hexpm", "7243cb6de1523c473cba5b1aefa3f85e1ff8cc75d08f367104c1e11919c8c029"}, "opentelemetry_semantic_conventions": {:hex, :opentelemetry_semantic_conventions, "0.2.0", "b67fe459c2938fcab341cb0951c44860c62347c005ace1b50f8402576f241435", [:mix, :rebar3], [], "hexpm", "d61fa1f5639ee8668d74b527e6806e0503efc55a42db7b5f39939d84c07d6895"}, "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"}, diff --git a/test/tracing/monitor_test.exs b/test/tracing/monitor_test.exs new file mode 100644 index 0000000..ccecba7 --- /dev/null +++ b/test/tracing/monitor_test.exs @@ -0,0 +1,4 @@ +defmodule Tracing.MonitorTest do + use ExUnit.Case + doctest Tracing.Monitor +end