honeybadger 5.27.0 → 6.2.0
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 +168 -0
- data/lib/honeybadger/agent.rb +108 -33
- data/lib/honeybadger/backend/base.rb +11 -11
- data/lib/honeybadger/backend/debug.rb +4 -4
- data/lib/honeybadger/backend/null.rb +2 -2
- data/lib/honeybadger/backend/server.rb +11 -11
- data/lib/honeybadger/backend/test.rb +2 -2
- data/lib/honeybadger/backend.rb +6 -6
- data/lib/honeybadger/backtrace.rb +27 -22
- data/lib/honeybadger/breadcrumbs/active_support.rb +10 -10
- data/lib/honeybadger/breadcrumbs/breadcrumb.rb +1 -2
- data/lib/honeybadger/breadcrumbs/collector.rb +4 -4
- data/lib/honeybadger/breadcrumbs/logging.rb +13 -14
- data/lib/honeybadger/breadcrumbs.rb +3 -3
- data/lib/honeybadger/cli/deploy.rb +7 -7
- data/lib/honeybadger/cli/exec.rb +41 -41
- data/lib/honeybadger/cli/helpers.rb +18 -18
- data/lib/honeybadger/cli/heroku.rb +36 -36
- data/lib/honeybadger/cli/install.rb +44 -44
- data/lib/honeybadger/cli/main.rb +107 -107
- data/lib/honeybadger/cli/notify.rb +13 -13
- data/lib/honeybadger/cli/test.rb +109 -94
- data/lib/honeybadger/cli.rb +3 -3
- data/lib/honeybadger/config/defaults.rb +252 -216
- data/lib/honeybadger/config/env.rb +5 -5
- data/lib/honeybadger/config/ruby.rb +19 -19
- data/lib/honeybadger/config/yaml.rb +12 -12
- data/lib/honeybadger/config.rb +116 -95
- data/lib/honeybadger/const.rb +4 -4
- data/lib/honeybadger/context_manager.rb +59 -11
- data/lib/honeybadger/conversions.rb +9 -6
- data/lib/honeybadger/counter.rb +4 -4
- data/lib/honeybadger/event.rb +4 -4
- data/lib/honeybadger/events_worker.rb +34 -33
- data/lib/honeybadger/gauge.rb +2 -2
- data/lib/honeybadger/histogram.rb +4 -4
- data/lib/honeybadger/init/hanami.rb +5 -5
- data/lib/honeybadger/init/rails.rb +14 -14
- data/lib/honeybadger/init/rake.rb +19 -21
- data/lib/honeybadger/init/ruby.rb +4 -4
- data/lib/honeybadger/init/sinatra.rb +11 -12
- data/lib/honeybadger/instrumentation.rb +26 -31
- data/lib/honeybadger/instrumentation_helper.rb +11 -12
- data/lib/honeybadger/karafka.rb +64 -65
- data/lib/honeybadger/logging.rb +22 -21
- data/lib/honeybadger/metric.rb +2 -2
- data/lib/honeybadger/metrics_worker.rb +12 -10
- data/lib/honeybadger/notice.rb +55 -58
- data/lib/honeybadger/notification_subscriber.rb +74 -51
- data/lib/honeybadger/plugin.rb +16 -18
- data/lib/honeybadger/plugins/active_agent.rb +38 -0
- data/lib/honeybadger/plugins/active_job.rb +11 -9
- data/lib/honeybadger/plugins/autotuner.rb +7 -7
- data/lib/honeybadger/plugins/breadcrumbs.rb +7 -7
- data/lib/honeybadger/plugins/delayed_job/plugin.rb +36 -37
- data/lib/honeybadger/plugins/delayed_job.rb +4 -4
- data/lib/honeybadger/plugins/faktory.rb +10 -10
- data/lib/honeybadger/plugins/flipper.rb +33 -0
- data/lib/honeybadger/plugins/karafka.rb +3 -3
- data/lib/honeybadger/plugins/lambda.rb +9 -11
- data/lib/honeybadger/plugins/local_variables.rb +4 -4
- data/lib/honeybadger/plugins/net_http.rb +12 -12
- data/lib/honeybadger/plugins/passenger.rb +4 -4
- data/lib/honeybadger/plugins/rails.rb +15 -9
- data/lib/honeybadger/plugins/resque.rb +7 -7
- data/lib/honeybadger/plugins/shoryuken.rb +6 -6
- data/lib/honeybadger/plugins/sidekiq.rb +79 -65
- data/lib/honeybadger/plugins/solid_queue.rb +8 -7
- data/lib/honeybadger/plugins/sucker_punch.rb +5 -5
- data/lib/honeybadger/plugins/system.rb +3 -3
- data/lib/honeybadger/plugins/thor.rb +5 -5
- data/lib/honeybadger/plugins/warden.rb +5 -8
- data/lib/honeybadger/rack/error_notifier.rb +14 -14
- data/lib/honeybadger/rack/user_feedback.rb +11 -12
- data/lib/honeybadger/rack/user_informer.rb +6 -6
- data/lib/honeybadger/registry.rb +2 -2
- data/lib/honeybadger/registry_execution.rb +1 -1
- data/lib/honeybadger/ruby.rb +2 -2
- data/lib/honeybadger/singleton.rb +49 -46
- data/lib/honeybadger/tasks.rb +3 -3
- data/lib/honeybadger/timer.rb +1 -1
- data/lib/honeybadger/util/http.rb +27 -27
- data/lib/honeybadger/util/request_hash.rb +11 -11
- data/lib/honeybadger/util/request_payload.rb +2 -2
- data/lib/honeybadger/util/revision.rb +14 -6
- data/lib/honeybadger/util/sanitizer.rb +29 -23
- data/lib/honeybadger/util/stats.rb +6 -3
- data/lib/honeybadger/version.rb +1 -1
- data/lib/honeybadger/worker.rb +31 -29
- data/lib/honeybadger.rb +5 -5
- data/lib/puma/plugin/honeybadger.rb +14 -10
- metadata +10 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "json"
|
|
2
2
|
|
|
3
3
|
module Honeybadger
|
|
4
4
|
# @api private
|
|
@@ -8,7 +8,7 @@ module Honeybadger
|
|
|
8
8
|
class Line
|
|
9
9
|
# Backtrace line regexp (optionally allowing leading X: for windows support).
|
|
10
10
|
# Capture quoted strings either with leading backtick (pre Ruby 3.4) or single quote.
|
|
11
|
-
INPUT_FORMAT = %r{^((?:[a-zA-Z]:)?[^:]+):(\d+)(?::in (?:`|')([^']+)')?$}
|
|
11
|
+
INPUT_FORMAT = %r{^((?:[a-zA-Z]:)?[^:]+):(\d+)(?::in (?:`|')([^']+)')?$}
|
|
12
12
|
|
|
13
13
|
# The file portion of the line (such as app/models/user.rb).
|
|
14
14
|
attr_reader :file
|
|
@@ -45,21 +45,19 @@ module Honeybadger
|
|
|
45
45
|
file, number, method = match[1], match[2], match[3]
|
|
46
46
|
filtered_args = [fmatch[1], fmatch[2], fmatch[3]]
|
|
47
47
|
new(file, number, method, *filtered_args, opts.fetch(:source_radius, 2))
|
|
48
|
-
else
|
|
49
|
-
nil
|
|
50
48
|
end
|
|
51
49
|
end
|
|
52
50
|
|
|
53
51
|
def initialize(file, number, method, filtered_file = file,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
self.filtered_file
|
|
52
|
+
filtered_number = number, filtered_method = method,
|
|
53
|
+
source_radius = 2)
|
|
54
|
+
self.filtered_file = filtered_file
|
|
57
55
|
self.filtered_number = filtered_number
|
|
58
56
|
self.filtered_method = filtered_method
|
|
59
|
-
self.file
|
|
60
|
-
self.number
|
|
61
|
-
self.method
|
|
62
|
-
self.source_radius
|
|
57
|
+
self.file = file
|
|
58
|
+
self.number = number
|
|
59
|
+
self.method = method
|
|
60
|
+
self.source_radius = source_radius
|
|
63
61
|
end
|
|
64
62
|
|
|
65
63
|
# Reconstructs the line in a readable fashion.
|
|
@@ -72,7 +70,7 @@ module Honeybadger
|
|
|
72
70
|
end
|
|
73
71
|
|
|
74
72
|
def inspect
|
|
75
|
-
"<Line:#{
|
|
73
|
+
"<Line:#{self}>"
|
|
76
74
|
end
|
|
77
75
|
|
|
78
76
|
# Determines if this line is part of the application trace or not.
|
|
@@ -102,8 +100,11 @@ module Honeybadger
|
|
|
102
100
|
|
|
103
101
|
l = 0
|
|
104
102
|
File.open(file) do |f|
|
|
105
|
-
start.times {
|
|
106
|
-
|
|
103
|
+
start.times {
|
|
104
|
+
f.gets
|
|
105
|
+
l += 1
|
|
106
|
+
}
|
|
107
|
+
return duration.times.map { (line = f.gets) ? [(l += 1), line] : nil }.compact.to_h
|
|
107
108
|
end
|
|
108
109
|
else
|
|
109
110
|
{}
|
|
@@ -121,7 +122,7 @@ module Honeybadger
|
|
|
121
122
|
Line.parse(unparsed_line.to_s, opts)
|
|
122
123
|
end.compact
|
|
123
124
|
|
|
124
|
-
|
|
125
|
+
new(lines)
|
|
125
126
|
end
|
|
126
127
|
|
|
127
128
|
def initialize(lines)
|
|
@@ -133,9 +134,9 @@ module Honeybadger
|
|
|
133
134
|
#
|
|
134
135
|
# Returns array containing backtrace lines.
|
|
135
136
|
def to_ary
|
|
136
|
-
lines.take(1000).map { |l| {
|
|
137
|
+
lines.take(1000).map { |l| {number: l.filtered_number, file: l.filtered_file, method: l.filtered_method, source: l.source} }
|
|
137
138
|
end
|
|
138
|
-
|
|
139
|
+
alias_method :to_a, :to_ary
|
|
139
140
|
|
|
140
141
|
# JSON support.
|
|
141
142
|
#
|
|
@@ -171,11 +172,15 @@ module Honeybadger
|
|
|
171
172
|
|
|
172
173
|
attr_writer :lines, :application_lines
|
|
173
174
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
backtrace
|
|
175
|
+
class << self
|
|
176
|
+
private
|
|
177
|
+
|
|
178
|
+
def split_multiline_backtrace(backtrace)
|
|
179
|
+
if backtrace.size == 1
|
|
180
|
+
backtrace.first.to_s.split(/\n\s*/)
|
|
181
|
+
else
|
|
182
|
+
backtrace
|
|
183
|
+
end
|
|
179
184
|
end
|
|
180
185
|
end
|
|
181
186
|
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "honeybadger/util/sql"
|
|
2
2
|
|
|
3
3
|
module Honeybadger
|
|
4
4
|
module Breadcrumbs
|
|
@@ -10,7 +10,7 @@ module Honeybadger
|
|
|
10
10
|
"sql.active_record" => {
|
|
11
11
|
message: lambda do |data|
|
|
12
12
|
# Disregard empty string names
|
|
13
|
-
name = data[:name] if data[:name] && !data[:name].strip.empty?
|
|
13
|
+
name = data[:name] if data[:name] && !data[:name].to_s.strip.empty?
|
|
14
14
|
|
|
15
15
|
["Active Record", name].compact.join(" - ")
|
|
16
16
|
end,
|
|
@@ -19,7 +19,7 @@ module Honeybadger
|
|
|
19
19
|
transform: lambda do |data|
|
|
20
20
|
if data[:sql]
|
|
21
21
|
connection = data.delete(:connection)
|
|
22
|
-
adapter =
|
|
22
|
+
adapter = connection&.adapter_name&.downcase || active_record_connection_db_config[:adapter]
|
|
23
23
|
data[:sql] = Util::SQL.obfuscate(data[:sql], adapter)
|
|
24
24
|
end
|
|
25
25
|
data
|
|
@@ -49,7 +49,7 @@ module Honeybadger
|
|
|
49
49
|
"perform_start.active_job" => {
|
|
50
50
|
message: "Active Job Perform Start",
|
|
51
51
|
select_keys: [],
|
|
52
|
-
category: "job"
|
|
52
|
+
category: "job"
|
|
53
53
|
},
|
|
54
54
|
|
|
55
55
|
# ActiveSupport Actions
|
|
@@ -67,32 +67,32 @@ module Honeybadger
|
|
|
67
67
|
#
|
|
68
68
|
"halted_callback.action_controller" => {
|
|
69
69
|
message: "Action Controller Callback Halted",
|
|
70
|
-
category: "request"
|
|
70
|
+
category: "request"
|
|
71
71
|
},
|
|
72
72
|
"process_action.action_controller" => {
|
|
73
73
|
message: "Action Controller Action Process",
|
|
74
74
|
select_keys: [:controller, :action, :format, :method, :path, :status, :view_runtime, :db_runtime],
|
|
75
|
-
category: "request"
|
|
75
|
+
category: "request"
|
|
76
76
|
},
|
|
77
77
|
"start_processing.action_controller" => {
|
|
78
78
|
message: "Action Controller Start Process",
|
|
79
79
|
select_keys: [:controller, :action, :format, :method, :path],
|
|
80
|
-
category: "request"
|
|
80
|
+
category: "request"
|
|
81
81
|
},
|
|
82
82
|
"redirect_to.action_controller" => {
|
|
83
83
|
message: "Action Controller Redirect",
|
|
84
|
-
category: "request"
|
|
84
|
+
category: "request"
|
|
85
85
|
},
|
|
86
86
|
|
|
87
87
|
# View Actions
|
|
88
88
|
#
|
|
89
89
|
"render_template.action_view" => {
|
|
90
90
|
message: "Action View Template Render",
|
|
91
|
-
category: "render"
|
|
91
|
+
category: "render"
|
|
92
92
|
},
|
|
93
93
|
"render_partial.action_view" => {
|
|
94
94
|
message: "Action View Partial Render",
|
|
95
|
-
category: "render"
|
|
95
|
+
category: "render"
|
|
96
96
|
},
|
|
97
97
|
|
|
98
98
|
# Mailer actions
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "time"
|
|
2
2
|
|
|
3
3
|
module Honeybadger
|
|
4
4
|
module Breadcrumbs
|
|
@@ -32,7 +32,6 @@ module Honeybadger
|
|
|
32
32
|
to_h <=> other.to_h
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
|
|
36
35
|
# Is the Breadcrumb active or not. Inactive Breadcrumbs not be included
|
|
37
36
|
# with any outgoing payloads.
|
|
38
37
|
#
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "forwardable"
|
|
2
2
|
|
|
3
3
|
module Honeybadger
|
|
4
4
|
module Breadcrumbs
|
|
@@ -35,7 +35,7 @@ module Honeybadger
|
|
|
35
35
|
#
|
|
36
36
|
# @return [self] Filtered breadcrumbs
|
|
37
37
|
def add!(breadcrumb)
|
|
38
|
-
return unless @config[:
|
|
38
|
+
return unless @config[:"breadcrumbs.enabled"]
|
|
39
39
|
@buffer.add!(breadcrumb)
|
|
40
40
|
|
|
41
41
|
self
|
|
@@ -48,7 +48,7 @@ module Honeybadger
|
|
|
48
48
|
# block returns a falsy value
|
|
49
49
|
#
|
|
50
50
|
def drop_previous_breadcrumb_if
|
|
51
|
-
@buffer.drop if
|
|
51
|
+
@buffer.drop if previous && block_given? && yield(previous)
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
# All active breadcrumbs you want to remove a breadcrumb from the trail,
|
|
@@ -61,7 +61,7 @@ module Honeybadger
|
|
|
61
61
|
|
|
62
62
|
def to_h
|
|
63
63
|
{
|
|
64
|
-
enabled: @config[:
|
|
64
|
+
enabled: @config[:"breadcrumbs.enabled"],
|
|
65
65
|
trail: trail.map(&:to_h)
|
|
66
66
|
}
|
|
67
67
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require "honeybadger/util/sanitizer"
|
|
2
|
+
|
|
1
3
|
module Honeybadger
|
|
2
4
|
module Breadcrumbs
|
|
3
5
|
# @api private
|
|
@@ -7,10 +9,10 @@ module Honeybadger
|
|
|
7
9
|
org_severity, org_message, org_progname = severity, message, progname
|
|
8
10
|
if defined?(Dry::Logger::Entry) && progname.is_a?(Dry::Logger::Entry) # Hanami uses dry-logger
|
|
9
11
|
message, progname = progname.message || progname.exception, progname.progname
|
|
10
|
-
|
|
11
|
-
message, progname = [progname, nil]
|
|
12
|
+
elsif message.nil?
|
|
13
|
+
message, progname = [progname, nil]
|
|
12
14
|
end
|
|
13
|
-
message
|
|
15
|
+
message &&= Util::Sanitizer.sanitize(message.to_s)&.strip
|
|
14
16
|
unless should_ignore_log?(message, progname)
|
|
15
17
|
Honeybadger.add_breadcrumb(message, category: :log, metadata: {
|
|
16
18
|
severity: format_severity(severity),
|
|
@@ -25,9 +27,9 @@ module Honeybadger
|
|
|
25
27
|
|
|
26
28
|
def should_ignore_log?(message, progname)
|
|
27
29
|
message.nil? ||
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
message == "" ||
|
|
31
|
+
Thread.current[:__hb_within_log_subscriber] ||
|
|
32
|
+
progname == "honeybadger"
|
|
31
33
|
end
|
|
32
34
|
end
|
|
33
35
|
|
|
@@ -39,17 +41,14 @@ module Honeybadger
|
|
|
39
41
|
# class that provides LogSubscriber events, we want to filter out those
|
|
40
42
|
# logs as they just become noise.
|
|
41
43
|
module LogSubscriberInjector
|
|
42
|
-
%w
|
|
44
|
+
%w[info debug warn error fatal unknown].each do |level|
|
|
43
45
|
define_method(level) do |*args, &block|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
Thread.current[:__hb_within_log_subscriber] = false
|
|
49
|
-
end
|
|
46
|
+
Thread.current[:__hb_within_log_subscriber] = true
|
|
47
|
+
super(*args, &block)
|
|
48
|
+
ensure
|
|
49
|
+
Thread.current[:__hb_within_log_subscriber] = false
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
1
|
+
require "honeybadger/breadcrumbs/ring_buffer"
|
|
2
|
+
require "honeybadger/breadcrumbs/breadcrumb"
|
|
3
|
+
require "honeybadger/breadcrumbs/collector"
|
|
4
4
|
|
|
5
5
|
module Honeybadger
|
|
6
6
|
module Breadcrumbs
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
4
|
-
require
|
|
1
|
+
require "forwardable"
|
|
2
|
+
require "honeybadger/cli/main"
|
|
3
|
+
require "honeybadger/cli/helpers"
|
|
4
|
+
require "honeybadger/util/http"
|
|
5
5
|
|
|
6
6
|
module Honeybadger
|
|
7
7
|
module CLI
|
|
@@ -19,9 +19,9 @@ module Honeybadger
|
|
|
19
19
|
def run
|
|
20
20
|
payload = {
|
|
21
21
|
environment: config.get(:env),
|
|
22
|
-
revision: options[
|
|
23
|
-
repository: options[
|
|
24
|
-
local_username: options[
|
|
22
|
+
revision: options["revision"],
|
|
23
|
+
repository: options["repository"],
|
|
24
|
+
local_username: options["user"]
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
response = config.backend.notify(:deploys, payload)
|
data/lib/honeybadger/cli/exec.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
require
|
|
9
|
-
require
|
|
1
|
+
require "erb"
|
|
2
|
+
require "forwardable"
|
|
3
|
+
require "honeybadger/cli/main"
|
|
4
|
+
require "honeybadger/cli/helpers"
|
|
5
|
+
require "honeybadger/util/http"
|
|
6
|
+
require "honeybadger/util/stats"
|
|
7
|
+
require "open3"
|
|
8
|
+
require "ostruct"
|
|
9
|
+
require "thor/shell"
|
|
10
10
|
|
|
11
11
|
module Honeybadger
|
|
12
12
|
module CLI
|
|
@@ -14,34 +14,34 @@ module Honeybadger
|
|
|
14
14
|
extend Forwardable
|
|
15
15
|
include Helpers::BackendCmd
|
|
16
16
|
|
|
17
|
-
FAILED_TEMPLATE =
|
|
18
|
-
Honeybadger detected failure or error output for the command:
|
|
19
|
-
`<%= args.join(' ') %>`
|
|
20
|
-
|
|
21
|
-
PROCESS ID: <%= pid %>
|
|
22
|
-
|
|
23
|
-
RESULT CODE: <%= code %>
|
|
24
|
-
|
|
25
|
-
ERROR OUTPUT:
|
|
26
|
-
<%= stderr %>
|
|
27
|
-
|
|
28
|
-
STANDARD OUTPUT:
|
|
29
|
-
<%= stdout %>
|
|
30
|
-
MSG
|
|
31
|
-
|
|
32
|
-
NO_EXEC_TEMPLATE =
|
|
33
|
-
Honeybadger failed to execute the following command:
|
|
34
|
-
`<%= args.join(' ') %>`
|
|
35
|
-
|
|
36
|
-
The command was not executable. Try adjusting permissions on the file.
|
|
37
|
-
MSG
|
|
38
|
-
|
|
39
|
-
NOT_FOUND_TEMPLATE =
|
|
40
|
-
Honeybadger failed to execute the following command:
|
|
41
|
-
`<%= args.join(' ') %>`
|
|
42
|
-
|
|
43
|
-
The command was not found. Make sure it exists in your PATH.
|
|
44
|
-
MSG
|
|
17
|
+
FAILED_TEMPLATE = <<~MSG
|
|
18
|
+
Honeybadger detected failure or error output for the command:
|
|
19
|
+
`<%= args.join(' ') %>`
|
|
20
|
+
|
|
21
|
+
PROCESS ID: <%= pid %>
|
|
22
|
+
|
|
23
|
+
RESULT CODE: <%= code %>
|
|
24
|
+
|
|
25
|
+
ERROR OUTPUT:
|
|
26
|
+
<%= stderr %>
|
|
27
|
+
|
|
28
|
+
STANDARD OUTPUT:
|
|
29
|
+
<%= stdout %>
|
|
30
|
+
MSG
|
|
31
|
+
|
|
32
|
+
NO_EXEC_TEMPLATE = <<~MSG
|
|
33
|
+
Honeybadger failed to execute the following command:
|
|
34
|
+
`<%= args.join(' ') %>`
|
|
35
|
+
|
|
36
|
+
The command was not executable. Try adjusting permissions on the file.
|
|
37
|
+
MSG
|
|
38
|
+
|
|
39
|
+
NOT_FOUND_TEMPLATE = <<~MSG
|
|
40
|
+
Honeybadger failed to execute the following command:
|
|
41
|
+
`<%= args.join(' ') %>`
|
|
42
|
+
|
|
43
|
+
The command was not found. Make sure it exists in your PATH.
|
|
44
|
+
MSG
|
|
45
45
|
|
|
46
46
|
def initialize(options, args, config)
|
|
47
47
|
@options = options
|
|
@@ -59,17 +59,17 @@ MSG
|
|
|
59
59
|
api_key: config.get(:api_key),
|
|
60
60
|
notifier: NOTIFIER,
|
|
61
61
|
error: {
|
|
62
|
-
class:
|
|
62
|
+
class: "honeybadger exec error",
|
|
63
63
|
message: result.msg
|
|
64
64
|
},
|
|
65
65
|
request: {
|
|
66
66
|
component: executable,
|
|
67
67
|
context: {
|
|
68
|
-
command: args.join(
|
|
68
|
+
command: args.join(" "),
|
|
69
69
|
code: result.code,
|
|
70
70
|
pid: result.pid,
|
|
71
71
|
pwd: Dir.pwd,
|
|
72
|
-
path: ENV[
|
|
72
|
+
path: ENV["PATH"]
|
|
73
73
|
}
|
|
74
74
|
},
|
|
75
75
|
server: {
|
|
@@ -112,7 +112,7 @@ MSG
|
|
|
112
112
|
end
|
|
113
113
|
|
|
114
114
|
def exec_cmd
|
|
115
|
-
stdout, stderr, status = Open3.capture3(args.join(
|
|
115
|
+
stdout, stderr, status = Open3.capture3(args.join(" "))
|
|
116
116
|
|
|
117
117
|
success = status.success? && stderr =~ BLANK
|
|
118
118
|
pid = status.pid
|
|
@@ -3,24 +3,24 @@ module Honeybadger
|
|
|
3
3
|
module Helpers
|
|
4
4
|
module BackendCmd
|
|
5
5
|
def error_message(response)
|
|
6
|
-
host = config.get(:
|
|
7
|
-
|
|
8
|
-
!! --- Honeybadger request failed --------------------------------------------- !!
|
|
9
|
-
|
|
10
|
-
We encountered an error when contacting the server:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
To fix this issue, please try the following:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
!! --- End -------------------------------------------------------------------- !!
|
|
23
|
-
MSG
|
|
6
|
+
host = config.get(:"connection.host")
|
|
7
|
+
<<~MSG
|
|
8
|
+
!! --- Honeybadger request failed --------------------------------------------- !!
|
|
9
|
+
|
|
10
|
+
We encountered an error when contacting the server:
|
|
11
|
+
|
|
12
|
+
#{response.error_message}
|
|
13
|
+
|
|
14
|
+
To fix this issue, please try the following:
|
|
15
|
+
|
|
16
|
+
- Make sure the gem is configured properly.
|
|
17
|
+
- Retry executing this command a few times.
|
|
18
|
+
- Make sure you can connect to #{host} (`curl https://#{host}/v1/notices`).
|
|
19
|
+
- Email support@honeybadger.io for help. Include as much debug info as you
|
|
20
|
+
can for a faster resolution!
|
|
21
|
+
|
|
22
|
+
!! --- End -------------------------------------------------------------------- !!
|
|
23
|
+
MSG
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
end
|
|
@@ -1,50 +1,50 @@
|
|
|
1
1
|
module Honeybadger
|
|
2
2
|
module CLI
|
|
3
3
|
class Heroku < Thor
|
|
4
|
-
class_option :app, aliases: :
|
|
4
|
+
class_option :app, aliases: :"-a", type: :string, default: nil, desc: "Specify optional Heroku APP"
|
|
5
5
|
|
|
6
|
-
desc
|
|
7
|
-
option :api_key, aliases: :
|
|
8
|
-
option :environment, aliases: :
|
|
6
|
+
desc "install_deploy_notification", "Install Heroku deploy notifications addon"
|
|
7
|
+
option :api_key, aliases: :"-k", type: :string, desc: "Api key of your Honeybadger application"
|
|
8
|
+
option :environment, aliases: :"-e", type: :string, desc: 'Environment of your Heroku application (i.e. "production", "staging")'
|
|
9
9
|
def install_deploy_notification
|
|
10
|
-
app
|
|
11
|
-
rails_env = options[
|
|
12
|
-
api_key
|
|
10
|
+
app = options.has_key?("app") ? options["app"] : detect_heroku_app(false)
|
|
11
|
+
rails_env = options["environment"] || heroku_var("RAILS_ENV", app)
|
|
12
|
+
api_key = options["api_key"] || heroku_var("HONEYBADGER_API_KEY", app)
|
|
13
13
|
|
|
14
|
-
unless
|
|
14
|
+
unless /\S/.match?(api_key)
|
|
15
15
|
say("Unable to detect your API key from Heroku.", :red)
|
|
16
|
-
say(
|
|
16
|
+
say("Have you configured multiple Heroku apps? Try using --app APP", :red) unless app
|
|
17
17
|
exit(1)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
unless
|
|
20
|
+
unless /\S/.match?(rails_env)
|
|
21
21
|
say("Unable to detect your environment from Heroku. Use --environment ENVIRONMENT.", :red)
|
|
22
|
-
say(
|
|
22
|
+
say("Have you configured multiple Heroku apps? Try using --app APP", :red) unless app
|
|
23
23
|
exit(1)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
cmd = %
|
|
26
|
+
cmd = %(heroku webhooks:add -i api:release -l notify -u "https://api.honeybadger.io/v1/deploys/heroku?environment=#{rails_env}&api_key=#{api_key}"#{app ? " --app #{app}" : ""})
|
|
27
27
|
|
|
28
28
|
say("Running: `#{cmd}`")
|
|
29
29
|
say(run(cmd))
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
desc
|
|
32
|
+
desc "install API_KEY", "Install Honeybadger on Heroku using API_KEY"
|
|
33
33
|
def install(api_key)
|
|
34
34
|
say("Installing Honeybadger #{VERSION} for Heroku")
|
|
35
35
|
|
|
36
36
|
app = options[:app] || detect_heroku_app(false)
|
|
37
37
|
say("Adding config HONEYBADGER_API_KEY=#{api_key} to Heroku.", :magenta)
|
|
38
|
-
unless write_heroku_env({
|
|
39
|
-
say(
|
|
38
|
+
unless write_heroku_env({"HONEYBADGER_API_KEY" => api_key}, app)
|
|
39
|
+
say("Unable to update heroku config. You may need to specify an app name with --app APP", :red)
|
|
40
40
|
exit(1)
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
if env = heroku_var(
|
|
44
|
-
say(
|
|
45
|
-
invoke :install_deploy_notification, [], {
|
|
43
|
+
if (env = heroku_var("RAILS_ENV", app, heroku_var("RACK_ENV", app)))
|
|
44
|
+
say("Installing deploy notification addon", :magenta)
|
|
45
|
+
invoke :install_deploy_notification, [], {app: app, api_key: api_key, environment: env}
|
|
46
46
|
else
|
|
47
|
-
say(
|
|
47
|
+
say("Skipping deploy notification installation: we were unable to determine the environment name from your Heroku app.", :yellow)
|
|
48
48
|
say("To install manually, try `honeybadger heroku install_deploy_notification#{app ? " -a #{app}" : ""} -k #{api_key} --environment ENVIRONMENT`", :yellow)
|
|
49
49
|
end
|
|
50
50
|
|
|
@@ -60,14 +60,14 @@ module Honeybadger
|
|
|
60
60
|
#
|
|
61
61
|
# Returns the String app name if detected, otherwise nil.
|
|
62
62
|
def detect_heroku_app(prompt_on_default = true)
|
|
63
|
-
apps, git_config = {}, File.join(Dir.pwd,
|
|
63
|
+
apps, git_config = {}, File.join(Dir.pwd, ".git", "config")
|
|
64
64
|
if File.exist?(git_config)
|
|
65
|
-
require
|
|
65
|
+
require "inifile"
|
|
66
66
|
ini = IniFile.load(git_config)
|
|
67
67
|
ini.each_section do |section|
|
|
68
|
-
if match = section.match(/remote
|
|
69
|
-
url = ini[section][
|
|
70
|
-
if url_match = url.match(/heroku\.com:(?<app>.+)\.git$/)
|
|
68
|
+
if (match = section.match(/remote "(?<remote>.+)"/))
|
|
69
|
+
url = ini[section]["url"]
|
|
70
|
+
if (url_match = url.match(/heroku\.com:(?<app>.+)\.git$/))
|
|
71
71
|
apps[match[:remote]] = url_match[:app]
|
|
72
72
|
end
|
|
73
73
|
end
|
|
@@ -78,16 +78,16 @@ module Honeybadger
|
|
|
78
78
|
apps.values.first
|
|
79
79
|
else
|
|
80
80
|
say "We detected a Heroku app named #{apps.values.first}. Do you want to load the config? (y/yes or n/no)"
|
|
81
|
-
if
|
|
81
|
+
if /(y|yes)/i.match?($stdin.gets.chomp)
|
|
82
82
|
apps.values.first
|
|
83
83
|
end
|
|
84
84
|
end
|
|
85
85
|
elsif apps.size > 1
|
|
86
86
|
say "We detected the following Heroku apps:"
|
|
87
|
-
apps.each_with_index {|a,i| say "\s\s#{i+1}. #{a[1]}" }
|
|
88
|
-
say "\s\s#{apps.size+1}. Use default"
|
|
89
|
-
say "Please select an option (1-#{apps.size+1}):"
|
|
90
|
-
apps.values[
|
|
87
|
+
apps.each_with_index { |a, i| say "\s\s#{i + 1}. #{a[1]}" }
|
|
88
|
+
say "\s\s#{apps.size + 1}. Use default"
|
|
89
|
+
say "Please select an option (1-#{apps.size + 1}):"
|
|
90
|
+
apps.values[$stdin.gets.chomp.to_i - 1]
|
|
91
91
|
end
|
|
92
92
|
end
|
|
93
93
|
end
|
|
@@ -97,29 +97,29 @@ module Honeybadger
|
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
def heroku_var(var, app_name, default = nil)
|
|
100
|
-
app = app_name ? "--app #{app_name}" :
|
|
100
|
+
app = app_name ? "--app #{app_name}" : ""
|
|
101
101
|
result = run("heroku config:get #{var} #{app} 2> /dev/null").strip
|
|
102
|
-
result.split.find(lambda { default }) {|x| x =~ /\S/ }
|
|
102
|
+
result.split.find(lambda { default }) { |x| x =~ /\S/ }
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
def read_heroku_env(app = nil)
|
|
106
|
-
cmd = [
|
|
106
|
+
cmd = ["heroku config"]
|
|
107
107
|
cmd << "--app #{app}" if app
|
|
108
108
|
output = run(cmd.join("\s"))
|
|
109
109
|
return false unless $?.to_i == 0
|
|
110
|
-
|
|
110
|
+
output.scan(/(HONEYBADGER_[^:]+):\s*(\S.*)\s*$/).to_h
|
|
111
111
|
end
|
|
112
112
|
|
|
113
113
|
def set_env_from_heroku(app = nil)
|
|
114
|
-
return false unless env = read_heroku_env(app)
|
|
115
|
-
env.each_pair do |k,v|
|
|
114
|
+
return false unless (env = read_heroku_env(app))
|
|
115
|
+
env.each_pair do |k, v|
|
|
116
116
|
ENV[k] ||= v
|
|
117
117
|
end
|
|
118
118
|
end
|
|
119
119
|
|
|
120
120
|
def write_heroku_env(env, app = nil)
|
|
121
121
|
cmd = ["heroku config:set"]
|
|
122
|
-
Hash(env).each_pair {|k,v| cmd << "#{k}=#{v}" }
|
|
122
|
+
Hash(env).each_pair { |k, v| cmd << "#{k}=#{v}" }
|
|
123
123
|
cmd << "--app #{app}" if app
|
|
124
124
|
run(cmd.join("\s"))
|
|
125
125
|
$?.to_i == 0
|