# Telemetria Cheatsheet
## Setup
### mix.exs
```elixir
def project do
[
compilers: [:telemetria],
deps: deps()
]
end
defp deps do
[{:telemetria, "~> 0.24"}]
end
```
### config.exs
```elixir
import Config
config :telemetria,
backend: :telemetry,
purge_level: :debug,
level: :info,
events: [[:my_app, :my_module, :my_function]],
throttle: %{my_group: {1_000, :last}}
```
## Module Attribute `@telemetria`
{: .col-2}
### Basic usage
```elixir
defmodule MyApp.Worker do
use Telemetria
@telemetria true
def process(data), do: do_work(data)
end
```
Wraps the function with telemetry, measuring execution time.
### With logging level
```elixir
@telemetria level: :warning
def important(data), do: handle(data)
```
Only emits the event when the configured `purge_level` allows `:warning` or above.
### With compile-time condition
```elixir
@telemetria if: Mix.env() == :prod
def prod_only(data), do: data
```
Telemetry code is included/excluded at compile time.
### With runtime condition
```elixir
@telemetria if: &match?({:ok, _}, &1)
def maybe_report(input) do
{:ok, process(input)}
end
```
The event is emitted only when the `if` function returns `true` for the result.
### Multi-clause functions
```elixir
@telemetria level: :info, locals: [:i]
def classify(i \\ nil)
def classify(nil), do: :none
def classify(i) when i > 0, do: :positive
def classify(_i), do: :negative
```
For multi-clause functions, place `@telemetria` on the **bodyless head clause** (the one with defaults). All clauses will be wrapped. Do not mix head-level and per-clause annotations.
### Per-clause annotations
```elixir
@telemetria level: :warning
def handle(:error), do: alert()
@telemetria level: :debug
def handle(:ok), do: :ok
```
Alternatively, annotate individual clauses separately (each gets its own event with its own options). Cannot be combined with head-level annotation on the same function.
## Attribute Parameters
{: .col-2}
### Export local variables
```elixir
@telemetria locals: [:celsius, :source]
def temperature(city) do
source = :weather_api
celsius = fetch_temp(city)
celsius
end
```
Captures the values of local variables and includes them in the telemetry event metadata.
### Throttled events
```elixir
# config.exs
config :telemetria,
throttle: %{api_calls: {5_000, :last}}
# module
@telemetria group: :api_calls
def call_api(params), do: HTTPClient.get(params)
```
Events in the `:api_calls` group are throttled: only the last event per 5-second window is emitted.
### Transform args and result
```elixir
@telemetria transform: [
args: &Enum.map(&1, fn {k, _} -> k end),
result: &inspect/1
]
def sensitive(credentials) do
authenticate(credentials)
end
```
Applies transformation functions to arguments and/or results before they reach the telemetry handler. Useful for redacting sensitive data.
### Reshape the event
```elixir
@telemetria reshape: &Map.take(&1, [:result, :args])
def compute(x), do: x * x
```
Reshapes the entire event payload before sending. Receives the full metadata map.
### Send to messenger
```elixir
# config.exs
config :telemetria,
messenger_channels: %{
slack: {:slack, url: "https://hooks.slack.com/..."}
}
# module
@telemetria messenger: :slack, level: :error
def critical_operation(input) do
risky_work(input)
end
```
Routes the event to the configured messenger channel (e.g. Slack) in addition to the telemetry backend.
### All parameters at once
```elixir
@telemetria level: :info,
if: &match?({:ok, _}, &1),
group: :reports,
locals: [:duration],
transform: [result: &elem(&1, 1)],
reshape: &Map.drop(&1, [:context]),
messenger: :slack
def generate_report(params) do
duration = measure(fn -> build(params) end)
{:ok, format(duration)}
end
```
## Macros
{: .col-2}
### `deft/2` -- public function
```elixir
import Telemetria
deft add(a, b) do
a + b
end
```
Equivalent to `def` but with telemetry attached.
### `defpt/2` -- private function
```elixir
import Telemetria
defpt multiply(a, b) do
a * b
end
```
Equivalent to `defp` but with telemetry attached.
### `t/1` -- wrap expression
```elixir
import Telemetria
def work do
result = t(expensive_computation())
result
end
```
Wraps a single expression with telemetry.
### `t/1` -- wrap block
```elixir
import Telemetria
def work do
t do
step_1()
step_2()
end
end
```
Wraps a `do`-block with telemetry.
### `t/2` -- with suffix
```elixir
t(&(&1 * 2), suffix: :doubler)
```
Appends `:doubler` to the event name for disambiguation.
### `t/1` -- anonymous function clauses
```elixir
divider =
t(fn
x when is_integer(x) -> x / 2
_ -> nil
end)
divider.(42) #=> 21.0
```
Each clause of the anonymous function gets its own telemetry event.
## Application Config
{: .col-2}
### Backends
| Value | Description |
| --- | --- |
| `:telemetry` | Standard `:telemetry` (requires `{:telemetry, "~> 1.0"}`) |
| `:open_telemetry` | OpenTelemetry spans (requires `{:opentelemetry_api, "~> 1.4"}`) |
| `:logger` | Fallback: logs events via `Logger` |
### Throttle modes
| Mode | Description |
| --- | --- |
| `:none` | No throttling, events fire immediately |
| `{ms, :last}` | Keep only the last event per `ms` window |
| `{ms, :all}` | Collect all events, flush every `ms` |
### Log levels
- `:emergency`
- `:alert`
- `:critical`
- `:error`
- `:warning`
- `:notice`
- `:info`
- `:debug`
### Key config options
| Option | Default | Description |
| --- | --- | --- |
| `:backend` | `Telemetria.Backend.Telemetry` | Telemetry backend module |
| `:level` | `:debug` | Min level to emit events |
| `:purge_level` | `:debug` | Events below this are removed at compile time |
| `:throttle` | `:none` | Throttling strategy |
| `:enabled` | `true` | Master switch |
| `:strict` | `false` | Require explicit `if:` on every `@telemetria` |
| `:process_info` | `false` | Include process info in events |