Packages

appsignal

0.6.0
2.17.4 2.17.3 2.17.2 2.17.1 2.17.0 2.16.0 2.15.11 2.15.10 2.15.9 2.15.8 2.15.7 2.15.6 2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.1 2.14.0 2.13.4 2.13.3 2.13.2 2.13.1 2.13.0 2.12.3 2.12.2 2.12.1 2.12.0 2.11.0 2.10.2 2.10.1 2.10.0 2.9.2 2.9.1 2.9.0 2.8.3 2.8.2 2.8.1 2.8.0 2.7.13 2.7.12 2.7.11 2.7.10 2.7.9 2.7.8 2.7.7 2.7.6 2.7.5 2.7.4 2.7.3 2.7.2 2.7.1 2.7.0 2.7.0-beta.1 2.6.1 2.6.0 2.5.3 2.5.2 2.5.1 2.5.0 2.4.3 2.4.2 2.4.1 2.4.0 2.3.1 2.3.0 2.2.19 2.2.18 2.2.17 2.2.16 2.2.15 2.2.14 2.2.13 2.2.12 retired 2.2.11 2.2.10 2.2.9 2.2.8 2.2.7 2.2.6 2.2.5 2.2.4 2.2.3 2.2.2 2.2.1 2.2.0 2.1.15 2.1.14 2.1.13 2.1.12 2.1.11 2.1.10 2.1.9 2.1.8 2.1.7 2.1.7-beta.1 2.1.6 2.1.5 2.1.4 2.1.3 2.1.2 2.1.1 2.1.0 2.0.8 2.0.7 2.0.6 2.0.6-beta.1 2.0.5 retired 2.0.4 retired 2.0.3 retired 2.0.2 retired 2.0.1 retired 2.0.0 retired 2.0.0-beta.11 2.0.0-beta.10 2.0.0-beta.9 2.0.0-beta.8 2.0.0-beta.7 2.0.0-beta.6 2.0.0-beta.5 2.0.0-beta.4 2.0.0-beta.3 2.0.0-beta.2 2.0.0-beta.1 2.0.0-alpha.7 2.0.0-alpha.6 2.0.0-alpha.5 2.0.0-alpha.4 2.0.0-alpha.3 2.0.0-alpha.2 2.0.0-alpha.1 1.13.5 1.13.4 1.13.3 1.13.2 1.13.1 1.13.0 1.13.0-beta.2 1.13.0-beta.1 1.12.1 1.12.0 1.12.0-beta.3 1.12.0-beta.2 1.12.0-beta.1 1.11.8 1.11.7 1.11.6 1.11.5 1.11.4 1.11.3 1.11.2 1.11.1 1.11.0 1.11.0-beta.1 1.10.13 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.4 1.9.3 1.9.2 1.9.1 1.9.1-beta.1 1.9.0 1.9.0-beta.1 1.9.0-alpha.1 1.8.2 1.8.1 1.8.1-beta.2 1.8.1-beta.1 1.8.0 1.7.2 1.7.1 1.7.0 1.7.0-beta.2 1.7.0-beta.1 1.7.0-alpha.4 1.7.0-alpha.3 1.7.0-alpha.2 1.7.0-alpha.1 1.6.7 1.6.6 1.6.6-beta.2 1.6.6-beta.1 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.6.0-beta.1 1.6.0-alpha.1 1.5.1 1.5.0 1.5.0-beta.2 1.5.0-beta.1 1.4.11-beta.1 1.4.10 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.4.0-alpha.1 1.3.6 1.3.6-beta.1 1.3.5 1.3.4 1.3.4-beta.1 1.3.3 1.3.2 1.3.1 1.3.0 1.3.0-beta.3 1.3.0-beta.2 1.3.0-beta.1 1.2.3 1.2.2 1.2.1 1.2.0 1.1.1 1.1.0 1.0.4 1.0.3 1.0.2 1.0.1 1.0.0 1.0.0-rc.1 0.13.0 0.12.3 0.12.2 0.12.1 0.12.0 0.11.6 0.11.5 0.11.4 0.11.3 0.11.2 0.11.1 0.11.0 0.10.0 0.9.2 0.9.1 0.9.0 0.8.0 0.7.1 0.7.0 0.6.2 0.6.1 0.6.0 0.5.0 0.4.0 0.3.0 0.2.0 0.1.0 0.0.9 0.0.8 0.0.7 0.0.6 0.0.5 0.0.4 0.0.3 0.0.2 0.0.1

