roqua-support 0.1.24 → 0.1.25

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: 3f1a04caaa757627735ff9ac6c83c220f21b0ea0
4
- data.tar.gz: 9ff7c7a188bb759645ed74e7b1253b43f0eab896
3
+ metadata.gz: c59df394193f13d45c71f26b935f59e890b98f96
4
+ data.tar.gz: b0f6dc5880a4dfda1d96f554d5460dd180e6fc3b
5
5
  SHA512:
6
- metadata.gz: e47f9a438f4cf20f34377b691e1d0964f5fcaec675f195297c109f689a12c63bf5b4445fdcaf801ad6213a199d1485493b71661a8e7868e275d3c0c4a2b2e54f
7
- data.tar.gz: '09c7e888632d9dd19df77b2d3a2a5813d10063c1ea19ef81bec447e0e9055815539d7318e6a0f45b71f2bd510eb4d22a98bac385140796932390b9ce63d933fc'
6
+ metadata.gz: 0ccdada5a2cff7e753ae5e8d0278473a70d4e39b7c0f85f1287811946850f73612ade4bed1d5a081290cc6edde938a4190a32969cad62913e5e401e178a57f68
7
+ data.tar.gz: 29ea857840bd5f40b59efd2b94eb599909cec72d2e9b58dcd16e71a210935ca9dd6344ad2dee79fda8772257db4edfa2276e9cd57745618d35c143b823474935
data/.gitlab-ci.yml CHANGED
@@ -1,21 +1,43 @@
1
- image: "roqua/roqua-build-images:ruby-2.3.3-phantomjs-2.1.1-bundler-gemnasium"
1
+ image: "registry.roqua.nl/roqua/roqua-build-images:ruby-2.3-rails-base-test"
2
2
 
3
3
  variables:
4
4
  RAILS_ENV: "test"
5
-
5
+
6
+ stages:
7
+ - test
8
+ - publish
9
+
10
+ cache:
11
+ paths:
12
+ - .gems
13
+
6
14
  before_script:
7
- - bundle install
8
- - gem install appraisal
15
+ - export BUNDLE_PATH=$CI_PROJECT_DIR/.gems
16
+ - bundle --jobs 2 --retry 3
9
17
  - bundle exec appraisal
18
+ - bundle --jobs 2 --retry 3
10
19
 
11
20
  rails_41:
21
+ stage: test
12
22
  script:
13
23
  - bundle exec appraisal rails41 bundle exec rspec
14
24
 
15
25
  rails_42:
26
+ stage: test
16
27
  script:
17
28
  - bundle exec appraisal rails42 bundle exec rspec
18
29
 
19
30
  rails_50:
31
+ stage: test
32
+ script:
33
+ - bundle exec appraisal rails50 bundle exec rspec
34
+
35
+ build_and_publish_gem:
36
+ stage: publish
37
+ dependencies:
38
+ - rails_41
39
+ - rails_42
40
+ - rails_50
20
41
  script:
21
- - bundle exec appraisal rails50 bundle exec rspec
42
+ - gem build roqua-support.gemspec
43
+ - gem push roqua-support-0.1.25.gem
data/Gemfile CHANGED
@@ -9,6 +9,7 @@ gem 'roqua_styleguide', git: 'https://gitlab.roqua.nl/roqua/styleguide.git'
9
9
  group :test do
10
10
  gem 'actionpack', '>= 4.0'
11
11
  gem 'active_interaction', '~> 3.0'
12
+ gem 'appsignal'
12
13
  gem 'combustion', '~> 0.5.2'
13
14
  gem 'guard-rspec', '~> 4.2.6'
14
15
  gem 'responders'
data/Gemfile.lock CHANGED
@@ -8,7 +8,7 @@ GIT
8
8
  PATH
9
9
  remote: .
10
10
  specs:
11
- roqua-support (0.1.23)
11
+ roqua-support (0.1.25)
12
12
  active_interaction (~> 3.0)
13
13
  activesupport (>= 3.2, < 6)
14
14
  naught (~> 1.0)
@@ -42,6 +42,8 @@ GEM
42
42
  bundler
43
43
  rake
44
44
  thor (>= 0.14.0)
45
+ appsignal (2.3.1)
46
+ rack
45
47
  ast (2.3.0)
46
48
  builder (3.2.3)
47
49
  coderay (1.1.1)
@@ -162,10 +164,11 @@ DEPENDENCIES
162
164
  actionpack (>= 4.0)
163
165
  active_interaction (~> 3.0)
164
166
  appraisal
167
+ appsignal
165
168
  bundler (~> 1.0)
166
169
  combustion (~> 0.5.2)
