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

Sign up to get free protection for your applications and to get access to all the features.
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: