{"id":20481154,"url":"https://github.com/airbrake/airbrake-ruby","last_synced_at":"2025-05-15T01:08:47.054Z","repository":{"id":40336234,"uuid":"47778822","full_name":"airbrake/airbrake-ruby","owner":"airbrake","description":"A plain Ruby Airbrake notifier","archived":false,"fork":false,"pushed_at":"2024-12-19T01:04:23.000Z","size":1556,"stargazers_count":81,"open_issues_count":9,"forks_count":69,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-04-15T00:46:12.987Z","etag":null,"topics":["airbrake","apm","crash-reporting","error-monitoring","performance-monitoring","ruby"],"latest_commit_sha":null,"homepage":"https://airbrake.io","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/airbrake.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-12-10T18:05:25.000Z","updated_at":"2024-10-31T00:30:18.000Z","dependencies_parsed_at":"2024-06-18T13:49:27.583Z","dependency_job_id":"8e64a928-b2ae-473d-bfcc-57f1e4d787a4","html_url":"https://github.com/airbrake/airbrake-ruby","commit_stats":{"total_commits":775,"total_committers":28,"mean_commits":"27.678571428571427","dds":0.05161290322580647,"last_synced_commit":"c08aa500237eb5f04578eabf7a7ebf4e2240704e"},"previous_names":[],"tags_count":128,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/airbrake%2Fairbrake-ruby","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/airbrake%2Fairbrake-ruby/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/airbrake%2Fairbrake-ruby/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/airbrake%2Fairbrake-ruby/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/airbrake","download_url":"https://codeload.github.com/airbrake/airbrake-ruby/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254254042,"owners_count":22039792,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["airbrake","apm","crash-reporting","error-monitoring","performance-monitoring","ruby"],"created_at":"2024-11-15T16:07:00.370Z","updated_at":"2025-05-15T01:08:42.046Z","avatar_url":"https://github.com/airbrake.png","language":"Ruby","readme":"# Airbrake Ruby\n\n![Build Status](https://github.com/airbrake/airbrake-ruby/workflows/airbrake-ruby/badge.svg)\n[![Code Climate](https://codeclimate.com/github/airbrake/airbrake-ruby.svg)](https://codeclimate.com/github/airbrake/airbrake-ruby)\n[![Gem Version](https://badge.fury.io/rb/airbrake-ruby.svg)](http://badge.fury.io/rb/airbrake-ruby)\n[![Documentation Status](http://inch-ci.org/github/airbrake/airbrake-ruby.svg?branch=master)](http://inch-ci.org/github/airbrake/airbrake-ruby)\n[![Downloads](https://img.shields.io/gem/dt/airbrake-ruby.svg?style=flat)](https://rubygems.org/gems/airbrake-ruby)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://airbrake-github-assets.s3.amazonaws.com/brand/airbrake-full-logo.png\" width=\"200\"\u003e\n\u003c/p\u003e\n\n- [Airbrake README][airbrake-gem]\n- [Airbrake Ruby README](https://github.com/airbrake/airbrake-ruby)\n- [YARD API documentation][yard-api]\n\n## Introduction\n\n_Airbrake Ruby_ is a plain Ruby notifier for [Airbrake][airbrake.io], the\nleading exception reporting service. Airbrake Ruby provides minimalist API that\nenables the ability to send _any_ Ruby exception to the Airbrake dashboard. The\nlibrary is extremely lightweight and it perfectly suits plain Ruby applications.\nFor apps that are built with _Rails_, _Sinatra_ or any other Rack-compliant web\nframework we offer the [`airbrake`][airbrake-gem] gem. It has additional\nfeatures such as _reporting of any unhandled exceptions automatically_,\nintegrations with Resque, Sidekiq, Delayed Job and many more.\n\n## Key features\n\n- Simple, consistent and easy-to-use [library API](#api)\n- Awesome performance (check out our [benchmarks](#running-benchmarks))\n- [Asynchronous exception reporting](#asynchronous-airbrake-options)\n- [Promise support](#promise)\n- Flexible [configuration options](#configuration)\n- Support for [proxying](#proxy)\n- Support for [environments](#environment)\n- [Filters](#airbrakeadd_filter) support (filter out sensitive or unwanted data\n  that shouldn't be sent)\n- Ability to [ignore exceptions](#airbrakeadd_filter) based on their class,\n  backtrace or any other condition\n- Support for Java exceptions occurring in JRuby\n- SSL support (all communication with Airbrake is encrypted by default)\n- Support for fatal exception reporting (the ones that terminate your program)\n- Support for [custom exception attributes](#custom-exception-attributes)\n- [Severity](#setting-severity) support\n- Support for [code hunks](#code_hunks) (lines of code surrounding each\n  backtrace frame)\n- Ability to add [context](#airbrakemerge_context) to reported exceptions\n- [Dependency tracking](#airbrakefiltersdependencyfilter) support\n- Automatic and manual [deploy tracking](#airbrakenotify_deploy)\n- [Performance monitoring](#performance_stats) (APM) for web applications (route\n  statistics, SQL queries, Job execution statistics)\n- Last but not least, we follow [semantic versioning 2.0.0][semver2]\n\n## Installation\n\n### Bundler\n\nAdd the Airbrake Ruby gem to your Gemfile:\n\n```ruby\ngem 'airbrake-ruby'\n```\n\n### Manual\n\nInvoke the following command from your terminal:\n\n```ruby\ngem install airbrake-ruby\n```\n\n## Example\n\nThis is the minimal example that you can use to test Airbrake Ruby with your\nproject.\n\n```ruby\nrequire 'airbrake-ruby'\n\n# Every Airbrake notifier must configure\n# two options: `project_id` and `project_key`.\nAirbrake.configure do |c|\n  c.project_id = 105138\n  c.project_key = 'fd04e13d806a90f96614ad8e529b2822'\nend\n\n# Asynchronous error delivery.\nbegin\n  1/0\nrescue ZeroDivisionError =\u003e ex\n  # Return value is always `nil`.\n  Airbrake.notify(ex)\nend\n\nputs 'A ZeroDivisionError was sent to Airbrake asynchronously!',\n     \"Find it at your project's dashboard on https://airbrake.io\"\n\n# Synchronous error delivery.\nbegin\n  1/0\nrescue ZeroDivisionError =\u003e ex\n  # Return value is a Hash.\n  response = Airbrake.notify_sync(ex)\nend\n\nputs \"\\nAnother ZeroDivisionError was sent to Airbrake, but this time synchronously.\",\n     \"See it at #{response['url']}\"\n```\n\n## Configuration\n\n#### project_id \u0026 project_key\n\nYou **must** set both `project_id` \u0026 `project_key`.\n\nTo find your `project_id` and `project_key` navigate to your project's\n_Settings_ and copy the values from the right sidebar.\n\n![][project-idkey]\n\n```ruby\nAirbrake.configure do |c|\n  c.project_id = 105138\n  c.project_key = 'fd04e13d806a90f96614ad8e529b2822'\nend\n```\n\n#### proxy\n\nIf your server is not able to directly reach Airbrake, you can use a built-in\nproxy. By default, Airbrake Ruby uses a direct connection.\n\n```ruby\nAirbrake.configure do |c|\n  c.proxy = {\n    host: 'proxy.example.com',\n    port: 4038,\n    user: 'john-doe',\n    password: 'p4ssw0rd'\n  }\nend\n```\n\n#### logger\n\nBy default, Airbrake Ruby outputs to `STDOUT`. The default logger level is\n`Logger::WARN`. It's possible to add your custom logger.\n\n```ruby\nAirbrake.configure do |c|\n  c.logger = Logger.new('log.txt')\nend\n```\n\n#### app_version\n\nThe version of your application that you can pass to differentiate exceptions\nbetween multiple versions. It's not set by default.\n\n```ruby\nAirbrake.configure do |c|\n  c.app_version = '1.0.0'\nend\n```\n\n#### versions\n\nA hash of arbitrary versions that your application uses that you want to\ntrack (Rails, Linux kernel, API version, etc.). By default, it's empty.\n\n```ruby\nAirbrake.configure do |c|\n  c.versions = {\n    'Rails' =\u003e '5.2.0',\n    'bundler' =\u003e '1.16.1',\n    'LinuxKernel' =\u003e '4.4.0-97-generic'\n  }\nend\n```\n\n#### error_host\n\nA web address to which the notifier should send errors.\n\nBy default, it is set to `airbrake.io`. It contains a scheme (\"http\" or\n\"https\"), a host and a port. You can omit the port (80 will be assumed) and the\nscheme (\"https\" will be assumed).\n\n```ruby\nAirbrake.configure do |c|\n  c.error_host = 'http://localhost:8080'\nend\n```\n\nIf your backend is hosted behind a subpath such as `http://localhost:8080/api`,\nmake sure to append a trailing slash to the end of the URL:\n\n```ruby\nAirbrake.configure do |c|\n  c.error_host = 'http://localhost:8080/api/' # Note the trailing slash\nend\n```\n\n#### apm_host\n\nA web address to which the notifier should send APM events.\n\nBy default, it is set to `airbrake.io`. It contains a scheme (\"http\" or\n\"https\"), a host and a port. You can omit the port (80 will be assumed) and the\nscheme (\"https\" will be assumed).\n\n```ruby\nAirbrake.configure do |c|\n  c.apm_host = 'http://localhost:8080'\nend\n```\n\nIf your backend is hosted behind a subpath such as `http://localhost:8080/api`,\nmake sure to append a trailing slash to the end of the URL:\n\n```ruby\nAirbrake.configure do |c|\n  c.apm_host = 'http://localhost:8080/api/' # Note the trailing slash\nend\n```\n\n#### root_directory\n\nConfigures the root directory of your project. Expects a String or a Pathname,\nwhich represents the path to your project. Providing this option helps us to\nfilter out repetitive data from backtrace frames and link to GitHub files\nfrom our dashboard.\n\n```ruby\nAirbrake.configure do |c|\n  c.root_directory = '/var/www/project'\nend\n```\n\n#### environment\n\nConfigures the environment the application is running in. Helps the Airbrake\ndashboard to distinguish between exceptions occurring in different\nenvironments. By default, it's not set.\n\n```ruby\nAirbrake.configure do |c|\n  c.environment = :production\nend\n```\n\n#### ignore_environments\n\nSetting this option allows Airbrake to filter exceptions occurring in unwanted\nenvironments such as `:test`. By default, it is equal to an empty Array, which\nmeans Airbrake Ruby sends exceptions occurring in all environments.\n\nThis will also disable performance stat collection for matched environments.\n\n```ruby\nAirbrake.configure do |c|\n  c.ignore_environments = [:production, /test.+/]\nend\n```\n\n#### timeout\n\nThe number of seconds to wait for the connection to Airbrake to open.\n\n```ruby\nAirbrake.configure do |c|\n  c.timeout = 10\nend\n```\n\n#### blocklist_keys\n\nSpecifies which keys in the payload (parameters, session data, environment data,\netc) should be filtered. Before sending an error, filtered keys will be\nsubstituted with the `[Filtered]` label.\n\nIt accepts Strings, Symbols \u0026 Regexps, which represent keys of values to be\nfiltered.\n\n```ruby\nAirbrake.configure do |c|\n  c.blocklist_keys = [:email, /credit/i, 'password']\nend\n\nAirbrake.notify('App crashed!', {\n  user: 'John',\n  password: 's3kr3t',\n  email: 'john@example.com',\n  credit_card: '5555555555554444'\n})\n\n# The dashboard will display this parameter as filtered, but other values won't\n# be affected:\n#   { user: 'John',\n#     password: '[Filtered]',\n#     email: '[Filtered]',\n#     credit_card: '[Filtered]' }\n```\n\n\u003e **Warning**\n\u003e This option doesn't filter complex objects. Only `Hash` is supported. For\n\u003e example, if you blocklist the `password` key and call `.notify` like this:\n\u003e\n\u003e ```ruby\n\u003e Airbrake.notify('oops', {\n\u003e   filterable_obj: { password: 's3kr3t' },\n\u003e   non_filterable_obj: OpenStruct.new(password: 's3kr3t')\n\u003e })\n\u003e ```\n\u003e\n\u003e Only `filterable_obj`'s password will be filtered. The library won't serialize\n\u003e or modify the OpenStruct object for you.\n\n##### Using Procs to delay filters configuration\n\nIf you cannot inline your keys (for example, they should be loaded from external\nprocess), there's a way to load them later. Let's imagine `Keyloader.load_keys`\nbuilds an Array of keys by talking to another process:\n\n```ruby\nmodule Keyloader\n  # Builds an Array of keys (talking to another process is omitted).\n  def self.load_keys\n    [:credit_card, :telephone]\n  end\nend\n```\n\nWe need to wrap this call in a Proc, so the library can execute it later (it\ngets executed on first notify, only once):\n\n```ruby\nAirbrake.configure do |c|\n  # You can mix inline keys and Procs.\n  c.blocklist_keys = [:email, proc { Keyloader.load_keys }, 'password']\nend\n```\n\nThe Proc _must_ return an Array consisting only of the elements, which are\nconsidered to be valid for this option.\n\n#### allowlist_keys\n\nSpecifies which keys in the payload (parameters, session data, environment data,\netc) should _not_ be filtered. All other keys will be substituted with the\n`[Filtered]` label.\n\nIt accepts Strings, Symbols \u0026 Regexps, which represent keys the values of which\nshouldn't be filtered.\n\n```ruby\nAirbrake.configure do |c|\n  c.allowlist_keys = [:email, /user/i, 'account_id']\nend\n\nAirbrake.notify(StandardError.new('App crashed!'), {\n  user: 'John',\n  password: 's3kr3t',\n  email: 'john@example.com',\n  account_id: 42\n})\n\n# The dashboard will display this parameter as is, but all other values will be\n# filtered:\n#   { user: 'John',\n#     password: '[Filtered]',\n#     email: 'john@example.com',\n#     account_id: 42 }\n```\n\n\u003e **Warning**\n\u003e This option doesn't filter complex objects. Only `Hash` is supported. For\n\u003e example, if you blocklist the `password` key and call `.notify` like this:\n\u003e\n\u003e ```ruby\n\u003e Airbrake.notify('oops', {\n\u003e   filterable_obj: { password: 's3kr3t' },\n\u003e   non_filterable_obj: OpenStruct.new(password: 's3kr3t')\n\u003e })\n\u003e ```\n\u003e\n\u003e Only `filterable_obj`'s password will be filtered. The library won't serialize\n\u003e or modify the OpenStruct object for you.\n\n##### Using Procs to delay filters configuration\n\nSee documentation about\n[blocklisting using Proc objects](#using-procs-to-delay-filters-configuration).\nIt's identical.\n\n#### code_hunks\n\nCode hunks are lines of code surrounding each backtrace frame. When\n`root_directory` is set to some value, code hunks are collected only for frames\ninside that directory. If `root_directory` isn't configured, then first ten code\nhunks are collected. By default, it's set to `true`.\n\n```ruby\nAirbrake.configure do |c|\n  c.code_hunks = false\nend\n```\n\n#### performance_stats\n\nConfigures [Airbrake Performance Monitoring][airbrake-performance-monitoring]\nstatistics collection aggregated per route. These are displayed on the\nPerformance tab of your project. By default, it's enabled.\n\nThe statistics is sent via:\n\n- [`Airbrake.notify_request`](#airbrakenotify_request)\n\n```ruby\nAirbrake.configure do |c|\n  c.performance_stats = true\nend\n```\n\n#### query_stats\n\nConfigures [Airbrake Performance Monitoring][airbrake-performance-monitoring]\nquery collection. These are displayed on the Performance tab of your project. If\n`performance_stats` is `false`, setting this to `true` won't have effect because\n`performance_stats` has higher precedence. By default, it's enabled.\n\nThe statistics is sent via:\n\n- [`Airbrake.notify_query`](#airbrakenotify_query)\n\n```ruby\nAirbrake.configure do |c|\n  c.query_stats = false\nend\n```\n\n#### job_stats\n\nConfigures Airbrake Performance Monitoring job (aka queue/task/worker)\nstatistics collection. It is displayed on the Performance tab of your\nproject. If `performance_stats` is `false`, setting this to `true` won't have\neffect because `performance_stats` has higher precedence. By default, it's\nenabled.\n\nThe statistics is sent via:\n\n- [`Airbrake.notify_queue`](#airbrakenotify_queue)\n\n```\nAirbrake.configure do |c|\n  c.job_stats = false\nend\n```\n\n#### error_notifications\n\nConfigures Airbrake error reporting. By default, it's enabled (recommended).\n\nWhen it's disabled, [`Airbrake.notify`](#airbrakenotify) \u0026\n[`Airbrake.notify_sync`](#airbrakenotify_sync) are no-op.\n\n```ruby\nAirbrake.configure do |c|\n  c.error_notifications = true\nend\n```\n\n#### remote_config_host\n\nConfigures the host from which the notifier should pull remote configuration. By\ndefault, it is set to `https://notifier-configs.airbrake.io`:\n\n```rb\nAirbrake.configure do |c|\n  c.remote_config_host = 'https://notifier-configs.example.com'\nend\n```\n\n#### remote_config\n\nConfigures the remote configuration feature. At regular intervals the notifier\nwill be making `GET` requests to Airbrake servers and fetching a JSON document\ncontaining configuration settings of the notifier. The notifier will apply these\nnew settings at runtime. By default, it is enabled.\n\nTo disable this feature, configure your notifier with:\n\n```rb\nAirbrake.configure do |c|\n  c.remote_config = false\nend\n```\n\n\u003e **Note**\n\u003e It is not recommended to disable this feature. It might negatively impact\n\u003e how your notifier works. Please use this option with caution.\n\n#### backlog\n\nTurns on/off the backlog feature. The backlog keeps track of errors or events\nthat Airbrake Ruby couldn't send due to a faulty network, Airbake API being at\nsend time, etc. The backlog is flushed every 2 minutes, meaning everything in\nthe backlog will be attempted to be sent to the Airbrake API again. If the error\nor event can't be successfully sent from the backlog, it gets rejected\npermanently.\n\nThe maximum backlog size is 100. By default, it's enabled.\n\n```ruby\nAirbrake.configure do |c|\n  c.backlog = true\nend\n```\n\n### Asynchronous Airbrake options\n\nThe options listed below apply to [`Airbrake.notify`](#airbrakenotify), they do\nnot apply to [`Airbrake.notify_sync`](#airbrakenotify_sync).\n\n#### queue_size\n\nThe size of the notice queue. The default value is 100. You can increase the\nvalue according to your needs.\n\n```ruby\nAirbrake.configure do |c|\n  c.queue_size = 200\nend\n```\n\n#### workers\n\nThe number of threads that handle notice sending. The default value is 1.\n\n```ruby\nAirbrake.configure do |c|\n  c.workers = 5\nend\n```\n\n## API\n\n### Airbrake\n\n#### Airbrake.notify\n\nSends an exception to Airbrake asynchronously.\n\n```ruby\nAirbrake.notify('App crashed!')\n```\n\nAs the first parameter, accepts:\n\n- an `Exception` (will be sent directly)\n- any object that can be converted to String with `#to_s` (the information from\n  the object will be used as the message of a `RuntimeException` that we build\n  internally)\n- an `Airbrake::Notice`\n\nAs the second parameter, accepts a hash with additional data. That data will be\ndisplayed in the _Params_ tab in your project's dashboard.\n\n```ruby\nAirbrake.notify('App crashed!', {\n  anything: 'you',\n  wish: 'to add'\n})\n```\n\nAccepts a block, which yields an `Airbrake::Notice`:\n\n```ruby\nAirbrake.notify('App crashed') do |notice|\n  notice[:params][:foo] = :bar\nend\n```\n\nReturns an [`Airbrake::Promise`](#promise), which can be used to read Airbrake\nerror ids.\n\n##### Setting severity\n\n[Severity][what-is-severity] allows categorizing how severe an error is. By\ndefault, it's set to `error`. To redefine severity, simply overwrite\n`context/severity` of a notice object. For example:\n\n```ruby\nAirbrake.notify('App crashed!') do |notice|\n  notice[:context][:severity] = 'critical'\nend\n```\n\n#### Airbrake.notify_sync\n\nSends an exception to Airbrake synchronously. Returns a Hash with an error ID\nand a URL to the error.\n\n```ruby\nAirbrake.notify_sync('App crashed!')\n#=\u003e {\"id\"=\u003e\"1516018011377823762\", \"url\"=\u003e\"https://airbrake.io/locate/1516018011377823762\"}\n```\n\nAccepts the same parameters as [`Airbrake.notify`](#airbrakenotify).\n\n#### Airbrake.add_filter\n\nRuns a callback before `.notify` kicks in. Yields an `Airbrake::Notice`. This is\nuseful if you want to ignore specific notices or filter the data the notice\ncontains.\n\nIf you want to ignore a notice, simply mark it with `Notice#ignore!`. This\ninterrupts the execution chain of the `add_filter` callbacks. Once you ignore\na notice, there's no way to unignore it.\n\nThis example demonstrates how to ignore **all** notices.\n\n```ruby\nAirbrake.add_filter(\u0026:ignore!)\n```\n\nInstead, you can ignore notices based on some condition.\n\n```ruby\nAirbrake.add_filter do |notice|\n  notice.ignore! if notice.stash[:exception].is_a?(StandardError)\n\n  if notice.stash[:exception].message.match(/Couldn't find Record/)\n    notice.ignore!\n  end\nend\n```\n\nIn order to filter a notice, simply change the data you are interested in.\n\n```ruby\nAirbrake.add_filter do |notice|\n  if notice[:params][:password]\n    # Filter out password.\n    notice[:params][:password] = '[Filtered]'\n  end\nend\n```\n\nNotices can carry custom objects attached to\nthe [notice stash](#noticestash--noticestash). Such notices can be produced\nby [`build_notice`](#airbrakebuild_notice) manually or provided to you by an\nAirbrake integration:\n\n```ruby\n# Build a notice and store a Request object in the stash.\nnotice = Airbrake.build_notice('oops')\nnotice.stash[:request] = Request.new\n\nAirbrake.add_filter do |notice|\n  # Access the stored request object inside a filter and interact with it.\n  notice[:params][:remoteIp] = notice.stash[:request].env['REMOTE_IP']\nend\n```\n\nBy default, the stash contains an exception object accessible via\n`notice.stash[:exception]`.\n\n#### Airbrake.delete_filter\n\nDeletes a filter added via [`add_filter`](#airbrakeadd_filter). Expects a class name of the filter.\n\n```ruby\n# Add a MyFilter filter (we pass an instance here).\nAirbrake.add_filter(MyFilter.new)\n\n# Delete the filter (we pass class name here).\nAirbrake.delete_filter(MyFilter)\n```\n\n\u003e **Note**\n\u003e This method cannot delete filters assigned via the Proc form.\n\n##### Optional filters\n\nThe library adds a few filters by default. However, some of them are optional\nand not added. This is because such filters are overly specific and may not suit\nevery type of application, so there's no need to include them only to clutter\nthe notice object. You have to include such filters manually, if you think you\nneed them. The list of optional filters include:\n\n###### Airbrake::Filters::ThreadFilter\n\nAttaches thread \u0026 fiber local variables along with general thread information.\n\n```ruby\nAirbrake.add_filter(Airbrake::Filters::ThreadFilter.new)\n```\n\n###### Airbrake::Filters::DependencyFilter\n\nAttaches loaded dependencies to the notice object (under\n`context/versions/dependencies`).\n\n```ruby\nAirbrake.add_filter(Airbrake::Filters::DependencyFilter.new)\n```\n\n###### Airbrake::Filters::SqlFilter\n\nFilters out sensitive data from queries that are sent via\n[`Airbrake.notify_query`](#airbrakenotify_query). Sensitive data is everything\nthat is not table names or fields (e.g. column values and such).\n\nAccepts a parameter, which signifies SQL dialect being used. Supported dialects:\n\n- `:postgres`\n- `:mysql`\n- `:sqlite`\n- `:cassandra`\n- `:oracle`\n\n```ruby\nAirbrake.add_filter(Airbrake::Filters::SqlFilter.new(:postgres))\n```\n\n##### Using classes for building filters\n\nFor more complex filters you can use the special API. Simply pass an object that\nresponds to the `#call` method.\n\n```ruby\nclass MyFilter\n  def call(notice)\n    # ...\n  end\nend\n\nAirbrake.add_filter(MyFilter.new)\n```\n\nThe library provides two default filters that you can use to filter notices:\n[KeysBlocklist][keysblocklist] \u0026 [KeysAllowlist][keysallowlist].\n\n#### Airbrake.build_notice\n\nBuilds an [Airbrake notice][notice-v3]. This is useful if you want to add or\nmodify a value only for a specific notice. When you're done modifying the\nnotice, send it with `Airbrake.notify` or `Airbrake.notify_sync`.\n\n```ruby\nnotice = Airbrake.build_notice('App crashed!')\nnotice[:params][:username] = user.name\nairbrake.notify_sync(notice)\n```\n\nSee the block form of [`Airbrake.notify`](#airbrakenotify) for shorter syntax.\n\n#### Airbrake.close\n\nMakes the notifier a no-op, which means you cannot use the `.notify` and\n`.notify_sync` methods anymore. It also stops the notifier's worker threads.\n\n```ruby\nAirbrake.close\nAirbrake.notify('App crashed!') #=\u003e raises Airbrake::Error\n```\n\nIf you want to guarantee delivery of all unsent exceptions on program exit, make\nsure to `close` your Airbrake notifier. Usually, this can be done with help of\nRuby's `at_exit` hook.\n\n```ruby\nat_exit do\n  # Closes the default notifier.\n  Airbrake.close\nend\n```\n\n#### Airbrake.notify_deploy\n\nNotifies Airbrake of a new deploy. Accepts a Hash with the following params:\n\n```ruby\nAirbrake.notify_deploy(\n  environment: 'development',\n  username: 'john',\n  repository: 'https://github.com/airbrake/airbrake-ruby',\n  revision: '0b77f289166c9fef4670588471b6584fbc34b0f3',\n  version: '1.2.3'\n)\n```\n\n#### Airbrake.configured?\n\nChecks whether the notifier is configured or not:\n\n```ruby\nAirbrake.configured? #=\u003e false\n```\n\n#### Airbrake.merge_context\n\nMerges the provided context Hash with the notifier context. Upon a\n[`notify/notify_sync`](#airbrakenotify) call the notifier context is attached to\nthe notice object under the `params/airbrake_context` key.\n\nAfter the error is attached, the notifier context is cleared, allowing other\n`notify` calls to start with a clean slate.\n\nThis method is specifically useful when you want to attach variables from\ndifferent scopes during the execution of your program and then send them to\nAirbrake on error.\n\n```ruby\nclass MerryGrocer\n  def load_fruits(fruits)\n    Airbrake.merge_context(fruits: fruits)\n  end\n\n  def deliver_fruits\n    Airbrake.notify('fruitception')\n  end\n\n  def load_veggies(veggies)\n    Airbrake.merge_context(veggies: veggies)\n  end\n\n  def deliver_veggies\n    Airbrake.notify('veggieboom!')\n  end\nend\n\ngrocer = MerryGrocer.new\n\n# The context is added to `notice[:params][:airbrake_context]`.\nAirbrake.add_filter do |notice|\n  puts \"Context: #{notice[:params][:airbrake_context] || 'empty'}\"\nend\n\n# Load some fruits to the context.\ngrocer.load_fruits(%w(mango banana apple))\n\n# Deliver the fruits. Note that we are not passing anything, `deliver_fruits`\n# knows that we loaded something.\ngrocer.deliver_fruits\n#=\u003e Context: ['mango', 'banana', 'apple']\n\n# Load some vegetables and deliver them to Airbrake. Note that the fruits have\n# been delivered and therefore the grocer doesn't have them anymore. We merge\n# veggies with the new context.\ngrocer.load_veggies(%w(cabbage carrot onion))\ngrocer.deliver_veggies\n#=\u003e Context: ['cabbage', 'carrot', 'onion']\n\n# The context is empty again, feel free to load more.\ngrocer.deliver_veggies\n#=\u003e Context: empty\n```\n\n#### Airbrake.notify_request\n\nSends request information (performance statistics of a route) to [Airbrake\nPerformance Monitoring][airbrake-performance-monitoring]. The performance\nstatistics are displayed on the Performance tab of your project.\n\n```ruby\nAirbrake.notify_request(\n  method: 'GET',\n  route: '/things/1',\n  status_code: 200,\n  timing: 123.45 # ms\n)\n```\n\nOptionally, you can attach information to the stash (`request_id` in this\nexample).\n\n```ruby\nAirbrake.notify_request(\n  {\n    # normal params\n  },\n  request_id: 123\n)\n```\n\nThis stash can be accessed from performance filters as\n`metric.stash[:request_id]`.\n\n##### Return value\n\nWhen [`config.performance_stats = false`](#performance_stats), it always returns\na rejected promise.\n\nWhen [`config.performance_stats = true`](#performance_stats), then it aggregates\nstatistics and sends as a batch every 15 seconds.\n\n#### Airbrake.notify_request_sync\n\nSends request information (performance statistics of a route) to [Airbrake\nPerformance Monitoring][airbrake-performance-monitoring] synchronously. The\nperformance statistics are displayed on the Performance tab of your project.\n\nAccepts the same parameters as\n[`Airbrake.notify_request`](#airbrakenotify_request).\n\n##### Return value\n\nAlways returns a Hash with response from the server.\n\n#### Airbrake.notify_query\n\nSends SQL performance statistics to Airbrake. The performance statistics is\ndisplayed on the Performance tab of your project.\n\n```ruby\nAirbrake.notify_query(\n  method: 'GET',\n  route: '/things/1',\n  query: 'SELECT * FROM foos',\n  func: 'foo', # optional\n  file: 'foo.rb', # optional\n  line: 123, # optional\n  timing: 123.45 # ms\n)\n```\n\nOptionally, you can attach information to the stash (`request_id` in this\nexample).\n\n```ruby\nAirbrake.notify_query(\n  {\n    # normal params\n  },\n  request_id: 123\n)\n```\n\nThis stash can be accessed from performance filters as\n`metric.stash[:request_id]`.\n\n##### Return value\n\nWhen [`config.performance_stats = false`](#performance_stats), it always returns\na rejected promise.\n\nWhen [`config.performance_stats = true`](#performance_stats), then it aggregates\nstatistics and sends as a batch every 15 seconds.\n\n#### Airbrake.notify_query_sync\n\nSends SQL performance statistics to Airbrake synchronously. The performance\nstatistics is displayed on the Performance tab of your project.\n\nAccepts the same parameters as\n[`Airbrake.notify_query`](#airbrakenotify_query).\n\n##### Return value\n\nAlways returns a Hash with response from the server.\n\n#### Airbrake.notify_performance_breakdown\n\nSends performance breakdown statistics by groups to Airbrake. The groups are\narbitrary (database, views, HTTP calls, etc.), but there can be only up to 10\ngroups per route in total.\n\n```ruby\nAirbrake.notify_performance_breakdown(\n  method: 'GET',\n  route: '/things/1',\n  response_type: 'json',\n  groups: { db: 24.0, view: 0.4 }, # ms\n  timing: 123.45 # ms\n)\n```\n\nOptionally, you can attach information to the stash (`request_id` in this\nexample).\n\n```ruby\nAirbrake.notify_performance_breakdown(\n  {\n    # normal params\n  },\n  request_id: 123\n)\n```\n\nThis stash can be accessed from performance filters as\n`metric.stash[:request_id]`.\n\n##### Return value\n\nWhen [`config.performance_stats = false`](#performance_stats), it always returns\na rejected promise.\n\nWhen [`config.performance_stats = true`](#performance_stats), then it aggregates\nstatistics and sends as a batch every 15 seconds.\n\n#### Airbrake.notify_performance_breakdown_sync\n\nSends performance breakdown statistics by groups to Airbrake synchronously. The\ngroups are arbitrary (database, views, HTTP calls, etc.), but there can be only\nup to 10 groups per route in total.\n\nAccepts the same parameters as\n[`Airbrake.notify_performance_breakdown`](#airbrakenotify_performance_breakdown).\n\n##### Return value\n\nAlways returns a Hash with response from the server.\n\n#### Airbrake.notify_queue\n\nSends queue (worker) statistics to Airbrake. Supports groups (similar to\n[performance breakdowns](#airbrakenotify_performance_breakdown)).\n\n- `queue` - name of the queue (worker)\n- `error_count` - how many times this worker failed\n- `groups` - where the job spent its time\n\n```ruby\nAirbrake.notify_queue(\n  queue: \"emails\",\n  error_count: 1,\n  groups: { redis: 24.0, sql: 0.4 }, # ms\n  timing: 0.05221 # ms\n)\n```\n\nOptionally, you can attach information to the stash (`job_id` in this\nexample).\n\n```ruby\nAirbrake.notify_queue(\n  {\n    # normal params\n  },\n  job_id: 123\n)\n```\n\nThis stash can be accessed from performance filters as\n`metric.stash[:job_id]`.\n\n##### Return value\n\nWhen [`config.performance_stats = false`](#performance_stats), it always returns\na rejected promise.\n\nWhen [`config.performance_stats = true`](#performance_stats), then it aggregates\nstatistics and sends as a batch every 15 seconds.\n\n#### Airbrake.notify_queue_sync\n\nSends queue (worker) statistics to Airbrake synchronously.\n\nAccepts the same parameters as [`Airbrake.notify_queue`](#airbrakenotify_queue).\n\n##### Return value\n\nAlways returns a Hash with response from the server.\n\n#### Airbrake.add_performance_filter\n\nAdds a performance filter that filters performance data. Works exactly like\n[`Airbrake.add_filter`](#airbrakeadd_filter). The only difference is that\ninstead of `Airbrake::Notice` it yields performance data (such as\n`Airbrake::Query` or `Airbrake::Request`). It's invoked after\n[`notify_request`](#airbrakenotify_request) or\n[`notify_query`](#airbrakenotify_query) (but [`notify`](#airbrakenotify) calls\ndon't trigger it!).\n\n```ruby\nAirbrake.add_performance_filter do |metric|\n  metric.ignore! if metric.route =~ %r{/health_check}\nend\n```\n\n#### Airbrake.delete_performance_filter\n\nDeletes a performance filter added via\n[`Airbrake.add_performance_filter`](#airbrakeadd_performance_filter). Works\nexactly like [`Airbrake.delete_filter`](#airbrakedelete_filter).\n\n### Notice\n\n#### Notice#ignore!\n\nIgnores a notice. Ignored notices never reach the Airbrake dashboard. This is\nuseful in conjunction with `Airbrake.add_filter`.\n\n```ruby\nnotice.ignore!\n```\n\n#### Notice#ignored?\n\nChecks whether the notice was ignored.\n\n```ruby\nnotice.ignored? #=\u003e false\n```\n\n#### Notice#[] \u0026 Notice#[]=\n\nAccesses a notice's payload, which can be read or filtered. Payload includes:\n\n- `:errors`\n- `:context`\n- `:environment`\n- `:session`\n- `:params`\n\n```ruby\nnotice[:params][:my_param] = 'foobar'\n```\n\n#### Notice#stash[] \u0026 Notice#stash[]=\n\nEach notice can carry arbitrary objects stored in the notice stash, accessible\nthrough the `stash` method. Callbacks defined\nvia [`add_filter`](#airbrakeadd_filter) can access the stash and attach stored\nobject's values to the notice payload:\n\n```ruby\nnotice.stash[:my_object] = Object.new\n\nAirbrake.add_filter do |notice|\n  # Access :my_object from the stash and directly call its method. The return\n  # value will be sent to Airbrake.\n  notice[:params][:object_id] = notice.stash[:my_object].object_id\nend\n```\n\n### Promise\n\n`Airbrake::Promise` represents a simplified promise object (similar to promises\nfound in JavaScript), which allows chaining callbacks that are executed when\nthe promise is either resolved or rejected.\n\n#### Promise#then\n\nAttaches a callback to be executed when a promise is resolved (fulfilled). The\npromise is resolved whenever the Airbrake API successfully accepts your\nexception.\n\nYields successful response containing the id of an error at Airbrake and URL to\nthe error at Airbrake. Returns `self`.\n\n```rb\nAirbrake.notify('Oops').then { |response| puts response }\n#=\u003e {\"id\"=\u003e\"00054415-8201-e9c6-65d6-fc4d231d2871\",\n#    \"url\"=\u003e\"http://localhost/locate/00054415-8201-e9c6-65d6-fc4d231d2871\"}\n```\n\n#### Promise#rescue\n\nAttaches a callback to be executed when a promise is rejected. The promise is\nrejected whenever the API returns an error response.\n\nYields an error message in the form of String explaining the failure and returns\n`self`.\n\n```rb\nAirbrake.notify('Oops').rescue { |error| puts error }\n#=\u003e Failed to open TCP connection to localhostt:80\n```\n\n### Custom exception attributes\n\nThe library supports custom exception attributes. This is useful if you work\nwith custom exceptions, which define non-standard attributes and you can't\nattach any additional data with help of the [`add_filter`](#airbrakeadd_filter)\nAPI due to the fact that the data isn't available at configuration time yet.\n\nIn this case, you could define a special hook method on your exception called\n`#to_airbrake`. The method must return a Hash the keys of which must be a subset\nof the ones mentioned in the [`Notice#[]`](#notice--notice) API.\n\n```ruby\nclass MyException\n  def initialize\n    @http_code = 404\n  end\n\n  # The library expects you to define this method. You must return a Hash,\n  # containing the keys you want to modify.\n  def to_airbrake\n    { params: { http_code: @http_code } }\n  end\nend\n\n# The `{ http_code: 404 }` Hash will transported to the Airbrake dashboard via\n# the `#to_airbrake` method.\nAirbrake.notify(MyException.new)\n```\n\n\u003e **Note**\n\u003e You don't have to call `Airbrake.notify` manually to be able to benefit\n\u003e from this API. It should \"just work\".\n\n### Benchmark\n\n#### .measure\n\nMeasures [monotonic time][monotonic] for the given operation. Returns elapsed\ntime in milliseconds.\n\n```ruby\ntime = Airbrake::Benchmark.measure do\n  (1..10_000).inject(:*)\nend\n\nputs \"Time: #{time}\"\n#=\u003e Time: 67.40199995040894\n```\n\n### TimedTrace\n\nRepresents a chunk of code performance of which was measured and stored under a\nlabel. The chunk is called a \"span\". Such spans can be used for [performance\nbreakdown](#notify_performance_breakdown) reporting.\n\n#### .span\n\n```ruby\n# Measure time for a span called 'operation'.\ntimed_trace = Airbrake::TimedTrace.span('operation') do\n  call_something\nend\ntimed_trace.spans #=\u003e { 'operation' =\u003e 0.123 }\n\n# Send the spans to the Airbrake dashboard.\nAirbrake.notify_performance_breakdown(\n  method: 'GET',\n  route: '/things/1',\n  response_type: 'json',\n  groups: timed_trace.spans\n)\n```\n\nSee [full documentation][yard-api] for more examples.\n\n## Additional notes\n\n### Exception limit\n\nThe maximum size of an exception is 64KB. Exceptions that exceed this limit\nwill be truncated to fit the size.\n\n### Running benchmarks\n\nTo run benchmarks related to asynchronous delivery, make sure to start a web\nserver on port 8080. We provide a simple server, which can be started with this\ncommand (you need to have the [Go][golang] programming language installed):\n\n```shell\ngo run benchmarks/server.go\n```\n\nIn order to run benchmarks against `master`, add the `lib` directory to your\n`LOAD_PATH` and choose the benchmark you are interested in:\n\n```shell\nruby -Ilib benchmarks/notify_async_vs_sync.rb\n```\n\n### Reporting critical exceptions\n\nCritical exceptions are unhandled exceptions that terminate your program. By\ndefault, the library doesn't report them. However, you can either depend on the\n[airbrake gem][airbrake-gem] instead, which supports them, or you can add\nthe following code somewhere in your app:\n\n```ruby\nat_exit do\n  Airbrake.notify_sync($!) if $!\nend\n```\n\n### Remote configuration\n\nEvery 10 minutes the notifier issues an HTTP GET request to fetch remote\nconfiguration. This might be undesirable while running tests. To suppress this\nHTTP call, you need to configure your [environment](#environment) to `test`.\n\n## Supported Rubies\n\n- CRuby \u003e= 2.3.0\n- JRuby \u003e= 9k\n\n## Contact\n\nIn case you have a problem, question or a bug report, feel free to:\n\n- [file an issue][issues]\n- [send us an email](mailto:support@airbrake.io)\n- [tweet at us][twitter]\n- chat with us (visit [airbrake.io][airbrake.io] and click on the round orange\n  button in the bottom right corner)\n\n## License\n\nThe project uses the MIT License. See LICENSE.md for details.\n\n[airbrake.io]: https://airbrake.io\n[airbrake-gem]: https://github.com/airbrake/airbrake\n[semver2]: http://semver.org/spec/v2.0.0.html\n[project-idkey]: https://s3.amazonaws.com/airbrake-github-assets/airbrake-ruby/project-id-key.png\n[issues]: https://github.com/airbrake/airbrake-ruby/issues\n[twitter]: https://twitter.com/airbrake\n[keysblocklist]: https://github.com/airbrake/airbrake-ruby/blob/master/lib/airbrake-ruby/filters/keys_blocklist.rb\n[keysallowlist]: https://github.com/airbrake/airbrake-ruby/blob/master/lib/airbrake-ruby/filters/keys_allowlist.rb\n[golang]: https://golang.org/\n[yard-api]: http://www.rubydoc.info/gems/airbrake-ruby\n[what-is-severity]: https://airbrake.io/docs/airbrake-faq/what-is-severity/\n[monotonic]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html\n[airbrake-performance-monitoring]: https://airbrake.io/product/performance\n[notice-v3]: https://airbrake.io/docs/api/#create-notice-v3\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fairbrake%2Fairbrake-ruby","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fairbrake%2Fairbrake-ruby","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fairbrake%2Fairbrake-ruby/lists"}