Skip to content

CityBaseInc/airbrake_client

Repository files navigation

Airbrake Client

Capture exceptions and send them to Airbrake or to your Errbit installation.

This library was originally forked from the airbrake Hex package. Development and support for that library seems to have lapsed, but we (the devs at CityBase) had changes and updates we wanted to make. So we decided to publish our own fork of the library.

Installation

Add airbrake_client to your dependencies:

defp deps do
  [
    {:airbrake_client, "~> 2.1"}
  ]
end

Configuration

config :airbrake_client,
  api_key: System.get_env("AIRBRAKE_API_KEY"),
  project_id: System.get_env("AIRBRAKE_PROJECT_ID"),
  context_environment: System.get_env("KUBERNETES_CLUSTER"),
  filter_parameters: ["password"],
  filter_headers: ["authorization"],
  session: :include_logger_metadata,
  json_encoder: Jason,
  production_aliases: ["prod"],
  host: "https://api.airbrake.io"

config :logger,
  backends: [{Airbrake.LoggerBackend, :error}, :console]

Split this config across your config/*.exs files (especially the runtime setting in config/runtime.exs).

Required configuration arguments:

  • :api_key - (binary) the token needed to access the Airbrake API. You can find it in User Settings.
  • :project_id - (integer) the id of your project at Airbrake.

Optional configuration arguments:

  • :context_environment - (binary or function returning binary) the deployment environment; used to set notice.context.environment. See the "Setting the environment in the context" section below.
    • This was formerly :environment, and this can still be used.
  • :filter_parameters - (list of strings) filters parameters that may map to sensitive data such as passwords and tokens.
  • :filter_headers - (list of strings) filters HTTP headers.
  • :host - (string) the URL of the HTTP host; defaults to https://api.airbrake.io.
  • :json_encoder - (module) payload sent to Airbrake is JSON encoded by calling module.encode!/1.
  • :ignore - (MapSet of binary or function returning boolean or :all) ignore some or all exceptions. See examples below.
  • :options - (keyword list or function returning keyword list) values that are included in all reports to Airbrake.io. See examples below.
  • :production_aliases - (list of strings) a list of "production" aliases. See the "Setting the environment in the context" section below.
  • :session - can be set to :include_logger_metadata to include Logger metadata in the session field of the report; omit this option if you do not want Logger metadata. See below for more information.

See the "Create notice v3" section in the Airbrake API docs to understand some of these options better.

Setting the environment in the context

The value for notice.context.environment when creating a notice can be set with the :context_environment config.

Often it is easiest to configure :context_environment with some environment variable. However, to get production notifications, the environment must be set to "production" (case independent). Maybe your environment variable returns the value "prod". Set :production_aliases to a list of strings that should be converted into "production". The config example above will turn "prod" into "production".

Logger metadata in the session

If you set the :session config to :include_logger_metadata, the Logger metadata from the process that invokes Airbrake.report/2 will be the initial session data for the session field. The values passed as :session in the options parameter of Airbrake.report/2 are added to the session value, overwriting any Logger metadata values.

If you do not set the :session config, only the :session value passed as the options to Airbrake.report/2 will be used for the session field in the report.

If the session turns out to be empty (for whatever reason), it is instead set to nil (and should not show up in the report).

Ignoring some exceptions

To ignore some exceptions use the :ignore config key. The value can be a MapSet:

config :airbrake_client,
  ignore: MapSet.new(["Custom.Error"])

The value can also be a two-argument function:

config :airbrake_client,
  ignore: fn type, message ->
    type == "Custom.Error" && String.contains?(message, "silent error")
  end

Or the value can be the atom :all to ignore all errors (and effectively turning off all reporting):

config :airbrake_client,
  ignore: :all

Shared options for reporting data to Airbrake

If you have data that should always be reported, they can be included in the config with the :options key. Its value should be a keyword list with any of these keys: :context, :params, :session, and :env.

config :airbrake_client,
  options: [env: %{"SOME_ENVIRONMENT_VARIABLE" => "environment variable"}]

Alternatively, you can specify a function (as a tuple) which returns a keyword list (with the same keys):

config :airbrake_client,
  options: {Web, :airbrake_options, 1}

The function takes a keyword list as its only parameter; the function arity is always 1.

Usage

Phoenix app

defmodule YourApp.Router do
  use Phoenix.Router
  use Airbrake.Plug # <- put this line to your router.ex

  # ...
end
  def channel do
    quote do
      use Phoenix.Channel
      use Airbrake.Channel # <- put this line to your web.ex
      # ...

Report an exception

try do
  String.upcase(nil)
rescue
  exception -> Airbrake.report(exception)
end

GenServer

Use Airbrake.GenServer instead of GenServer:

defmodule MyServer do
  use Airbrake.GenServer
  # ...
end

Any Elixir process

By pid:

Airbrake.monitor(pid)

By name:

Airbrake.monitor(Registered.Process.Name)

Integration Apps

The Elixir apps defined in integration_test_apps are used for testing different dependency scenarios. If you make changes to the way jason or poison is used this library, you should consider adding tests to those apps.

Migrating from airbrake

If you are switching from the original airbrake library:

  1. Replace the :airbrake dependency with the :airbrake_client dependency above.
    • You may want to start with version ~> 0.8.0 for maximum backwards compatibility.
  2. Remove the airbrake dependency in your lockfile.
    • Command: mix deps.unlock --unused
    • If the dependency remains in the lockfile, check all of your apps and all of your dependencies.
  3. Update your config/*.exs files to configure :airbrake_client instead of :airbrake.
    • A search-and-replace-in-project on config :airbrake can work really well.
    • When you run your project(even running the tests), you should get a complaint if you're still configuring :airbrake.