167
170
  guard-rspec (~> 4.2.6)
168
- rake
171
+ rake (~> 12.1)
169
172
  responders
170
173
  roqua-support!
171
174
  roqua_styleguide!
data/Guardfile CHANGED
@@ -3,6 +3,6 @@
3
3
 
4
4
  guard :rspec, cmd: 'bundle exec rspec --colour' do
5
5
  watch(%r{^spec/.+_spec\.rb$})
6
- watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
7
7
  watch('spec/spec_helper.rb') { "spec" }
8
8
  end
@@ -20,88 +20,71 @@ module Roqua
20
20
  end
21
21
 
22
22
  def self.report(exception, context = {})
23
- return if const_defined?(:Rails) and Rails.env.test?
24
- context = {} unless context.is_a? Hash
23
+ return if const_defined?(:Rails) && Rails.env.test?
25
24
 
26
- parameters, controller, skip_backtrace = merge_parameters(exception, context)
25
+ namespace, parameters, _controller, skip_backtrace = merge_parameters(exception, context)
26
+ notification_urls = [notify_appsignal(exception, parameters, namespace)]
27
27
 
28
- notification_urls = [notify_airbrake(exception, controller, parameters),
29
- notify_appsignal(exception, parameters)]
30
28
  # Notify Roqua logging
31
29
  log_exception(exception, parameters, notification_urls.compact, skip_backtrace)
32
30
  end
33
31
 
34
- private
35
-
36
- def self.merge_parameters(exception, context = {})
37
- parameters = extra_parameters.dup
38
- controller = context.delete :controller
39
- skip_backtrace = context.delete :skip_backtrace
40
- parameters.merge! context
41
- parameters.merge! extra_parameters_from_exception(exception)
42
- [parameters, controller, skip_backtrace]
43
- rescue Exception
32
+ def self.appsignal_namespace_for_category(category)
33
+ case category
34
+ when :background then Appsignal::Transaction::BACKGROUND_JOB
35
+ when :web then Appsignal::Transaction::HTTP_REQUEST
36
+ else Appsignal::Transaction::BLANK
37
+ end
44
38
  end
45
39
 
46
- def self.extra_parameters_from_exception(exception)
47
- exception.instance_variable_get(:@roqua_extra_parameters) || {}
48
- end
40
+ class << self
41
+ private
49
42
 
50
- def self.log_exception(exception, parameters = {}, notification_urls = [], skip_backtrace = false)
51
- if Roqua.respond_to?(:logger)
52
- exception_info = {class_name: exception.class.to_s,
53
- message: exception.message,
54
- parameters: parameters}
55
- exception_info[:notification_urls] = notification_urls if notification_urls.present?
56
- exception_info[:backtrace] = exception.backtrace unless skip_backtrace
57
- puts exception_info.inspect
58
- Roqua.logger.error('roqua.exception', exception_info)
43
+ def merge_parameters(exception, context = {})
44
+ controller = context.delete :controller
45
+ skip_backtrace = context.delete :skip_backtrace
46
+ namespace = context.delete(:namespace) || :background
47
+
48
+ [namespace,
49
+ extra_parameters.merge(context).merge(extra_parameters_from_exception(exception)),
50
+ controller,
51
+ skip_backtrace]
59
52
  end
60
- rescue Exception
61
- end
62
53
 
63
- def self.notify_airbrake(exception, controller, parameters = {})
64
- if const_defined?(:Airbrake)
65
- if controller && controller.respond_to?(:airbrake_request_data)
66
- request_data = controller.airbrake_request_data
67
- if request_data.is_a?(Hash)
68
- request_data[:parameters] ||= {}
69
- if request_data[:parameters].is_a?(Hash)
70
- request_data[:parameters] = parameters.merge request_data[:parameters]
71
- end
72
- else
73
- request_data = nil
74
- end
54
+ def extra_parameters_from_exception(exception)
55
+ exception.instance_variable_get(:@roqua_extra_parameters) || {}
56
+ end
57
+
58
+ def log_exception(exception, parameters = {}, notification_urls = [], skip_backtrace = false)
59
+ if Roqua.respond_to?(:logger)
60
+ exception_info = {class_name: exception.class.to_s,
61
+ message: exception.message,
62
+ parameters: parameters}
63
+ exception_info[:notification_urls] = notification_urls if notification_urls.present?
64
+ exception_info[:backtrace] = exception.backtrace unless skip_backtrace
65
+ puts exception_info.inspect
66
+ Roqua.logger.error('roqua.exception', exception_info)
75
67
  end
