exception_handling 3.0.pre.1 → 3.0.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 +5 -5
- data/.github/CODEOWNERS +1 -0
- data/.github/workflows/pipeline.yml +36 -0
- data/.gitignore +3 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -1
- data/.tool-versions +1 -0
- data/Appraisals +13 -0
- data/CHANGELOG.md +150 -0
- data/Gemfile +10 -16
- data/Gemfile.lock +65 -128
- data/README.md +51 -19
- data/Rakefile +8 -11
- data/exception_handling.gemspec +11 -13
- data/gemfiles/rails_5.gemfile +16 -0
- data/gemfiles/rails_6.gemfile +16 -0
- data/gemfiles/rails_7.gemfile +16 -0
- data/lib/exception_handling/escalate_callback.rb +19 -0
- data/lib/exception_handling/exception_info.rb +15 -11
- data/lib/exception_handling/log_stub_error.rb +2 -1
- data/lib/exception_handling/logging_methods.rb +21 -0
- data/lib/exception_handling/testing.rb +9 -12
- data/lib/exception_handling/version.rb +1 -1
- data/lib/exception_handling.rb +83 -173
- data/{test → spec}/helpers/exception_helpers.rb +2 -2
- data/spec/rake_test_warning_false.rb +20 -0
- data/{test/test_helper.rb → spec/spec_helper.rb} +63 -66
- data/spec/unit/exception_handling/escalate_callback_spec.rb +81 -0
- data/spec/unit/exception_handling/exception_catalog_spec.rb +85 -0
- data/spec/unit/exception_handling/exception_description_spec.rb +82 -0
- data/{test/unit/exception_handling/exception_info_test.rb → spec/unit/exception_handling/exception_info_spec.rb} +170 -114
- data/{test/unit/exception_handling/log_error_stub_test.rb → spec/unit/exception_handling/log_error_stub_spec.rb} +38 -22
- data/spec/unit/exception_handling/logging_methods_spec.rb +38 -0
- data/spec/unit/exception_handling_spec.rb +1063 -0
- metadata +62 -91
- data/lib/exception_handling/honeybadger_callbacks.rb +0 -59
- data/lib/exception_handling/mailer.rb +0 -70
- data/lib/exception_handling/methods.rb +0 -101
- data/lib/exception_handling/sensu.rb +0 -28
- data/semaphore_ci/setup.sh +0 -3
- data/test/unit/exception_handling/exception_catalog_test.rb +0 -85
- data/test/unit/exception_handling/exception_description_test.rb +0 -82
- data/test/unit/exception_handling/honeybadger_callbacks_test.rb +0 -122
- data/test/unit/exception_handling/mailer_test.rb +0 -98
- data/test/unit/exception_handling/methods_test.rb +0 -84
- data/test/unit/exception_handling/sensu_test.rb +0 -52
- data/test/unit/exception_handling_test.rb +0 -1109
- data/views/exception_handling/mailer/escalate_custom.html.erb +0 -17
- data/views/exception_handling/mailer/escalation_notification.html.erb +0 -17
- data/views/exception_handling/mailer/log_parser_exception_notification.html.erb +0 -82
- /data/{test → spec}/helpers/controller_helpers.rb +0 -0
metadata
CHANGED
@@ -1,123 +1,101 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exception_handling
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
8
|
-
autorequire:
|
7
|
+
- Invoca
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '5.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '5.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: contextual_logger
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '1.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '1.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: escalate
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '0.3'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: contextual_logger
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :runtime
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
54
|
+
version: '0.3'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
56
|
+
name: invoca-utils
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
59
|
- - "~>"
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
61
|
+
version: '0.3'
|
76
62
|
type: :runtime
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
66
|
- - "~>"
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
68
|
+
version: '0.3'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :runtime
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: invoca-utils
|
70
|
+
name: psych
|
99
71
|
requirement: !ruby/object:Gem::Requirement
|
100
72
|
requirements:
|
101
73
|
- - "~>"
|
102
74
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
75
|
+
version: '3.0'
|
104
76
|
type: :runtime
|
105
77
|
prerelease: false
|
106
78
|
version_requirements: !ruby/object:Gem::Requirement
|
107
79
|
requirements:
|
108
80
|
- - "~>"
|
109
81
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
111
|
-
description: Exception handling logger
|
82
|
+
version: '3.0'
|
83
|
+
description: Exception handling logger
|
112
84
|
email:
|
113
|
-
-
|
85
|
+
- development@invoca.com
|
114
86
|
executables: []
|
115
87
|
extensions: []
|
116
88
|
extra_rdoc_files: []
|
117
89
|
files:
|
90
|
+
- ".github/CODEOWNERS"
|
91
|
+
- ".github/workflows/pipeline.yml"
|
118
92
|
- ".gitignore"
|
93
|
+
- ".rspec"
|
119
94
|
- ".rubocop.yml"
|
120
95
|
- ".ruby-version"
|
96
|
+
- ".tool-versions"
|
97
|
+
- Appraisals
|
98
|
+
- CHANGELOG.md
|
121
99
|
- Gemfile
|
122
100
|
- Gemfile.lock
|
123
101
|
- LICENSE
|
@@ -125,39 +103,35 @@ files:
|
|
125
103
|
- Rakefile
|
126
104
|
- config/exception_filters.yml
|
127
105
|
- exception_handling.gemspec
|
106
|
+
- gemfiles/rails_5.gemfile
|
107
|
+
- gemfiles/rails_6.gemfile
|
108
|
+
- gemfiles/rails_7.gemfile
|
128
109
|
- lib/exception_handling.rb
|
110
|
+
- lib/exception_handling/escalate_callback.rb
|
129
111
|
- lib/exception_handling/exception_catalog.rb
|
130
112
|
- lib/exception_handling/exception_description.rb
|
131
113
|
- lib/exception_handling/exception_info.rb
|
132
|
-
- lib/exception_handling/honeybadger_callbacks.rb
|
133
114
|
- lib/exception_handling/log_stub_error.rb
|
134
|
-
- lib/exception_handling/
|
135
|
-
- lib/exception_handling/methods.rb
|
136
|
-
- lib/exception_handling/sensu.rb
|
115
|
+
- lib/exception_handling/logging_methods.rb
|
137
116
|
- lib/exception_handling/testing.rb
|
138
117
|
- lib/exception_handling/version.rb
|
139
|
-
-
|
140
|
-
-
|
141
|
-
-
|
142
|
-
-
|
143
|
-
-
|
144
|
-
-
|
145
|
-
-
|
146
|
-
-
|
147
|
-
-
|
148
|
-
-
|
149
|
-
-
|
150
|
-
- test/unit/exception_handling/sensu_test.rb
|
151
|
-
- test/unit/exception_handling_test.rb
|
152
|
-
- views/exception_handling/mailer/escalate_custom.html.erb
|
153
|
-
- views/exception_handling/mailer/escalation_notification.html.erb
|
154
|
-
- views/exception_handling/mailer/log_parser_exception_notification.html.erb
|
118
|
+
- spec/helpers/controller_helpers.rb
|
119
|
+
- spec/helpers/exception_helpers.rb
|
120
|
+
- spec/rake_test_warning_false.rb
|
121
|
+
- spec/spec_helper.rb
|
122
|
+
- spec/unit/exception_handling/escalate_callback_spec.rb
|
123
|
+
- spec/unit/exception_handling/exception_catalog_spec.rb
|
124
|
+
- spec/unit/exception_handling/exception_description_spec.rb
|
125
|
+
- spec/unit/exception_handling/exception_info_spec.rb
|
126
|
+
- spec/unit/exception_handling/log_error_stub_spec.rb
|
127
|
+
- spec/unit/exception_handling/logging_methods_spec.rb
|
128
|
+
- spec/unit/exception_handling_spec.rb
|
155
129
|
homepage: https://github.com/Invoca/exception_handling
|
156
130
|
licenses: []
|
157
131
|
metadata:
|
158
132
|
source_code_uri: https://github.com/Invoca/exception_handling
|
159
133
|
allowed_push_host: https://rubygems.org
|
160
|
-
post_install_message:
|
134
|
+
post_install_message:
|
161
135
|
rdoc_options: []
|
162
136
|
require_paths:
|
163
137
|
- lib
|
@@ -168,26 +142,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
168
142
|
version: '0'
|
169
143
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
144
|
requirements:
|
171
|
-
- - "
|
145
|
+
- - ">="
|
172
146
|
- !ruby/object:Gem::Version
|
173
|
-
version:
|
147
|
+
version: '0'
|
174
148
|
requirements: []
|
175
|
-
|
176
|
-
|
177
|
-
signing_key:
|
149
|
+
rubygems_version: 3.3.7
|
150
|
+
signing_key:
|
178
151
|
specification_version: 4
|
179
|
-
summary: Invoca's exception handling logger
|
180
|
-
Works with Rails or EventMachine or EventMachine+Synchrony.
|
152
|
+
summary: Invoca's exception handling logger layer, based on exception_notifier.
|
181
153
|
test_files:
|
182
|
-
-
|
183
|
-
-
|
184
|
-
-
|
185
|
-
-
|
186
|
-
-
|
187
|
-
-
|
188
|
-
-
|
189
|
-
-
|
190
|
-
-
|
191
|
-
-
|
192
|
-
-
|
193
|
-
- test/unit/exception_handling_test.rb
|
154
|
+
- spec/helpers/controller_helpers.rb
|
155
|
+
- spec/helpers/exception_helpers.rb
|
156
|
+
- spec/rake_test_warning_false.rb
|
157
|
+
- spec/spec_helper.rb
|
158
|
+
- spec/unit/exception_handling/escalate_callback_spec.rb
|
159
|
+
- spec/unit/exception_handling/exception_catalog_spec.rb
|
160
|
+
- spec/unit/exception_handling/exception_description_spec.rb
|
161
|
+
- spec/unit/exception_handling/exception_info_spec.rb
|
162
|
+
- spec/unit/exception_handling/log_error_stub_spec.rb
|
163
|
+
- spec/unit/exception_handling/logging_methods_spec.rb
|
164
|
+
- spec/unit/exception_handling_spec.rb
|
@@ -1,59 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ExceptionHandling
|
4
|
-
module HoneybadgerCallbacks
|
5
|
-
class << self
|
6
|
-
def register_callbacks
|
7
|
-
if ExceptionHandling.honeybadger_defined?
|
8
|
-
Honeybadger.local_variable_filter(&method(:local_variable_filter))
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
def inspect_object(object, filter_keys)
|
15
|
-
inspection_output = object.inspect
|
16
|
-
|
17
|
-
if contains_filter_key?(filter_keys, inspection_output)
|
18
|
-
filtered_object(object)
|
19
|
-
else
|
20
|
-
inspection_output
|
21
|
-
end
|
22
|
-
rescue => ex
|
23
|
-
details = if object.respond_to?(:to_pk)
|
24
|
-
" @pk=#{object.to_pk}"
|
25
|
-
elsif object.respond_to?(:id)
|
26
|
-
" @id=#{object.id}"
|
27
|
-
end
|
28
|
-
|
29
|
-
"#<#{object.class.name}#{details} [error '#{ex.class.name}: #{ex.message}' while calling #inspect]>"
|
30
|
-
end
|
31
|
-
|
32
|
-
def local_variable_filter(_symbol, object, filter_keys)
|
33
|
-
case object
|
34
|
-
# Honeybadger will filter these data types for us
|
35
|
-
when String, Hash, Array, Set, Numeric, TrueClass, FalseClass, NilClass
|
36
|
-
object
|
37
|
-
else # handle other Ruby objects, intended for POROs
|
38
|
-
inspect_object(object, filter_keys)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def contains_filter_key?(filter_keys, string)
|
43
|
-
filter_keys._?.any? { |key| string.include?(key) }
|
44
|
-
end
|
45
|
-
|
46
|
-
def filtered_object(object)
|
47
|
-
# make the output look similar to inspect
|
48
|
-
# use [FILTERED], just like honeybadger does
|
49
|
-
if object.respond_to?(:to_pk)
|
50
|
-
"#<#{object.class.name} @pk=#{object.to_pk}, [FILTERED]>"
|
51
|
-
elsif object.respond_to?(:id)
|
52
|
-
"#<#{object.class.name} @id=#{object.id}, [FILTERED]>"
|
53
|
-
else
|
54
|
-
"#<#{object.class.name} [FILTERED]>"
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,70 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'action_mailer'
|
4
|
-
|
5
|
-
module ExceptionHandling
|
6
|
-
class Mailer < ActionMailer::Base
|
7
|
-
default content_type: "text/html"
|
8
|
-
|
9
|
-
append_view_path "#{File.dirname(__FILE__)}/../../views"
|
10
|
-
|
11
|
-
[:email_environment, :server_name, :sender_address, :exception_recipients, :escalation_recipients].each do |method|
|
12
|
-
define_method method do
|
13
|
-
ExceptionHandling.send(method) or raise "No #{method} set!"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def email_prefix
|
18
|
-
"#{email_environment} exception: "
|
19
|
-
end
|
20
|
-
|
21
|
-
class << self
|
22
|
-
def reloadable?
|
23
|
-
false
|
24
|
-
end
|
25
|
-
|
26
|
-
def mailer_method_category
|
27
|
-
{
|
28
|
-
log_parser_exception_notification: :NetworkOptout
|
29
|
-
}
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def escalation_notification(summary, data, custom_recipients = nil)
|
34
|
-
subject = "#{email_environment} Escalation: #{summary}"
|
35
|
-
from = sender_address.gsub('xception', 'scalation')
|
36
|
-
recipients = begin
|
37
|
-
custom_recipients || escalation_recipients
|
38
|
-
rescue
|
39
|
-
exception_recipients
|
40
|
-
end
|
41
|
-
|
42
|
-
@summary = summary
|
43
|
-
@server = ExceptionHandling.server_name
|
44
|
-
@cleaned_data = data
|
45
|
-
|
46
|
-
mail(from: from,
|
47
|
-
to: recipients,
|
48
|
-
subject: subject)
|
49
|
-
end
|
50
|
-
|
51
|
-
def log_parser_exception_notification(cleaned_data, key)
|
52
|
-
if cleaned_data.is_a?(Hash)
|
53
|
-
cleaned_data = cleaned_data.symbolize_keys
|
54
|
-
local_subject = cleaned_data[:error]
|
55
|
-
else
|
56
|
-
local_subject = "#{key}: #{cleaned_data}"
|
57
|
-
cleaned_data = { error: cleaned_data.to_s }
|
58
|
-
end
|
59
|
-
|
60
|
-
@subject = "#{email_prefix}#{local_subject}"[0, 300]
|
61
|
-
@recipients = exception_recipients
|
62
|
-
from = sender_address
|
63
|
-
@cleaned_data = cleaned_data
|
64
|
-
|
65
|
-
mail(from: from,
|
66
|
-
to: @recipients,
|
67
|
-
subject: @subject)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
@@ -1,101 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support/concern'
|
4
|
-
|
5
|
-
module ExceptionHandling
|
6
|
-
module Methods # included on models and controllers
|
7
|
-
extend ActiveSupport::Concern
|
8
|
-
|
9
|
-
protected
|
10
|
-
|
11
|
-
def log_error(exception_or_string, exception_context = '')
|
12
|
-
controller = self if respond_to?(:request) && respond_to?(:session)
|
13
|
-
ExceptionHandling.log_error(exception_or_string, exception_context, controller)
|
14
|
-
end
|
15
|
-
|
16
|
-
def log_error_rack(exception_or_string, exception_context = '', rack_filter = '')
|
17
|
-
ExceptionHandling.log_error_rack(exception_or_string, exception_context, rack_filter)
|
18
|
-
end
|
19
|
-
|
20
|
-
def log_warning(message)
|
21
|
-
ExceptionHandling.log_warning(message)
|
22
|
-
end
|
23
|
-
|
24
|
-
def log_info(message)
|
25
|
-
ExceptionHandling.logger.info(message)
|
26
|
-
end
|
27
|
-
|
28
|
-
def log_debug(message)
|
29
|
-
ExceptionHandling.logger.debug(message)
|
30
|
-
end
|
31
|
-
|
32
|
-
def ensure_safe(exception_context = "")
|
33
|
-
yield
|
34
|
-
rescue => ex
|
35
|
-
log_error ex, exception_context
|
36
|
-
nil
|
37
|
-
end
|
38
|
-
|
39
|
-
def escalate_error(exception_or_string, email_subject)
|
40
|
-
ExceptionHandling.escalate_error(exception_or_string, email_subject)
|
41
|
-
end
|
42
|
-
|
43
|
-
def escalate_warning(message, email_subject)
|
44
|
-
ExceptionHandling.escalate_warning(message, email_subject)
|
45
|
-
end
|
46
|
-
|
47
|
-
def ensure_escalation(*args)
|
48
|
-
ExceptionHandling.ensure_escalation(*args) do
|
49
|
-
yield
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def alert_warning(*args)
|
54
|
-
ExceptionHandling.alert_warning(*args)
|
55
|
-
end
|
56
|
-
|
57
|
-
def ensure_alert(*args)
|
58
|
-
ExceptionHandling.ensure_alert(*args) do
|
59
|
-
yield
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def long_controller_action_timeout
|
64
|
-
if defined?(Rails) && Rails.respond_to?(:env) && Rails.env == 'test'
|
65
|
-
300
|
66
|
-
else
|
67
|
-
30
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def set_current_controller
|
72
|
-
ExceptionHandling.current_controller = self
|
73
|
-
result = nil
|
74
|
-
time = Benchmark.measure do
|
75
|
-
result = yield
|
76
|
-
end
|
77
|
-
if time.real > long_controller_action_timeout && !['development', 'test'].include?(ExceptionHandling.email_environment)
|
78
|
-
name = begin
|
79
|
-
" in #{controller_name}::#{action_name}"
|
80
|
-
rescue
|
81
|
-
" "
|
82
|
-
end
|
83
|
-
log_error("Long controller action detected#{name} %.4fs " % time.real)
|
84
|
-
end
|
85
|
-
result
|
86
|
-
ensure
|
87
|
-
ExceptionHandling.current_controller = nil
|
88
|
-
end
|
89
|
-
|
90
|
-
included do
|
91
|
-
around_filter :set_current_controller if respond_to? :around_filter
|
92
|
-
end
|
93
|
-
|
94
|
-
class_methods do
|
95
|
-
def set_long_controller_action_timeout(timeout)
|
96
|
-
define_method(:long_controller_action_timeout) { timeout }
|
97
|
-
protected :long_controller_action_timeout
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "socket"
|
4
|
-
|
5
|
-
module ExceptionHandling
|
6
|
-
module Sensu
|
7
|
-
LEVELS = {
|
8
|
-
warning: 1,
|
9
|
-
critical: 2
|
10
|
-
}.freeze
|
11
|
-
|
12
|
-
class << self
|
13
|
-
def generate_event(name, message, level = :warning)
|
14
|
-
status = LEVELS[level] or raise "Invalid alert level #{level}"
|
15
|
-
|
16
|
-
event = { name: ExceptionHandling.sensu_prefix.to_s + name, output: message, status: status }
|
17
|
-
|
18
|
-
send_event(event)
|
19
|
-
end
|
20
|
-
|
21
|
-
def send_event(event)
|
22
|
-
Socket.tcp(ExceptionHandling.sensu_host, ExceptionHandling.sensu_port) do |sock|
|
23
|
-
sock.send(event.to_json, 0)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
data/semaphore_ci/setup.sh
DELETED
@@ -1,85 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require File.expand_path('../../test_helper', __dir__)
|
4
|
-
|
5
|
-
module ExceptionHandling
|
6
|
-
class ExceptionCatalogTest < ActiveSupport::TestCase
|
7
|
-
|
8
|
-
context "With stubbed yaml content" do
|
9
|
-
setup do
|
10
|
-
filter_list = { exception1: { error: "my error message" },
|
11
|
-
exception2: { error: "some other message", session: "misc data" } }
|
12
|
-
stub(YAML).load_file { filter_list }
|
13
|
-
|
14
|
-
# bump modified time up to get the above filter loaded
|
15
|
-
stub(File).mtime { incrementing_mtime }
|
16
|
-
end
|
17
|
-
|
18
|
-
context "with loaded data" do
|
19
|
-
setup do
|
20
|
-
stub(File).mtime { incrementing_mtime }
|
21
|
-
@exception_catalog = ExceptionCatalog.new(ExceptionHandling.filter_list_filename)
|
22
|
-
@exception_catalog.send :load_file
|
23
|
-
end
|
24
|
-
|
25
|
-
should "have loaded filters" do
|
26
|
-
assert_equal 2, @exception_catalog.instance_eval("@filters").size
|
27
|
-
end
|
28
|
-
|
29
|
-
should "find messages in the catalog" do
|
30
|
-
assert !@exception_catalog.find(error: "Scott says unlikely to ever match")
|
31
|
-
end
|
32
|
-
|
33
|
-
should "find matching data" do
|
34
|
-
exception_description = @exception_catalog.find(error: "this is my error message, which should match something")
|
35
|
-
assert exception_description
|
36
|
-
assert_equal :exception1, exception_description.filter_name
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
should "write errors loading the yaml file directly to the log file" do
|
41
|
-
@exception_catalog = ExceptionCatalog.new(ExceptionHandling.filter_list_filename)
|
42
|
-
|
43
|
-
mock(ExceptionHandling).log_error.never
|
44
|
-
mock(ExceptionHandling).write_exception_to_log(anything, "ExceptionCatalog#refresh_filters: ./config/exception_filters.yml", anything)
|
45
|
-
mock(@exception_catalog).load_file { raise "noooooo" }
|
46
|
-
|
47
|
-
@exception_catalog.find({})
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
context "with live yaml content" do
|
52
|
-
setup do
|
53
|
-
@filename = File.expand_path('../../../config/exception_filters.yml', __dir__)
|
54
|
-
@exception_catalog = ExceptionCatalog.new(@filename)
|
55
|
-
assert_nothing_raised "Loading the exception filter should not raise" do
|
56
|
-
@exception_catalog.send :load_file
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
should "load the filter data" do
|
61
|
-
assert !@exception_catalog.find(error: "Scott says unlikely to ever match")
|
62
|
-
assert !@exception_catalog.find(error: "Scott says unlikely to ever match")
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
context "with no yaml content" do
|
67
|
-
setup do
|
68
|
-
@exception_catalog = ExceptionCatalog.new(nil)
|
69
|
-
end
|
70
|
-
|
71
|
-
should "not load filter data" do
|
72
|
-
mock(ExceptionHandling).write_exception_to_log.with_any_args.never
|
73
|
-
@exception_catalog.find(error: "Scott says unlikely to ever match")
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
|
79
|
-
def incrementing_mtime
|
80
|
-
@mtime ||= Time.now
|
81
|
-
@mtime += 1.day
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require File.expand_path('../../test_helper', __dir__)
|
4
|
-
|
5
|
-
module ExceptionHandling
|
6
|
-
class ExceptionDescriptionTest < ActiveSupport::TestCase
|
7
|
-
|
8
|
-
context "Filter" do
|
9
|
-
should "allow direct matching of strings" do
|
10
|
-
@f = ExceptionDescription.new(:filter1, error: "my error message")
|
11
|
-
assert @f.match?('error' => "my error message")
|
12
|
-
end
|
13
|
-
|
14
|
-
should "allow direct matching of strings on with symbol keys" do
|
15
|
-
@f = ExceptionDescription.new(:filter1, error: "my error message")
|
16
|
-
assert @f.match?(error: "my error message")
|
17
|
-
end
|
18
|
-
|
19
|
-
should "allow wildcards to cross line boundries" do
|
20
|
-
@f = ExceptionDescription.new(:filter1, error: "my error message.*with multiple lines")
|
21
|
-
assert @f.match?(error: "my error message\nwith more than one, with multiple lines")
|
22
|
-
end
|
23
|
-
|
24
|
-
should "complain when no regexps have a value" do
|
25
|
-
assert_raise(ArgumentError, "has all blank regexe") { ExceptionDescription.new(:filter1, error: nil) }
|
26
|
-
end
|
27
|
-
|
28
|
-
should "report when an invalid key is passed" do
|
29
|
-
assert_raise(ArgumentError, "Unknown section: not_a_parameter") { ExceptionDescription.new(:filter1, error: "my error message", not_a_parameter: false) }
|
30
|
-
end
|
31
|
-
|
32
|
-
should "allow send_to_honeybadger to be specified and have it disabled by default" do
|
33
|
-
assert !ExceptionDescription.new(:filter1, error: "my error message", send_to_honeybadger: false).send_to_honeybadger
|
34
|
-
assert ExceptionDescription.new(:filter1, error: "my error message", send_to_honeybadger: true).send_to_honeybadger
|
35
|
-
assert !ExceptionDescription.new(:filter1, error: "my error message").send_to_honeybadger
|
36
|
-
end
|
37
|
-
|
38
|
-
should "allow send_metric to be configured" do
|
39
|
-
assert !ExceptionDescription.new(:filter1, error: "my error message", send_metric: false).send_metric
|
40
|
-
assert ExceptionDescription.new(:filter1, error: "my error message").send_metric
|
41
|
-
end
|
42
|
-
|
43
|
-
should "provide metric name" do
|
44
|
-
assert_equal "filter1", ExceptionDescription.new(:filter1, error: "my error message").metric_name
|
45
|
-
assert_equal "some_other_metric_name", ExceptionDescription.new(:filter1, error: "my error message", metric_name: :some_other_metric_name).metric_name
|
46
|
-
end
|
47
|
-
|
48
|
-
should "replace spaces in metric name" do
|
49
|
-
@f = ExceptionDescription.new(:"filter has spaces", error: "my error message")
|
50
|
-
assert_equal "filter_has_spaces", @f.metric_name
|
51
|
-
end
|
52
|
-
|
53
|
-
should "allow notes to be recorded" do
|
54
|
-
assert_nil ExceptionDescription.new(:filter1, error: "my error message").notes
|
55
|
-
assert_equal "a long string", ExceptionDescription.new(:filter1, error: "my error message", notes: "a long string").notes
|
56
|
-
end
|
57
|
-
|
58
|
-
should "not consider config options in the filter set" do
|
59
|
-
assert ExceptionDescription.new(:filter1, error: "my error message", send_metric: false).match?(error: "my error message")
|
60
|
-
assert ExceptionDescription.new(:filter1, error: "my error message", metric_name: "false").match?(error: "my error message")
|
61
|
-
assert ExceptionDescription.new(:filter1, error: "my error message", notes: "hey").match?(error: "my error message")
|
62
|
-
end
|
63
|
-
|
64
|
-
should "provide exception details" do
|
65
|
-
exception_description = ExceptionDescription.new(:filter1, error: "my error message", notes: "hey")
|
66
|
-
|
67
|
-
expected = { "send_metric" => true, "metric_name" => "filter1", "notes" => "hey" }
|
68
|
-
|
69
|
-
assert_equal expected, exception_description.exception_data
|
70
|
-
end
|
71
|
-
|
72
|
-
should "match multiple email addresses" do
|
73
|
-
mobi = "ExceptionHandling::Warning: LoginAttempt::IPAddressLocked: failed login for 'mcc@mobistreak.com'"
|
74
|
-
credit = "ExceptionHandling::Warning: LoginAttempt::IPAddressLocked: failed login for 'damon@thecreditpros.com'"
|
75
|
-
|
76
|
-
exception_description = ExceptionDescription.new(:filter1, error: "ExceptionHandling::Warning: LoginAttempt::IPAddressLocked: failed login for '(mcc\@mobistreak|damon\@thecreditpros).com'")
|
77
|
-
assert exception_description.match?(error: mobi), "does not match mobi"
|
78
|
-
assert exception_description.match?(error: credit), "does not match credit"
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|