Skill 76 · Instrument Error Tracking
Subchapter 76.8
references/elixir.mdMarkdown9 KBView on GitHub
AI agents: this is one page from PostHog’s docs. Full index of Markdown docs for LLMs: https://posthog.com/llms.txt (opens in a new tab)
1
Required
Add the PostHog Elixir SDK (opens in a new tab) to your list of dependencies in mix.exs:
Elixir
def deps do
[
{:posthog, "~> 2.5"}
]
endThen run:
Terminal
mix deps.getSource code context
The Elixir SDK supports displaying the surrounding lines of source code in the Error Tracking UI. Since Elixir is a compiled language, source files must be packaged at build time. See the source context step below for setup instructions.
2
Required
Add your project token and host to your config:
config/config.exs
config :posthog,
api_host: "https://us.i.posthog.com",
api_key: "<ph_project_token>"To get the most out of Error Tracking, set in_app_otp_apps to your application name. This marks stack trace frames from your code as “in-app”, making it easier to identify relevant frames in the PostHog UI:
config/config.exs
config :posthog,
api_host: "https://us.i.posthog.com",
3
Required
Error Tracking is enabled by default. The SDK hooks into Elixir’s built-in Logger (opens in a new tab) handler system, so it automatically captures:
Logger.error/1 message at or above the configured levelNo additional code is needed. Any crash or error log in your application is sent to PostHog as a $exception event with full stack traces.
What gets captured
The handler captures log messages based on two rules:
crash_reason metadata (e.g., GenServer/Task crashes) is captured regardless of log level.capture_level (default: :error) are captured.4
Recommended
If you’re using Phoenix or Plug, add the PostHog.Integrations.Plug middleware to automatically attach HTTP context (URL, host, path, IP) to error events.
For Phoenix, add it to your endpoint.ex before the router:
lib/my_app_web/endpoint.ex
plug PostHog.Integrations.Plug
plug MyAppWeb.RouterFor Plug apps, add it to your router:
Elixir
defmodule MyRouter do
use
5
Recommended
By default, errors are attributed to "unknown". To associate errors with specific users, set a context with a distinct_id early in your request lifecycle – for example, in a Plug pipeline after authentication:
Elixir
PostHog.set_context(%{distinct_id: current_user.id})This is process-scoped, so any error that occurs in the same process (i.e., the same request) will include the user’s distinct ID.
For Phoenix apps, a common pattern is to add this in a plug or controller action:
lib/my_app_web/plugs/set_posthog_context.ex
defmodule MyAppWeb.Plugs.
6
Optional
The SDK supports several configuration options for Error Tracking:
config/config.exs
config :posthog,
api_host: "https://us.i.posthog.com",
api_key: "<ph_project_token>",
# Mark your app's stacktrace frames as "in_app"
in_app_otp_apps: [:my_app],
7
Optional
Since Elixir is a compiled language, source files aren’t available at runtime by default. To display the surrounding lines of code in PostHog’s Error Tracking UI, you need to package your source code at build time.
Step 1: Enable source context in your config:
config/config.exs
config :posthog,
api_host: "https://us.i.posthog.com",
api_key: "<ph_project_token>",
enable_source_code_context: true,
root_source_code_paths: [File.
Recommended
Trigger a test exception to confirm errors are being sent to PostHog. You should see them appear in the Error Tracking (opens in a new tab) tab.
Elixir
# In an IEx session or a test route
require Logger
Logger.error("Test error from Elixir")Or raise an exception in a controller or GenServer to test crash capture:
Elixir
Ask PostHog AI
HelpfulCould be better
This automatically includes $current_url, $host, $pathname, and $ip on every error event that occurs during request processing. It also reads X-PostHog-Distinct-Id and X-PostHog-Session-Id tracing headers, so errors can link back to frontend users and sessions when your client SDK sends those headers.
If you’re using PostHog JS (opens in a new tab) on the frontend, configure tracing_headers (opens in a new tab) for your Phoenix or Plug backend hostname. For more details, see the Elixir request context docs (opens in a new tab).
Then add it to your router pipeline:
Elixir
pipeline :browser do
# ... other plugs
plug MyAppWeb.Plugs.SetPostHogContext
end| Option | Type | Default | Description |
|---|---|---|---|
in_app_otp_apps | list of atoms | [] | OTP app names whose stacktrace frames are marked as “in_app” in the UI. |
capture_level | log level or nil | :error | Minimum log level to capture. Crashes with crash_reason are always captured. Set to nil to only capture crashes. |
metadata | list of atoms or :all | [] | Logger metadata keys to include as event properties. |
enable_error_tracking | boolean | true | Set to false to disable automatic Error Tracking entirely. |
global_properties | map | %{} | Properties added to all captured events (not just errors). |
Step 2: Package source code before building your release:
Terminal
mix posthog.package_source_code
mix releaseThis reads all .ex files from your project, compresses them into priv/posthog_source.map, and bundles them with your release. When an error occurs, the SDK matches stack trace frames to the packaged source and includes pre_context, context_line, and post_context in each frame.
Development mode
In development, if root_source_code_paths is set and source files are accessible on disk, the SDK reads them directly at startup – no packaging step needed.
| Option | Type | Default | Description |
|---|---|---|---|
enable_source_code_context | boolean | false | Enable source code context in stack frames. |
root_source_code_paths | list of strings | [] | Root paths to scan for source files. |
source_code_path_pattern | string | "**/*.ex" | Glob pattern for files to include. |
source_code_exclude_patterns | list of regexes | [~r"^_build/", ~r"^priv/", ~r"^test/"] | Patterns to exclude. |
context_lines | integer | 5 | Number of lines to include before and after the error line. |
source_code_map_path | string | nil | Custom path to a packaged source map file. |
Terminal
# Custom output path
mix posthog.package_source_code --output path/to/output.map
# Custom root paths (overrides config)
mix posthog.package_source_code --root-path /app/lib --root-path /app/src