honeybadger 2.0.0.beta.4 → 2.0.0.beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ba1be7a850ea94ace04e9efa6fa6d4c6e0ac1db6
4
- data.tar.gz: c38fd1d1ef9abb8fe11cb6e753e492b6b8693b7e
3
+ metadata.gz: edb87206be0175b43798167c6e093aed0e558197
4
+ data.tar.gz: 87c340cd804c678a4c9a5e4623fd3a670bc088a7
5
5
  SHA512:
6
- metadata.gz: 71ceaf81608805c2e63f8eff80f9e78d77c5a7e3793aa9b27d8850dcea79801d19a588f41a722388d9c1d06ff4d5feb1b30fad4860574dd0a5325329cef419f8
7
- data.tar.gz: 1336df3462a84175207ab6c6f4fac477f2ed64ba990a0fad4bdd5472316befc2ccc40f1e720b7876c4ee75befb866a88166448e2feeb5c9f46d40d0ac937f712
6
+ metadata.gz: 4c943955fad4f187e3bd56c20fb8ab0b6eb08751d3811dbcc929f62a55473bd6279b78bbb6c2def674883bbb08f5fe5fa3c6c06afb396274602c067b08f1b049
7
+ data.tar.gz: eacf1d47e855c9cff4be194ce6c127b203173923a88a10dbbe85af4c38632c249d7c213a146c8d5b3af58cf97c4012524bbdf98dc3da87332147744720df5536
@@ -51,10 +51,10 @@ module Honeybadger
51
51
  end
52
52
 
53
53
  if config[:disabled]
54
- config.logger.info('Unable to start Honeybadger -- disabled by configuration.')
54
+ config.logger.warn('Unable to start Honeybadger -- disabled by configuration.')
55
55
  return false
56
56
  elsif !config.valid?
57
- config.logger.warn('Unable to start Honeybadger -- invalid configuration.')
57
+ config.logger.warn('Unable to start Honeybadger -- api_key is missing or invalid.')
58
58
  return false
59
59
  elsif !config.ping
60
60
  config.logger.warn('Unable to start Honeybadger -- failed to connect to server.')
@@ -98,6 +98,20 @@ module Honeybadger
98
98
  @at_exit
99
99
  end
100
100
 
101
+ # Internal: Not for public consumption. :)
102
+ #
103
+ # Prefer dependency injection over accessing config directly, but some
104
+ # cases (such as the delayed_job plugin) necessitate it.
105
+ #
106
+ # Returns the Agent's config if running, otherwise default config
107
+ def self.config
108
+ if running?
109
+ instance.send(:config)
110
+ else
111
+ @config ||= Config.new
112
+ end
113
+ end
114
+
101
115
  def initialize(config)
102
116
  @config = config
103
117
  @worker = Worker.new(config)
@@ -108,11 +122,14 @@ module Honeybadger
108
122
  end
109
123
  end
110
124
 
111
- def_delegators :@worker, :start, :fork, :trace, :timing, :increment
125
+ def_delegators :@worker, :stop, :fork, :trace, :timing, :increment
126
+
127
+ def start
128
+ unless worker.backend.kind_of?(Backend::Server)
129
+ warn('Initializing development backend: data will not be reported.')
130
+ end
112
131
 
113
- def stop(force = false)
114
- info("Shutting down Honeybadger version #{VERSION}")
115
- worker.stop(force)
132
+ worker.start
116
133
  end
117
134
 
118
135
  def notice(opts)
@@ -2,9 +2,12 @@ require 'honeybadger/backend/null'
2
2
 
3
3
  module Honeybadger
4
4
  module Backend
5
+ # Internal: Logs the notice payload rather than sending it. The purpose of
6
+ # this backend is primarily for programmatically inspecting JSON payloads
7
+ # in integration tests.
5
8
  class Debug < Null
6
9
  def notify(feature, payload)
7
- logger.debug("notifying debug backend of feature=#{feature}\n\t#{payload.to_json}")
10
+ logger.unknown("notifying debug backend of feature=#{feature}\n\t#{payload.to_json}")
8
11
  super
9
12
  end
10
13
  end
@@ -5,7 +5,6 @@ module Honeybadger
5
5
  class Null < Base
6
6
  def initialize(*args)
7
7
  super
8
- logger.warn('Initializing development backend: data will not be reported.')
9
8
  end
10
9
 
11
10
  def notify(feature, payload)
@@ -68,7 +68,7 @@ module Honeybadger
68
68
  out = StringIO.new
69
69
  $stdout = out
70
70
 
71
- Agent.at_exit do
71
+ flush = Proc.new do
72
72
  $stdout = STDOUT
