> ## Content Index
> Fetch the complete content index at: https://til.codes/llms.txt
> Use this file to discover other available public pages before exploring further.

# Tracing in Elixir/Erlang using :erlang.trace and GenServer
- URL: https://til.codes/tracing-in-elixir/
- Published: 2020-10-30T15:19:11.000Z
- Updated: 2020-12-05T01:31:25.000Z
- Author: Manu Ajith
- Tags: elixir, #Import 2024-07-13 21:01

Recently, I wanted to trace a running Elixir system and see the messages that a function received. I was looking to inspect the params that it received and even manipulate the params to fiddle with some edge cases in the system.

I knew that I could use `dbg` to start a trace on the function and play with the arguments and get more info on the results.

I wrote about some tips on using `dbg` here before 

[Tracing in Elixir/Erlang using dbg trips and tricks.Tips and tricks for tracing in elixir/erlang using dbg module and some helper functions.![](https://til.codes/favicon.ico)Today I learnedManu S Ajith![](https://www.gravatar.com/avatar/966eb8b0d931ad79a0a031b50d1f5feb?s=250&d=mm&r=x)](https://til.codes/tracing-in-elixir-erlang-using-dbg-trips-and-tricks/)

After a bit of googling, I came across [this amazing answer in StackOverflow](https://stackoverflow.com/a/28914950/1598425?ref=til.codes) by Saša Jurić, where he provided an example where he wrapped the `:erlang.trace` around a GenServer which can be hooked to the module.

Copying the code that he shared:

```ruby
defmodule Tracer do
  use GenServer

  def start(modules), do: GenServer.start(__MODULE__, modules)

  def init(modules) do
    :erlang.trace(:all, true, [:call])

    for module <- modules do
      :erlang.trace_pattern({module, :_, :_}, [{:_, [], [{:return_trace}]}])
    end

    {:ok, nil}
  end

  def handle_info({:trace, _, :call, {mod, fun, args}}, state) do
    IO.puts "called #{mod}.#{fun}(#{Enum.join(Enum.map(args, &inspect/1), ",")})"
    {:noreply, state}
  end

  def handle_info({:trace, _, :return_from, {mod, fun, arity}, res}, state) do
    IO.puts "#{mod}.#{fun}/#{arity} returned #{res}"
    {:noreply, state}
  end

  def handle_info(_, state), do: {:noreply, state}
end
```

And then you can trace any module like:

```elixir
Tracer.start([YourModule])
```

Pretty neat stuff.!

Just reminds me again how powerful tracing in Elixir/Erlang is.

Reference:

[Elixir compile-time code injection / AOPI’ve previously used AOP-style code to separate Logic from Logging, and been very pleased with the results. I recognize that opinions on AOP vary, but I’d like to figure out a solution in Elixir, ...![](https://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon.png?v=c78bd457575a)Stack OverflowChris Meyer![](https://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon@2.png?v=73d79a89bded)](https://stackoverflow.com/a/28914950/1598425?ref=til.codes)