76
- request_data ||= {parameters: parameters}
77
- uuid = Airbrake.notify_or_ignore(exception, request_data)
78
- "https://airbrake.io/locate/#{uuid}" if uuid
68
+ rescue Exception
79
69
  end
80
- rescue Exception
81
- end
82
70
 
83
- def self.notify_appsignal(exception, parameters = {})
84
- if const_defined?(:Appsignal) and
85
- not Appsignal.is_ignored_exception?(exception)
86
- # TODO: If and when https://github.com/appsignal/appsignal/pull/9 is merged,
87
- # this functionality should be supported directly by Appsignal.send_exception.
88
- # Appsignal.send_exception(exception, parameters: parameters)
71
+ def notify_appsignal?(exception)
72
+ const_defined?(:Appsignal) && !Appsignal.is_ignored_exception?(exception) && Appsignal.active?
73
+ end
74
+
75
+ def notify_appsignal(exception, labels, namespace)
76
+ return unless notify_appsignal?(exception)
77
+
78
+ namespace = appsignal_namespace_for_category(namespace)
79
+ current_transaction = Appsignal::Transaction.current
89
80
 
90
- if Appsignal.active?
91
- # Hackety hack around stateful mess of Appsignal gem
92
- if Appsignal::Transaction.current
93
- Appsignal::Transaction.current.set_tags(parameters)
94
- Appsignal::Transaction.current.add_exception(exception)
95
- else
96
- transaction = Appsignal::Transaction.create(SecureRandom.uuid, ENV.to_hash)
97
- transaction.set_tags(parameters)
98
- transaction.add_exception(exception)
99
- transaction.complete!
100
- Appsignal.agent.send_queue
101
- end
81
+ if current_transaction.namespace == Appsignal::Transaction::HTTP_REQUEST
82
+ current_transaction.set_tags(labels)
83
+ current_transaction.add_exception(exception)
84
+ else
85
+ Appsignal.send_error exception, labels, namespace
102
86
  end
103
87
  end
104
- rescue Exception
105
88
  end
106
89
  end
107
90
  end
@@ -1,5 +1,5 @@
1
1
  module Roqua
2
2
  module Support
3
- VERSION = '0.1.24'.freeze
3
+ VERSION = '0.1.25'.freeze
4
4
  end
5
5
  end
@@ -23,6 +23,7 @@ Gem::Specification.new do |gem|
23
23
  gem.add_dependency 'active_interaction', '~> 3.0'
24
24
 
25
25
  gem.add_development_dependency 'bundler', '~> 1.0'
26
- gem.add_development_dependency 'rake'
26
+ gem.add_development_dependency 'rake', '~> 12.1'
27
27
  gem.add_development_dependency 'rspec', '>= 2.12.0', '< 4.0'
28
+ gem.add_development_dependency 'appsignal', '~> 2.3', '>= 2.3.1'
28
29
  end
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'roqua/support/errors'
3
+ require 'appsignal'
3
4
 
4
5
  describe 'Error reporting' do
5
6
  let(:exception) do
@@ -19,34 +20,34 @@ describe 'Error reporting' do
19
20
 
20
21
  context 'when the Roqua logger is defined' do
21
22
  it 'supports default extra params' do
22
- Roqua::Support::Errors.stub(extra_parameters: {organization: 'some_org'})
23
- Roqua.logger.should_receive(:error).with('roqua.exception',
24
- class_name: 'Exception',
25
- message: 'exception_message',
26
- backtrace: ['back', 'trace', 'lines'],
27
- parameters: {organization: 'some_org'})
23
+ allow(Roqua::Support::Errors).to receive(:extra_parameters).and_return(organization: 'some_org')
24
+ expect(Roqua.logger).to receive(:error).with('roqua.exception',
25
+ class_name: 'Exception',
26
+ message: 'exception_message',
27
+ backtrace: ['back', 'trace', 'lines'],
28
+ parameters: {organization: 'some_org'})
28
29
  Roqua::Support::Errors.report exception
29
30
  end
30
31
 
31
32
  it 'sends notifications to the eventlog' do
32
- Roqua.logger.should_receive(:error).with('roqua.exception',
33
- class_name: 'Exception',
34
- message: 'exception_message',
35
- backtrace: ['back', 'trace', 'lines'],
36
- parameters: {})
33
+ expect(Roqua.logger).to receive(:error).with('roqua.exception',
34
+ class_name: 'Exception',
35
+ message: 'exception_message',
36
+ backtrace: ['back', 'trace', 'lines'],
37
+ parameters: {})
37
38
  Roqua::Support::Errors.report exception
38
39
  end
39
40
 
40
41
  it 'skips the backtrace when the skip_backtrace flag is set' do