73
73
  File.open(options[:file], 'w+') do |f|
74
74
  out.rewind
@@ -77,11 +77,15 @@ module Honeybadger
77
77
 
78
78
  say("Output written to #{options[:file]}", :green)
79
79
  end
80
- end
81
80
 
82
- ENV['HONEYBADGER_LOGGING_PATH'] ||= 'STDOUT'
83
- ENV['HONEYBADGER_LOGGING_LEVEL'] ||= '0'
84
- ENV['HONEYBADGER_REPORT_DATA'] ||= 'true'
81
+ Agent.at_exit(&flush)
82
+
83
+ at_exit do
84
+ # If the agent couldn't be started, the callback should happen here
85
+ # instead.
86
+ flush.() unless Agent.running?
87
+ end
88
+ end
85
89
 
86
90
  exit(1) unless !options[:platform] || load_platform(options[:platform], options[:app])
87
91
  say("\n") if options[:platform] # Print a blank line if we just logged the platform.
@@ -89,15 +93,24 @@ module Honeybadger
89
93
  say("Detecting framework\n\n", :bold)
90
94
  load_rails(verbose: true)
91
95
 
96
+ ENV['HONEYBADGER_LOGGING_LEVEL'] = '0'
97
+ ENV['HONEYBADGER_LOGGING_TTY_LEVEL'] = '0'
98
+ ENV['HONEYBADGER_LOGGING_PATH'] = 'STDOUT'
99
+ ENV['HONEYBADGER_DEBUG'] = 'true'
100
+ ENV['HONEYBADGER_REPORT_DATA'] = 'true'
101
+
92
102
  config = Config.new(rails_framework_opts)
93
103
  say("\nConfiguration\n\n", :bold)
94
104
  output_config(config.to_hash)
95
105
 
106
+ say("\nStarting Honeybadger\n\n", :bold)
107
+ Honeybadger.start(config) unless load_rails_env(verbose: true)
108
+
96
109
  if options[:test]
97
- Honeybadger.start(config) unless load_rails_env(verbose: true)
98
110
  say("\nSending test notice\n\n", :bold)
99
111
  send_test
100
112
  end
113
+
101
114
  say("\nRunning at exit hooks\n\n", :bold)
102
115
  end
103
116
 
@@ -106,14 +119,15 @@ module Honeybadger
106
119
  def install(api_key)
107
120
  say("Installing Honeybadger #{VERSION}")
108
121
 
109
- ENV['HONEYBADGER_LOGGING_PATH'] ||= 'STDOUT'
110
- ENV['HONEYBADGER_LOGGING_LEVEL'] ||= '2'
111
- ENV['HONEYBADGER_REPORT_DATA'] ||= 'true'
112
-
113
122
  exit(1) unless !options[:platform] || load_platform(options[:platform], options[:app])
114
123
 
115
124
  load_rails(verbose: true)
116
125
 
126
+ ENV['HONEYBADGER_LOGGING_LEVEL'] = '2'
127
+ ENV['HONEYBADGER_LOGGING_TTY_LEVEL'] = '0'
128
+ ENV['HONEYBADGER_LOGGING_PATH'] = 'STDOUT'
129
+ ENV['HONEYBADGER_REPORT_DATA'] = 'true'
130
+
117
131
  config = Config.new(rails_framework_opts)
118
132
  config[:api_key] = api_key
119
133
 
@@ -44,15 +44,15 @@ module Honeybadger
44
44
 
45
45
  update(Env.new(ENV))
46
46
 
47
- self.logger = Logging::SupplementedLogger.new(build_logger(l))
48
- Logging::BootLogger.instance.flush(logger)
47
+ @logger = Logging::ConfigLogger.new(self, build_logger(l))
48
+ Logging::BootLogger.instance.flush(@logger)
49
49
 
50
50
  @features = Hash[FEATURES.map{|f| [f, true] }]
51
51
  end
52
52
 
53
53
  def_delegators :@values, :update
54
54
 
55
- attr_reader :features
55
+ attr_reader :logger, :features
56
56
 
57
57
  def get(key)
58
58
  key = key.to_sym
@@ -97,12 +97,8 @@ module Honeybadger
97
97
  self[:api_key] =~ /\S/
98
98
  end
99
99
 
100
- def logger
101
- @logger || Logging::SupplementedLogger.new(Logging::BootLogger.instance)
102
- end
103
-
104
- def logger=(logger)
105
- @logger = logger.nil? ? Logger.new('/dev/null') : logger
100
+ def debug?
101
+ self[:debug]
106
102
  end
107
103
 
108
104
  # Internal: Optional path to honeybadger.log log file. If nil, STDOUT will be used