Collects error and performance data from your Elixir applications and sends it to AppSignal

Current section

Files

Jump to
appsignal lib appsignal helpers.ex
Raw

lib/appsignal/helpers.ex

defmodule Appsignal.Helpers do
@moduledoc """
Helper functions and macros to instrument function calls.
"""
alias Appsignal.{Transaction, TransactionRegistry}
alias Plug.Conn
@type instrument_arg :: Transaction.t | Conn.t | pid()
@doc """
Execute the given function in start / finish event calls. See `instrument/6`.
"""
@spec instrument(instrument_arg, String.t, String.t, function) :: any
def instrument(arg, name, title, function) do
instrument(arg, name, title, "", function)
end
@doc """
Execute the given function in start / finish event calls. See `instrument/6`.
"""
@spec instrument(instrument_arg, String.t, String.t, String.t, function) :: any
def instrument(arg, name, title, body, function) do
instrument(arg, name, title, body, 0, function)
end
@doc """
Execute the given function in start / finish event calls.
The result of the function's execution is returned. For example, to
instrument a backend HTTP call in a Phoenix controller, do the
following:
```
import Appsignal.Helpers, only: [instrument: 4]
def index(conn, _params) do
result = instrument(conn, "net.http", "Some slow backend call", fn() ->
Backend.get_result()
end
json conn, result
end
```
"""
@spec instrument(instrument_arg, String.t, String.t, String.t, integer, function) :: any
def instrument(pid, name, title, body, body_format, function) when is_pid(pid) do
case TransactionRegistry.lookup(pid) do
nil ->
function.()
t = %Transaction{} ->
instrument(t, name, title, body, body_format, function)
end
end
def instrument(%Conn{} = conn, name, title, body, body_format, function) do
instrument(conn.assigns.appsignal_transaction, name, title, body, body_format, function)
end
def instrument(%Transaction{} = transaction, name, title, body, body_format, function) do
Transaction.start_event(transaction)
result = function.()
Transaction.finish_event(transaction, name, title, body, body_format)
result
end
@doc """
Automatically instrument all function definitions in the nested block using a given category
All `def` statements that are passed in into the macro are
transformed to call `Appsignal.Helpers.instrument/6` automatically.
```
defmodule MyInstrumentedModule do
import Appsignal.Helpers
instrumented do
def bar(arg) do
# code to be instrumented
end
# more functions...
end
end
```
Whenever `MyInstrumentedModule.bar()` is called now, it will be
using `instrument/6` to record an Appsignal event. The name of the
event is the same as the function name. When a category (atom) is
given, the category is postfixed to the function name, so given the
following code:
```
instrumented :http do
def load_data(arg) do
# code to be instrumented
end
end
```
events will be recorded under the event name `load_data.http` whenever `load_data()` is called.
"""
defmacro instrumented(category, code) do
expand_instrumented(".#{category}", code)
end
@doc """
Automatically instrument all function definitions in the nested block
See `instrumented/2`
"""
defmacro instrumented(code) do
expand_instrumented("", code)
end
defp expand_instrumented(postfix, [do: {tag, _meta, _rest} = deftuple]) when tag in [:def, :defp] do
[do: instrument_def(deftuple, postfix)]
end
defp expand_instrumented(postfix, [do: {:__block__, arg, tuples}]) do
[do: {:__block__, arg, tuples |> Enum.map(&(instrument_def(&1, postfix)))}]
end
defp instrument_def({tag, defmeta, [{name, _, _}=defname, [do: doblock]]}, postfix) when tag in [:def, :defp] do
name = Atom.to_string(name)
{tag,
defmeta,
[defname,
[do: quote do
Appsignal.Helpers.instrument(self(), unquote(name) <> unquote(postfix), Atom.to_string(__MODULE__) <> "." <> unquote(name), fn() -> unquote(doblock) end)
end]]}
end
defp instrument_def(code, _postfix) do
code
end
end