41
- Roqua.logger.should_receive(:error).with('roqua.exception',
42
- class_name: 'Exception',
43
- message: 'exception_message',
44
- parameters: {})
42
+ expect(Roqua.logger).to receive(:error).with('roqua.exception',
43
+ class_name: 'Exception',
44
+ message: 'exception_message',
45
+ parameters: {})
45
46
  Roqua::Support::Errors.report exception, skip_backtrace: true
46
47
  end
47
48
 
48
49
  it 'can add extra parameters by calling add_parameters' do
49
- Roqua.logger.should_receive(:error).with \
50
+ expect(Roqua.logger).to receive(:error).with \
50
51
  'roqua.exception', class_name: 'RuntimeError',
51
52
  message: 'exception_message',
52
53
  parameters: {more: 'params',
@@ -69,7 +70,7 @@ describe 'Error reporting' do
69
70
  end
70
71
 
71
72
  it 'will not fail when called outside of rescue or when passed the wrong format to add_parameters' do
72
- Roqua.logger.should_receive(:error).with \
73
+ expect(Roqua.logger).to receive(:error).with \
73
74
  'roqua.exception', class_name: 'RuntimeError',
74
75
  message: 'exception_message',
75
76
  parameters: {}
@@ -86,75 +87,77 @@ describe 'Error reporting' do
86
87
  Roqua::Support::Errors.report e, skip_backtrace: true
87
88
  end
88
89
  end
89
-
90
- it 'logs notification_urls when present' do
91
- stub_const('Airbrake', double('Airbrake', notify_or_ignore: 'uuid'))
92
- Roqua.logger.should_receive(:error)
93
- .with('roqua.exception',
94
- class_name: 'Exception',
95
- message: 'exception_message',
96
- backtrace: ['back', 'trace', 'lines'],
97
- notification_urls: ['https://airbrake.io/locate/uuid'],
98
- parameters: {})
99
- Roqua::Support::Errors.report exception
100
- end
101
90
  end
102
91
 
103
- context 'when Airbrake is defined' do
92
+ context 'when Appsignal is loaded' do
93
+ let(:agent) { double("agent") }
94
+ let(:transaction) { double("transaction") }
95
+
104
96
  before do
105
- stub_const('Airbrake', double('Airbrake', is_ignored_exception?: false))
97
+ allow(Appsignal).to receive(:active?).and_return(true)
98
+ allow(Appsignal).to receive(:is_ignored_exception?).and_return(false)
99
+ allow(Appsignal).to receive(:agent).and_return(agent)
106
100
  end
107
101
 
108
- it 'sends notifications to airbrake' do
109
- Airbrake.should_receive(:notify_or_ignore).with(exception, parameters: {})
102
+ it 'it will send an error' do
103
+ expect(Appsignal).to receive(:send_error)
110
104
  Roqua::Support::Errors.report exception
111
105
  end
112
106
 
113
- it 'adds request data when a controller is passed in' do
114
- controller = double(airbrake_request_data: {request: 'data', parameters: {request: 'param'}})
115
- expect(Airbrake).to receive(:notify_or_ignore)
116
- .with(exception, request: 'data', parameters: {request: 'param', some: 'context'})
117
- Roqua::Support::Errors.report exception, controller: controller, some: 'context'
107
+ it 'defaults to a background job' do
108
+ expect(Appsignal).to receive(:send_error).with(exception, {}, Appsignal::Transaction::BACKGROUND_JOB)
109
+ Roqua::Support::Errors.report exception
118
110
  end
119
111
 
120
- it 'does not fail with context of incompatible type' do
121
- expect(Airbrake).to receive(:notify_or_ignore).with(exception, parameters: {})
122
- Roqua::Support::Errors.report exception, ['controller', 'extra_param']
123
- end
112
+ it 'it will send an error under the provided category' do
113
+ expect(Appsignal)
114
+ .to receive(:send_error)
115
+ .with(exception, {a: 'b'}, Appsignal::Transaction::HTTP_REQUEST)
124
116
 
125
- it 'does not fail with request data of incompatible type' do
126
- controller = double(airbrake_request_data: ['request', 'data'])
127
- expect(Airbrake).to receive(:notify_or_ignore).with(exception, parameters: {})
128
- Roqua::Support::Errors.report exception, controller: controller
117
+ Roqua::Support::Errors.report exception, a: 'b', namespace: :web
129
118
  end
130
- end
131
119
 
132
- context 'when Appsignal is loaded' do
133
- let(:agent) { double("agent") }
134
- let(:transaction) { double("transaction") }
120
+ describe 'when a current transaction is present' do
121
+ let(:current_transaction) do
122
+ Appsignal::Transaction.new(SecureRandom.uuid, Appsignal::Transaction::HTTP_REQUEST, nil)
123
+ end
135
124
 
136
- it 'sends notifications to appsignal when there is no current exception' do
137
- stub_const("Appsignal", Module.new)
138
- Appsignal.stub(active?: true)
139
- Appsignal.stub(is_ignored_exception?: false, agent: agent)
140
- stub_const("Appsignal::Transaction", double("Transaction", create: transaction, current: nil))
125
+ before do
126
+ expect(Appsignal::Transaction).to receive(:current).at_least(:once).and_return(current_transaction)
127
+ end
141
128
 
142
- transaction.should_receive(:set_tags).with({})
143
- transaction.should_receive(:add_exception).with(exception)
144
- transaction.should_receive(:complete!)
145
- agent.should_receive(:send_queue)
146
- Roqua::Support::Errors.report exception
129
+ it 'sets the correct properties if a current transaction is present' do
130
+ expect(current_transaction).to receive(:set_tags).with(a: 'b').and_call_original
131
+ expect(current_transaction).to receive(:add_exception).with(exception).and_call_original
132
+
133
+ Roqua::Support::Errors.report exception, a: 'b', namespace: :web
134
+ end
135
+
136
+ describe "if the current transaction isn't a http request" do
137
+ let(:current_transaction) do
138
+ Appsignal::Transaction.new(SecureRandom.uuid, Appsignal::Transaction::BACKGROUND_JOB, nil)
139
+ end
140
+
141
+ it "will not set the properties if the current transaction isn't a http request" do
142
+ expect(current_transaction).to_not receive(:set_tags)
143
+ expect(current_transaction).to_not receive(:add_exception)
144
+
145
+ Roqua::Support::Errors.report exception, a: 'b', namespace: :web
146
+ end
147
+ end
147
148
  end
149
+ end
148
150
 
149
- it 'sends notifications to appsignal when there already is a current exception' do
150
- stub_const("Appsignal", Module.new)
151
- Appsignal.stub(active?: true)
152
- Appsignal.stub(is_ignored_exception?: false, agent: agent)
153
- stub_const("Appsignal::Transaction", double("Transaction", current: transaction))
151
+ context '.appsignal_namespace_for_category' do
152
+ it 'returns the correct string based on the category' do
153
+ expect(Roqua::Support::Errors.appsignal_namespace_for_category(:background))
154
+ .to eql(Appsignal::Transaction::BACKGROUND_JOB)
154
155
 
155
- transaction.should_receive(:set_tags).with({})
156
- transaction.should_receive(:add_exception).with(exception)
157
- Roqua::Support::Errors.report exception
156
+ expect(Roqua::Support::Errors.appsignal_namespace_for_category(:web))
157
+ .to eql(Appsignal::Transaction::HTTP_REQUEST)
158
+
159
+ expect(Roqua::Support::Errors.appsignal_namespace_for_category(''))
160
+ .to eql(Appsignal::Transaction::BLANK)
158
161
  end
159
162
  end
160
163
  end
data/spec/spec_helper.rb CHANGED
@@ -5,4 +5,5 @@ require 'combustion'
5
5
 
6
6
  Combustion.initialize! :action_controller
7
7
 
8
+ require 'appsignal'
8
9
  require 'rspec/rails'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roqua-support
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.24
4
+ version: 0.1.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marten Veldthuis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-25 00:00:00.000000000 Z
11
+ date: 2017-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -76,16 +76,16 @@ dependencies:
76
76
  name: rake
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - ">="
79
+ - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: '0'
81
+ version: '12.1'
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
- - - ">="
86
+ - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: '0'
88
+ version: '12.1'
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: rspec
91
91
  requirement: !ruby/object:Gem::Requirement
@@ -106,6 +106,26 @@ dependencies:
106
106
  - - "<"
107
107
  - !ruby/object:Gem::Version
108
108
  version: '4.0'
109
+ - !ruby/object:Gem::Dependency
110
+ name: appsignal
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: '2.3'
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: 2.3.1
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: '2.3'
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: 2.3.1
109
129
  description: 'Logging backend, freedom patches, '
110
130
  email: marten@roqua.nl
111
131
  executables: []
@@ -190,7 +210,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
190
210
  version: '0'
191
211
  requirements: []
192
212
  rubyforge_project:
193
- rubygems_version: 2.5.2.1
213
+ rubygems_version: 2.5.2
194
214
  signing_key:
195
215
  specification_version: 4
196
216
  summary: Helper objects and proxies used by a lot of RoQua applications