@@ -204,8 +200,8 @@ api_key: #{self[:api_key]}
204
200
  end
205
201
  end
206
202
 
207
- def log_level
208
- case self[:'logging.level'].to_s
203
+ def log_level(key = :'logging.level')
204
+ case self[key].to_s
209
205
  when /\A(0|debug)\z/i then Logger::DEBUG
210
206
  when /\A(1|info)\z/i then Logger::INFO
211
207
  when /\A(2|warn)\z/i then Logger::WARN
@@ -46,7 +46,7 @@ module Honeybadger
46
46
  default: false
47
47
  },
48
48
  development_environments: {
49
- description: 'Environments which are disabled by default (use report_data to enable/disable explicitly).',
49
+ description: 'Environments which will not report data by default (use report_data to enable/disable explicitly).',
50
50
  default: ['development'.freeze, 'test'.freeze, 'cucumber'.freeze].freeze
51
51
  },
52
52
  plugins: {
@@ -69,6 +69,10 @@ module Honeybadger
69
69
  description: 'The log level.',
70
70
  default: 'INFO'
71
71
  },
72
+ :'logging.tty_level' => {
73
+ description: 'Level to log when attached to a terminal (anything < logging.level will always be ignored).',
74
+ default: 'DEBUG'
75
+ },
72
76
  :'connection.secure' => {
73
77
  description: 'Use SSL when sending data.',
74
78
  default: true
@@ -180,6 +184,10 @@ module Honeybadger
180
184
  :'traces.threshold' => {
181
185
  description: 'The threshold in seconds to send traces.',
182
186
  default: 2000
187
+ },
188
+ :'delayed_job.attempt_threshold' => {
189
+ description: 'The number of attempts before notifications will be sent.',
190
+ default: 0
183
191
  }
184
192
  }.freeze
185
193
 
@@ -6,27 +6,32 @@ module Honeybadger
6
6
  module Logging
7
7
  PREFIX = '** [Honeybadger] '.freeze
8
8
 
9
+ # Internal: Logging helper methods. Requires a Honeybadger::Config @config
10
+ # instance variable to exist and/or #logger to be defined. Each
11
+ # method is defined/block captured in this module rather than delegating to
12
+ # the logger directly to avoid extra object allocation.
9
13
  module Helper
10
14
  def debug(msg = nil)
11
- return if Logger::Severity::DEBUG < logger.level
15
+ return true unless logger.debug?
12
16
  msg = yield if block_given?
13
17
  logger.debug(msg)
14
18
  end
19
+ alias :d :debug
15
20
 
16
21
  def info(msg = nil)
17
- return if Logger::Severity::INFO < logger.level
22
+ return true if Logger::Severity::INFO < logger.level
18
23
  msg = yield if block_given?
19
24
  logger.info(msg)
20
25
  end
21
26
 
22
27
  def warn(msg = nil)
23
- return if Logger::Severity::WARN < logger.level
28
+ return true if Logger::Severity::WARN < logger.level
24
29
  msg = yield if block_given?
25
30
  logger.warn(msg)
26
31
  end
27
32
 
28
33
  def error(msg = nil)
29
- return if Logger::Severity::ERROR < logger.level
34
+ return true if Logger::Severity::ERROR < logger.level
30
35
  msg = yield if block_given?
31
36
  logger.error(msg)
32
37
  end
@@ -43,7 +48,7 @@ module Honeybadger
43
48
  end
44
49
  end
45
50
 
46
- def add(severity, message)
51
+ def add(severity, msg)
47
52
  raise NotImplementedError, 'must define #add on subclass.'
48
53
  end
49
54
 
@@ -52,7 +57,26 @@ module Honeybadger
52
57
  end
53
58
  end
54
59
 
55
- class FormattedLogger < Base
60
+ class BootLogger < Base
61
+ include Singleton
62
+
63
+ def initialize
64
+ @messages = []
65
+ end
66
+
67
+ def add(severity, msg)
68
+ @messages << [severity, msg]
69
+ end
70
+
71
+ def flush(logger)
72
+ @messages.each do |msg|
73
+ logger.add(*msg)
74
+ end
75
+ @messages.clear
76
+ end
77
+ end
78
+
79
+ class StandardLogger < Base
56
80
  def initialize(logger = Logger.new('/dev/null'))
57
81
  raise ArgumentError, 'logger not specified' unless logger
58
82
  raise ArgumentError, 'logger must be a logger' unless logger.respond_to?(:add)
@@ -60,67 +84,79 @@ module Honeybadger
60
84
  @logger = logger
61
85
  end
62
86
 
