class Honeybadger::Agent
The Honeybadger
agent contains all the methods for interacting with the Honeybadger
service. It can be used to send notifications to multiple projects in large apps. The global agent instance ({Agent.instance}) should always be accessed through the {Honeybadger} singleton.
=== Context
Context is global by default, meaning agents created via Honeybadger::Agent.new
will share context (added via Honeybadger.context
or {Honeybadger::Agent#context}) with other agents. This also includes the Rack
environment when using the {Honeybadger::Rack::ErrorNotifier} middleware. To localize context for a custom agent, use the +local_context: true+ option when initializing.
@example
# Standard usage: OtherBadger = Honeybadger::Agent.new # With local context: OtherBadger = Honeybadger::Agent.new(local_context: true) OtherBadger.configure do |config| config.api_key = 'project api key' end begin # Risky operation rescue => e OtherBadger.notify(e) end
Attributes
@api private
@api private
@api private
Public Class Methods
@api private
# File lib/honeybadger/agent.rb, line 51 def self.instance @instance end
@api private
# File lib/honeybadger/agent.rb, line 56 def self.instance=(instance) @instance = instance end
# File lib/honeybadger/agent.rb, line 60 def initialize(opts = {}) if opts.kind_of?(Config) @config = opts opts = {} end @context = opts.delete(:context) local_context = opts.delete(:local_context) @config ||= Config.new(opts) if local_context @context ||= ContextManager.new @breadcrumbs = Breadcrumbs::Collector.new(config) else @breadcrumbs = nil end init_worker end
Public Instance Methods
Perform a synchronous check_in.
@example Honeybadger.check_in(‘1MqIo1’)
@param [String] id The unique check in id (e.g. ‘1MqIo1’) or the check in url.
@return [Boolean] true if the check in was successful and false otherwise.
# File lib/honeybadger/agent.rb, line 195 def check_in(id) # this is to allow check ins even if a url is passed check_in_id = id.to_s.strip.gsub(/\/$/, '').split('/').last response = backend.check_in(check_in_id) response.success? end
Clear all transaction scoped data.
# File lib/honeybadger/agent.rb, line 270 def clear! context_manager.clear! breadcrumbs.clear! end
Save global context for the current request.
@example Honeybadger.context({my_data: ‘my value’})
# Inside a Rails controller: before_action do Honeybadger.context({user_id: current_user.id}) end # Explicit conversion class User < ActiveRecord::Base def to_honeybadger_context { user_id: id, user_email: email } end end user = User.first Honeybadger.context(user) # Clearing global context: Honeybadger.context.clear!
@param [Hash] context A Hash of data which will be sent to Honeybadger
when an error occurs. If the object responds to #to_honeybadger_context
, the return value of that method will be used (explicit conversion). Can include any key/value, but a few keys have a special meaning in Honeybadger
.
@option context [String] :user_id The user ID used by Honeybadger
to aggregate user data across occurrences on the error page (optional). @option context [String] :user_email The user email address (optional). @option context [String] :tags The comma-separated list of tags. When present, tags will be applied to errors with this context (optional).
@return [Object, self] value of the block if passed, otherwise self
# File lib/honeybadger/agent.rb, line 262 def context(context = nil, &block) block_result = context_manager.set_context(context, &block) unless context.nil? return block_result if block_given? self end
Sends event to events backend
@example # With event type as first argument (recommended): Honeybadger.event(“user_signed_up”, user_id: 123)
# With just a payload: Honeybadger.event(event_type: "user_signed_up", user_id: 123)
@param event_name [String, Hash] a String describing the event or a Hash when the second argument is omitted. @param payload [Hash] Additional data to be sent with the event as keyword arguments
@return [void]
# File lib/honeybadger/agent.rb, line 387 def event(event_type, payload = {}) init_events_worker ts = DateTime.now.new_offset(0).rfc3339 merged = {ts: ts} if event_type.is_a?(String) merged.merge!(event_type: event_type) else merged.merge!(Hash(event_type)) end merged.merge!(Hash(payload)) events_worker.push(merged) end
Flushes all data from workers before returning. This is most useful in tests when using the test backend, where normally the asynchronous nature of this library could create race conditions.
@example # Without a block: it “sends a notification to Honeybadger” do expect { Honeybadger.notify
(StandardError.new(‘test backend’)) Honeybadger.flush }.to change(Honeybadger::Backend::Test.notifications, :size).by(0) end
# With a block: it "sends a notification to Honeybadger" do expect { Honeybadger.flush do 49.times do Honeybadger.notify(StandardError.new('test backend')) end end }.to change(Honeybadger::Backend::Test.notifications[:notices], :size).by(49) end
@yield An optional block to execute (exceptions will propagate after data is flushed).
@return [Object, Boolean] value of block if block is given, otherwise true on success or false if Honeybadger
isn’t running.
# File lib/honeybadger/agent.rb, line 355 def flush return true unless block_given? yield ensure worker.flush events_worker&.flush end
Get global context for the current request.
@example Honeybadger.context({my_data: ‘my value’}) Honeybadger.get_context # => {my_data: ‘my value’}
@return [Hash, nil]
# File lib/honeybadger/agent.rb, line 282 def get_context context_manager.get_context end
Sends an exception to Honeybadger
. Does not report ignored exceptions by default.
@example # With an exception: begin fail ‘oops’ rescue => exception Honeybadger.notify
(exception, context: { my_data: ‘value’ }) # => ‘-1dfb92ae-9b01-42e9-9c13-31205b70744a’ end
# Custom notification: Honeybadger.notify('Something went wrong.', error_class: 'MyClass', context: {my_data: 'value'} ) # => '06220c5a-b471-41e5-baeb-de247da45a56'
@param [Exception, Hash, Object] exception_or_opts An Exception object, or a Hash of options which is used to build the notice. All other types of objects will be converted to a String and used as the :error_message. @param [Hash] opts The options Hash when the first argument is an Exception. @param [Hash] kwargs options as keyword args.
@option opts [String] :error_message The error message. @option opts [String] :error_class (‘Notice’) The class name of the error. @option opts [Array] :backtrace The backtrace of the error (optional). @option opts [String] :fingerprint The grouping fingerprint of the exception (optional). @option opts [Boolean] :force (false) Always report the exception when true, even when ignored (optional). @option opts [Boolean] :sync (false) Send data synchronously (skips the worker) (optional). @option opts [String] :tags The comma-separated list of tags (optional). @option opts [Hash] :context The context to associate with the exception (optional). @option opts [String] :controller The controller name (such as a Rails controller) (optional). @option opts [String] :action The action name (such as a Rails controller action) (optional). @option opts [Hash] :parameters The HTTP request paramaters (optional). @option opts [Hash] :session The HTTP request session (optional). @option opts [String] :url The HTTP request URL (optional). @option opts [Exception] :cause The cause for this error (optional).
@return [String] UUID reference to the notice within Honeybadger
. @return [false] when ignored.
# File lib/honeybadger/agent.rb, line 123 def notify(exception_or_opts = nil, opts = {}, **kwargs) opts = opts.dup opts.merge!(kwargs) if exception_or_opts.is_a?(Exception) already_reported_notice_id = exception_or_opts.instance_variable_get(:@__hb_notice_id) return already_reported_notice_id if already_reported_notice_id opts[:exception] = exception_or_opts elsif exception_or_opts.respond_to?(:to_hash) opts.merge!(exception_or_opts.to_hash) elsif !exception_or_opts.nil? opts[:error_message] = exception_or_opts.to_s end validate_notify_opts!(opts) add_breadcrumb( "Honeybadger Notice", metadata: opts, category: "notice" ) if config[:'breadcrumbs.enabled'] opts[:rack_env] ||= context_manager.get_rack_env opts[:global_context] ||= context_manager.get_context opts[:breadcrumbs] ||= breadcrumbs.dup notice = Notice.new(config, opts) config.before_notify_hooks.each do |hook| break if notice.halted? with_error_handling { hook.call(notice) } end unless notice.api_key =~ NOT_BLANK error { sprintf('Unable to send error report: API key is missing. id=%s', notice.id) } return false end if !opts[:force] && notice.ignore? debug { sprintf('ignore notice feature=notices id=%s', notice.id) } return false end if notice.halted? debug { 'halted notice feature=notices' } return false end info { sprintf('Reporting error id=%s', notice.id) } if opts[:sync] || config[:sync] send_now(notice) else push(notice) end if exception_or_opts.is_a?(Exception) exception_or_opts.instance_variable_set(:@__hb_notice_id, notice.id) unless exception_or_opts.frozen? end notice.id end
Stops the Honeybadger
service.
@example Honeybadger.stop # => nil
# File lib/honeybadger/agent.rb, line 367 def stop(force = false) worker.shutdown(force) events_worker&.shutdown(force) true end
Track a new deployment
@example Honeybadger.track_deployment(revision: ‘be2ceb6’)
@param [String] :environment The environment name. Defaults to the current configured environment. @param [String] :revision The VCS revision being deployed. Defaults to the currently configured revision. @param [String] :local_username The name of the user who performed the deploy. @param [String] :repository The base URL of the VCS repository. It should be HTTPS-style.
@return [Boolean] true if the deployment was successfully tracked and false otherwise.
# File lib/honeybadger/agent.rb, line 214 def track_deployment(environment: nil, revision: nil, local_username: nil, repository: nil) opts = { environment: environment || config[:env], revision: revision || config[:revision], local_username: local_username, repository: repository } response = backend.track_deployment(opts) response.success? end
@api private
# File lib/honeybadger/agent.rb, line 468 def with_rack_env(rack_env, &block) context_manager.set_rack_env(rack_env) yield ensure context_manager.set_rack_env(nil) end
Private Instance Methods
# File lib/honeybadger/agent.rb, line 498 def context_manager return @context if @context ContextManager.current end
# File lib/honeybadger/agent.rb, line 518 def init_events_worker return if @events_worker @events_worker = EventsWorker.new(config) end
# File lib/honeybadger/agent.rb, line 513 def init_worker return if @worker @worker = Worker.new(config) end
# File lib/honeybadger/agent.rb, line 503 def push(object) worker.push(object) true end
# File lib/honeybadger/agent.rb, line 508 def send_now(object) worker.send_now(object) true end
# File lib/honeybadger/agent.rb, line 490 def validate_notify_opts!(opts) return if opts.has_key?(:exception) return if opts.has_key?(:error_message) msg = sprintf('`Honeybadger.notify` was called with invalid arguments. You must pass either an Exception or options Hash containing the `:error_message` key. location=%s', caller[caller.size-1]) raise ArgumentError.new(msg) if config.dev? warn(msg) end
# File lib/honeybadger/agent.rb, line 523 def with_error_handling yield rescue => ex error { "Rescued an error in a before notify hook: #{ex.message}" } end