appsignal 1.0.7 → 1.1.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +5 -21
- data/Rakefile +2 -0
- data/circle.yml +2 -1
- data/ext/agent.yml +7 -7
- data/ext/appsignal_extension.c +3 -5
- data/ext/extconf.rb +6 -15
- data/gemfiles/grape.gemfile +7 -0
- data/lib/appsignal/config.rb +2 -5
- data/lib/appsignal/event_formatter.rb +0 -2
- data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +47 -1
- data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +29 -0
- data/lib/appsignal/event_formatter/moped/query_formatter.rb +7 -6
- data/lib/appsignal/hooks.rb +33 -0
- data/lib/appsignal/hooks/net_http.rb +1 -1
- data/lib/appsignal/hooks/sequel.rb +7 -4
- data/lib/appsignal/hooks/sidekiq.rb +10 -19
- data/lib/appsignal/integrations/capistrano/appsignal.cap +1 -1
- data/lib/appsignal/integrations/delayed_job_plugin.rb +20 -11
- data/lib/appsignal/integrations/grape.rb +44 -0
- data/lib/appsignal/integrations/mongo_ruby_driver.rb +5 -9
- data/lib/appsignal/integrations/railtie.rb +4 -0
- data/lib/appsignal/integrations/resque.rb +1 -1
- data/lib/appsignal/js_exception_transaction.rb +2 -3
- data/lib/appsignal/subscriber.rb +2 -3
- data/lib/appsignal/transaction.rb +2 -8
- data/lib/appsignal/transmitter.rb +1 -1
- data/lib/appsignal/utils.rb +7 -43
- data/lib/appsignal/version.rb +1 -1
- data/lib/tasks/diag.rake +75 -0
- data/spec/lib/appsignal/capistrano3_spec.rb +1 -21
- data/spec/lib/appsignal/config_spec.rb +0 -12
- data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +1 -1
- data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +186 -14
- data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +54 -0
- data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +4 -4
- data/spec/lib/appsignal/extension_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +49 -14
- data/spec/lib/appsignal/hooks/sequel_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +29 -62
- data/spec/lib/appsignal/hooks_spec.rb +115 -0
- data/spec/lib/appsignal/integrations/grape_spec.rb +94 -0
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +5 -8
- data/spec/lib/appsignal/integrations/resque_spec.rb +0 -1
- data/spec/lib/appsignal/js_exception_transaction_spec.rb +0 -1
- data/spec/lib/appsignal/subscriber_spec.rb +5 -23
- data/spec/lib/appsignal/transaction_spec.rb +0 -21
- data/spec/lib/appsignal/utils_spec.rb +1 -68
- data/spec/spec_helper.rb +16 -0
- data/spec/support/helpers/env_helpers.rb +0 -1
- data/spec/support/stubs/delayed_job.rb +0 -0
- metadata +15 -11
- data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +0 -88
- data/lib/appsignal/event_formatter/sequel/sql_formatter.rb +0 -13
- data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +0 -115
- data/spec/lib/appsignal/event_formatter/sequel/sql_formatter_spec.rb +0 -22
@@ -74,3 +74,118 @@ describe Appsignal::Hooks do
|
|
74
74
|
Appsignal::Hooks.hooks[:mock_error_hook].installed?.should be_false
|
75
75
|
end
|
76
76
|
end
|
77
|
+
|
78
|
+
describe Appsignal::Hooks::Helpers do
|
79
|
+
class ClassWithHelpers
|
80
|
+
include Appsignal::Hooks::Helpers
|
81
|
+
end
|
82
|
+
let(:with_helpers) { ClassWithHelpers.new }
|
83
|
+
|
84
|
+
describe "#truncate" do
|
85
|
+
let(:very_long_text) do
|
86
|
+
"a" * 400
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should truncate the text to 200 chars max" do
|
90
|
+
with_helpers.truncate(very_long_text).should == "#{'a' * 197}..."
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "#string_or_inspect" do
|
95
|
+
context "when string" do
|
96
|
+
it "should return the string" do
|
97
|
+
with_helpers.string_or_inspect('foo').should == 'foo'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "when integer" do
|
102
|
+
it "should return the string" do
|
103
|
+
with_helpers.string_or_inspect(1).should == '1'
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "when object" do
|
108
|
+
let(:object) { Object.new }
|
109
|
+
|
110
|
+
it "should return the string" do
|
111
|
+
with_helpers.string_or_inspect(object).should == object.inspect
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "#extract_value" do
|
117
|
+
context "for a hash" do
|
118
|
+
let(:hash) { {:key => 'value'} }
|
119
|
+
|
120
|
+
context "when the key exists" do
|
121
|
+
subject { with_helpers.extract_value(hash, :key) }
|
122
|
+
|
123
|
+
it { should == 'value' }
|
124
|
+
end
|
125
|
+
|
126
|
+
context "when the key does not exist" do
|
127
|
+
subject { with_helpers.extract_value(hash, :nonexistent_key) }
|
128
|
+
|
129
|
+
it { should be_nil }
|
130
|
+
|
131
|
+
context "with a default value" do
|
132
|
+
subject { with_helpers.extract_value(hash, :nonexistent_key, 1) }
|
133
|
+
|
134
|
+
it { should == 1 }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context "for an object" do
|
140
|
+
let(:object) { double(:existing_method => 'value') }
|
141
|
+
|
142
|
+
context "when the method exists" do
|
143
|
+
subject { with_helpers.extract_value(object, :existing_method) }
|
144
|
+
|
145
|
+
it { should == 'value' }
|
146
|
+
end
|
147
|
+
|
148
|
+
context "when the method does not exist" do
|
149
|
+
subject { with_helpers.extract_value(object, :nonexistent_method) }
|
150
|
+
|
151
|
+
it { should be_nil }
|
152
|
+
|
153
|
+
context "and there is a default value" do
|
154
|
+
subject { with_helpers.extract_value(object, :nonexistent_method, 1) }
|
155
|
+
|
156
|
+
it { should == 1 }
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
context "when we need to call to_s on the value" do
|
163
|
+
let(:object) { double(:existing_method => 1) }
|
164
|
+
|
165
|
+
subject { with_helpers.extract_value(object, :existing_method, nil, true) }
|
166
|
+
|
167
|
+
it { should == '1' }
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe "#format_args" do
|
172
|
+
let(:object) { Object.new }
|
173
|
+
let(:args) do
|
174
|
+
[
|
175
|
+
'Model',
|
176
|
+
1,
|
177
|
+
object,
|
178
|
+
'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
|
179
|
+
]
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should format the arguments" do
|
183
|
+
with_helpers.format_args(args).should == [
|
184
|
+
'Model',
|
185
|
+
'1',
|
186
|
+
object.inspect,
|
187
|
+
'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ...'
|
188
|
+
]
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
if grape_present?
|
4
|
+
require 'appsignal/integrations/grape'
|
5
|
+
|
6
|
+
describe Appsignal::Grape::Middleware do
|
7
|
+
|
8
|
+
before :all do
|
9
|
+
start_agent
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:app) { double(:call => true) }
|
13
|
+
let(:api_endpoint) { double(:options => options) }
|
14
|
+
let(:options) { {
|
15
|
+
:for => 'Api::PostPut',
|
16
|
+
:method => ['POST'],
|
17
|
+
:path => ['ping']
|
18
|
+
}}
|
19
|
+
let(:env) do
|
20
|
+
http_request_env_with_data('api.endpoint' => api_endpoint)
|
21
|
+
end
|
22
|
+
let(:middleware) { Appsignal::Grape::Middleware.new(app) }
|
23
|
+
|
24
|
+
describe "#call" do
|
25
|
+
context "when appsignal is active" do
|
26
|
+
before { Appsignal.stub(:active? => true) }
|
27
|
+
|
28
|
+
it "should call with monitoring" do
|
29
|
+
expect( middleware ).to receive(:call_with_appsignal_monitoring).with(env)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when appsignal is not active" do
|
34
|
+
before { Appsignal.stub(:active? => false) }
|
35
|
+
|
36
|
+
it "should not call with monitoring" do
|
37
|
+
expect( middleware ).to_not receive(:call_with_appsignal_monitoring)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should call the app" do
|
41
|
+
expect( app ).to receive(:call).with(env)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
after { middleware.call(env) }
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#call_with_appsignal_monitoring" do
|
49
|
+
before { SecureRandom.stub(:uuid => '1') }
|
50
|
+
|
51
|
+
it "should create a transaction" do
|
52
|
+
Appsignal::Transaction.should_receive(:create).with(
|
53
|
+
'1',
|
54
|
+
Appsignal::Transaction::HTTP_REQUEST,
|
55
|
+
kind_of(::Rack::Request)
|
56
|
+
).and_return(
|
57
|
+
double(
|
58
|
+
:set_action => nil,
|
59
|
+
:set_http_or_background_queue_start => nil,
|
60
|
+
:set_metadata => nil
|
61
|
+
)
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should call the app" do
|
66
|
+
app.should_receive(:call).with(env)
|
67
|
+
end
|
68
|
+
|
69
|
+
context "with an error" do
|
70
|
+
let(:error) { VerySpecificError.new }
|
71
|
+
let(:app) do
|
72
|
+
double.tap do |d|
|
73
|
+
d.stub(:call).and_raise(error)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should set the error" do
|
78
|
+
Appsignal::Transaction.any_instance.should_receive(:set_error).with(error)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should set metadata" do
|
83
|
+
Appsignal::Transaction.any_instance.should_receive(:set_metadata).twice
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should set the action and queue start" do
|
87
|
+
Appsignal::Transaction.any_instance.should_receive(:set_action).with('POST::Api::PostPut#ping')
|
88
|
+
Appsignal::Transaction.any_instance.should_receive(:set_http_or_background_queue_start)
|
89
|
+
end
|
90
|
+
|
91
|
+
after { middleware.call(env) rescue VerySpecificError }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -11,15 +11,13 @@ describe Appsignal::Hooks::MongoMonitorSubscriber do
|
|
11
11
|
describe "#started" do
|
12
12
|
let(:event) do
|
13
13
|
double(
|
14
|
-
:request_id
|
15
|
-
:
|
16
|
-
:command => {'foo' => 'bar'}
|
14
|
+
:request_id => 1,
|
15
|
+
:command => {'foo' => 'bar'}
|
17
16
|
)
|
18
17
|
end
|
19
18
|
|
20
19
|
it "should sanitize command" do
|
21
|
-
Appsignal::
|
22
|
-
.should receive(:format).with('find', {'foo' => 'bar'})
|
20
|
+
Appsignal::Utils.should receive(:sanitize).with({'foo' => 'bar'} )
|
23
21
|
|
24
22
|
subscriber.started(event)
|
25
23
|
end
|
@@ -83,9 +81,8 @@ describe Appsignal::Hooks::MongoMonitorSubscriber do
|
|
83
81
|
Appsignal::Extension.should receive(:finish_event).with(
|
84
82
|
transaction.transaction_index,
|
85
83
|
'query.mongodb',
|
86
|
-
'find
|
87
|
-
"{\"foo\"
|
88
|
-
0
|
84
|
+
'find',
|
85
|
+
"test | SUCCEEDED | {\"foo\"=>\"?\"}"
|
89
86
|
)
|
90
87
|
|
91
88
|
subscriber.finish('SUCCEEDED', event)
|
@@ -87,7 +87,6 @@ describe Appsignal::JSExceptionTransaction do
|
|
87
87
|
describe "#complete!" do
|
88
88
|
it "should call all required methods" do
|
89
89
|
expect( Appsignal::Extension ).to receive(:finish_transaction).with(kind_of(Integer))
|
90
|
-
expect( Appsignal::Extension ).to receive(:complete_transaction).with(kind_of(Integer))
|
91
90
|
transaction.complete!
|
92
91
|
end
|
93
92
|
end
|
@@ -98,10 +98,10 @@ describe Appsignal::Subscriber do
|
|
98
98
|
|
99
99
|
it "should call native start and finish event for every event" do
|
100
100
|
Appsignal::Extension.should_receive(:start_event).exactly(4).times
|
101
|
-
Appsignal::Extension.should_receive(:finish_event).with(kind_of(Integer), 'one', '', ''
|
102
|
-
Appsignal::Extension.should_receive(:finish_event).with(kind_of(Integer), 'two', '', ''
|
103
|
-
Appsignal::Extension.should_receive(:finish_event).with(kind_of(Integer), 'two.three', '', ''
|
104
|
-
Appsignal::Extension.should_receive(:finish_event).with(kind_of(Integer), 'one.three', '', ''
|
101
|
+
Appsignal::Extension.should_receive(:finish_event).with(kind_of(Integer), 'one', '', '').once
|
102
|
+
Appsignal::Extension.should_receive(:finish_event).with(kind_of(Integer), 'two', '', '').once
|
103
|
+
Appsignal::Extension.should_receive(:finish_event).with(kind_of(Integer), 'two.three', '', '').once
|
104
|
+
Appsignal::Extension.should_receive(:finish_event).with(kind_of(Integer), 'one.three', '', '').once
|
105
105
|
|
106
106
|
ActiveSupport::Notifications.instrument('one') do
|
107
107
|
ActiveSupport::Notifications.instrument('two') do
|
@@ -119,8 +119,7 @@ describe Appsignal::Subscriber do
|
|
119
119
|
kind_of(Integer),
|
120
120
|
'request.net_http',
|
121
121
|
'GET http://www.google.com',
|
122
|
-
''
|
123
|
-
0
|
122
|
+
''
|
124
123
|
).once
|
125
124
|
|
126
125
|
ActiveSupport::Notifications.instrument(
|
@@ -131,23 +130,6 @@ describe Appsignal::Subscriber do
|
|
131
130
|
)
|
132
131
|
end
|
133
132
|
|
134
|
-
it "should call finish with title, body and body format if there is a formatter that returns it" do
|
135
|
-
Appsignal::Extension.should_receive(:start_event).once
|
136
|
-
Appsignal::Extension.should_receive(:finish_event).with(
|
137
|
-
kind_of(Integer),
|
138
|
-
'sql.active_record',
|
139
|
-
'Something load',
|
140
|
-
'SELECT * FROM something',
|
141
|
-
1
|
142
|
-
).once
|
143
|
-
|
144
|
-
ActiveSupport::Notifications.instrument(
|
145
|
-
'sql.active_record',
|
146
|
-
:name => 'Something load',
|
147
|
-
:sql => 'SELECT * FROM something'
|
148
|
-
)
|
149
|
-
end
|
150
|
-
|
151
133
|
context "when paused" do
|
152
134
|
before { transaction.pause! }
|
153
135
|
|
@@ -331,11 +331,6 @@ describe Appsignal::Transaction do
|
|
331
331
|
'params',
|
332
332
|
'{"controller":"blog_posts","action":"show","id":"1"}'
|
333
333
|
).once
|
334
|
-
Appsignal::Extension.should_receive(:set_transaction_sample_data).with(
|
335
|
-
kind_of(Integer),
|
336
|
-
'metadata',
|
337
|
-
'{"key":"value"}'
|
338
|
-
).once
|
339
334
|
Appsignal::Extension.should_receive(:set_transaction_sample_data).with(
|
340
335
|
kind_of(Integer),
|
341
336
|
'tags',
|
@@ -621,22 +616,6 @@ describe Appsignal::Transaction do
|
|
621
616
|
end
|
622
617
|
end
|
623
618
|
|
624
|
-
describe "#metadata" do
|
625
|
-
subject { transaction.send(:metadata) }
|
626
|
-
|
627
|
-
context "when env is nil" do
|
628
|
-
before { transaction.request.stub(:env => nil) }
|
629
|
-
|
630
|
-
it { should be_nil }
|
631
|
-
end
|
632
|
-
|
633
|
-
context "when env is present" do
|
634
|
-
let(:env) { {:metadata => {:key => 'value'}} }
|
635
|
-
|
636
|
-
it { should == env[:metadata] }
|
637
|
-
end
|
638
|
-
end
|
639
|
-
|
640
619
|
describe '#sanitized_tags' do
|
641
620
|
before do
|
642
621
|
transaction.set_tags(
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
1
|
require 'spec_helper'
|
4
2
|
|
5
3
|
describe Appsignal::Utils do
|
@@ -20,22 +18,13 @@ describe Appsignal::Utils do
|
|
20
18
|
end
|
21
19
|
end
|
22
20
|
|
23
|
-
context "when params is an array of strings" do
|
21
|
+
context "when params is an array of strings " do
|
24
22
|
let(:params) { ['foo', 'bar'] }
|
25
23
|
|
26
24
|
it "should sanitize all hash values with a single questionmark" do
|
27
25
|
expect( Appsignal::Utils.sanitize(params) ).to eq(['?'])
|
28
26
|
end
|
29
27
|
end
|
30
|
-
|
31
|
-
context "when params is a mixed array" do
|
32
|
-
let(:params) { [nil, 'foo', 'bar'] }
|
33
|
-
|
34
|
-
it "should sanitize all hash values with a single questionmark" do
|
35
|
-
expect( Appsignal::Utils.sanitize(params) ).to eq(['?'])
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
28
|
context "when params is a string" do
|
40
29
|
let(:params) { 'bar'}
|
41
30
|
|
@@ -44,60 +33,4 @@ describe Appsignal::Utils do
|
|
44
33
|
end
|
45
34
|
end
|
46
35
|
end
|
47
|
-
|
48
|
-
describe ".sanitize_key" do
|
49
|
-
it "should not sanitize key when no key_sanitizer is given" do
|
50
|
-
expect( Appsignal::Utils.sanitize_key('foo', nil) ).to eql('foo')
|
51
|
-
end
|
52
|
-
|
53
|
-
context "with mongodb sanitizer" do
|
54
|
-
it "should not sanitize key when no dots are in the key" do
|
55
|
-
expect( Appsignal::Utils.sanitize_key('foo', :mongodb) ).to eql('foo')
|
56
|
-
end
|
57
|
-
|
58
|
-
it "should sanitize key when dots are in the key" do
|
59
|
-
expect( Appsignal::Utils.sanitize_key('foo.bar', :mongodb) ).to eql('foo.?')
|
60
|
-
end
|
61
|
-
|
62
|
-
it "should sanitize a symbol" do
|
63
|
-
expect( Appsignal::Utils.sanitize_key(:ismaster, :mongodb) ).to eql('ismaster')
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
describe ".json_generate" do
|
69
|
-
subject { Appsignal::Utils.json_generate(body) }
|
70
|
-
|
71
|
-
context "with a valid body" do
|
72
|
-
let(:body) { {'the' => 'payload'} }
|
73
|
-
|
74
|
-
it { should == "{\"the\":\"payload\"}" }
|
75
|
-
end
|
76
|
-
|
77
|
-
context "with a body that contains strings with invalid utf-8 content" do
|
78
|
-
let(:string_with_invalid_utf8) { [0x61, 0x61, 0x85].pack('c*') }
|
79
|
-
let(:body) { {
|
80
|
-
'field_one' => [0x61, 0x61].pack('c*'),
|
81
|
-
'field_two' => string_with_invalid_utf8,
|
82
|
-
'field_three' => [
|
83
|
-
'one', string_with_invalid_utf8
|
84
|
-
],
|
85
|
-
'field_four' => {
|
86
|
-
'one' => string_with_invalid_utf8
|
87
|
-
}
|
88
|
-
} }
|
89
|
-
|
90
|
-
it { should == "{\"field_one\":\"aa\",\"field_two\":\"aa�\",\"field_three\":[\"one\",\"aa�\"],\"field_four\":{\"one\":\"aa�\"}}" }
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
describe ".encode_utf8" do
|
95
|
-
subject { Appsignal::Utils.encode_utf8(value) }
|
96
|
-
|
97
|
-
context "value with invalid utf-8 content" do
|
98
|
-
let(:value) { [0x61, 0x61, 0x85].pack('c*') }
|
99
|
-
|
100
|
-
it { should == "aa�" }
|
101
|
-
end
|
102
|
-
end
|
103
36
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -7,6 +7,8 @@ require 'webmock/rspec'
|
|
7
7
|
|
8
8
|
puts "Runnings specs in #{RUBY_VERSION} on #{RUBY_PLATFORM}"
|
9
9
|
|
10
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'support/stubs'))
|
11
|
+
|
10
12
|
begin
|
11
13
|
require 'rails'
|
12
14
|
Dir[File.expand_path(File.join(File.dirname(__FILE__), 'support/rails','*.rb'))].each {|f| require f}
|
@@ -21,6 +23,13 @@ def rails_present?
|
|
21
23
|
RAILS_PRESENT
|
22
24
|
end
|
23
25
|
|
26
|
+
def active_job_present?
|
27
|
+
require 'active_job'
|
28
|
+
true
|
29
|
+
rescue LoadError
|
30
|
+
false
|
31
|
+
end
|
32
|
+
|
24
33
|
def active_record_present?
|
25
34
|
require 'active_record'
|
26
35
|
true
|
@@ -67,6 +76,13 @@ rescue LoadError
|
|
67
76
|
false
|
68
77
|
end
|
69
78
|
|
79
|
+
def grape_present?
|
80
|
+
require 'grape'
|
81
|
+
true
|
82
|
+
rescue LoadError
|
83
|
+
false
|
84
|
+
end
|
85
|
+
|
70
86
|
require 'appsignal'
|
71
87
|
|
72
88
|
Dir[File.expand_path(File.join(File.dirname(__FILE__), 'support/helpers','*.rb'))].each {|f| require f}
|