honeybadger 2.7.2 → 3.0.0.beta1
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 +4 -4
- data/CHANGELOG.md +58 -3
- data/README.md +8 -15
- data/lib/honeybadger.rb +9 -232
- data/lib/honeybadger/agent.rb +292 -134
- data/lib/honeybadger/backend.rb +6 -6
- data/lib/honeybadger/backend/base.rb +11 -0
- data/lib/honeybadger/backend/server.rb +2 -14
- data/lib/honeybadger/cli.rb +0 -2
- data/lib/honeybadger/cli/deploy.rb +42 -0
- data/lib/honeybadger/cli/exec.rb +138 -0
- data/lib/honeybadger/cli/heroku.rb +1 -22
- data/lib/honeybadger/cli/install.rb +74 -0
- data/lib/honeybadger/cli/main.rb +138 -153
- data/lib/honeybadger/cli/notify.rb +66 -0
- data/lib/honeybadger/cli/test.rb +266 -0
- data/lib/honeybadger/config.rb +178 -162
- data/lib/honeybadger/config/defaults.rb +5 -5
- data/lib/honeybadger/config/env.rb +8 -6
- data/lib/honeybadger/config/ruby.rb +100 -0
- data/lib/honeybadger/config/yaml.rb +18 -19
- data/lib/honeybadger/const.rb +3 -16
- data/lib/honeybadger/context_manager.rb +50 -0
- data/lib/honeybadger/init/rails.rb +9 -21
- data/lib/honeybadger/init/rake.rb +2 -0
- data/lib/honeybadger/init/ruby.rb +9 -0
- data/lib/honeybadger/init/sinatra.rb +13 -6
- data/lib/honeybadger/notice.rb +29 -14
- data/lib/honeybadger/plugins/delayed_job/plugin.rb +4 -5
- data/lib/honeybadger/plugins/passenger.rb +1 -2
- data/lib/honeybadger/plugins/rails.rb +0 -28
- data/lib/honeybadger/plugins/resque.rb +2 -5
- data/lib/honeybadger/plugins/shoryuken.rb +2 -2
- data/lib/honeybadger/plugins/sidekiq.rb +2 -2
- data/lib/honeybadger/plugins/sucker_punch.rb +1 -0
- data/lib/honeybadger/plugins/thor.rb +2 -2
- data/lib/honeybadger/plugins/warden.rb +1 -0
- data/lib/honeybadger/rack/error_notifier.rb +11 -9
- data/lib/honeybadger/rack/user_feedback.rb +6 -4
- data/lib/honeybadger/rack/user_informer.rb +6 -4
- data/lib/honeybadger/ruby.rb +2 -0
- data/lib/honeybadger/singleton.rb +26 -0
- data/lib/honeybadger/util/http.rb +12 -0
- data/lib/honeybadger/util/request_hash.rb +71 -0
- data/lib/honeybadger/util/sanitizer.rb +101 -64
- data/lib/honeybadger/version.rb +1 -1
- data/lib/honeybadger/worker.rb +246 -0
- metadata +17 -13
- data/lib/honeybadger/agent/batch.rb +0 -50
- data/lib/honeybadger/agent/null_worker.rb +0 -26
- data/lib/honeybadger/agent/worker.rb +0 -243
- data/lib/honeybadger/cli/helpers.rb +0 -160
- data/lib/honeybadger/config/callbacks.rb +0 -70
- data/lib/honeybadger/plugins/unicorn.rb +0 -27
- data/lib/honeybadger/rack/metrics_reporter.rb +0 -16
- data/lib/honeybadger/rack/request_hash.rb +0 -55
data/lib/honeybadger/backend.rb
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
|
3
|
+
require 'honeybadger/backend/base'
|
4
|
+
require 'honeybadger/backend/server'
|
5
|
+
require 'honeybadger/backend/test'
|
6
|
+
require 'honeybadger/backend/null'
|
7
|
+
require 'honeybadger/backend/debug'
|
8
|
+
|
3
9
|
module Honeybadger
|
4
10
|
module Backend
|
5
11
|
class BackendError < StandardError; end
|
@@ -16,11 +22,5 @@ module Honeybadger
|
|
16
22
|
def self.for(backend)
|
17
23
|
mapping[backend] or raise(BackendError, "Unable to locate backend: #{backend}")
|
18
24
|
end
|
19
|
-
|
20
|
-
autoload :Base, 'honeybadger/backend/base'
|
21
|
-
autoload :Server, 'honeybadger/backend/server'
|
22
|
-
autoload :Test, 'honeybadger/backend/test'
|
23
|
-
autoload :Null, 'honeybadger/backend/null'
|
24
|
-
autoload :Debug, 'honeybadger/backend/debug'
|
25
25
|
end
|
26
26
|
end
|
@@ -11,6 +11,13 @@ module Honeybadger
|
|
11
11
|
|
12
12
|
attr_reader :code, :body, :message, :error
|
13
13
|
|
14
|
+
FRIENDLY_ERRORS = {
|
15
|
+
429 => "Your project is currently sending too many errors.\nThis issue should resolve itself once error traffic is reduced.".freeze,
|
16
|
+
503 => "Your project is currently sending too many errors.\nThis issue should resolve itself once error traffic is reduced.".freeze,
|
17
|
+
402 => "The project owner's billing information has expired (or the trial has ended).\nPlease check your payment details or email support@honeybadger.io for help.".freeze,
|
18
|
+
403 => "The API key is invalid. Please check your API key and try again.".freeze
|
19
|
+
}.freeze
|
20
|
+
|
14
21
|
# Public: Initializes the Response instance.
|
15
22
|
#
|
16
23
|
# response - With 1 argument Net::HTTPResponse, the code, body, and
|
@@ -37,6 +44,10 @@ module Honeybadger
|
|
37
44
|
@success
|
38
45
|
end
|
39
46
|
|
47
|
+
def error_message
|
48
|
+
FRIENDLY_ERRORS[code] || message
|
49
|
+
end
|
50
|
+
|
40
51
|
private
|
41
52
|
|
42
53
|
def parse_error(body)
|
@@ -15,17 +15,7 @@ module Honeybadger
|
|
15
15
|
deploys: '/v1/deploys'.freeze
|
16
16
|
}.freeze
|
17
17
|
|
18
|
-
HTTP_ERRORS =
|
19
|
-
Errno::EINVAL,
|
20
|
-
Errno::ECONNRESET,
|
21
|
-
Errno::ECONNREFUSED,
|
22
|
-
Errno::ENETUNREACH,
|
23
|
-
EOFError,
|
24
|
-
Net::HTTPBadResponse,
|
25
|
-
Net::HTTPHeaderSyntaxError,
|
26
|
-
Net::ProtocolError,
|
27
|
-
OpenSSL::SSL::SSLError,
|
28
|
-
SocketError].freeze
|
18
|
+
HTTP_ERRORS = Util::HTTP::ERRORS
|
29
19
|
|
30
20
|
def initialize(config)
|
31
21
|
@http = Util::HTTP.new(config)
|
@@ -42,9 +32,7 @@ module Honeybadger
|
|
42
32
|
ENDPOINTS[feature] or raise(BackendError, "Unknown feature: #{feature}")
|
43
33
|
Response.new(@http.post(ENDPOINTS[feature], payload, payload_headers(payload)))
|
44
34
|
rescue *HTTP_ERRORS => e
|
45
|
-
Response.new(:error, nil, "HTTP Error: #{e.class}")
|
46
|
-
error { sprintf('http error class=%s message=%s', e.class, e.message.dump) }
|
47
|
-
end
|
35
|
+
Response.new(:error, nil, "HTTP Error: #{e.class}")
|
48
36
|
end
|
49
37
|
|
50
38
|
private
|
data/lib/honeybadger/cli.rb
CHANGED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'honeybadger/cli/main'
|
3
|
+
require 'honeybadger/util/http'
|
4
|
+
|
5
|
+
module Honeybadger
|
6
|
+
module CLI
|
7
|
+
class Deploy
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
def initialize(options, args, config)
|
11
|
+
@options = options
|
12
|
+
@args = args
|
13
|
+
@config = config
|
14
|
+
@shell = ::Thor::Base.shell.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
payload = {
|
19
|
+
environment: options['environment'],
|
20
|
+
revision: options['revision'],
|
21
|
+
repository: options['repository'],
|
22
|
+
local_username: options['user']
|
23
|
+
}
|
24
|
+
|
25
|
+
http = Util::HTTP.new(config)
|
26
|
+
result = http.post('/v1/deploys', payload)
|
27
|
+
if result.code == '201'
|
28
|
+
say("Deploy notification complete.", :green)
|
29
|
+
else
|
30
|
+
say("Invalid response from server: #{result.code}", :red)
|
31
|
+
exit(1)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
attr_reader :options, :args, :config
|
38
|
+
|
39
|
+
def_delegator :@shell, :say
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'forwardable'
|
3
|
+
require 'honeybadger/cli/main'
|
4
|
+
require 'honeybadger/util/http'
|
5
|
+
require 'honeybadger/util/stats'
|
6
|
+
require 'open3'
|
7
|
+
require 'ostruct'
|
8
|
+
require 'thor/shell'
|
9
|
+
|
10
|
+
module Honeybadger
|
11
|
+
module CLI
|
12
|
+
class Exec
|
13
|
+
extend Forwardable
|
14
|
+
|
15
|
+
FAILED_TEMPLATE = <<-MSG
|
16
|
+
Honeybadger detected failure or error output for the command:
|
17
|
+
`<%= args.join(' ') %>`
|
18
|
+
|
19
|
+
PROCESS ID: <%= pid %>
|
20
|
+
|
21
|
+
RESULT CODE: <%= code %>
|
22
|
+
|
23
|
+
ERROR OUTPUT:
|
24
|
+
<%= stderr %>
|
25
|
+
|
26
|
+
STANDARD OUTPUT:
|
27
|
+
<%= stdout %>
|
28
|
+
MSG
|
29
|
+
|
30
|
+
NO_EXEC_TEMPLATE = <<-MSG
|
31
|
+
Honeybadger failed to execute the following command:
|
32
|
+
`<%= args.join(' ') %>`
|
33
|
+
|
34
|
+
The command was not executable. Try adjusting permissions on the file.
|
35
|
+
MSG
|
36
|
+
|
37
|
+
NOT_FOUND_TEMPLATE = <<-MSG
|
38
|
+
Honeybadger failed to execute the following command:
|
39
|
+
`<%= args.join(' ') %>`
|
40
|
+
|
41
|
+
The command was not found. Make sure it exists in your PATH.
|
42
|
+
MSG
|
43
|
+
|
44
|
+
def initialize(options, args, config)
|
45
|
+
@options = options
|
46
|
+
@args = args
|
47
|
+
@config = config
|
48
|
+
@shell = ::Thor::Base.shell.new
|
49
|
+
end
|
50
|
+
|
51
|
+
def run
|
52
|
+
result = exec_cmd
|
53
|
+
return if result.success
|
54
|
+
|
55
|
+
payload = {
|
56
|
+
api_key: config.get(:api_key),
|
57
|
+
notifier: NOTIFIER,
|
58
|
+
error: {
|
59
|
+
class: 'honeybdager exec error',
|
60
|
+
message: result.msg
|
61
|
+
},
|
62
|
+
request: {
|
63
|
+
context: {
|
64
|
+
executable: args.first,
|
65
|
+
code: result.code,
|
66
|
+
pid: result.pid
|
67
|
+
}
|
68
|
+
},
|
69
|
+
server: {
|
70
|
+
project_root: Dir.pwd,
|
71
|
+
environment_name: config.get(:env),
|
72
|
+
time: Time.now,
|
73
|
+
stats: Util::Stats.all
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
http = Util::HTTP.new(config)
|
78
|
+
|
79
|
+
begin
|
80
|
+
response = http.post('/v1/notices', payload)
|
81
|
+
rescue
|
82
|
+
say(result.msg)
|
83
|
+
raise
|
84
|
+
end
|
85
|
+
|
86
|
+
if response.code != '201'
|
87
|
+
say(result.msg)
|
88
|
+
say("\nFailed to notify Honeybadger: #{response.code}", :red)
|
89
|
+
exit(1)
|
90
|
+
end
|
91
|
+
|
92
|
+
unless quiet?
|
93
|
+
say(result.msg)
|
94
|
+
say("\nSuccessfully notified Honeybadger")
|
95
|
+
end
|
96
|
+
|
97
|
+
exit(0)
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
attr_reader :options, :args, :config
|
103
|
+
|
104
|
+
def_delegator :@shell, :say
|
105
|
+
|
106
|
+
def quiet?
|
107
|
+
!!options[:quiet]
|
108
|
+
end
|
109
|
+
|
110
|
+
def exec_cmd
|
111
|
+
stdout, stderr, status = Open3.capture3(args.join(' '))
|
112
|
+
|
113
|
+
pid = status.pid
|
114
|
+
code = status.to_i
|
115
|
+
msg = ERB.new(FAILED_TEMPLATE).result(binding) unless status.success?
|
116
|
+
|
117
|
+
OpenStruct.new(
|
118
|
+
msg: msg,
|
119
|
+
pid: pid,
|
120
|
+
code: code,
|
121
|
+
stdout: stdout,
|
122
|
+
stderr: stderr,
|
123
|
+
success: status.success? && stderr =~ BLANK
|
124
|
+
)
|
125
|
+
rescue Errno::EACCES, Errno::ENOEXEC
|
126
|
+
OpenStruct.new(
|
127
|
+
msg: ERB.new(NO_EXEC_TEMPLATE).result(binding),
|
128
|
+
code: 126
|
129
|
+
)
|
130
|
+
rescue Errno::ENOENT
|
131
|
+
OpenStruct.new(
|
132
|
+
msg: ERB.new(NOT_FOUND_TEMPLATE).result(binding),
|
133
|
+
code: 127
|
134
|
+
)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -1,10 +1,6 @@
|
|
1
|
-
require 'honeybadger/cli/helpers'
|
2
|
-
|
3
1
|
module Honeybadger
|
4
2
|
module CLI
|
5
3
|
class Heroku < Thor
|
6
|
-
include Helpers
|
7
|
-
|
8
4
|
class_option :app, aliases: :'-a', type: :string, default: nil, desc: 'Specify optional Heroku APP'
|
9
5
|
|
10
6
|
desc 'install_deploy_notification', 'Install Heroku deploy notifications addon'
|
@@ -37,19 +33,10 @@ module Honeybadger
|
|
37
33
|
def install(api_key)
|
38
34
|
say("Installing Honeybadger #{VERSION} for Heroku")
|
39
35
|
|
40
|
-
load_rails(verbose: true)
|
41
|
-
|
42
|
-
ENV['HONEYBADGER_LOGGING_LEVEL'] = '2'
|
43
|
-
ENV['HONEYBADGER_LOGGING_TTY_LEVEL'] = '0'
|
44
|
-
ENV['HONEYBADGER_LOGGING_PATH'] = 'STDOUT'
|
45
|
-
ENV['HONEYBADGER_REPORT_DATA'] = 'true'
|
46
|
-
|
47
|
-
ENV['HONEYBADGER_API_KEY'] = api_key
|
48
|
-
|
49
36
|
app = options[:app] || detect_heroku_app(false)
|
50
37
|
say("Adding config HONEYBADGER_API_KEY=#{api_key} to Heroku.", :magenta)
|
51
38
|
unless write_heroku_env({'HONEYBADGER_API_KEY' => api_key}, app)
|
52
|
-
say('Unable to update heroku config.
|
39
|
+
say('Unable to update heroku config. You may need to specify an app name with --app APP', :red)
|
53
40
|
exit(1)
|
54
41
|
end
|
55
42
|
|
@@ -61,14 +48,6 @@ module Honeybadger
|
|
61
48
|
say("To install manually, try `honeybadger heroku install_deploy_notification#{app ? " -a #{app}" : ""} -k #{api_key} --environment ENVIRONMENT`", :yellow)
|
62
49
|
end
|
63
50
|
|
64
|
-
config = Config.new(rails_framework_opts)
|
65
|
-
Honeybadger.start(config) unless load_rails_env(verbose: true)
|
66
|
-
say('Sending test notice')
|
67
|
-
unless Agent.instance && send_test(false)
|
68
|
-
say("Honeybadger is installed, but failed to send a test notice. Try `HONEYBADGER_API_KEY=#{api_key} honeybadger test`.", :red)
|
69
|
-
exit(1)
|
70
|
-
end
|
71
|
-
|
72
51
|
say("Installation complete. Happy 'badgering!", :green)
|
73
52
|
end
|
74
53
|
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'honeybadger/cli/main'
|
3
|
+
require 'honeybadger/cli/test'
|
4
|
+
require 'pathname'
|
5
|
+
|
6
|
+
module Honeybadger
|
7
|
+
module CLI
|
8
|
+
class Install
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
def initialize(options, api_key)
|
12
|
+
@options = options
|
13
|
+
@api_key = api_key
|
14
|
+
@shell = ::Thor::Base.shell.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
say("Installing Honeybadger #{VERSION}")
|
19
|
+
|
20
|
+
begin
|
21
|
+
require File.join(Dir.pwd, 'config', 'application.rb')
|
22
|
+
rescue LoadError
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
root = defined?(Rails.root) ? Rails.root : Pathname.new(Dir.pwd)
|
27
|
+
config_root = defined?(Rails.root) ? root.join('config') : root
|
28
|
+
config_path = config_root.join('honeybadger.yml')
|
29
|
+
|
30
|
+
if config_path.exist?
|
31
|
+
say("You're already on Honeybadger, so you're all set.", :yellow)
|
32
|
+
else
|
33
|
+
say("Writing configuration to: #{config_path}", :yellow)
|
34
|
+
|
35
|
+
path = config_path
|
36
|
+
|
37
|
+
if path.exist?
|
38
|
+
say("The configuration file #{config_path} already exists.", :red)
|
39
|
+
exit(1)
|
40
|
+
elsif !path.dirname.writable?
|
41
|
+
say("The configuration path #{config_path.dirname} is not writable.", :red)
|
42
|
+
exit(1)
|
43
|
+
end
|
44
|
+
|
45
|
+
File.open(path, 'w+') do |file|
|
46
|
+
file.write(<<-CONFIG)
|
47
|
+
---
|
48
|
+
api_key: '#{api_key}'
|
49
|
+
CONFIG
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
if (capfile = root.join('Capfile')).exist?
|
54
|
+
if capfile.read.match(/honeybadger/)
|
55
|
+
say("Detected Honeybadger in Capfile; skipping Capistrano installation.", :yellow)
|
56
|
+
else
|
57
|
+
say("Appending Capistrano tasks to: #{capfile}", :yellow)
|
58
|
+
File.open(capfile, 'a') do |f|
|
59
|
+
f.puts("\nrequire 'capistrano/honeybadger'")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
Test.new({install: true}.freeze).run
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
attr_reader :options, :api_key
|
70
|
+
|
71
|
+
def_delegator :@shell, :say
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/honeybadger/cli/main.rb
CHANGED
@@ -1,195 +1,180 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
require 'honeybadger/cli/
|
1
|
+
require 'honeybadger/cli/deploy'
|
2
|
+
require 'honeybadger/cli/exec'
|
3
|
+
require 'honeybadger/cli/heroku'
|
4
|
+
require 'honeybadger/cli/install'
|
5
|
+
require 'honeybadger/cli/notify'
|
6
|
+
require 'honeybadger/cli/test'
|
7
|
+
require 'honeybadger/config'
|
8
|
+
require 'honeybadger/config/defaults'
|
9
|
+
require 'honeybadger/util/http'
|
10
|
+
require 'honeybadger/version'
|
11
|
+
require 'logger'
|
4
12
|
|
5
13
|
module Honeybadger
|
6
14
|
module CLI
|
15
|
+
BLANK = /\A\s*\z/
|
16
|
+
|
17
|
+
NOTIFIER = {
|
18
|
+
name: 'honeybadger-ruby (cli)'.freeze,
|
19
|
+
url: 'https://github.com/honeybadger-io/honeybadger-ruby'.freeze,
|
20
|
+
version: VERSION,
|
21
|
+
language: nil
|
22
|
+
}.freeze
|
23
|
+
|
7
24
|
class Main < Thor
|
8
|
-
|
25
|
+
def self.project_options
|
26
|
+
option :api_key, required: false, aliases: :'-k', type: :string, desc: 'Api key of your Honeybadger application'
|
27
|
+
option :environment, required: false, aliases: [:'-e', :'-env'], type: :string, desc: 'Environment this command is being executed in (i.e. "production", "staging")'
|
28
|
+
end
|
9
29
|
|
10
|
-
|
30
|
+
desc 'install API_KEY', 'Install Honeybadger into a new project'
|
31
|
+
def install(api_key)
|
32
|
+
Install.new(options, api_key).run
|
33
|
+
rescue => e
|
34
|
+
log_error(e)
|
35
|
+
exit(1)
|
36
|
+
end
|
11
37
|
|
12
|
-
|
38
|
+
desc 'test', 'Send a test notification from Honeybadger'
|
39
|
+
option :dry_run, type: :boolean, aliases: :'-d', default: false, desc: 'Skip sending data to Honeybadger'
|
40
|
+
option :file, type: :string, aliases: :'-f', default: nil, desc: 'Write the output to FILE'
|
41
|
+
def test
|
42
|
+
Test.new(options).run
|
43
|
+
rescue => e
|
44
|
+
log_error(e)
|
45
|
+
exit(1)
|
46
|
+
end
|
13
47
|
|
14
48
|
desc 'deploy', 'Notify Honeybadger of deployment'
|
15
|
-
|
16
|
-
option :
|
17
|
-
option :
|
18
|
-
option :user, aliases: :'-u',
|
19
|
-
option :api_key, aliases: :'-k', type: :string, desc: 'Api key of your Honeybadger application'
|
49
|
+
project_options
|
50
|
+
option :repository, required: true, type: :string, aliases: :'-r', desc: 'The address of your repository'
|
51
|
+
option :revision, required: true, type: :string, aliases: :'-s', desc: 'The revision/sha that is being deployed'
|
52
|
+
option :user, required: true, type: :string, aliases: :'-u', default: ENV['USER'] || ENV['USERNAME'], desc: 'The local user who is deploying'
|
20
53
|
def deploy
|
21
|
-
|
54
|
+
config = build_config(options)
|
22
55
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
ENV['HONEYBADGER_LOGGING_LEVEL'] = '2'
|
27
|
-
ENV['HONEYBADGER_LOGGING_TTY_LEVEL'] = '0'
|
28
|
-
ENV['HONEYBADGER_LOGGING_PATH'] = 'STDOUT'
|
29
|
-
ENV['HONEYBADGER_REPORT_DATA'] = 'true'
|
30
|
-
|
31
|
-
say('Loading configuration')
|
32
|
-
config = Config.new(rails_framework_opts)
|
33
|
-
config.update(api_key: options[:api_key]) if options[:api_key] =~ NOT_BLANK
|
34
|
-
|
35
|
-
unless (payload[:environment] ||= config[:env]) =~ NOT_BLANK
|
36
|
-
say('Unable to determine environment. (see: `honeybadger help deploy`)', :red)
|
37
|
-
exit(1)
|
56
|
+
if config.get(:api_key).to_s =~ BLANK
|
57
|
+
say("No value provided for required options '--api-key'")
|
58
|
+
return
|
38
59
|
end
|
39
60
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
61
|
+
Deploy.new(options, [], config).run
|
62
|
+
rescue => e
|
63
|
+
log_error(e)
|
64
|
+
exit(1)
|
65
|
+
end
|
44
66
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
67
|
+
desc 'notify', 'Notify Honeybadger of an error'
|
68
|
+
project_options
|
69
|
+
option :class, required: true, type: :string, aliases: :'-c', default: 'CLI Notification', desc: 'The class name of the error. (Default: CLI Notification)'
|
70
|
+
option :message, required: true, type: :string, aliases: :'-m', desc: 'The error message.'
|
71
|
+
option :action, required: false, type: :string, aliases: :'-a', desc: 'The action.'
|
72
|
+
option :component, required: false, type: :string, aliases: :'-C', desc: 'The component.'
|
73
|
+
option :fingerprint, required: false, type: :string, aliases: :'-f', desc: 'The component.'
|
74
|
+
option :tags, required: false, type: :string, aliases: :'-t', desc: 'The tags.'
|
75
|
+
option :url, required: false, type: :string, aliases: :'-u', desc: 'The URL.'
|
76
|
+
def notify
|
77
|
+
config = build_config(options)
|
78
|
+
|
79
|
+
if config.get(:api_key).to_s =~ BLANK
|
80
|
+
say("No value provided for required options '--api-key'")
|
81
|
+
return
|
51
82
|
end
|
83
|
+
|
84
|
+
Notify.new(options, [], config).run
|
52
85
|
rescue => e
|
53
|
-
|
86
|
+
log_error(e)
|
54
87
|
exit(1)
|
55
88
|
end
|
56
89
|
|
57
|
-
desc '
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
config =
|
62
|
-
output_config(config.to_hash(options[:default]))
|
63
|
-
end
|
90
|
+
desc 'exec', 'Execute a command. If the exit status is not 0, report the result to Honeybadger'
|
91
|
+
project_options
|
92
|
+
option :quiet, required: false, type: :boolean, aliases: :'-q', default: false, desc: 'Suppress all output unless Honeybdager notification fails.'
|
93
|
+
def exec(*args)
|
94
|
+
config = build_config(options)
|
64
95
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
def test
|
69
|
-
if options[:file]
|
70
|
-
out = StringIO.new
|
71
|
-
$stdout = out
|
72
|
-
|
73
|
-
flush = Proc.new do
|
74
|
-
$stdout = STDOUT
|
75
|
-
File.open(options[:file], 'w+') do |f|
|
76
|
-
out.rewind
|
77
|
-
out.each_line {|l| f.write(l) }
|
78
|
-
end
|
79
|
-
|
80
|
-
say("Output written to #{options[:file]}", :green)
|
81
|
-
end
|
82
|
-
|
83
|
-
Agent.at_exit(&flush)
|
84
|
-
|
85
|
-
at_exit do
|
86
|
-
# If the agent couldn't be started, the callback should happen here
|
87
|
-
# instead.
|
88
|
-
flush.() unless Agent.running?
|
89
|
-
end
|
96
|
+
if config.get(:api_key).to_s =~ BLANK
|
97
|
+
say("No value provided for required options '--api-key'")
|
98
|
+
return
|
90
99
|
end
|
91
100
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
ENV['HONEYBADGER_LOGGING_PATH'] = 'STDOUT'
|
98
|
-
ENV['HONEYBADGER_DEBUG'] = 'true'
|
99
|
-
ENV['HONEYBADGER_REPORT_DATA'] = options[:dry_run] ? 'false' : 'true'
|
101
|
+
Exec.new(options, args, config).run
|
102
|
+
rescue => e
|
103
|
+
log_error(e)
|
104
|
+
exit(1)
|
105
|
+
end
|
100
106
|
|
101
|
-
|
102
|
-
|
103
|
-
output_config(config.to_hash)
|
107
|
+
desc 'heroku SUBCOMMAND ...ARGS', 'Manage Honeybadger on Heroku'
|
108
|
+
subcommand 'heroku', Heroku
|
104
109
|
|
105
|
-
|
106
|
-
Honeybadger.start(config) unless load_rails_env(verbose: true)
|
110
|
+
private
|
107
111
|
|
108
|
-
|
109
|
-
|
112
|
+
def fetch_value(options, key)
|
113
|
+
options[key] == key ? nil : options[key]
|
114
|
+
end
|
110
115
|
|
111
|
-
|
116
|
+
def build_config(options)
|
117
|
+
config = Config.new(logger: Logger.new('/dev/null'))
|
118
|
+
config.set(:api_key, fetch_value(options, 'api_key')) if options.has_key?('api_key')
|
119
|
+
config.set(:env, fetch_value(options, 'environment')) if options.has_key?('environment')
|
120
|
+
config.init!({
|
121
|
+
framework: :cli
|
122
|
+
})
|
123
|
+
config
|
112
124
|
end
|
113
125
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
126
|
+
def log_error(e)
|
127
|
+
case e
|
128
|
+
when *Util::HTTP::ERRORS
|
129
|
+
say(<<-MSG, :red)
|
130
|
+
!! --- Failed to notify Honeybadger ------------------------------------------- !!
|
131
|
+
|
132
|
+
# What happened?
|
133
|
+
|
134
|
+
We encountered an HTTP error while contacting our service. Issues like this are
|
135
|
+
usually temporary.
|
136
|
+
|
137
|
+
# Error details
|
118
138
|
|
119
|
-
|
139
|
+
#{e.class}: #{e.message}\n at #{e.backtrace && e.backtrace.first}
|
120
140
|
|
121
|
-
|
122
|
-
ENV['HONEYBADGER_LOGGING_TTY_LEVEL'] = '0'
|
123
|
-
ENV['HONEYBADGER_LOGGING_PATH'] = 'STDOUT'
|
124
|
-
ENV['HONEYBADGER_REPORT_DATA'] = 'true'
|
141
|
+
# What can I do?
|
125
142
|
|
126
|
-
|
127
|
-
|
143
|
+
- Retry the command.
|
144
|
+
- Make sure you can connect to api.honeybadger.io (`ping api.honeybadger.io`).
|
145
|
+
- If you continue to see this message, email us at support@honeybadger.io
|
146
|
+
(don't forget to attach this output!)
|
128
147
|
|
129
|
-
|
130
|
-
|
148
|
+
!! --- End -------------------------------------------------------------------- !!
|
149
|
+
MSG
|
131
150
|
else
|
132
|
-
say(
|
133
|
-
|
134
|
-
begin
|
135
|
-
config.write
|
136
|
-
rescue Config::ConfigError => e
|
137
|
-
error("Error: Unable to write configuration file:\n\t#{e}")
|
138
|
-
return
|
139
|
-
rescue StandardError => e
|
140
|
-
error("Error: Unable to write configuration file:\n\t#{e.class} -- #{e.message}\n\t#{e.backtrace.join("\n\t")}")
|
141
|
-
return
|
142
|
-
end
|
143
|
-
end
|
151
|
+
say(<<-MSG, :red)
|
152
|
+
!! --- Honeybadger command failed --------------------------------------------- !!
|
144
153
|
|
145
|
-
|
146
|
-
if capfile.read.match(/honeybadger/)
|
147
|
-
say("Detected Honeybadger in Capfile; skipping Capistrano installation.", :yellow)
|
148
|
-
else
|
149
|
-
say("Appending Capistrano tasks to: #{capfile}", :yellow)
|
150
|
-
File.open(capfile, 'a') do |f|
|
151
|
-
f.puts("\nrequire 'capistrano/honeybadger'")
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
154
|
+
# What did you try to do?
|
155
155
|
|
156
|
-
|
157
|
-
|
158
|
-
say('Sending test notice', :yellow)
|
159
|
-
unless Agent.instance && send_test(false)
|
160
|
-
say('Honeybadger is installed, but failed to send a test notice. Try `honeybadger test`.', :red)
|
161
|
-
exit(1)
|
162
|
-
end
|
163
|
-
end
|
156
|
+
You tried to execute the following command:
|
157
|
+
`honeybadger #{ARGV.join(' ')}`
|
164
158
|
|
165
|
-
|
166
|
-
end
|
159
|
+
# What actually happend?
|
167
160
|
|
168
|
-
|
169
|
-
subcommand 'heroku', Heroku
|
161
|
+
We encountered a Ruby exception and were forced to cancel your request.
|
170
162
|
|
171
|
-
|
163
|
+
# Error details
|
172
164
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
say(indent + "Type: #{Config::OPTIONS[dotted_key].fetch(:type, String).name.split('::').last}")
|
184
|
-
say(indent + "Default: #{Config::OPTIONS[dotted_key][:default].inspect}")
|
185
|
-
say(indent + "Current: #{value.inspect}")
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
165
|
+
#{e.class}: #{e.message}
|
166
|
+
#{e.backtrace && e.backtrace.join("\n ")}
|
167
|
+
|
168
|
+
# What can I do?
|
169
|
+
|
170
|
+
- If you're calling the `install` or `test` command in a Rails app, make sure
|
171
|
+
you can boot the Rails console: `bundle exec rails console`.
|
172
|
+
- Retry the command.
|
173
|
+
- If you continue to see this message, email us at support@honeybadger.io
|
174
|
+
(don't forget to attach this output!)
|
189
175
|
|
190
|
-
|
191
|
-
|
192
|
-
number.times { s << "\s\s" }
|
176
|
+
!! --- End -------------------------------------------------------------------- !!
|
177
|
+
MSG
|
193
178
|
end
|
194
179
|
end
|
195
180
|
end
|