elixir reference: Documentation for the Honeybadger Elixir client library (SDK) and platform. # Honeybadger for Elixir > Honeybadger monitors your Elixir applications for errors and performance bottlenecks so that you can fix them wicked fast. Hi there! You’ve found Honeybadger’s guide to **Elixir error tracking and performance monitoring**. Once installed, Honeybadger will automatically report errors and telemetry in your Elixir application. ## How you should read the docs [Section titled “How you should read the docs”](#how-you-should-read-the-docs) * If you’re installing Honeybadger in your **Phoenix** application for the first time, check out the **[Phoenix Integration Guide](/lib/elixir/integrations/phoenix/)**. If you use a different framework, start with the **[General Integration Guide](/lib/elixir/integrations/other/)** instead. * The **How-To Guides** (in the left-hand navigation menu) are general guides on how to do things with the library, and should apply to all types of applications. * There is a wealth of additional knowledge about Honeybadger in the **Package Reference** and **Support** sections. ## Getting support [Section titled “Getting support”](#getting-support) If you’re having trouble working with the package (such as you aren’t receiving error reports when you should be): 1. Read [Frequently asked questions](/lib/elixir/support/faq/) 2. Upgrade to the latest package version if possible (you can find a list of bugfixes and other changes in the [CHANGELOG](https://github.com/honeybadger-io/honeybadger-elixir/blob/master/CHANGELOG.md)) 3. Run through our [Troubleshooting guide](/lib/elixir/support/troubleshooting/) 4. If you believe you’ve found a bug, [submit an issue on GitHub](https://github.com/honeybadger-io/honeybadger-elixir/issues/) For all other problems, contact support for help: # Breadcrumbs > Add breadcrumbs to Elixir error reports to track events leading up to errors and improve debugging. Breadcrumbs are a useful debugging tool that give you the ability to record contextual data as an event called a `breadcrumb`. When your Project reports an Error (Notice), we send along the breadcrumbs recorded during the execution (request, job, task, etc…). [Context](/lib/elixir/errors/context/) is another way to store extra data to help with debugging. Context is still a great way to attach global data to an error, however, there are scenarios where Breadcrumbs might be a better choice: * You want to record metadata that contains duplicate keys * You want to group related data * You care about when an event happened in relation to an error `Honeybadger.add_breadcrumb/2` appends a breadcrumb to the notice. Use this when you want to add some custom data to your breadcrumb trace in effort to help debugging. If a notice is reported to Honeybadger, all breadcrumbs within the execution path will be appended to the notice. You will be able to view the breadcrumb trace in the Honeybadger interface to see what events led up to the notice. ```elixir Honeybadger.add_breadcrumb("Email sent", metadata: %{ user: user.id, message: message }) ``` # Adding context to errors > Add context to Elixir error reports with custom metadata to improve debugging and error resolution. Honeybadger can display additional custom key/value metadata — or “context” — with each error report. Context is what you’re looking for if: * You want to record the current user’s id or email address at the time of an exception * You need to send raw POST data for use in debugging * You have any other metadata you’d like to send with an exception There are two ways to add context to errors in your code: [global](#global-context) and [local](#local-context). While you can add any key/value data to context, a few keys [have a special meaning in Honeybadger](#special-context-keys). ## Global context [Section titled “Global context”](#global-context) `Honeybadger.context/1` is provided for adding extra data to the notification that gets sent to Honeybadger. You can make use of this in places such as a Plug in your Phoenix Router or Controller to ensure useful debugging data is sent along. ```elixir def MyPhoenixApp.Controller use MyPhoenixApp.Web, :controller plug :set_honeybadger_context def set_honeybadger_context(conn, _opts) do user = get_user(conn) Honeybadger.context(user_id: user.id, account: user.account.name) conn end end ``` `Honeybadger.context/1` stores the context data in the process dictionary, so it will be sent with errors/notifications on the same process. The following `Honeybadger.notify/1` call will not see the context data set in the previous line. ```elixir Honeybadger.context(user_id: 5) Task.start(fn -> # this notify does not see the context set earlier # as this runs in a different elixir/erlang process. Honeybadger.notify(%RuntimeError{message: "critical error"}) end) ``` ## Local context [Section titled “Local context”](#local-context) You can also add context to a manual error report using the `metadata` option, like this: ```elixir context = %{user_id: 5, account_name: "Foo"} Honeybadger.notify(exception, metadata: context, stacktrace: __STACKTRACE__) ``` Local context always overrides any global values when the error is reported. ## Special context keys [Section titled “Special context keys”](#special-context-keys) While you can add any key/value data to context, a few keys have special meaning in Honeybadger: | Option | Description | | ------------ | ----------------------------------------------------------------------------------------------------- | | `user_id` | The `String` user ID used by Honeybadger to aggregate user data across occurrences on the error page. | | `user_email` | Same as `user_id`, but for email addresses | ## Limits [Section titled “Limits”](#limits) Honeybadger uses the following limits to ensure the service operates smoothly for everyone: * Nested objects have a max depth of 20 * Context values have a max size of 64Kb When an error notification includes context data that exceed these limits, the context data will be truncated, and the notification will still be processed. # Customizing error grouping > Customize how errors are grouped in Elixir applications to better organize and prioritize error reports. Honeybadger groups similar exceptions together using rules which we’ve found to work the best in most cases. The default information we use to group errors is: 1. The file name, method name, and line number of the error’s location 2. The class name of the error 3. The component/controller name We use this information to construct a “fingerprint” of the exception. Exceptions with the same fingerprint are treated as the same error in Honeybadger. You can customize the grouping for each exception by changing the error class name, component, or stack trace—or by sending a custom fingerprint. See the [Error Monitoring Guide](https://docs.honeybadger.io/guides/errors/#error-grouping) for more information about how honeybadger groups similar exception together. You can customize the grouping for each exception in Elixir by sending a custom *fingerprint* when the exception is reported. To customize the fingerprint for all exceptions that are reported from your app, use the `fingerprint_adapter` configuration option in `config.ex`: ```elixir config :honeybadger, fingerprint_adapter: MyApp.CustomFingerprint ``` Then, implement the `Honeybadger.FingerprintAdapter` behaviour in your module: ```elixir defmodule MyApp.CustomFingerprint do @behaviour Honeybadger.FingerprintAdapter def parse(notice) do notice.notifier.language <> "-" <> notice.notifier.name end end ``` You can also customize the fingerprint for individual exceptions when calling `Honeybadger.notify`: ```elixir Honeybadger.notify(%RuntimeError{}, fingerprint: "culprit_id-123") ``` # Environments > Configure environment-specific error tracking settings for Elixir applications across development, staging, and production. Honeybadger groups errors by the environment they belong to. You don’t have to set an environment, but it can be useful if you’re running your app in different locations, such as “production” and “staging”. The best way to set the environment is to use [Elixir’s `config_env()` function](https://hexdocs.pm/elixir/main/Config.html#config_env/0) in your `config.exs` file: ```elixir config :honeybadger, environment_name: config_env() ``` You can also configure Honeybadger for each of your Mix environments—for example, by adding the following to each of your `config/#{env}.exs` files in Phoenix: config/dev.exs ```elixir config :honeybadger, environment_name: :dev # config/test.exs config :honeybadger, environment_name: :test # config/prod.exs config :honeybadger, environment_name: :prod ``` If `environment_name` is not set we will fall back to the value of `Mix.env()`. `Mix.env()` uses the atomized value of the `MIX_ENV` environment variable and defaults to `:prod` when the environment variable is not set. If you want to have an `environment_name` which is different from `Mix.env()` (`:dev`, for example), you should set `environment_name` in your `config.exs` as described above. This ensures that we can give you accurate environment information at compile time. ## Development environments [Section titled “Development environments”](#development-environments) Some environments should usually not report errors at all, such as when you are developing on your local machine or running your test suite (locally or in CI). The *honeybadger* package has an internal list of environment names which it considers development environments: ```plaintext dev test ``` Honeybadger **does not** report errors in these environments. To send data to all environments, you can set the `exclude_envs` configuration option to an empty list: ```elixir config :honeybadger, exclude_envs: [] ``` # Filtering sensitive data > Filter sensitive data from Elixir error reports to protect user privacy and comply with security requirements. You have complete control over the data that Honeybadger reports when an error occurs. Before data is sent to Honeybadger, it is passed through a filter to remove sensitive fields and do other processing on the data. The default configuration is equivalent to: ```elixir config :honeybadger, filter: Honeybadger.Filter.Default, filter_keys: [:password, :credit_card] ``` This will remove any entries in the `context`, `session`, `cgi_data` and `params` that match one of the filter keys. The filter is case insensitive and matches atoms or strings. If `Honeybadger.Filter.Default` does not suit your needs, you can implement your own filter. See the `Honeybadger.Filter.Mixin` module doc for details on implementing your own filter. ## Filtering arguments [Section titled “Filtering arguments”](#filtering-arguments) Honeybadger can show arguments in the stacktrace for `FunctionClauseError` exceptions. To enable argument reporting, set `filter_args` to `false`: ```elixir config :honeybadger, filter_args: false ``` # Reducing noise > Reduce error noise in Elixir applications by ignoring specific errors and filtering unwanted notifications. Sometimes there are errors that you would rather not send to Honeybadger because they are not actionable or are handled internally. By default Honeybadger will be notified when any error occurs. To override this configuration in order not to send out errors to Honeybadger, set `exclude_errors` option in `config/config.exs`. This can be done by passing a list of errors to be excluded: ```elixir config :honeybadger, exclude_errors: ["RuntimeError"] ``` or ```elixir config :honeybadger, exclude_errors: [RuntimeError] ``` Also you can implement the `Honeybadger.ExcludeErrors` behaviour function `exclude_error?/1`, which receives the full `Honeybadger.Notice` and returns a boolean signalling the error exclusion or not. ```elixir defmodule ExcludeFunClauseErrors do alias Honeybadger.ExcludeErrors @behaviour ExcludeErrors @impl ExcludeErrors def exclude_error?(notice) do notice.error.class == "FunctionClauseError" end end ``` ```elixir config :honeybadger, exclude_errors: ExcludeFunClauseErrors ``` # Reporting errors > Report errors from Elixir applications to Honeybadger with automatic notifications and custom error handling. Honeybadger reports uncaught errors automatically. In all other cases, use `Honeybadger.notify/1,2` to send errors to Honeybadger. Use the `Honeybadger.notify/2` function to send exception information to the [Exceptions API](/api/reporting-exceptions/). The first parameter is the exception and the second parameter is the context/metadata/fingerprint. ```elixir try do File.read! "this_file_really_should_exist_dang_it.txt" rescue exception -> Honeybadger.notify(exception, metadata: %{}, stacktrace: __STACKTRACE__, fingerprint: "") end ``` There is also a `Honeybadger.notify/1` which doesn’t require the second parameter. ```elixir Honeybadger.notify("Send this to Honeybadger") ``` # Tagging errors > Add tags to Elixir error reports to categorize and filter errors for better organization and analysis. Each error in Honeybadger has tags. Tags can be used to filter results when searching and can even apply to integrations so that only errors with a combination of certain tags trigger an email or a Slack message, for example. Tags can be used to create custom workflows, such as: * Find all errors tagged “badgers” and resolve them. * Tag critical errors as “critical” and configure PagerDuty to alert you only when a critical error happens. * If you have errors which aren’t actionable (but you still want to know about them), you could tag them with “low\_priority” and exclude those errors when automatically creating issues via the GitHub integration. * Tag all errors that happen in an area of your app with the name of the team that is responsible for them, then notify their Slack channel for only those errors. These are just examples: you can use tags however you want! While you can always add tags to existing errors through the Honeybadger UI, they are most useful when you add them programmatically as the exceptions happen. There are two ways to add tags to errors from your Elixir app: ## Tagging errors in global context [Section titled “Tagging errors in global context”](#tagging-errors-in-global-context) Every exception which is reported within the current context will have the tags “critical” and “badgers” added: ```elixir Honeybadger.context(tags: "critical, badgers") ``` ## Tagging errors in `Honeybadger.notify` [Section titled “Tagging errors in Honeybadger.notify”](#tagging-errors-in-honeybadgernotify) The tags will be added for just the current error being reported: ```elixir context = %{tags: "critical, badgers"} Honeybadger.notify(exception, metadata: context, stacktrace: __STACKTRACE__) ``` # Tracking deployments > Track deployments from Elixir applications to correlate errors with releases and identify problematic code changes. Honeybadger has an API to keep track of project deployments. Whenever you deploy, all errors for that environment will be resolved automatically. You can choose to enable or disable the auto-resolve feature from your Honeybadger project settings page. ## Deploying with GitHub Actions [Section titled “Deploying with GitHub Actions”](#deploying-with-github-actions) If your CI/CD pipeline is hosted with GitHub Actions, you can use the [Honeybadger Deploy Action](https://github.com/marketplace/actions/honeybadger-deploy-action) to notify our API about deployments. ## Deploying with `curl` [Section titled “Deploying with curl”](#deploying-with-curl) ```sh HONEYBADGER_ENV="production" \ HONEYBADGER_REVISION="$(git rev-parse HEAD)" \ HONEYBADGER_REPOSITORY="$(git config --get remote.origin.url)" \ HONEYBADGER_API_KEY="Your project API key" \ && curl -g "https://api.honeybadger.io/v1/deploys?deploy[environment]=$HONEYBADGER_ENV&deploy[local_username]=$USER&deploy[revision]=$HONEYBADGER_REVISION&deploy[repository]=$HONEYBADGER_REPOSITORY&api_key=$HONEYBADGER_API_KEY" ``` If you are using our EU stack, you should use `eu-api.honeybadger.io` instead of `api.honeybadger.io` for the domain name. # Insights overview > Query automatic Phoenix, Ecto, Oban, and Absinthe instrumentation alongside custom application events from Elixir in Honeybadger Insights. [Insights](/guides/insights/) lets you observe what your Elixir application does in production. Honeybadger records common Elixir activity automatically, including Phoenix requests, Ecto queries, LiveView lifecycle events, Oban jobs, Absinthe operations, and Finch and Tesla HTTP calls. From there, you can add context and custom events from your own code, then use [BadgerQL](/guides/insights/badgerql/) to ask questions across the whole event stream. Any field you send is queryable as soon as it arrives, with no schema to define ahead of time. ## Start with automatic instrumentation [Section titled “Start with automatic instrumentation”](#start-with-automatic-instrumentation) Set `insights_enabled: true` in your config and the package starts recording events as soon as your app boots. [Automatic instrumentation](/lib/elixir/insights/automatic-instrumentation/)Configure what the package captures. [Elixir event reference](/insights/event-types/elixir/)See every Elixir event type and field. ## Add a built-in dashboard [Section titled “Add a built-in dashboard”](#add-a-built-in-dashboard) Automatic events power built-in dashboards. [Oban](/guides/dashboards/oban/)Job counts by status, durations by worker, and slowest job runs [Phoenix](/guides/dashboards/phoenix/)Request stats, slowest controllers and Ecto queries, LiveView event performance ## Add application context [Section titled “Add application context”](#add-application-context) Context adds fields to the current process. Once set, every event emitted from that process carries them. Say the app is A/B testing a new checkout flow against the control. Each checkout request sets context like this: Set the variant on context ```elixir Honeybadger.event_context(%{ checkout_variant: checkout_variant }) ``` The `checkout_variant` field is now on every Ecto event for that request. You can group by it like any other field. Ecto work by checkout variant ```badgerql filter event_type::str == "MyApp.Repo.query" and isNotNull(checkout_variant::str) | stats count() as queries, avg(query_time::float) as avg_us by checkout_variant::str | sort queries desc ``` | queries | avg\_us | checkout\_variant | | ------- | ------- | ----------------- | | 26815 | 287 | new | | 11873 | 261 | control | (`MyApp.Repo.query` is the telemetry prefix from your Ecto repo configuration. Substitute your own.) The new variant ran more than twice as many queries with similar per-query time. Keep in mind that adding another A/B variant will extend any of the examples here without the need to change anything on the Honeybadger side. [Event context](/lib/elixir/insights/event-context/)Plug setup, process inheritance, and cross-process propagation. ## Record application events [Section titled “Record application events”](#record-application-events) Custom events record activity the framework cannot see at all. Phoenix knows a checkout request ran. Only your app knows whether the payment authorized: Send a custom payment event ```elixir Honeybadger.event("payment.authorized", %{ payment_provider: payment.provider, amount: checkout.total, currency: checkout.currency, authorization_id: payment.authorization_id }) ``` This query breaks down the amounts collected by variant and provider: Payments by variant and provider ```badgerql filter event_type::str == "payment.authorized" | stats count() as authorizations, sum(amount::float) as authorized_amount by checkout_variant::str, payment_provider::str | sort authorized_amount desc ``` | authorizations | authorized\_amount | checkout\_variant | payment\_provider | | -------------- | ------------------ | ----------------- | ----------------- | | 413 | 34108.00 | new | stripe | | 218 | 18722.00 | new | paypal | | 418 | 32167.00 | control | stripe | | 220 | 13639.00 | control | paypal | [Sending custom events](/lib/elixir/insights/sending-custom-events/)The full Honeybadger.event API. # Automatic instrumentation > Events the Honeybadger Elixir package captures automatically from Ecto, Phoenix, Oban, and more for Honeybadger Insights. Honeybadger Insights allows you to automatically track various events in your application. To enable Insights automatic instrumentation, add the following to your configuration: ```elixir config :honeybadger, insights_enabled: true ``` Honeybadger automatically instruments the following libraries when they are available: * **Ecto**: Database queries * **Plug/Phoenix**: HTTP requests * **LiveView**: Phoenix LiveView lifecycle events * **Oban**: Background job processing * **Absinthe**: GraphQL query execution * **Finch**: HTTP client requests, often used by other libraries like Req * **Tesla**: HTTP client requests The following libraries require additional setup (see [Instrumented libraries](#instrumented-libraries)): * **Ash**: Ash Framework actions and operations See the [Elixir event reference](/insights/event-types/elixir/) for every event the package emits, with field schemas and types. ## Instrumented libraries [Section titled “Instrumented libraries”](#instrumented-libraries) Each instrumented library has its own configuration options. You can customize the telemetry events that are captured, as well as the data that is sent to Honeybadger. *** ### Ecto [Section titled “Ecto”](#ecto) Captures database query telemetry events from Ecto repositories. #### Default configuration [Section titled “Default configuration”](#default-configuration) By default, this module listens for telemetry events from all configured Ecto repositories. It reads the `:ecto_repos` configuration to identify repositories and their telemetry prefixes: ```elixir config :honeybadger, ecto_repos: [MyApp.Repo] ``` #### Custom configuration [Section titled “Custom configuration”](#custom-configuration) You can customize this module’s behavior with the following configuration options: ```elixir config :honeybadger, insights_config: %{ ecto: %{ # Disable Ecto telemetry events disabled: false, # A list of strings or regex patterns of queries to exclude excluded_queries: [ ~r/^(begin|commit)( immediate)?( transaction)?$/i, ~r/SELECT pg_notify/, ~r/schema_migrations/ ], # Format & include the stacktrace with each query. You must also # update your repo config to enable: # # config :my_app, MyApp.Repo, # stacktrace: true # # Can be a boolean to enable for all or a list of sources to enable. include_stacktrace: true # Alternative source whitelist example: # include_stacktrace: ["source_a", "source_b"], # Format & include the query parameters with each query. Can be a # boolean to enable for all or a list of sources to enable. include_params: true # Alternative source whitelist example: # include_params:["source_a", "source_b"], # A list of table/source names to exclude excluded_sources: [ "schema_migrations", "oban_jobs", "oban_peers" ] } } ``` By default, transaction bookkeeping queries and schema migration checks are excluded, as well as queries to common background job tables. *** ### Plug/Phoenix [Section titled “Plug/Phoenix”](#plugphoenix) Captures telemetry events from HTTP requests processed by Plug and Phoenix. #### Default configuration [Section titled “Default configuration”](#default-configuration-1) By default, this module listens for the standard Phoenix endpoint telemetry event: * `phoenix.endpoint.stop` This is compatible with the default Phoenix configuration that adds telemetry via `Plug.Telemetry`: plug Plug.Telemetry, event\_prefix: \[:my, :prefix] #### Custom configuration [Section titled “Custom configuration”](#custom-configuration-1) You can customize the telemetry events to listen for by updating the insights\_config: ```elixir config :honeybadger, insights_config: %{ plug: %{ # Disable Plug/Phoenix telemetry events disabled: false, telemetry_events: [[:my, :prefix, :stop]] } } ``` *** ### LiveView [Section titled “LiveView”](#liveview) Captures telemetry events from Phoenix LiveView. #### Default configuration [Section titled “Default configuration”](#default-configuration-2) By default, this module listens for the following LiveView telemetry events: * `phoenix.live_view.mount.stop` * `phoenix.live_view.handle_params.stop` * `phoenix.live_view.handle_event.stop` * `phoenix.live_component.update.stop` * `phoenix.live_component.handle_event.stop` #### Custom configuration [Section titled “Custom configuration”](#custom-configuration-2) You can customize the telemetry events to listen for by updating the insights\_config: ```elixir config :honeybadger, insights_config: %{ live_view: %{ # Disable LiveView telemetry events disabled: false, telemetry_events: [ [:phoenix, :live_view, :mount, :stop], [:phoenix, :live_component, :handle_event, :stop], [:phoenix, :live_component, :update, :stop] [:phoenix, :live_view, :handle_event, :stop], [:phoenix, :live_view, :handle_params, :stop], [:phoenix, :live_view, :update, :stop] ] } } ``` *** ### Oban [Section titled “Oban”](#oban) Captures telemetry events from Oban job processing. #### Default configuration [Section titled “Default configuration”](#default-configuration-3) By default, this module listens for the following Oban telemetry events: * `oban.job.stop` * `oban.job.exception` #### Custom configuration [Section titled “Custom configuration”](#custom-configuration-3) You can customize the telemetry events to listen for by updating the insights\_config: ```elixir config :honeybadger, insights_config: %{ oban: %{ # Disable Oban telemetry events disabled: false, telemetry_events: [ [:oban, :job, :stop], [:oban, :job, :exception], [:oban, :engine, :start] ] } } ``` #### Job event context [Section titled “Job event context”](#job-event-context) We attempt to automatically inject `request_id` and any other event context into events emitted from a Job. The method for inheriting event context might not work in all cases, so you can explicitly add event context to a job by using the `add_event_context/1` function: ```elixir MyApp.Worker.new() |> Honeybadger.Insights.Oban.add_event_context() |> Oban.insert() ``` Ensure that the event context is available in the caller’s process dictionary before inserting into the job. *** ### Absinthe [Section titled “Absinthe”](#absinthe) Captures telemetry events from GraphQL operations executed via Absinthe. #### Default configuration [Section titled “Default configuration”](#default-configuration-4) By default, this module listens for the following Absinthe telemetry events: * `absinthe.execute.operation.stop` * `absinthe.execute.operation.exception` #### Custom configuration [Section titled “Custom configuration”](#custom-configuration-4) You can customize the telemetry events to listen for by updating the insights\_config: ```elixir config :honeybadger, insights_config: %{ absinthe: %{ # Disable Absinthe telemetry events disabled: false, telemetry_events: [ [:absinthe, :execute, :operation, :stop], [:absinthe, :execute, :operation, :exception], [:absinthe, :resolve, :field, :stop] ] } } ``` Note that adding field-level events like “absinthe.resolve.field.stop” can significantly increase the number of telemetry events generated. *** ### Finch [Section titled “Finch”](#finch) Captures telemetry events from HTTP requests made using Finch. #### Default configuration [Section titled “Default configuration”](#default-configuration-5) By default, this module listens for the standard Finch request telemetry event: * `finch.request.stop` #### Custom configuration [Section titled “Custom configuration”](#custom-configuration-5) You can customize the telemetry events to listen for by updating the insights\_config: ```elixir config :honeybadger, insights_config: %{ finch: %{ # Disable Finch telemetry events disabled: false, telemetry_events: ["finch.request.stop", "finch.request.exception"], # Include full URLs in telemetry events (default: false - only hostname is included) full_url: false } } ``` By default, only the hostname from URLs is captured for security and privacy reasons. If you need to capture the full URL including paths (but not query parameters), you can enable the `full_url` option. *** ### Tesla [Section titled “Tesla”](#tesla) Captures telemetry events from HTTP requests made using Tesla. #### Default configuration [Section titled “Default configuration”](#default-configuration-6) By default, this module listens for the standard Tesla request telemetry events: * `tesla.request.stop` * `tesla.request.exception` #### Custom configuration [Section titled “Custom configuration”](#custom-configuration-6) This module can be configured in the application config: ```elixir config :honeybadger, insights_config: %{ tesla: %{ # Disable Tesla telemetry events disabled: false, # Include full URLs in telemetry events (default: false - only hostname is included) full_url: false, # Custom telemetry event patterns to listen for (optional) telemetry_events: [ [:tesla, :request, :stop], [:tesla, :request, :exception] ] } } ``` *** ### Ash [Section titled “Ash”](#ash) Captures operations from the [Ash Framework](https://ash-hq.org/) using the `Ash.Tracer` behaviour. Unlike the other integrations which use telemetry events, the Ash integration implements a tracer. You need to add `Honeybadger.Insights.Ash` as a tracer in your Ash domain or resources. #### Setup [Section titled “Setup”](#setup) Add the tracer to your Ash domain: ```elixir use Ash.Domain, tracers: [Honeybadger.Insights.Ash] ``` Or per-resource: ```elixir use Ash.Resource, domain: YourDomain, tracers: [Honeybadger.Insights.Ash] ``` #### Default configuration [Section titled “Default configuration”](#default-configuration-7) By default, this module traces `:custom` and `:action` span types. #### Custom configuration [Section titled “Custom configuration”](#custom-configuration-7) You can customize which span types are traced via insights\_config: ```elixir config :honeybadger, insights_config: %{ ash: %{ trace_types: [:custom, :action, :query] } } ``` #### AshOban event context [Section titled “AshOban event context”](#ashoban-event-context) If you use [AshOban](https://hexdocs.pm/ash_oban) to run Ash actions as background jobs, you can pass the current Honeybadger event context to the job using the `extra_args` option in your trigger: ```elixir oban do triggers do trigger :my_trigger do action :my_action extra_args(&Honeybadger.Insights.Ash.AshOban.capture_event_context/1) end end end ``` The Honeybadger Oban integration will automatically restore the event context when the job runs, preserving request IDs and other context across async boundaries. ## Sending your own events [Section titled “Sending your own events”](#sending-your-own-events) Automatic instrumentation covers the libraries the package knows about. To send your own application events, see [Sending custom events](/lib/elixir/insights/sending-custom-events/). ## Sending logs from your infrastructure [Section titled “Sending logs from your infrastructure”](#sending-logs-from-your-infrastructure) Honeybadger isn’t just for errors and application data! You can use our [syslog](/guides/insights/integrations/systemd/), [Vector](/guides/insights/integrations/log-files/), or [PaaS integrations](/guides/insights/#adding-data-from-other-sources) to send additional data from your infrastructure to [Honeybadger Insights](/guides/insights/), where you can query, visualize, and analyze all of your production data in one place. # Event context > Add contextual data to Insights events in Elixir to improve debugging and understanding of application behavior. You can add custom metadata to the events sent to Honeybadger Insights by using the `event_context/1` function. This metadata will be included in each event call within the same process. Note: This will add the metadata to all events sent, so be careful not to include too much data. Try to keep it to simple key/value pairs. For example, you can add user ID information to all events (via plug): ```elixir defmodule MyAppWeb.Plug.UserContext do import Plug.Conn def init(opts), do: opts def call(conn, _opts) do user = get_session(conn, :user) Honeybadger.event_context(%{user_id: user.id}) conn end end ``` Event context is not automatically propagated to other processes. If you want to add context to events in a different process, you can use the `Honeybadger.event_context/0` function to get the current context and pass it to the `Honeybadger.event/1` function: ```elixir defmodule MyApp.MyGenServer do use GenServer def set(value) do GenServer.cast(__MODULE__, {:set, value, Honeybadger.event_context()}) end def handle_cast({:set, value, hb_context}, _state) do Honeybadger.event_context(hb_context) Honeybadger.event("set_value", %{value: value}) {:noreply, value} end end ``` ## Inheriting context [Section titled “Inheriting context”](#inheriting-context) If you know the parent process is alive and part of the process tree, you can use `Honeybadger.inherit_event_context/0` to inherit the context from the parent process. This method works best if you are running OTP 25+. ```elixir Task.async(fn -> Honeybadger.inherit_event_context() # Do some work here Honeybadger.event("work", %{did: "some_work"}) end) ``` Scenarios when inheriting context is useful include: * Direct process spawning (`spawn`, `spawn_link`) * `Task.async/1`, `Task.await/1`, etc. * Other scenarios where direct parent-child relationships are maintained When explicit passing is needed: * GenServer * Supervised processes * Processes started through other OTP abstractions # Filtering events > Filter Insights events in Elixir applications to reduce noise and focus on relevant data. You can filter out or customize events sent to Honeybadger Insights by using the `Honeybadger.EventFilter.Mixin` module. You can customize both the event built from telemetry data (`filter_telemetry_event/3`) and the event right before it is sent to Honeybadger (`filter_event/1`): ```elixir defmodule MyApp.MyFilter do use Honeybadger.EventFilter.Mixin # Drop analytics events by returning nil def filter_event(%{event_type: "analytics"} = _event), do: nil # Anonymize user data in login events def filter_event(%{event_type: "login"} = event) do event |> update_in([:data, :user_email], fn _ -> "[REDACTED]" end) |> put_in([:metadata, :filtered], true) end # Remove query field for a specific repo def filter_event(%{event_type: "my_app.repo.query"} = event) do Map.delete(event, :query) |> put_in([:metadata, :filtered], true) end # For telemetry events, you can customize while still applying default filtering def filter_telemetry_event(data, raw, event) do # First apply default filtering filtered_data = apply_default_telemetry_filtering(data) # Then apply custom logic case event do [:auth, :login, :start] -> Map.put(filtered_data, :security_filtered, true) _ -> filtered_data end end # Keep all other events as they are def filter_event(event), do: event end ``` Then configure the filter in your application’s configuration: ```elixir config :honeybadger, event_filter: MyApp.EventFilter ``` # Sampling events > Configure event sampling in Elixir to control Insights data volume while maintaining statistical accuracy. You can enable event sampling to reduce the number of events sent to Honeybadger. This is especially useful if you are hitting your daily event quota limit: ```elixir config :honeybadger, # Sample 50% of events insights_sample_rate: 50 ``` The `insights_sample_rate` option accepts a whole percentage value between 0 and 100, where 0 means no events will be sent and 100 means all events will be sent. The default is no sampling (100%). Events are sampled by hashing the `request_id` if available in the event payload, otherwise random sampling is used. This deterministic approach ensures that related events from the same request are consistently sampled together. ## Per-event sampling [Section titled “Per-event sampling”](#per-event-sampling) The sample rate is applied to all events sent to Honeybadger Insights, including automatic instrumentation events. You can also set the sample rate per event by adding the `sample_rate` key to the event metadata map: ```elixir Honeybadger.event("user_created", %{ user_id: user.id, _hb: %{sample_rate: 100} }) ``` The event sample rate can also be set within the `event_context/1` function. This can be handy if you want to set an overall sample rate for a process or ensure that specific instrumented events get sent: ```elixir # Set a higher sampling rate for this entire process Honeybadger.event_context(%{_hb: %{sample_rate: 100}}) # Now all events from this process, including automatic instrumentation, # will use the 100% sample rate Ecto.Repo.insert!(%MyApp.User{}) # This instrumented event will be sent ``` Remember that context is process-bound and applies to all events sent from the same process after the `event_context/1` call, until it’s changed or the process terminates. When setting sample rates below the global setting, be aware that this affects how events with the same `request_id` are sampled. Since sampling is deterministic based on the `request_id` hash, all events sharing the same `request_id` will either all be sampled or all be skipped together. This ensures consistency across related events. With that in mind, it’s recommended to default to the global sample rate and use per-event sampling for specific cases where you want to ensure events are sent regardless of the global setting, or you are setting the sample rate in the context where all events with the same `request_id` will also share the same sampling rate. # Sending custom events > Send custom events from Elixir applications to Honeybadger Insights for monitoring and analysis. You can send your own application events to [Honeybadger Insights](/guides/insights/). (For the events the package captures on its own, see [Automatic instrumentation](/lib/elixir/insights/automatic-instrumentation/).) Use the `Honeybadger.event/1` function to send event data to the events API. A `ts` field with the current timestamp will be added to the data if it isn’t provided. You can also use `Honeybadger.event/2`, which accepts a string as the first parameter and adds that value to the `event_type` field in the map before being sent to the API. ```elixir Honeybadger.event(%{ event_type: "user_created", user: user.id }) Honeybadger.event("project_deleted", %{ project: project.name }) ``` # Elixir integration guide > Install and configure Honeybadger error tracking and application monitoring for Elixir applications outside of Phoenix and Plug frameworks. **Typical installation time:** 5 minutes Hi there! You’ve found Honeybadger’s guide to **Elixir error tracking and performance monitoring**. If you use *Phoenix* or *Plug*, go check out the [Phoenix Integration Guide](../phoenix/). If not, then read on. This guide will teach you how to install the `honeybadger` Hex package in your Elixir project and use it to manually report errors to Honeybadger. You can also enable some [automatic logging and performance insights](/lib/elixir/insights/automatic-instrumentation/) (via telemetry) by setting the `insights_enabled` option to `true` in your configuration. On this page: ## Installing the package [Section titled “Installing the package”](#installing-the-package) Add the Honeybadger package to `deps/0` in your application’s `mix.exs`: ```elixir defp deps do [{:honeybadger, "~> 0.24"}] end ``` Then run: ```sh mix do deps.get, deps.compile ``` Finally, update your app’s `config.exs` file to include the Honeybadger configuration: ```elixir config :honeybadger, app: :my_app, api_key: "PROJECT_API_KEY", environment_name: config_env(), insights_enabled: true # Enable logging and performance insights ``` See the [Configuration reference](/lib/elixir/reference/configuration/) for additional info. ## Testing your installation [Section titled “Testing your installation”](#testing-your-installation) To test your installation, fire up `iex -S mix`, then run: ```elixir Honeybadger.notify("Hello Elixir!") ``` If Honeybadger is configured correctly, you should see a new error report in your Honeybadger project dashboard. ## Configuring Elixir’s logger [Section titled “Configuring Elixir’s logger”](#configuring-elixirs-logger) When configured, Honeybadger will report errors for any [SASL](http://www.erlang.org/doc/apps/sasl/error_logging.html)-compliant processes when they crash. Just set the `use_logger` option to `true` in your application’s `config.exs` and you’re good to go: ```elixir config :honeybadger, use_logger: true ``` ## Manually reporting errors [Section titled “Manually reporting errors”](#manually-reporting-errors) You can use the `Honeybadger.notify/2` function to manually report rescued exceptions: ```elixir try do # Buggy code goes here rescue exception -> Honeybadger.notify(exception, stacktrace: __STACKTRACE__) end ``` You can also pass a string message to the `notify` function (the second argument is optional): ```elixir Honeybadger.notify("Sign in failed", metadata: %{ user_id: current_user.id }) ``` See [Reporting Errors](/lib/elixir/errors/reporting-errors/) for more information. ## Reporting custom events [Section titled “Reporting custom events”](#reporting-custom-events) Use the `Honeybadger.event/1` and `Honeybadger.event/2` functions to send events to [Honeybadger Insights](/guides/insights/) for logging and performance monitoring: ```elixir Honeybadger.event(%{ event_type: "user_created", user: user.id }) # Honeybadger.event/2 is a shorthand that automatically adds the event_type # property to the event: Honeybadger.event("project_deleted", %{ project: project.name }) ``` See [Sending custom events](/lib/elixir/insights/sending-custom-events/) for more details. ## Sending logs from your infrastructure [Section titled “Sending logs from your infrastructure”](#sending-logs-from-your-infrastructure) Honeybadger isn’t just for errors and application data! You can use our [syslog](/guides/insights/integrations/systemd/), [Vector](/guides/insights/integrations/log-files/), or [PaaS integrations](/guides/insights/#adding-data-from-other-sources) to send additional data from your infrastructure to [Honeybadger Insights](/guides/insights/), where you can query, visualize, and analyze all of your production data in one place. ## Version requirements [Section titled “Version requirements”](#version-requirements) See [Supported Versions](/lib/elixir/reference/supported-versions/). # Phoenix and Plug integration guide > Install and configure Honeybadger application monitoring for Phoenix and Plug applications with automatic error reporting. **Typical installation time:** 5 minutes Hi there! You’ve found Honeybadger’s guide to **Phoenix error tracking and performance monitoring**. Once installed, Honeybadger will automatically report errors and performance insights from your Phoenix application. ## Installing the package [Section titled “Installing the package”](#installing-the-package) Add the Honeybadger package to `deps/0` in your application’s `mix.exs`: ```elixir defp deps do [{:honeybadger, "~> 0.24"}] end ``` Then run: ```sh mix do deps.get, deps.compile ``` Finally, update your app’s `config.exs` file to include the Honeybadger configuration: ```elixir config :honeybadger, app: :my_app, api_key: "PROJECT_API_KEY", environment_name: config_env(), insights_enabled: true # Enable logging and performance insights ``` See the [Configuration reference](/lib/elixir/reference/configuration/) for additional info. ## Testing your installation [Section titled “Testing your installation”](#testing-your-installation) To test your installation, fire up `iex -S mix`, then run: ```elixir Honeybadger.notify("Hello Elixir!") ``` If Honeybadger is configured correctly, you should see a new error report in your Honeybadger project dashboard. After you’ve tested your Honeybadger installation, you may want to configure one or more of the following integrations to automatically report errors. ## Enabling automatic error reporting [Section titled “Enabling automatic error reporting”](#enabling-automatic-error-reporting) The Honeybadger package can be used as a Plug alongside your Phoenix applications, as a logger backend, and/or as a standalone client for sprinkling in exception notifications where they are needed. The Honeybadger Plug adds a [Plug.ErrorHandler](https://github.com/elixir-lang/plug/blob/master/lib/plug/error_handler.ex) to your pipeline. Simply `use` the `Honeybadger.Plug` module inside of a Plug or Phoenix.Router and any crashes will be automatically reported to Honeybadger. It’s best to `use Honeybadger.Plug` **after the Router plugs** so that exceptions due to non-matching routes are not reported to Honeybadger. ### Phoenix example [Section titled “Phoenix example”](#phoenix-example) ```elixir defmodule MyappWeb.Router do use MyappWeb, :router use Honeybadger.Plug pipeline :browser do [...] end end ``` ### Plug example [Section titled “Plug example”](#plug-example) ```elixir defmodule MyPlugApp do use Plug.Router use Honeybadger.Plug [... the rest of your plug ...] end ``` ### Configuring Elixir’s logger [Section titled “Configuring Elixir’s logger”](#configuring-elixirs-logger) When configured, Honeybadger will report errors for any [SASL](http://www.erlang.org/doc/apps/sasl/error_logging.html)-compliant processes when they crash. Just set the `use_logger` option to `true` in your application’s `config.exs` and you’re good to go: ```elixir config :honeybadger, use_logger: true ``` ## Manually reporting errors [Section titled “Manually reporting errors”](#manually-reporting-errors) You can use the `Honeybadger.notify/2` function to manually report rescued exceptions: ```elixir try do # Buggy code goes here rescue exception -> Honeybadger.notify(exception, stacktrace: __STACKTRACE__) end ``` You can also pass a string message to the `notify` function (the second argument is optional): ```elixir Honeybadger.notify("Sign in failed", metadata: %{ user_id: current_user.id }) ``` See [Reporting Errors](/lib/elixir/errors/reporting-errors/) for more information. ## Reporting custom events [Section titled “Reporting custom events”](#reporting-custom-events) Use the `Honeybadger.event/1` and `Honeybadger.event/2` functions to send events to [Honeybadger Insights](/guides/insights/) for logging and performance monitoring: ```elixir Honeybadger.event(%{ event_type: "user_created", user: user.id }) # Honeybadger.event/2 is a shorthand that automatically adds the event_type # property to the event: Honeybadger.event("project_deleted", %{ project: project.name }) ``` See [Sending custom events](/lib/elixir/insights/sending-custom-events/) for more details. ## Sending logs from your infrastructure [Section titled “Sending logs from your infrastructure”](#sending-logs-from-your-infrastructure) Honeybadger isn’t just for errors and application data! You can use our [syslog](/guides/insights/integrations/systemd/), [Vector](/guides/insights/integrations/log-files/), or [PaaS integrations](/guides/insights/#adding-data-from-other-sources) to send additional data from your infrastructure to [Honeybadger Insights](/guides/insights/), where you can query, visualize, and analyze all of your production data in one place. ## Version requirements [Section titled “Version requirements”](#version-requirements) See [Supported Versions](/lib/elixir/reference/supported-versions/). # Configuration > Complete configuration reference for Honeybadger's Elixir library with all available options and settings. You can set configuration options in `config.exs`. It looks like this: ```elixir config :honeybadger, api_key: "PROJECT_API_KEY", environment_name: :prod ``` If you’d rather read, eg., `environment_name` from the OS environment, you can do like this: ```elixir config :honeybadger, environment_name: {:system, "HONEYBADGER_ENV"}, revision: {:system, "HEROKU_SLUG_COMMIT"} ``` *NOTE: This works only for the string options, and `environment_name`.* Here are all of the options you can pass in the keyword list: | Name | Description | Default | | -------------------------- | -------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | | `app` | Name of your app’s OTP Application as an atom | `nil` | | `api_key` | Your application’s Honeybadger API key | `System.get_env("HONEYBADGER_API_KEY")` | | `environment_name` | (required) The name of the environment your app is running in. | `:prod` | | `exclude_errors` | Filters out errors from being sent to Honeybadger | `[]` | | `exclude_envs` | Environments that you want to disable Honeybadger notifications | `[:dev, :test]` | | `hostname` | Hostname of the system your application is running on | `:inet.gethostname` | | `origin` | URL for the Honeybadger API | `"https://api.honeybadger.io"` | | `project_root` | Directory root for where your application is running | `System.cwd/0` | | `revision` | The project’s git revision | `nil` | | `filter` | Module implementing `Honeybadger.Filter` to filter data before sending to Honeybadger.io | `Honeybadger.Filter.Default` | | `filter_keys` | A list of keywords (atoms) to filter. Only valid if `filter` is `Honeybadger.Filter.Default` | `[:password, :credit_card, :__changed__, :flash, :_csrf_token]` | | `filter_args` | If true, will remove function arguments in backtraces | `true` | | `filter_disable_url` | If true, will remove the request url | `false` | | `filter_disable_session` | If true, will remove the request session | `false` | | `filter_disable_params` | If true, will remove the request params | `false` | | `filter_disable_assigns` | If true, will remove the live\_view event assigns | `false` | | `fingerprint_adapter` | Implementation of FingerprintAdapter behaviour | | | `notice_filter` | Module implementing `Honeybadger.NoticeFilter`. If `nil`, no filtering is done. | `Honeybadger.NoticeFilter.Default` | | `sasl_logging_only` | If true, will notifiy for SASL errors but not Logger calls | `true` | | `use_logger` | Enable the Honeybadger Logger for handling errors outside of web requests | `true` | | `ignored_domains` | Add domains to ignore Error events in `Honeybadger.Logger`. | `[:cowboy]` | | `breadcrumbs_enabled` | Enable breadcrumb event tracking | `false` | | `ecto_repos` | Modules with implemented Ecto.Repo behaviour for tracking SQL breadcrumb events | `[]` | | `event_filter` | Module implementing `Honeybadger.EventFilter`. If `nil`, no filtering is done. | `Honeybadger.EventFilter.Default` | | `insights_enabled` | Enable sending automatic events to Honeybadger Insights | `false` | | `insights_config` | Specific library Configuration for Honeybadger Insights. | `%{}` | | `http_adapter` | Module implementing `Honeybadger.HttpAdapter` to send data to Honeybadger.io | Any available adapter (`Req`, `hackney`) | | `events_worker_enabled` | Enable sending events in a separate process | `true` | | `events_max_batch_retries` | Maximum number of retries for sending events | `3` | | `events_batch_size` | Maximum number of events to send in a single batch | `1000` | | `events_max_queue_size` | Maximum number of events to queue before dropping | `10000` | | `events_timeout` | Timeout in milliseconds for sending events | `5000` | | `events_throttle_wait` | Time in milliseconds to wait before retrying a failed batch | `60000` | ## HTTP adapters [Section titled “HTTP adapters”](#http-adapters) The HTTP client used to send data to Honeybadger can be customized. We will use either `Req` or `hackney` (in that order) by default if they are loaded. If you want to use a different HTTP client, you can set the `http_adapter` configuration option to any of our pre-built adapter modules. ```elixir config :honeybadger, # Without options http_adapter: Honeybadger.HTTPAdapter.Hackney # With options http_adapter: {Honeybadger.HTTPAdapter.Hackney, [...]} ``` You can also implement your own HTTP adapter to send data to Honeybadger. The adapter must implement the `Honeybadger.HttpAdapter` behaviour. # Supported Versions > View supported Elixir and Phoenix versions for Honeybadger's error tracking and application monitoring library. The support tables below are for the latest version of the Honeybadger package, which aims to support all maintained (non-EOL) versions of Elixir and supported frameworks. If you’re using an older version of Elixir or your framework, you may need to install an older version of the package. | Library | Supported Version | Notes | | ------- | ----------------- | ------------------------------------------------------------------------------------------------- | | Erlang | >= 26.0 | | | Elixir | >= 1.16 | | | Plug | >= 1.10 | | | Phoenix | >= 1.0 | This is an optional dependency and the version requirement applies only if you are using Phoenix. | # Frequently asked questions > Find answers to frequently asked questions about Honeybadger's Elixir library for error tracking and application monitoring. ## Why aren’t my errors being reported? [Section titled “Why aren’t my errors being reported?”](#why-arent-my-errors-being-reported) The most common reason for errors not being reported is that the app is in a development environment. See the [Environments](/lib/elixir/errors/environments/#development-environments) chapter in the **Error Tracking** guide for more information. The second most common reason is that the error being reported is covered by the [exclude\_errors list](/lib/elixir/errors/reducing-noise/). If neither of these is the issue, check out the [Troubleshooting guide](/lib/elixir/support/troubleshooting/#all-errors-are-not-reported). ## Why aren’t I getting notifications? [Section titled “Why aren’t I getting notifications?”](#why-arent-i-getting-notifications) By default we only send notifications the first time an exception happens, and when it re-occurs after being marked resolved. If an exception happens 100 times, but was never resolved you’ll only get 1 email about it. # Troubleshooting > Troubleshoot common issues with Honeybadger's Elixir error tracking and application monitoring library and resolve integration problems. Common issues/workarounds for [`honeybadger-elixir`](https://github.com/honeybadger-io/honeybadger-elixir) are documented here. If you don’t find a solution to your problem here or in our [support documentation](/lib/elixir/#getting-support), email and we’ll assist you! ## Before you start troubleshooting [Section titled “Before you start troubleshooting”](#before-you-start-troubleshooting) 1. Make sure you are on the latest version of [honeybadger-elixir](https://hexdocs.pm/honeybadger/). ### All errors are not reported [Section titled “All errors are not reported”](#all-errors-are-not-reported) If *no* errors are reported (even [manually via `Honeybadger.notify`](/lib/elixir/errors/reporting-errors/)): 1. [Is the `api_key` config option configured?](/lib/elixir/reference/configuration/) 2. [Are you in an excluded environment configured by `exclude_envs`?](/lib/elixir/errors/environments/#development-environments) ### Some errors are not reported [Section titled “Some errors are not reported”](#some-errors-are-not-reported) 1. [Is the error ignored via config?](/lib/elixir/errors/reducing-noise/)