Class: Honeybadger::Plugin

Inherits:
Object
  • Object
show all
Defined in:
lib/honeybadger/plugin.rb

Overview

Honeybadger::Plugin defines the API for registering plugins with Honeybadger. Each plugin has requirements which must be satisfied before executing the plugin’s execution block(s). This allows us to detect optional dependencies and load the plugin for each dependency only if it’s present in the application.

See the plugins/ directory for examples of official plugins. If you’re interested in developing a plugin for Honeybadger, see the Integration Guide: docs.honeybadger.io/ruby/gem-reference/integration.html

Examples:


require 'honeybadger/plugin'
require 'honeybadger/ruby'

module Honeybadger
  module Plugins
    # Register your plugin with an optional name. If the name (such as
    # "my_framework") is not provided, Honeybadger will try to infer the name
    # from the current file.
    Plugin.register 'my_framework' do
      requirement do
        # Check to see if the thing you're integrating with is loaded. Return true
        # if it is, or false if it isn't. An exception in this block is equivalent
        # to returning false. Multiple requirement blocks are supported.
        defined?(MyFramework)
      end

      execution do
        # Write your integration. This code will be executed only if all requirement
        # blocks return true. An exception in this block will disable the plugin.
        # Multiple execution blocks are supported.
        MyFramework.on_exception do |exception|
          Honeybadger.notify(exception)
        end
      end
    end
  end
end

Defined Under Namespace

Classes: Execution

Constant Summary collapse

CALLER_FILE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Regexp.new('\A(?:\w:)?([^:]+)(?=(:\d+))').freeze
@@instances =

This classvariable is part of a private API. You should avoid using this classvariable if possible, as it may be removed or be changed in the future.

{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ Plugin

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Plugin.



115
116
117
118
119
120
# File 'lib/honeybadger/plugin.rb', line 115

def initialize(name)
  @name         = name
  @loaded       = false
  @requirements = []
  @executions   = []
end

Instance Attribute Details

#executionsObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



208
209
210
# File 'lib/honeybadger/plugin.rb', line 208

def executions
  @executions
end

#nameObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



208
209
210
# File 'lib/honeybadger/plugin.rb', line 208

def name
  @name
end

#requirementsObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



208
209
210
# File 'lib/honeybadger/plugin.rb', line 208

def requirements
  @requirements
end

Class Method Details

.instancesObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



52
53
54
# File 'lib/honeybadger/plugin.rb', line 52

def instances
  @@instances
end

.load!(config) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



77
78
79
80
81
82
83
84
85
# File 'lib/honeybadger/plugin.rb', line 77

def load!(config)
  instances.each_pair do |name, plugin|
    if config.load_plugin?(name)
      plugin.load!(config)
    else
      config.logger.debug(sprintf('skip plugin name=%s reason=disabled', name))
    end
  end
end

.name_from_caller(caller) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



88
89
90
91
92
# File 'lib/honeybadger/plugin.rb', line 88

def name_from_caller(caller)
  caller && caller[0].match(CALLER_FILE) or
    fail("Unable to determine name from caller: #{caller.inspect}")
  File.basename($1)[/[^\.]+/]
end

.register(name = nil, &block) ⇒ Object

Register a new plugin with Honeybadger. See #requirement and #execution.

Examples:


Honeybadger::Plugin.register 'my_framework' do
  requirement { }
  execution { }
end

Parameters:

  • name (String, Symbol) (defaults to: nil)

    The optional name of the plugin. Should use snake_case. The name is inferred from the current file name if omitted.

Returns:

  • nil



69
70
71
72
73
74
# File 'lib/honeybadger/plugin.rb', line 69

def register(name = nil, &block)
  name ||= name_from_caller(caller) or
    raise(ArgumentError, 'Plugin name is required, but was nil.')
  instances[key = name.to_sym] and fail("Already registered: #{name}")
  instances[key] = new(name).tap { |d| d.instance_eval(&block) }
end

Instance Method Details

#execution(&block) ⇒ Object

Define an execution block. Execution blocks will be executed if all requirement blocks return true.

Examples:


Honeybadger::Plugin.register 'my_framework' do
  requirement { defined?(MyFramework) }

  execution do
    MyFramework.on_exception {|err| Honeybadger.notify(err) }
  end

  execution do
    # Honeybadger's configuration object is available inside
    # execution blocks. It should generally not be used outside of
    # internal plugins. See +Config+.
    MyFramework.use_middleware(MyMiddleware) if config[:'my_framework.use_middleware']
  end
end

Returns:

  • nil



164
165
166
# File 'lib/honeybadger/plugin.rb', line 164

def execution(&block)
  @executions << block
end

#load!(config) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/honeybadger/plugin.rb', line 177

def load!(config)
  if @loaded
    config.logger.debug(sprintf('skip plugin name=%s reason=loaded', name))
    return false
  elsif ok?(config)
    config.logger.debug(sprintf('load plugin name=%s', name))
    @executions.each {|e| Execution.new(config, &e).call }
    @loaded = true
  else
    config.logger.debug(sprintf('skip plugin name=%s reason=requirement', name))
  end

  @loaded
rescue => e
  config.logger.error(sprintf("plugin error name=%s class=%s message=%s\n\t%s", name, e.class, e.message.dump, Array(e.backtrace).join("\n\t")))
  @loaded = true
  false
end

#loaded?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


197
198
199
# File 'lib/honeybadger/plugin.rb', line 197

def loaded?
  @loaded
end

#ok?(config) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


169
170
171
172
173
174
# File 'lib/honeybadger/plugin.rb', line 169

def ok?(config)
  @requirements.all? {|r| Execution.new(config, &r).call }
rescue => e
  config.logger.error(sprintf("plugin error name=%s class=%s message=%s\n\t%s", name, e.class, e.message.dump, Array(e.backtrace).join("\n\t")))
  false
end

#requirement(&block) ⇒ Object

Define a requirement. All requirement blocks must return true for the plugin to be executed.

Examples:


Honeybadger::Plugin.register 'my_framework' do
  requirement { defined?(MyFramework) }

  # Honeybadger's configuration object is available inside
  # requirement blocks. It should generally not be used outside of
  # internal plugins. See +Config+.
  requirement { config[:'my_framework.enabled'] }

  execution { }
end

Returns:

  • nil



139
140
141
# File 'lib/honeybadger/plugin.rb', line 139

def requirement(&block)
  @requirements << block
end

#reset!Object

Used for testing only; don’t normally call this. :)



203
204
205
# File 'lib/honeybadger/plugin.rb', line 203

def reset!
  @loaded = false
end