Airbrake Ruby
Introduction
Airbrake Ruby is a plain Ruby notifier for Airbrake, the
leading exception reporting service. Airbrake Ruby provides minimalist API that
enables the ability to send any Ruby exception to the Airbrake dashboard. The
library is extremely lightweight and it perfectly suits plain Ruby applications.
For apps that are built with Rails, Sinatra or any other Rack-compliant web
framework we offer the airbrake
gem. It has additional
features such as reporting of any unhandled exceptions automatically,
integrations with Resque, Sidekiq, Delayed Job and many more.
Key features
- Simple, consistent and easy-to-use library API
- Awesome performance (check out our benchmarks)
- Asynchronous exception reporting
- Promise support
- Flexible configuration options
- Support for proxying
- Support for environments
- Filters support (filter out sensitive or unwanted data that shouldn't be sent)
- Ability to ignore exceptions based on their class, backtrace or any other condition
- Support for Java exceptions occurring in JRuby
- SSL support (all communication with Airbrake is encrypted by default)
- Support for fatal exception reporting (the ones that terminate your program)
- Support for custom exception attributes
- Severity support
- Support for code hunks (lines of code surrounding each backtrace frame)
- Ability to add context to reported exceptions
- Dependency tracking support
- Automatic and manual deploy tracking
- Performance monitoring (APM) for web applications (route statistics, SQL queries, Job execution statistics)
- Last but not least, we follow semantic versioning 2.0.0
Installation
Bundler
Add the Airbrake Ruby gem to your Gemfile:
gem 'airbrake-ruby'
Manual
Invoke the following command from your terminal:
gem install airbrake-ruby
Example
This is the minimal example that you can use to test Airbrake Ruby with your project.
require 'airbrake-ruby'
# Every Airbrake notifier must configure
# two options: `project_id` and `project_key`.
Airbrake.configure do |c|
c.project_id = 105138
c.project_key = 'fd04e13d806a90f96614ad8e529b2822'
end
# Asynchronous error delivery.
begin
1/0
rescue ZeroDivisionError => ex
# Return value is always `nil`.
Airbrake.notify(ex)
end
puts 'A ZeroDivisionError was sent to Airbrake asynchronously!',
"Find it at your project's dashboard on https://airbrake.io"
# Synchronous error delivery.
begin
1/0
rescue ZeroDivisionError => ex
# Return value is a Hash.
response = Airbrake.notify_sync(ex)
end
puts "\nAnother ZeroDivisionError was sent to Airbrake, but this time synchronously.",
"See it at #{response['url']}"
Configuration
project_id & project_key
You must set both project_id
& project_key
.
To find your project_id
and project_key
navigate to your project's
Settings and copy the values from the right sidebar.
Airbrake.configure do |c|
c.project_id = 105138
c.project_key = 'fd04e13d806a90f96614ad8e529b2822'
end
proxy
If your server is not able to directly reach Airbrake, you can use a built-in proxy. By default, Airbrake Ruby uses a direct connection.
Airbrake.configure do |c|
c.proxy = {
host: 'proxy.example.com',
port: 4038,
user: 'john-doe',
password: 'p4ssw0rd'
}
end
logger
By default, Airbrake Ruby outputs to STDOUT
. The default logger level is
Logger::WARN
. It's possible to add your custom logger.
Airbrake.configure do |c|
c.logger = Logger.new('log.txt')
end
app_version
The version of your application that you can pass to differentiate exceptions between multiple versions. It's not set by default.
Airbrake.configure do |c|
c.app_version = '1.0.0'
end
versions
A hash of arbitrary versions that your application uses that you want to track (Rails, Linux kernel, API version, etc.). By default, it's empty.
Airbrake.configure do |c|
c.versions = {
'Rails' => '5.2.0',
'bundler' => '1.16.1',
'LinuxKernel' => '4.4.0-97-generic'
}
end
error_host
A web address to which the notifier should send errors.
By default, it is set to airbrake.io
. It contains a scheme ("http" or
"https"), a host and a port. You can omit the port (80 will be assumed) and the
scheme ("https" will be assumed).
Airbrake.configure do |c|
c.error_host = 'http://localhost:8080'
end
If your backend is hosted behind a subpath such as http://localhost:8080/api
,
make sure to append a trailing slash to the end of the URL:
Airbrake.configure do |c|
c.error_host = 'http://localhost:8080/api/' # Note the trailing slash
end
apm_host
A web address to which the notifier should send APM events.
By default, it is set to airbrake.io
. It contains a scheme ("http" or
"https"), a host and a port. You can omit the port (80 will be assumed) and the
scheme ("https" will be assumed).
Airbrake.configure do |c|
c.apm_host = 'http://localhost:8080'
end
If your backend is hosted behind a subpath such as http://localhost:8080/api
,
make sure to append a trailing slash to the end of the URL:
Airbrake.configure do |c|
c.apm_host = 'http://localhost:8080/api/' # Note the trailing slash
end
root_directory
Configures the root directory of your project. Expects a String or a Pathname, which represents the path to your project. Providing this option helps us to filter out repetitive data from backtrace frames and link to GitHub files from our dashboard.
Airbrake.configure do |c|
c.root_directory = '/var/www/project'
end
environment
Configures the environment the application is running in. Helps the Airbrake dashboard to distinguish between exceptions occurring in different environments. By default, it's not set.
Airbrake.configure do |c|
c.environment = :production
end
ignore_environments
Setting this option allows Airbrake to filter exceptions occurring in unwanted
environments such as :test
. By default, it is equal to an empty Array, which
means Airbrake Ruby sends exceptions occurring in all environments.
This will also disable performance stat collection for matched environments.
Airbrake.configure do |c|
c.ignore_environments = [:production, /test.+/]
end
timeout
The number of seconds to wait for the connection to Airbrake to open.
Airbrake.configure do |c|
c.timeout = 10
end
blocklist_keys
Specifies which keys in the payload (parameters, session data, environment data,
etc) should be filtered. Before sending an error, filtered keys will be
substituted with the [Filtered]
label.
It accepts Strings, Symbols & Regexps, which represent keys of values to be filtered.
Airbrake.configure do |c|
c.blocklist_keys = [:email, /credit/i, 'password']
end
Airbrake.notify('App crashed!', {
user: 'John',
password: 's3kr3t',
email: 'john@example.com',
credit_card: '5555555555554444'
})
# The dashboard will display this parameter as filtered, but other values won't
# be affected:
# { user: 'John',
# password: '[Filtered]',
# email: '[Filtered]',
# credit_card: '[Filtered]' }
Warning This option doesn't filter complex objects. Only
Hash
is supported. For example, if you blocklist thepassword
key and call.notify
like this:Airbrake.notify('oops', { filterable_obj: { password: 's3kr3t' }, non_filterable_obj: OpenStruct.new(password: 's3kr3t') })Only
filterable_obj
's password will be filtered. The library won't serialize or modify the OpenStruct object for you.
Using Procs to delay filters configuration
If you cannot inline your keys (for example, they should be loaded from external
process), there's a way to load them later. Let's imagine Keyloader.load_keys
builds an Array of keys by talking to another process:
module Keyloader
# Builds an Array of keys (talking to another process is omitted).
def self.load_keys
[:credit_card, :telephone]
end
end
We need to wrap this call in a Proc, so the library can execute it later (it gets executed on first notify, only once):
Airbrake.configure do |c|
# You can mix inline keys and Procs.
c.blocklist_keys = [:email, proc { Keyloader.load_keys }, 'password']
end
The Proc must return an Array consisting only of the elements, which are considered to be valid for this option.
allowlist_keys
Specifies which keys in the payload (parameters, session data, environment data,
etc) should not be filtered. All other keys will be substituted with the
[Filtered]
label.
It accepts Strings, Symbols & Regexps, which represent keys the values of which shouldn't be filtered.
Airbrake.configure do |c|
c.allowlist_keys = [:email, /user/i, 'account_id']
end
Airbrake.notify(StandardError.new('App crashed!'), {
user: 'John',
password: 's3kr3t',
email: 'john@example.com',
account_id: 42
})
# The dashboard will display this parameter as is, but all other values will be
# filtered:
# { user: 'John',
# password: '[Filtered]',
# email: 'john@example.com',
# account_id: 42 }
Warning This option doesn't filter complex objects. Only
Hash
is supported. For example, if you blocklist thepassword
key and call.notify
like this:Airbrake.notify('oops', { filterable_obj: { password: 's3kr3t' }, non_filterable_obj: OpenStruct.new(password: 's3kr3t') })Only
filterable_obj
's password will be filtered. The library won't serialize or modify the OpenStruct object for you.
Using Procs to delay filters configuration
See documentation about blocklisting using Proc objects. It's identical.
code_hunks
Code hunks are lines of code surrounding each backtrace frame. When
root_directory
is set to some value, code hunks are collected only for frames
inside that directory. If root_directory
isn't configured, then first ten code
hunks are collected. By default, it's set to true
.
Airbrake.configure do |c|
c.code_hunks = false
end
performance_stats
Configures Airbrake Performance Monitoring statistics collection aggregated per route. These are displayed on the Performance tab of your project. By default, it's enabled.
The statistics is sent via:
Airbrake.notify_request
Airbrake.configure do |c|
c.performance_stats = true
end
query_stats
Configures Airbrake Performance Monitoring
query collection. These are displayed on the Performance tab of your project. If
performance_stats
is false
, setting this to true
won't have effect because
performance_stats
has higher precedence. By default, it's enabled.
The statistics is sent via:
Airbrake.notify_query
Airbrake.configure do |c|
c.query_stats = false
end
job_stats
Configures Airbrake Performance Monitoring job (aka queue/task/worker)
statistics collection. It is displayed on the Performance tab of your
project. If performance_stats
is false
, setting this to true
won't have
effect because performance_stats
has higher precedence. By default, it's
enabled.
The statistics is sent via:
Airbrake.notify_queue
Airbrake.configure do |c|
c.job_stats = false
end
error_notifications
Configures Airbrake error reporting. By default, it's enabled (recommended).
When it's disabled, Airbrake.notify
&
Airbrake.notify_sync
are no-op.
Airbrake.configure do |c|
c.error_notifications = true
end
remote_config_host
Configures the host from which the notifier should pull remote configuration. By
default, it is set to https://notifier-configs.airbrake.io
:
Airbrake.configure do |c|
c.remote_config_host = 'https://notifier-configs.example.com'
end
remote_config
Configures the remote configuration feature. At regular intervals the notifier
will be making GET
requests to Airbrake servers and fetching a JSON document
containing configuration settings of the notifier. The notifier will apply these
new settings at runtime. By default, it is enabled.
To disable this feature, configure your notifier with:
Airbrake.configure do |c|
c.remote_config = false
end
Note It is not recommended to disable this feature. It might negatively impact how your notifier works. Please use this option with caution.
backlog
Turns on/off the backlog feature. The backlog keeps track of errors or events that Airbrake Ruby couldn't send due to a faulty network, Airbake API being at send time, etc. The backlog is flushed every 2 minutes, meaning everything in the backlog will be attempted to be sent to the Airbrake API again. If the error or event can't be successfully sent from the backlog, it gets rejected permanently.
The maximum backlog size is 100. By default, it's enabled.
Airbrake.configure do |c|
c.backlog = true
end
Asynchronous Airbrake options
The options listed below apply to Airbrake.notify
, they do
not apply to Airbrake.notify_sync
.
queue_size
The size of the notice queue. The default value is 100. You can increase the value according to your needs.
Airbrake.configure do |c|
c.queue_size = 200
end
workers
The number of threads that handle notice sending. The default value is 1.
Airbrake.configure do |c|
c.workers = 5
end
API
Airbrake
Airbrake.notify
Sends an exception to Airbrake asynchronously.
Airbrake.notify('App crashed!')
As the first parameter, accepts:
- an
Exception
(will be sent directly) - any object that can be converted to String with
#to_s
(the information from the object will be used as the message of aRuntimeException
that we build internally) - an
Airbrake::Notice
As the second parameter, accepts a hash with additional data. That data will be displayed in the Params tab in your project's dashboard.
Airbrake.notify('App crashed!', {
anything: 'you',
wish: 'to add'
})
Accepts a block, which yields an Airbrake::Notice
:
Airbrake.notify('App crashed') do |notice|
notice[:params][:foo] = :bar
end
Returns an Airbrake::Promise
, which can be used to read Airbrake
error ids.
Setting severity
Severity allows categorizing how severe an error is. By
default, it's set to error
. To redefine severity, simply overwrite
context/severity
of a notice object. For example:
Airbrake.notify('App crashed!') do |notice|
notice[:context][:severity] = 'critical'
end
Airbrake.notify_sync
Sends an exception to Airbrake synchronously. Returns a Hash with an error ID and a URL to the error.
Airbrake.notify_sync('App crashed!')
#=> {"id"=>"1516018011377823762", "url"=>"https://airbrake.io/locate/1516018011377823762"}
Accepts the same parameters as Airbrake.notify
.
Airbrake.add_filter
Runs a callback before .notify
kicks in. Yields an Airbrake::Notice
. This is
useful if you want to ignore specific notices or filter the data the notice
contains.
If you want to ignore a notice, simply mark it with Notice#ignore!
. This
interrupts the execution chain of the add_filter
callbacks. Once you ignore
a notice, there's no way to unignore it.
This example demonstrates how to ignore all notices.
Airbrake.add_filter(&:ignore!)
Instead, you can ignore notices based on some condition.
Airbrake.add_filter do |notice|
notice.ignore! if notice.stash[:exception].is_a?(StandardError)
if notice.stash[:exception].message.match(/Couldn't find Record/)
notice.ignore!
end
end
In order to filter a notice, simply change the data you are interested in.
Airbrake.add_filter do |notice|
if notice[:params][:password]
# Filter out password.
notice[:params][:password] = '[Filtered]'
end
end
Notices can carry custom objects attached to
the notice stash. Such notices can be produced
by build_notice
manually or provided to you by an
Airbrake integration:
# Build a notice and store a Request object in the stash.
notice = Airbrake.build_notice('oops')
notice.stash[:request] = Request.new
Airbrake.add_filter do |notice|
# Access the stored request object inside a filter and interact with it.
notice[:params][:remoteIp] = notice.stash[:request].env['REMOTE_IP']
end
By default, the stash contains an exception object accessible via
notice.stash[:exception]
.
Airbrake.delete_filter
Deletes a filter added via add_filter
. Expects a class name of the filter.
# Add a MyFilter filter (we pass an instance here).
Airbrake.add_filter(MyFilter.new)
# Delete the filter (we pass class name here).
Airbrake.delete_filter(MyFilter)
Note This method cannot delete filters assigned via the Proc form.
Optional filters
The library adds a few filters by default. However, some of them are optional and not added. This is because such filters are overly specific and may not suit every type of application, so there's no need to include them only to clutter the notice object. You have to include such filters manually, if you think you need them. The list of optional filters include:
Airbrake::Filters::ThreadFilter
Attaches thread & fiber local variables along with general thread information.
Airbrake.add_filter(Airbrake::Filters::ThreadFilter.new)
Airbrake::Filters::DependencyFilter
Attaches loaded dependencies to the notice object (under
context/versions/dependencies
).
Airbrake.add_filter(Airbrake::Filters::DependencyFilter.new)
Airbrake::Filters::SqlFilter
Filters out sensitive data from queries that are sent via
Airbrake.notify_query
. Sensitive data is everything
that is not table names or fields (e.g. column values and such).
Accepts a parameter, which signifies SQL dialect being used. Supported dialects:
:postgres
:mysql
:sqlite
:cassandra
:oracle
Airbrake.add_filter(Airbrake::Filters::SqlFilter.new(:postgres))
Using classes for building filters
For more complex filters you can use the special API. Simply pass an object that
responds to the #call
method.
class MyFilter
def call(notice)
# ...
end
end
Airbrake.add_filter(MyFilter.new)
The library provides two default filters that you can use to filter notices: KeysBlocklist & KeysAllowlist.
Airbrake.build_notice
Builds an Airbrake notice. This is useful if you want to add or
modify a value only for a specific notice. When you're done modifying the
notice, send it with Airbrake.notify
or Airbrake.notify_sync
.
notice = Airbrake.build_notice('App crashed!')
notice[:params][:username] = user.name
airbrake.notify_sync(notice)
See the block form of Airbrake.notify
for shorter syntax.
Airbrake.close
Makes the notifier a no-op, which means you cannot use the .notify
and
.notify_sync
methods anymore. It also stops the notifier's worker threads.
Airbrake.close
Airbrake.notify('App crashed!') #=> raises Airbrake::Error
If you want to guarantee delivery of all unsent exceptions on program exit, make
sure to close
your Airbrake notifier. Usually, this can be done with help of
Ruby's at_exit
hook.
at_exit do
# Closes the default notifier.
Airbrake.close
end
Airbrake.notify_deploy
Notifies Airbrake of a new deploy. Accepts a Hash with the following params:
Airbrake.notify_deploy(
environment: 'development',
username: 'john',
repository: 'https://github.com/airbrake/airbrake-ruby',
revision: '0b77f289166c9fef4670588471b6584fbc34b0f3',
version: '1.2.3'
)
Airbrake.configured?
Checks whether the notifier is configured or not:
Airbrake.configured? #=> false
Airbrake.merge_context
Merges the provided context Hash with the notifier context. Upon a
notify/notify_sync
call the notifier context is attached to
the notice object under the params/airbrake_context
key.
After the error is attached, the notifier context is cleared, allowing other
notify
calls to start with a clean slate.
This method is specifically useful when you want to attach variables from different scopes during the execution of your program and then send them to Airbrake on error.
class MerryGrocer
def load_fruits(fruits)
Airbrake.merge_context(fruits: fruits)
end
def deliver_fruits
Airbrake.notify('fruitception')
end
def load_veggies(veggies)
Airbrake.merge_context(veggies: veggies)
end
def deliver_veggies
Airbrake.notify('veggieboom!')
end
end
grocer = MerryGrocer.new
# The context is added to `notice[:params][:airbrake_context]`.
Airbrake.add_filter do |notice|
puts "Context: #{notice[:params][:airbrake_context] || 'empty'}"
end
# Load some fruits to the context.
grocer.load_fruits(%w(mango banana apple))
# Deliver the fruits. Note that we are not passing anything, `deliver_fruits`
# knows that we loaded something.
grocer.deliver_fruits
#=> Context: ['mango', 'banana', 'apple']
# Load some vegetables and deliver them to Airbrake. Note that the fruits have
# been delivered and therefore the grocer doesn't have them anymore. We merge
# veggies with the new context.
grocer.load_veggies(%w(cabbage carrot onion))
grocer.deliver_veggies
#=> Context: ['cabbage', 'carrot', 'onion']
# The context is empty again, feel free to load more.
grocer.deliver_veggies
#=> Context: empty
Airbrake.notify_request
Sends request information (performance statistics of a route) to Airbrake Performance Monitoring. The performance statistics are displayed on the Performance tab of your project.
Airbrake.notify_request(
method: 'GET',
route: '/things/1',
status_code: 200,
timing: 123.45 # ms
)
Optionally, you can attach information to the stash (request_id
in this
example).
Airbrake.notify_request(
{
# normal params
},
request_id: 123
)
This stash can be accessed from performance filters as
metric.stash[:request_id]
.
Return value
When config.performance_stats = false
, it always returns
a rejected promise.
When config.performance_stats = true
, then it aggregates
statistics and sends as a batch every 15 seconds.
Airbrake.notify_request_sync
Sends request information (performance statistics of a route) to Airbrake Performance Monitoring synchronously. The performance statistics are displayed on the Performance tab of your project.
Accepts the same parameters as
Airbrake.notify_request
.
Return value
Always returns a Hash with response from the server.
Airbrake.notify_query
Sends SQL performance statistics to Airbrake. The performance statistics is displayed on the Performance tab of your project.
Airbrake.notify_query(
method: 'GET',
route: '/things/1',
query: 'SELECT * FROM foos',
func: 'foo', # optional
file: 'foo.rb', # optional
line: 123, # optional
timing: 123.45 # ms
)
Optionally, you can attach information to the stash (request_id
in this
example).
Airbrake.notify_query(
{
# normal params
},
request_id: 123
)
This stash can be accessed from performance filters as
metric.stash[:request_id]
.
Return value
When config.performance_stats = false
, it always returns
a rejected promise.
When config.performance_stats = true
, then it aggregates
statistics and sends as a batch every 15 seconds.
Airbrake.notify_query_sync
Sends SQL performance statistics to Airbrake synchronously. The performance statistics is displayed on the Performance tab of your project.
Accepts the same parameters as
Airbrake.notify_query
.
Return value
Always returns a Hash with response from the server.
Airbrake.notify_performance_breakdown
Sends performance breakdown statistics by groups to Airbrake. The groups are arbitrary (database, views, HTTP calls, etc.), but there can be only up to 10 groups per route in total.
Airbrake.notify_performance_breakdown(
method: 'GET',
route: '/things/1',
response_type: 'json',
groups: { db: 24.0, view: 0.4 }, # ms
timing: 123.45 # ms
)
Optionally, you can attach information to the stash (request_id
in this
example).
Airbrake.notify_performance_breakdown(
{
# normal params
},
request_id: 123
)
This stash can be accessed from performance filters as
metric.stash[:request_id]
.
Return value
When config.performance_stats = false
, it always returns
a rejected promise.
When config.performance_stats = true
, then it aggregates
statistics and sends as a batch every 15 seconds.
Airbrake.notify_performance_breakdown_sync
Sends performance breakdown statistics by groups to Airbrake synchronously. The groups are arbitrary (database, views, HTTP calls, etc.), but there can be only up to 10 groups per route in total.
Accepts the same parameters as
Airbrake.notify_performance_breakdown
.
Return value
Always returns a Hash with response from the server.
Airbrake.notify_queue
Sends queue (worker) statistics to Airbrake. Supports groups (similar to performance breakdowns).
-
queue
- name of the queue (worker) -
error_count
- how many times this worker failed -
groups
- where the job spent its time
Airbrake.notify_queue(
queue: "emails",
error_count: 1,
groups: { redis: 24.0, sql: 0.4 }, # ms
timing: 0.05221 # ms
)
Optionally, you can attach information to the stash (job_id
in this
example).
Airbrake.notify_queue(
{
# normal params
},
job_id: 123
)
This stash can be accessed from performance filters as
metric.stash[:job_id]
.
Return value
When config.performance_stats = false
, it always returns
a rejected promise.
When config.performance_stats = true
, then it aggregates
statistics and sends as a batch every 15 seconds.
Airbrake.notify_queue_sync
Sends queue (worker) statistics to Airbrake synchronously.
Accepts the same parameters as Airbrake.notify_queue
.
Return value
Always returns a Hash with response from the server.
Airbrake.add_performance_filter
Adds a performance filter that filters performance data. Works exactly like
Airbrake.add_filter
. The only difference is that
instead of Airbrake::Notice
it yields performance data (such as
Airbrake::Query
or Airbrake::Request
). It's invoked after
notify_request
or
notify_query
(but notify
calls
don't trigger it!).
Airbrake.add_performance_filter do |metric|
metric.ignore! if metric.route =~ %r{/health_check}
end
Airbrake.delete_performance_filter
Deletes a performance filter added via
Airbrake.add_performance_filter
. Works
exactly like Airbrake.delete_filter
.
Notice
Notice#ignore!
Ignores a notice. Ignored notices never reach the Airbrake dashboard. This is
useful in conjunction with Airbrake.add_filter
.
notice.ignore!
Notice#ignored?
Checks whether the notice was ignored.
notice.ignored? #=> false
Notice#[] & Notice#[]=
Accesses a notice's payload, which can be read or filtered. Payload includes:
:errors
:context
:environment
:session
:params
notice[:params][:my_param] = 'foobar'
Notice#stash[] & Notice#stash[]=
Each notice can carry arbitrary objects stored in the notice stash, accessible
through the stash
method. Callbacks defined
via add_filter
can access the stash and attach stored
object's values to the notice payload:
notice.stash[:my_object] = Object.new
Airbrake.add_filter do |notice|
# Access :my_object from the stash and directly call its method. The return
# value will be sent to Airbrake.
notice[:params][:object_id] = notice.stash[:my_object].object_id
end
Promise
Airbrake::Promise
represents a simplified promise object (similar to promises
found in JavaScript), which allows chaining callbacks that are executed when
the promise is either resolved or rejected.
Promise#then
Attaches a callback to be executed when a promise is resolved (fulfilled). The promise is resolved whenever the Airbrake API successfully accepts your exception.
Yields successful response containing the id of an error at Airbrake and URL to
the error at Airbrake. Returns self
.
Airbrake.notify('Oops').then { |response| puts response }
#=> {"id"=>"00054415-8201-e9c6-65d6-fc4d231d2871",
# "url"=>"http://localhost/locate/00054415-8201-e9c6-65d6-fc4d231d2871"}
Promise#rescue
Attaches a callback to be executed when a promise is rejected. The promise is rejected whenever the API returns an error response.
Yields an error message in the form of String explaining the failure and returns
self
.
Airbrake.notify('Oops').rescue { |error| puts error }
#=> Failed to open TCP connection to localhostt:80
Custom exception attributes
The library supports custom exception attributes. This is useful if you work
with custom exceptions, which define non-standard attributes and you can't
attach any additional data with help of the add_filter
API due to the fact that the data isn't available at configuration time yet.
In this case, you could define a special hook method on your exception called
#to_airbrake
. The method must return a Hash the keys of which must be a subset
of the ones mentioned in the Notice#[]
API.
class MyException
def initialize
@http_code = 404
end
# The library expects you to define this method. You must return a Hash,
# containing the keys you want to modify.
def to_airbrake
{ params: { http_code: @http_code } }
end
end
# The `{ http_code: 404 }` Hash will transported to the Airbrake dashboard via
# the `#to_airbrake` method.
Airbrake.notify(MyException.new)
Note You don't have to call
Airbrake.notify
manually to be able to benefit from this API. It should "just work".
Benchmark
.measure
Measures monotonic time for the given operation. Returns elapsed time in milliseconds.
time = Airbrake::Benchmark.measure do
(1..10_000).inject(:*)
end
puts "Time: #{time}"
#=> Time: 67.40199995040894
TimedTrace
Represents a chunk of code performance of which was measured and stored under a label. The chunk is called a "span". Such spans can be used for performance breakdown reporting.
.span
# Measure time for a span called 'operation'.
timed_trace = Airbrake::TimedTrace.span('operation') do
call_something
end
timed_trace.spans #=> { 'operation' => 0.123 }
# Send the spans to the Airbrake dashboard.
Airbrake.notify_performance_breakdown(
method: 'GET',
route: '/things/1',
response_type: 'json',
groups: timed_trace.spans
)
See full documentation for more examples.
Additional notes
Exception limit
The maximum size of an exception is 64KB. Exceptions that exceed this limit will be truncated to fit the size.
Running benchmarks
To run benchmarks related to asynchronous delivery, make sure to start a web server on port 8080. We provide a simple server, which can be started with this command (you need to have the Go programming language installed):
go run benchmarks/server.go
In order to run benchmarks against master
, add the lib
directory to your
LOAD_PATH
and choose the benchmark you are interested in:
ruby -Ilib benchmarks/notify_async_vs_sync.rb
Reporting critical exceptions
Critical exceptions are unhandled exceptions that terminate your program. By default, the library doesn't report them. However, you can either depend on the airbrake gem instead, which supports them, or you can add the following code somewhere in your app:
at_exit do
Airbrake.notify_sync($!) if $!
end
Remote configuration
Every 10 minutes the notifier issues an HTTP GET request to fetch remote
configuration. This might be undesirable while running tests. To suppress this
HTTP call, you need to configure your environment to test
.
Supported Rubies
- CRuby >= 2.3.0
- JRuby >= 9k
Contact
In case you have a problem, question or a bug report, feel free to:
- file an issue
- send us an email
- tweet at us
- chat with us (visit airbrake.io and click on the round orange button in the bottom right corner)
License
The project uses the MIT License. See LICENSE.md for details.