Class: Honeybadger::Config
- Inherits:
-
Object
- Object
- Honeybadger::Config
- Extended by:
- Forwardable
- Includes:
- Logging::Helper
- Defined in:
- lib/honeybadger/config.rb,
lib/honeybadger/config/env.rb,
lib/honeybadger/config/yaml.rb,
lib/honeybadger/config/defaults.rb,
lib/honeybadger/config/callbacks.rb
Defined Under Namespace
Classes: Boolean, Callbacks, ConfigError, Env, Yaml
Constant Summary collapse
- KEY_REPLACEMENT =
Regexp.new('[^a-z\d_]', Regexp::IGNORECASE).freeze
- DOTTED_KEY =
Regexp.new('\A([^\.]+)\.(.+)\z').freeze
- NOT_BLANK =
Regexp.new('\S').freeze
- FEATURES =
[:notices, :local_variables, :metrics, :traces].freeze
- MERGE_DEFAULT =
[:'exceptions.ignore'].freeze
- OVERRIDE =
{ :'exceptions.ignore' => :'exceptions.ignore_only' }.freeze
- DEFAULT_REQUEST_HASH =
{}.freeze
- IGNORE_DEFAULT =
['ActionController::RoutingError', 'AbstractController::ActionNotFound', 'ActionController::MethodNotAllowed', 'ActionController::UnknownHttpMethod', 'ActionController::NotImplemented', 'ActionController::UnknownFormat', 'ActionController::InvalidAuthenticityToken', 'ActionController::InvalidCrossOriginRequest', 'ActionDispatch::ParamsParser::ParseError', 'ActionController::BadRequest', 'ActionController::ParameterMissing', 'ActiveRecord::RecordNotFound', 'ActionController::UnknownAction', 'CGI::Session::CookieStore::TamperedWithCookie', 'Mongoid::Errors::DocumentNotFound', 'Sinatra::NotFound'].map(&:freeze).freeze
- DEVELOPMENT_ENVIRONMENTS =
['development', 'test', 'cucumber'].map(&:freeze).freeze
- DEFAULT_PATHS =
['honeybadger.yml', 'config/honeybadger.yml'].map(&:freeze).freeze
- OPTIONS =
{ api_key: { description: 'The API key for your Honeybadger project.', default: nil, type: String }, env: { description: 'The current application\'s environment name.', default: ENV['HONEYBADGER_ENV'] || ENV['RACK_ENV'], type: String }, report_data: { description: 'Enable/disable reporting of data. Defaults to true for non-development environments.', default: nil, type: Boolean }, root: { description: 'The project\'s absolute root path.', default: Dir.pwd, type: String }, hostname: { description: 'The hostname of the current box.', default: Socket.gethostname, type: String }, backend: { description: 'An alternate backend to use for reporting data.', default: nil, type: String }, debug: { description: 'Forces metrics and traces to be reported every 10 seconds rather than 60.', default: false, type: Boolean }, disabled: { description: 'Prevents Honeybadger from starting entirely.', default: false, type: Boolean }, development_environments: { description: 'Environments which will not report data by default (use report_data to enable/disable explicitly).', default: DEVELOPMENT_ENVIRONMENTS, type: Array }, :'send_data_at_exit' => { description: 'Send remaining data when Ruby exits.', default: true, type: Boolean }, plugins: { description: 'An optional list of plugins to load. Default is to load all plugins.', default: nil, type: Array }, :'plugins.skip' => { description: 'An optional list of plugins to skip.', default: nil, type: Array }, :'config.path' => { description: 'The path (absolute, or relative from config.root) to the project\'s YAML configuration file.', default: DEFAULT_PATHS, type: String }, :'logging.path' => { description: 'The path (absolute, or relative from config.root) to the log file.', default: nil, type: String }, :'logging.level' => { description: 'The log level.', default: 'INFO', type: String }, :'logging.debug' => { description: 'Override debug logging.', default: nil, type: Boolean }, :'logging.tty_level' => { description: 'Level to log when attached to a terminal (anything < logging.level will always be ignored).', default: 'DEBUG', type: String }, :'connection.secure' => { description: 'Use SSL when sending data.', default: true, type: Boolean }, :'connection.host' => { description: 'The host to use when sending data.', default: 'api.honeybadger.io'.freeze, type: String }, :'connection.port' => { description: 'The port to use when sending data.', default: nil, type: Integer }, :'connection.system_ssl_cert_chain' => { description: 'Use the system\'s SSL certificate chain (if available).', default: false, type: Boolean }, :'connection.http_open_timeout' => { description: 'The HTTP open timeout when connecting to the server.', default: 2, type: Integer }, :'connection.http_read_timeout' => { description: 'The HTTP read timeout when connecting to the server.', default: 5, type: Integer }, :'connection.proxy_host' => { description: 'The proxy host to use when sending data.', default: nil, type: String }, :'connection.proxy_port' => { description: 'The proxy port to use when sending data.', default: nil, type: Integer }, :'connection.proxy_user' => { description: 'The proxy user to use when sending data.', default: nil, type: String }, :'connection.proxy_pass' => { description: 'The proxy password to use when sending data.', default: nil, type: String }, :'request.filter_keys' => { description: 'A list of keys to filter when sending request data.', default: ['password'.freeze, 'password_confirmation'.freeze].freeze, type: Array }, :'request.disable_session' => { description: 'Prevent session from being sent with request data.', default: false, type: Boolean }, :'request.disable_params' => { description: 'Prevent params from being sent with request data.', default: false, type: Boolean }, :'request.disable_environment' => { description: 'Prevent Rack environment from being sent with request data.', default: false, type: Boolean }, :'request.disable_url' => { description: 'Prevent url from being sent with request data (Rack environment may still contain it in some cases).', default: false, type: Boolean }, :'user_informer.enabled' => { description: 'Enable the UserInformer middleware.', default: true, type: Boolean }, :'user_informer.info' => { description: 'Replacement string for HTML comment in templates.', default: 'Honeybadger Error {{error_id}}'.freeze, type: String }, :'feedback.enabled' => { description: 'Enable the UserFeedback middleware.', default: true, type: Boolean }, :'exceptions.enabled' => { description: 'Enable automatic reporting of exceptions.', default: true, type: Boolean }, :'exceptions.ignore' => { description: 'A list of additional exceptions to ignore (includes default ignored exceptions).', default: IGNORE_DEFAULT, type: Array }, :'exceptions.ignore_only' => { description: 'A list of exceptions to ignore (overrides the default ignored exceptions).', default: [].freeze, type: Array }, :'exceptions.ignored_user_agents' => { description: 'A list of user agents to ignore.', default: [].freeze, type: Array }, :'exceptions.rescue_rake' => { description: 'Enable rescuing exceptions in rake tasks.', default: true, type: Boolean }, :'exceptions.source_radius' => { description: 'The number of lines before and after the source when reporting snippets.', default: 2, type: Integer }, :'exceptions.local_variables' => { description: 'Enable sending local variables. Requires binding_of_caller to be loaded.', default: false, type: Boolean }, :'exceptions.unwrap' => { description: 'Reports #original_exception or #cause one level up from rescued exception when available.', default: false, type: Boolean }, :'metrics.enabled' => { description: 'Enable sending metrics.', default: true, type: Boolean }, :'metrics.gc_profiler' => { description: 'Enable sending GC metrics (GC::Profiler must be enabled)', default: false, type: Boolean }, :'traces.enabled' => { description: 'Enable sending traces.', default: true, type: Boolean }, :'traces.threshold' => { description: 'The threshold in seconds to send traces.', default: 2000, type: Integer }, :'delayed_job.attempt_threshold' => { description: 'The number of attempts before notifications will be sent.', default: 0, type: Integer }, :'sidekiq.attempt_threshold' => { description: 'The number of attempts before notifications will be sent.', default: 0, type: Integer }, :'sinatra.enabled' => { description: 'Enable Sinatra auto-initialization.', default: true, type: Boolean } }.freeze
- DEFAULTS =
Hash[OPTIONS.map{|k,v| [k, v[:default]] }].freeze
Instance Attribute Summary collapse
-
#features ⇒ Object
readonly
Returns the value of attribute features.
Instance Method Summary collapse
- #backend ⇒ Object
- #ca_bundle_path ⇒ Object
-
#config_path ⇒ Object
Internal: Path to honeybadger.yml configuration file; this should be the root directory if no path was specified.
- #config_paths ⇒ Object
- #connection_port ⇒ Object
- #connection_protocol ⇒ Object
- #debug? ⇒ Boolean
- #default_backend ⇒ Object
- #dev? ⇒ Boolean
- #excluded_request_keys ⇒ Object
- #feature?(feature) ⇒ Boolean
- #framework ⇒ Object
- #framework_name ⇒ Object
- #get(key) ⇒ Object (also: #[])
-
#initialize(opts = {}) ⇒ Config
constructor
A new instance of Config.
- #load_plugin?(name) ⇒ Boolean
- #local_cert_path ⇒ Object
- #log_debug? ⇒ Boolean
- #log_level(key = :'logging.level') ⇒ Object
-
#log_path ⇒ Object
Internal: Optional path to honeybadger.log log file.
- #logger ⇒ Object
- #params_filters ⇒ Object
- #ping ⇒ Object
- #public? ⇒ Boolean
- #rails_params_filters ⇒ Object
- #request ⇒ Object
- #request_hash ⇒ Object
-
#root_regexp ⇒ Object
Internal: Match the project root.
- #set(key, value) ⇒ Object (also: #[]=)
- #to_hash(defaults = false) ⇒ Object (also: #to_h)
- #valid? ⇒ Boolean
- #with_request(request, &block) ⇒ Object
- #write ⇒ Object
Constructor Details
#initialize(opts = {}) ⇒ Config
Returns a new instance of Config.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/honeybadger/config.rb', line 43 def initialize(opts = {}) l = opts.delete(:logger) @values = opts priority = {} priority.update(opts) load_config_from_disk {|yml| priority.update(yml) } priority.update(Env.new(ENV)) update(merge_defaults!(priority)) @logger = Logging::ConfigLogger.new(self, build_logger(l)) Logging::BootLogger.instance.flush(@logger) @features = Hash[FEATURES.map{|f| [f, true] }] end |
Instance Attribute Details
#features ⇒ Object (readonly)
Returns the value of attribute features.
62 63 64 |
# File 'lib/honeybadger/config.rb', line 62 def features @features end |
Instance Method Details
#backend ⇒ Object
95 96 97 |
# File 'lib/honeybadger/config.rb', line 95 def backend Backend.for((self[:backend] || default_backend).to_sym).new(self) end |
#ca_bundle_path ⇒ Object
154 155 156 157 158 159 160 |
# File 'lib/honeybadger/config.rb', line 154 def ca_bundle_path if self[:'connection.system_ssl_cert_chain'] && File.exist?(OpenSSL::X509::DEFAULT_CERT_FILE) OpenSSL::X509::DEFAULT_CERT_FILE else local_cert_path end end |
#config_path ⇒ Object
Internal: Path to honeybadger.yml configuration file; this should be the root directory if no path was specified.
Returns the Pathname configuration path.
144 145 146 |
# File 'lib/honeybadger/config.rb', line 144 def config_path config_paths.first end |
#config_paths ⇒ Object
148 149 150 151 152 |
# File 'lib/honeybadger/config.rb', line 148 def config_paths Array(ENV['HONEYBADGER_CONFIG_PATH'] || get(:'config.path')).map do |c| locate_absolute_path(c, self[:root]) end end |
#connection_port ⇒ Object
166 167 168 169 170 171 172 173 174 |
# File 'lib/honeybadger/config.rb', line 166 def connection_port if self[:'connection.port'] self[:'connection.port'] elsif self[:'connection.secure'] 443 else 80 end end |
#connection_protocol ⇒ Object
176 177 178 179 180 181 182 |
# File 'lib/honeybadger/config.rb', line 176 def connection_protocol if self[:'connection.secure'] 'https' else 'http' end end |
#debug? ⇒ Boolean
121 122 123 |
# File 'lib/honeybadger/config.rb', line 121 def debug? !!self[:debug] end |
#default_backend ⇒ Object
109 110 111 112 113 114 115 |
# File 'lib/honeybadger/config.rb', line 109 def default_backend if public? :server else :null end end |
#dev? ⇒ Boolean
99 100 101 |
# File 'lib/honeybadger/config.rb', line 99 def dev? self[:env] && Array(self[:development_environments]).include?(self[:env]) end |
#excluded_request_keys ⇒ Object
208 209 210 211 212 213 214 215 |
# File 'lib/honeybadger/config.rb', line 208 def excluded_request_keys [].tap do |keys| keys << :session if self[:'request.disable_session'] keys << :params if self[:'request.disable_params'] keys << :cgi_data if self[:'request.disable_environment'] keys << :url if self[:'request.disable_url'] end end |
#feature?(feature) ⇒ Boolean
87 88 89 |
# File 'lib/honeybadger/config.rb', line 87 def feature?(feature) !!features[feature.to_sym] end |
#framework ⇒ Object
260 261 262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/honeybadger/config.rb', line 260 def framework if self[:framework] =~ NOT_BLANK self[:framework].to_sym elsif defined?(::Rails::VERSION) && ::Rails::VERSION::STRING > '3.0' :rails elsif defined?(::Sinatra::VERSION) :sinatra elsif defined?(::Rack.release) :rack else :ruby end end |
#framework_name ⇒ Object
274 275 276 277 278 279 280 281 282 |
# File 'lib/honeybadger/config.rb', line 274 def framework_name case framework when :rails then "Rails #{::Rails::VERSION::STRING}" when :sinatra then "Sinatra #{::Sinatra::VERSION}" when :rack then "Rack #{::Rack.release}" else "Ruby #{RUBY_VERSION}" end end |
#get(key) ⇒ Object Also known as: []
64 65 66 67 68 69 70 71 72 73 |
# File 'lib/honeybadger/config.rb', line 64 def get(key) key = key.to_sym if OVERRIDE.has_key?(key) && @values.has_key?(OVERRIDE[key]) @values[OVERRIDE[key]] elsif @values.has_key?(key) @values[key] else DEFAULTS[key] end end |
#load_plugin?(name) ⇒ Boolean
245 246 247 248 249 |
# File 'lib/honeybadger/config.rb', line 245 def load_plugin?(name) return false if Array(self[:'plugins.skip']).include?(name) return true if self[:plugins].nil? Array(self[:plugins]).include?(name) end |
#local_cert_path ⇒ Object
162 163 164 |
# File 'lib/honeybadger/config.rb', line 162 def local_cert_path File.(File.join('..', '..', '..', 'resources', 'ca-bundle.crt'), __FILE__) end |
#log_debug? ⇒ Boolean
125 126 127 128 |
# File 'lib/honeybadger/config.rb', line 125 def log_debug? return debug? if self[:'logging.debug'].nil? !!self[:'logging.debug'] end |
#log_level(key = :'logging.level') ⇒ Object
234 235 236 237 238 239 240 241 242 243 |
# File 'lib/honeybadger/config.rb', line 234 def log_level(key = :'logging.level') case self[key].to_s when /\A(0|debug)\z/i then Logger::DEBUG when /\A(1|info)\z/i then Logger::INFO when /\A(2|warn)\z/i then Logger::WARN when /\A(3|error)\z/i then Logger::ERROR else Logger::INFO end end |
#log_path ⇒ Object
Internal: Optional path to honeybadger.log log file. If nil, STDOUT will be used instead.
Returns the Pathname log path if a log path was specified.
134 135 136 137 138 |
# File 'lib/honeybadger/config.rb', line 134 def log_path if self[:'logging.path'] && self[:'logging.path'] != 'STDOUT' locate_absolute_path(self[:'logging.path'], self[:root]) end end |
#logger ⇒ Object
91 92 93 |
# File 'lib/honeybadger/config.rb', line 91 def logger @logger || Logging::BootLogger.instance end |
#params_filters ⇒ Object
200 201 202 |
# File 'lib/honeybadger/config.rb', line 200 def params_filters self[:'request.filter_keys'] + rails_params_filters end |
#ping ⇒ Object
251 252 253 254 255 256 257 258 |
# File 'lib/honeybadger/config.rb', line 251 def ping if result = send_ping @features = symbolize_keys(result['features']) if result['features'] return true end false end |
#public? ⇒ Boolean
103 104 105 106 107 |
# File 'lib/honeybadger/config.rb', line 103 def public? return true if self[:report_data] return false if self[:report_data] == false !self[:env] || !dev? end |
#rails_params_filters ⇒ Object
204 205 206 |
# File 'lib/honeybadger/config.rb', line 204 def rails_params_filters request && request.env['action_dispatch.parameter_filter'] or [] end |
#request ⇒ Object
184 185 186 |
# File 'lib/honeybadger/config.rb', line 184 def request Thread.current[:__honeybadger_request] end |
#request_hash ⇒ Object
195 196 197 198 |
# File 'lib/honeybadger/config.rb', line 195 def request_hash return DEFAULT_REQUEST_HASH unless request Rack::RequestHash.new(request) end |
#root_regexp ⇒ Object
Internal: Match the project root.
Returns Regexp matching the project root in a file string.
287 288 289 290 291 292 293 294 295 |
# File 'lib/honeybadger/config.rb', line 287 def root_regexp return @root_regexp if @root_regexp return nil if @no_root root = get(:root).to_s @no_root = true and return nil unless root =~ NOT_BLANK @root_regexp = Regexp.new("^#{ Regexp.escape(root) }") end |
#set(key, value) ⇒ Object Also known as: []=
76 77 78 |
# File 'lib/honeybadger/config.rb', line 76 def set(key, value) @values[key] = value end |
#to_hash(defaults = false) ⇒ Object Also known as: to_h
81 82 83 84 |
# File 'lib/honeybadger/config.rb', line 81 def to_hash(defaults = false) hash = defaults ? DEFAULTS.merge(@values) : @values undotify_keys(hash.select {|k,v| DEFAULTS.has_key?(k) }) end |
#valid? ⇒ Boolean
117 118 119 |
# File 'lib/honeybadger/config.rb', line 117 def valid? self[:api_key].to_s =~ /\S/ end |
#with_request(request, &block) ⇒ Object
188 189 190 191 192 193 |
# File 'lib/honeybadger/config.rb', line 188 def with_request(request, &block) Thread.current[:__honeybadger_request] = request yield ensure Thread.current[:__honeybadger_request] = nil end |
#write ⇒ Object
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/honeybadger/config.rb', line 217 def write path = config_path if path.exist? raise ConfigError, "The configuration file #{path} already exists." elsif !path.dirname.writable? raise ConfigError, "The configuration path #{path.dirname} is not writable." end File.open(path, 'w+') do |file| file.write(<<-CONFIG) --- api_key: '#{self[:api_key]}' CONFIG end end |