63
- def add(severity, message)
64
- @logger.add(severity, format_message(message))
87
+ def add(severity, msg)
88
+ @logger.add(severity, msg)
65
89
  end
66
90
 
67
91
  def level
68
92
  @logger.level
69
93
  end
70
-
71
- private
72
-
73
- def format_message(message)
74
- return message unless message.kind_of?(String)
75
- PREFIX + message
76
- end
77
94
  end
78
95
 
79
- class BootLogger < Base
80
- include Singleton
81
-
82
- def initialize
83
- @messages = []
96
+ class FormattedLogger < StandardLogger
97
+ def add(severity, msg)
98
+ super(severity, format_message(msg))
84
99
  end
85
100
 
86
- def add(severity, message)
87
- @messages << [severity, message]
88
- end
101
+ private
89
102
 
90
- def flush(logger)
91
- @messages.each do |msg|
92
- logger.add(*msg)
93
- end
94
- @messages.clear
103
+ def format_message(msg)
104
+ return msg unless msg.kind_of?(String)
105
+ PREFIX + msg
95
106
  end
96
107
  end
97
108
 
98
- class SupplementedLogger < SimpleDelegator
109
+ class ConfigLogger < StandardLogger
99
110
  LOCATE_CALLER_LOCATION = Regexp.new("#{Regexp.escape(__FILE__)}").freeze
100
111
  CALLER_LOCATION = Regexp.new("#{Regexp.escape(File.expand_path('../../../', __FILE__))}/(.*)").freeze
101
112
 
102
113
  INFO_SUPPLEMENT = ' level=%s pid=%s'.freeze
103
114
  DEBUG_SUPPLEMENT = ' at=%s'.freeze
104
115
 
105
- def initialize(logger = Logger.new('/dev/null'))
106
- raise ArgumentError, 'logger not specified' unless logger
107
- super
116
+ def initialize(config, logger = Logger.new('/dev/null'))
117
+ @config = config
118
+ @tty = STDOUT.tty?
119
+ @tty_level = @config.log_level(:'logging.tty_level')
120
+ super(logger)
108
121
  end
109
122
 
110
- Logger::Severity.constants.each do |severity|
111
- define_method l = severity.downcase do |msg|
112
- __getobj__().send(l, supplement(msg, l))
123
+ def add(severity, msg)
124
+ return true if suppress_tty?(severity)
125
+
126
+ # There is no debug level in Honeybadger. Debug logs will be logged at
127
+ # the info level if the debug config option is on.
128
+ if severity == Logger::Severity::DEBUG
129
+ return true if suppress_debug?
130
+ super(Logger::Severity::INFO, supplement(msg, Logger::Severity::DEBUG))
131
+ else
132
+ super(severity, supplement(msg, severity))
113
133
  end
114
134
  end
115
135
 
136
+ def debug?
137
+ @config.debug?
138
+ end
139
+
116
140
  private
117
141
 
118
- def supplement(msg, level)
119
- msg << sprintf(INFO_SUPPLEMENT, level, Process.pid)
120
- if level == :debug && l = caller_location
121
- msg << sprintf(DEBUG_SUPPLEMENT, l.dump)
142
+ def suppress_debug?
143
+ !debug?
144
+ end
145
+
146
+ def suppress_tty?(severity)
147
+ @tty && severity < @tty_level
148
+ end
149
+
150
+ def supplement(msg, severity)
151
+ return msg unless msg.kind_of?(String)
152
+
153
+ r = msg.dup
154
+ r << sprintf(INFO_SUPPLEMENT, severity, Process.pid)
155
+ if severity == Logger::Severity::DEBUG && l = caller_location
156
+ r << sprintf(DEBUG_SUPPLEMENT, l.dump)
122
157
  end
123
- msg
158
+
159
+ r
124
160
  end
125
161
 
126
162
  def caller_location
@@ -23,7 +23,7 @@ module Honeybadger
23
23
  :attempts => job.attempts,
24
24
  :queue => job.queue
25
25
  }
26
- )
26
+ ) if job.attempts.to_i >= ::Honeybadger::Agent.config[:'delayed_job.attempt_threshold'].to_i
27
27
  raise error
28
28
  ensure
29
29
  ::Honeybadger.context.clear!
@@ -1,4 +1,4 @@
1
1
  module Honeybadger
2
2
  # Public: The current String Honeybadger version.
3
- VERSION = '2.0.0.beta.4'.freeze
3
+ VERSION = '2.0.0.beta.5'.freeze
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honeybadger
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.beta.4
4
+ version: 2.0.0.beta.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Honeybadger Industries LLC
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-15 00:00:00.000000000 Z
11
+ date: 2014-09-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Make managing application errors a more pleasant experience.
14
14
  email: