appsignal 2.5.0.alpha.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (211) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +33 -0
  3. data/.rspec +4 -0
  4. data/.rubocop.yml +66 -0
  5. data/.rubocop_todo.yml +124 -0
  6. data/.travis.yml +72 -0
  7. data/.yardopts +8 -0
  8. data/CHANGELOG.md +639 -0
  9. data/Gemfile +3 -0
  10. data/LICENSE +20 -0
  11. data/README.md +264 -0
  12. data/Rakefile +214 -0
  13. data/appsignal.gemspec +42 -0
  14. data/benchmark.rake +77 -0
  15. data/bin/appsignal +13 -0
  16. data/ext/Rakefile +27 -0
  17. data/ext/agent.yml +64 -0
  18. data/ext/appsignal_extension.c +692 -0
  19. data/ext/base.rb +79 -0
  20. data/ext/extconf.rb +35 -0
  21. data/gemfiles/capistrano2.gemfile +7 -0
  22. data/gemfiles/capistrano3.gemfile +7 -0
  23. data/gemfiles/grape.gemfile +7 -0
  24. data/gemfiles/no_dependencies.gemfile +5 -0
  25. data/gemfiles/padrino.gemfile +7 -0
  26. data/gemfiles/que.gemfile +5 -0
  27. data/gemfiles/rails-3.2.gemfile +6 -0
  28. data/gemfiles/rails-4.0.gemfile +6 -0
  29. data/gemfiles/rails-4.1.gemfile +6 -0
  30. data/gemfiles/rails-4.2.gemfile +10 -0
  31. data/gemfiles/rails-5.0.gemfile +5 -0
  32. data/gemfiles/rails-5.1.gemfile +5 -0
  33. data/gemfiles/resque.gemfile +12 -0
  34. data/gemfiles/sequel-435.gemfile +11 -0
  35. data/gemfiles/sequel.gemfile +11 -0
  36. data/gemfiles/sinatra.gemfile +6 -0
  37. data/gemfiles/webmachine.gemfile +5 -0
  38. data/lib/appsignal.rb +804 -0
  39. data/lib/appsignal/auth_check.rb +65 -0
  40. data/lib/appsignal/capistrano.rb +10 -0
  41. data/lib/appsignal/cli.rb +108 -0
  42. data/lib/appsignal/cli/demo.rb +63 -0
  43. data/lib/appsignal/cli/diagnose.rb +500 -0
  44. data/lib/appsignal/cli/helpers.rb +72 -0
  45. data/lib/appsignal/cli/install.rb +277 -0
  46. data/lib/appsignal/cli/notify_of_deploy.rb +113 -0
  47. data/lib/appsignal/config.rb +287 -0
  48. data/lib/appsignal/demo.rb +107 -0
  49. data/lib/appsignal/event_formatter.rb +74 -0
  50. data/lib/appsignal/event_formatter/action_view/render_formatter.rb +24 -0
  51. data/lib/appsignal/event_formatter/active_record/instantiation_formatter.rb +14 -0
  52. data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +14 -0
  53. data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +32 -0
  54. data/lib/appsignal/event_formatter/faraday/request_formatter.rb +19 -0
  55. data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +89 -0
  56. data/lib/appsignal/event_formatter/moped/query_formatter.rb +80 -0
  57. data/lib/appsignal/extension.rb +63 -0
  58. data/lib/appsignal/extension/jruby.rb +460 -0
  59. data/lib/appsignal/garbage_collection_profiler.rb +48 -0
  60. data/lib/appsignal/hooks.rb +105 -0
  61. data/lib/appsignal/hooks/action_cable.rb +113 -0
  62. data/lib/appsignal/hooks/active_support_notifications.rb +52 -0
  63. data/lib/appsignal/hooks/celluloid.rb +30 -0
  64. data/lib/appsignal/hooks/data_mapper.rb +18 -0
  65. data/lib/appsignal/hooks/delayed_job.rb +19 -0
  66. data/lib/appsignal/hooks/mongo_ruby_driver.rb +21 -0
  67. data/lib/appsignal/hooks/net_http.rb +29 -0
  68. data/lib/appsignal/hooks/passenger.rb +22 -0
  69. data/lib/appsignal/hooks/puma.rb +35 -0
  70. data/lib/appsignal/hooks/que.rb +21 -0
  71. data/lib/appsignal/hooks/rake.rb +39 -0
  72. data/lib/appsignal/hooks/redis.rb +30 -0
  73. data/lib/appsignal/hooks/sequel.rb +60 -0
  74. data/lib/appsignal/hooks/shoryuken.rb +43 -0
  75. data/lib/appsignal/hooks/sidekiq.rb +144 -0
  76. data/lib/appsignal/hooks/unicorn.rb +40 -0
  77. data/lib/appsignal/hooks/webmachine.rb +23 -0
  78. data/lib/appsignal/integrations/capistrano/appsignal.cap +39 -0
  79. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +52 -0
  80. data/lib/appsignal/integrations/data_mapper.rb +33 -0
  81. data/lib/appsignal/integrations/delayed_job_plugin.rb +54 -0
  82. data/lib/appsignal/integrations/grape.rb +53 -0
  83. data/lib/appsignal/integrations/mongo_ruby_driver.rb +55 -0
  84. data/lib/appsignal/integrations/object.rb +35 -0
  85. data/lib/appsignal/integrations/padrino.rb +84 -0
  86. data/lib/appsignal/integrations/que.rb +43 -0
  87. data/lib/appsignal/integrations/railtie.rb +41 -0
  88. data/lib/appsignal/integrations/rake.rb +2 -0
  89. data/lib/appsignal/integrations/resque.rb +20 -0
  90. data/lib/appsignal/integrations/resque_active_job.rb +30 -0
  91. data/lib/appsignal/integrations/sinatra.rb +17 -0
  92. data/lib/appsignal/integrations/webmachine.rb +38 -0
  93. data/lib/appsignal/js_exception_transaction.rb +54 -0
  94. data/lib/appsignal/marker.rb +63 -0
  95. data/lib/appsignal/minutely.rb +42 -0
  96. data/lib/appsignal/rack/generic_instrumentation.rb +49 -0
  97. data/lib/appsignal/rack/js_exception_catcher.rb +70 -0
  98. data/lib/appsignal/rack/rails_instrumentation.rb +51 -0
  99. data/lib/appsignal/rack/sinatra_instrumentation.rb +99 -0
  100. data/lib/appsignal/rack/streaming_listener.rb +73 -0
  101. data/lib/appsignal/system.rb +81 -0
  102. data/lib/appsignal/transaction.rb +498 -0
  103. data/lib/appsignal/transmitter.rb +107 -0
  104. data/lib/appsignal/utils.rb +127 -0
  105. data/lib/appsignal/utils/params_sanitizer.rb +59 -0
  106. data/lib/appsignal/utils/query_params_sanitizer.rb +55 -0
  107. data/lib/appsignal/version.rb +3 -0
  108. data/lib/sequel/extensions/appsignal_integration.rb +3 -0
  109. data/resources/appsignal.yml.erb +39 -0
  110. data/resources/cacert.pem +3866 -0
  111. data/spec/.rubocop.yml +7 -0
  112. data/spec/lib/appsignal/auth_check_spec.rb +80 -0
  113. data/spec/lib/appsignal/capistrano2_spec.rb +224 -0
  114. data/spec/lib/appsignal/capistrano3_spec.rb +237 -0
  115. data/spec/lib/appsignal/cli/demo_spec.rb +67 -0
  116. data/spec/lib/appsignal/cli/diagnose_spec.rb +988 -0
  117. data/spec/lib/appsignal/cli/helpers_spec.rb +171 -0
  118. data/spec/lib/appsignal/cli/install_spec.rb +632 -0
  119. data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +168 -0
  120. data/spec/lib/appsignal/cli_spec.rb +56 -0
  121. data/spec/lib/appsignal/config_spec.rb +637 -0
  122. data/spec/lib/appsignal/demo_spec.rb +87 -0
  123. data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +44 -0
  124. data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +21 -0
  125. data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +21 -0
  126. data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +52 -0
  127. data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +21 -0
  128. data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +113 -0
  129. data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +112 -0
  130. data/spec/lib/appsignal/event_formatter_spec.rb +100 -0
  131. data/spec/lib/appsignal/extension/jruby_spec.rb +43 -0
  132. data/spec/lib/appsignal/extension_spec.rb +137 -0
  133. data/spec/lib/appsignal/garbage_collection_profiler_spec.rb +66 -0
  134. data/spec/lib/appsignal/hooks/action_cable_spec.rb +370 -0
  135. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +92 -0
  136. data/spec/lib/appsignal/hooks/celluloid_spec.rb +35 -0
  137. data/spec/lib/appsignal/hooks/data_mapper_spec.rb +39 -0
  138. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +358 -0
  139. data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +44 -0
  140. data/spec/lib/appsignal/hooks/net_http_spec.rb +53 -0
  141. data/spec/lib/appsignal/hooks/passenger_spec.rb +30 -0
  142. data/spec/lib/appsignal/hooks/puma_spec.rb +80 -0
  143. data/spec/lib/appsignal/hooks/que_spec.rb +19 -0
  144. data/spec/lib/appsignal/hooks/rake_spec.rb +73 -0
  145. data/spec/lib/appsignal/hooks/redis_spec.rb +55 -0
  146. data/spec/lib/appsignal/hooks/sequel_spec.rb +46 -0
  147. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +192 -0
  148. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +419 -0
  149. data/spec/lib/appsignal/hooks/unicorn_spec.rb +52 -0
  150. data/spec/lib/appsignal/hooks/webmachine_spec.rb +35 -0
  151. data/spec/lib/appsignal/hooks_spec.rb +195 -0
  152. data/spec/lib/appsignal/integrations/data_mapper_spec.rb +65 -0
  153. data/spec/lib/appsignal/integrations/grape_spec.rb +225 -0
  154. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +127 -0
  155. data/spec/lib/appsignal/integrations/object_spec.rb +249 -0
  156. data/spec/lib/appsignal/integrations/padrino_spec.rb +323 -0
  157. data/spec/lib/appsignal/integrations/que_spec.rb +174 -0
  158. data/spec/lib/appsignal/integrations/railtie_spec.rb +129 -0
  159. data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +83 -0
  160. data/spec/lib/appsignal/integrations/resque_spec.rb +92 -0
  161. data/spec/lib/appsignal/integrations/sinatra_spec.rb +73 -0
  162. data/spec/lib/appsignal/integrations/webmachine_spec.rb +69 -0
  163. data/spec/lib/appsignal/js_exception_transaction_spec.rb +128 -0
  164. data/spec/lib/appsignal/marker_spec.rb +51 -0
  165. data/spec/lib/appsignal/minutely_spec.rb +50 -0
  166. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +90 -0
  167. data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +147 -0
  168. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +117 -0
  169. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +213 -0
  170. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +161 -0
  171. data/spec/lib/appsignal/system_spec.rb +131 -0
  172. data/spec/lib/appsignal/transaction_spec.rb +1146 -0
  173. data/spec/lib/appsignal/transmitter_spec.rb +152 -0
  174. data/spec/lib/appsignal/utils/params_sanitizer_spec.rb +136 -0
  175. data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +192 -0
  176. data/spec/lib/appsignal/utils_spec.rb +150 -0
  177. data/spec/lib/appsignal_spec.rb +1049 -0
  178. data/spec/spec_helper.rb +116 -0
  179. data/spec/support/fixtures/containers/cgroups/docker +14 -0
  180. data/spec/support/fixtures/containers/cgroups/docker_systemd +8 -0
  181. data/spec/support/fixtures/containers/cgroups/lxc +10 -0
  182. data/spec/support/fixtures/containers/cgroups/no_permission +0 -0
  183. data/spec/support/fixtures/containers/cgroups/none +1 -0
  184. data/spec/support/fixtures/generated_config.yml +24 -0
  185. data/spec/support/fixtures/uploaded_file.txt +0 -0
  186. data/spec/support/helpers/api_request_helper.rb +19 -0
  187. data/spec/support/helpers/cli_helpers.rb +26 -0
  188. data/spec/support/helpers/config_helpers.rb +21 -0
  189. data/spec/support/helpers/dependency_helper.rb +73 -0
  190. data/spec/support/helpers/directory_helper.rb +27 -0
  191. data/spec/support/helpers/env_helpers.rb +33 -0
  192. data/spec/support/helpers/example_exception.rb +13 -0
  193. data/spec/support/helpers/example_standard_error.rb +13 -0
  194. data/spec/support/helpers/log_helpers.rb +22 -0
  195. data/spec/support/helpers/std_streams_helper.rb +66 -0
  196. data/spec/support/helpers/system_helpers.rb +8 -0
  197. data/spec/support/helpers/time_helpers.rb +11 -0
  198. data/spec/support/helpers/transaction_helpers.rb +37 -0
  199. data/spec/support/matchers/contains_log.rb +7 -0
  200. data/spec/support/mocks/fake_gc_profiler.rb +19 -0
  201. data/spec/support/mocks/mock_extension.rb +6 -0
  202. data/spec/support/project_fixture/config/application.rb +0 -0
  203. data/spec/support/project_fixture/config/appsignal.yml +32 -0
  204. data/spec/support/project_fixture/config/environments/development.rb +0 -0
  205. data/spec/support/project_fixture/config/environments/production.rb +0 -0
  206. data/spec/support/project_fixture/config/environments/test.rb +0 -0
  207. data/spec/support/project_fixture/log/.gitkeep +0 -0
  208. data/spec/support/rails/my_app.rb +6 -0
  209. data/spec/support/shared_examples/instrument.rb +43 -0
  210. data/spec/support/stubs/delayed_job.rb +0 -0
  211. metadata +483 -0
@@ -0,0 +1,35 @@
1
+ describe Appsignal::Hooks::WebmachineHook do
2
+ if DependencyHelper.webmachine_present?
3
+ context "with webmachine" do
4
+ let(:fsm) { Webmachine::Decision::FSM.new(double(:trace? => false), double, double) }
5
+ before(:context) { start_agent }
6
+
7
+ describe "#dependencies_present?" do
8
+ subject { described_class.new.dependencies_present? }
9
+
10
+ it { is_expected.to be_truthy }
11
+ end
12
+
13
+ it "should include the run alias methods" do
14
+ expect(fsm).to respond_to(:run_with_appsignal)
15
+ expect(fsm).to respond_to(:run_without_appsignal)
16
+ end
17
+
18
+ it "should include the handle_exceptions alias methods" do
19
+ expect(
20
+ fsm.respond_to?(:handle_exceptions_with_appsignal, true)
21
+ ).to be_truthy
22
+
23
+ expect(
24
+ fsm.respond_to?(:handle_exceptions_without_appsignal, true)
25
+ ).to be_truthy
26
+ end
27
+ end
28
+ else
29
+ describe "#dependencies_present?" do
30
+ subject { described_class.new.dependencies_present? }
31
+
32
+ it { is_expected.to be_falsy }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,195 @@
1
+ class MockPresentHook < Appsignal::Hooks::Hook
2
+ def dependencies_present?
3
+ true
4
+ end
5
+
6
+ def install
7
+ MockPresentHook.call_something
8
+ end
9
+
10
+ def self.call_something
11
+ end
12
+ end
13
+
14
+ class MockNotPresentHook < Appsignal::Hooks::Hook
15
+ def dependencies_present?
16
+ false
17
+ end
18
+
19
+ def install
20
+ MockNotPresentHook.call_something
21
+ end
22
+ end
23
+
24
+ class MockErrorHook < Appsignal::Hooks::Hook
25
+ def dependencies_present?
26
+ true
27
+ end
28
+
29
+ def install
30
+ raise "error"
31
+ end
32
+ end
33
+
34
+ describe Appsignal::Hooks do
35
+ it "should register and install a hook once" do
36
+ Appsignal::Hooks::Hook.register(:mock_present_hook, MockPresentHook)
37
+
38
+ expect(Appsignal::Hooks.hooks[:mock_present_hook]).to be_instance_of(MockPresentHook)
39
+ expect(Appsignal::Hooks.hooks[:mock_present_hook].installed?).to be_falsy
40
+
41
+ expect(MockPresentHook).to receive(:call_something).once
42
+
43
+ Appsignal::Hooks.load_hooks
44
+ Appsignal::Hooks.load_hooks
45
+ Appsignal::Hooks.load_hooks
46
+ expect(Appsignal::Hooks.hooks[:mock_present_hook].installed?).to be_truthy
47
+ Appsignal::Hooks.hooks.delete(:mock_present_hook)
48
+ end
49
+
50
+ it "should not install if depencies are not present" do
51
+ Appsignal::Hooks::Hook.register(:mock_not_present_hook, MockNotPresentHook)
52
+
53
+ expect(Appsignal::Hooks.hooks[:mock_not_present_hook]).to be_instance_of(MockNotPresentHook)
54
+ expect(Appsignal::Hooks.hooks[:mock_not_present_hook].installed?).to be_falsy
55
+
56
+ expect(MockPresentHook).to_not receive(:call_something)
57
+
58
+ Appsignal::Hooks.load_hooks
59
+
60
+ expect(Appsignal::Hooks.hooks[:mock_not_present_hook].installed?).to be_falsy
61
+ Appsignal::Hooks.hooks.delete(:mock_not_present_hook)
62
+ end
63
+
64
+ it "should not install if there is an error while installing" do
65
+ Appsignal::Hooks::Hook.register(:mock_error_hook, MockErrorHook)
66
+
67
+ expect(Appsignal::Hooks.hooks[:mock_error_hook]).to be_instance_of(MockErrorHook)
68
+ expect(Appsignal::Hooks.hooks[:mock_error_hook].installed?).to be_falsy
69
+
70
+ expect(Appsignal.logger).to receive(:error).with("Error while installing mock_error_hook hook: error").once
71
+
72
+ Appsignal::Hooks.load_hooks
73
+
74
+ expect(Appsignal::Hooks.hooks[:mock_error_hook].installed?).to be_falsy
75
+ Appsignal::Hooks.hooks.delete(:mock_error_hook)
76
+ end
77
+ end
78
+
79
+ describe Appsignal::Hooks::Helpers do
80
+ class ClassWithHelpers
81
+ include Appsignal::Hooks::Helpers
82
+ end
83
+ let(:with_helpers) { ClassWithHelpers.new }
84
+
85
+ describe "#truncate" do
86
+ let(:very_long_text) do
87
+ "a" * 400
88
+ end
89
+
90
+ it "should truncate the text to 200 chars max" do
91
+ expect(with_helpers.truncate(very_long_text)).to eq "#{"a" * 197}..."
92
+ end
93
+ end
94
+
95
+ describe "#string_or_inspect" do
96
+ context "when string" do
97
+ it "should return the string" do
98
+ expect(with_helpers.string_or_inspect("foo")).to eq "foo"
99
+ end
100
+ end
101
+
102
+ context "when integer" do
103
+ it "should return the string" do
104
+ expect(with_helpers.string_or_inspect(1)).to eq "1"
105
+ end
106
+ end
107
+
108
+ context "when object" do
109
+ let(:object) { Object.new }
110
+
111
+ it "should return the string" do
112
+ expect(with_helpers.string_or_inspect(object)).to eq object.inspect
113
+ end
114
+ end
115
+ end
116
+
117
+ describe "#extract_value" do
118
+ context "for a hash" do
119
+ let(:hash) { { :key => "value" } }
120
+
121
+ context "when the key exists" do
122
+ subject { with_helpers.extract_value(hash, :key) }
123
+
124
+ it { is_expected.to eq "value" }
125
+ end
126
+
127
+ context "when the key does not exist" do
128
+ subject { with_helpers.extract_value(hash, :nonexistent_key) }
129
+
130
+ it { is_expected.to be_nil }
131
+
132
+ context "with a default value" do
133
+ subject { with_helpers.extract_value(hash, :nonexistent_key, 1) }
134
+
135
+ it { is_expected.to eq 1 }
136
+ end
137
+ end
138
+ end
139
+
140
+ context "for a struct" do
141
+ before :context do
142
+ TestStruct = Struct.new(:key)
143
+ end
144
+ let(:struct) { TestStruct.new("value") }
145
+
146
+ context "when the key exists" do
147
+ subject { with_helpers.extract_value(struct, :key) }
148
+
149
+ it { is_expected.to eq "value" }
150
+ end
151
+
152
+ context "when the key does not exist" do
153
+ subject { with_helpers.extract_value(struct, :nonexistent_key) }
154
+
155
+ it { is_expected.to be_nil }
156
+
157
+ context "with a default value" do
158
+ subject { with_helpers.extract_value(struct, :nonexistent_key, 1) }
159
+
160
+ it { is_expected.to eq 1 }
161
+ end
162
+ end
163
+ end
164
+
165
+ context "for an object" do
166
+ let(:object) { double(:existing_method => "value") }
167
+
168
+ context "when the method exists" do
169
+ subject { with_helpers.extract_value(object, :existing_method) }
170
+
171
+ it { is_expected.to eq "value" }
172
+ end
173
+
174
+ context "when the method does not exist" do
175
+ subject { with_helpers.extract_value(object, :nonexistent_method) }
176
+
177
+ it { is_expected.to be_nil }
178
+
179
+ context "and there is a default value" do
180
+ subject { with_helpers.extract_value(object, :nonexistent_method, 1) }
181
+
182
+ it { is_expected.to eq 1 }
183
+ end
184
+ end
185
+ end
186
+
187
+ context "when we need to call to_s on the value" do
188
+ let(:object) { double(:existing_method => 1) }
189
+
190
+ subject { with_helpers.extract_value(object, :existing_method, nil, true) }
191
+
192
+ it { is_expected.to eq "1" }
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,65 @@
1
+ require "appsignal/integrations/data_mapper"
2
+
3
+ describe Appsignal::Hooks::DataMapperLogListener do
4
+ module DataMapperLog
5
+ def log(message)
6
+ end
7
+ end
8
+
9
+ describe "#log" do
10
+ let(:transaction) { double }
11
+ let(:message) do
12
+ double(
13
+ :query => "SELECT * from users",
14
+ :duration => 100
15
+ )
16
+ end
17
+ let(:connection_class) do
18
+ module DataObjects
19
+ module Sqlite3
20
+ class Connection
21
+ include DataMapperLog
22
+ include Appsignal::Hooks::DataMapperLogListener
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ before { allow(Appsignal::Transaction).to receive(:current) { transaction } }
29
+
30
+ it "should record the log entry in an event" do
31
+ expect(transaction).to receive(:record_event).with(
32
+ "query.data_mapper",
33
+ "DataMapper Query",
34
+ "SELECT * from users",
35
+ 100,
36
+ Appsignal::EventFormatter::SQL_BODY_FORMAT
37
+ )
38
+ end
39
+
40
+ context "when scheme is not sql-like" do
41
+ let(:connection_class) do
42
+ module DataObjects
43
+ module MongoDB
44
+ class Connection
45
+ include DataMapperLog
46
+ include Appsignal::Hooks::DataMapperLogListener
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ it "should record the log entry in an event without body" do
53
+ expect(transaction).to receive(:record_event).with(
54
+ "query.data_mapper",
55
+ "DataMapper Query",
56
+ "",
57
+ 100,
58
+ Appsignal::EventFormatter::DEFAULT
59
+ )
60
+ end
61
+ end
62
+
63
+ after { connection_class.new.log(message) }
64
+ end
65
+ end
@@ -0,0 +1,225 @@
1
+ if DependencyHelper.grape_present?
2
+ require "appsignal/integrations/grape"
3
+
4
+ describe Appsignal::Grape::Middleware do
5
+ let(:app) do
6
+ Class.new(::Grape::API) do
7
+ format :json
8
+ post :ping do
9
+ { :message => "Hello world!" }
10
+ end
11
+ end
12
+ end
13
+ let(:api_endpoint) { app.endpoints.first }
14
+ let(:env) do
15
+ http_request_env_with_data \
16
+ "api.endpoint" => api_endpoint,
17
+ "REQUEST_METHOD" => "POST",
18
+ :path => "/ping"
19
+ end
20
+ let(:middleware) { Appsignal::Grape::Middleware.new(api_endpoint) }
21
+ around do |example|
22
+ GrapeExample = Module.new
23
+ GrapeExample.send(:const_set, :Api, app)
24
+ example.run
25
+ Object.send(:remove_const, :GrapeExample)
26
+ end
27
+
28
+ describe "#call" do
29
+ context "when AppSignal is not active" do
30
+ before(:context) do
31
+ Appsignal.config = nil
32
+ Appsignal::Hooks.load_hooks
33
+ end
34
+
35
+ it "creates no transaction" do
36
+ expect(Appsignal::Transaction).to_not receive(:create)
37
+ end
38
+
39
+ it "calls the endpoint normally" do
40
+ expect(api_endpoint).to receive(:call).with(env)
41
+ end
42
+
43
+ after { middleware.call(env) }
44
+ end
45
+
46
+ context "when AppSignal is active" do
47
+ let(:transaction) { http_request_transaction }
48
+ before :context do
49
+ Appsignal.config = project_fixture_config
50
+ expect(Appsignal.active?).to be_truthy
51
+ end
52
+ before do
53
+ expect(Appsignal::Transaction).to receive(:create).with(
54
+ kind_of(String),
55
+ Appsignal::Transaction::HTTP_REQUEST,
56
+ kind_of(::Rack::Request)
57
+ ).and_return(transaction)
58
+ end
59
+
60
+ context "without error" do
61
+ it "calls the endpoint" do
62
+ expect(api_endpoint).to receive(:call).with(env)
63
+ end
64
+
65
+ it "sets metadata" do
66
+ expect(transaction).to receive(:set_http_or_background_queue_start)
67
+ expect(transaction).to receive(:set_action_if_nil).with("POST::GrapeExample::Api#/ping")
68
+ expect(transaction).to receive(:set_metadata).with("path", "/ping")
69
+ expect(transaction).to receive(:set_metadata).with("method", "POST")
70
+ end
71
+
72
+ after { middleware.call(env) }
73
+ end
74
+
75
+ context "with error" do
76
+ let(:app) do
77
+ Class.new(::Grape::API) do
78
+ format :json
79
+ post :ping do
80
+ raise ExampleException
81
+ end
82
+ end
83
+ end
84
+
85
+ it "sets metadata" do
86
+ expect(transaction).to receive(:set_http_or_background_queue_start)
87
+ expect(transaction).to receive(:set_action_if_nil).with("POST::GrapeExample::Api#/ping")
88
+ expect(transaction).to receive(:set_metadata).with("path", "/ping")
89
+ expect(transaction).to receive(:set_metadata).with("method", "POST")
90
+ end
91
+
92
+ it "sets the error" do
93
+ expect(transaction).to receive(:set_error).with(kind_of(ExampleException))
94
+ end
95
+
96
+ after do
97
+ expect { middleware.call(env) }.to raise_error ExampleException
98
+ end
99
+ end
100
+
101
+ context "with route" do
102
+ let(:app) do
103
+ Class.new(::Grape::API) do
104
+ route [:get, :post], "hello" do
105
+ "Hello!"
106
+ end
107
+ end
108
+ end
109
+ let(:env) do
110
+ http_request_env_with_data \
111
+ "api.endpoint" => api_endpoint,
112
+ "REQUEST_METHOD" => "GET",
113
+ :path => ""
114
+ end
115
+
116
+ it "sets non-unique route path" do
117
+ expect(transaction).to receive(:set_action).with("GET::GrapeExample::Api#/hello")
118
+ expect(transaction).to receive(:set_metadata).with("path", "/hello")
119
+ expect(transaction).to receive(:set_metadata).with("method", "GET")
120
+ end
121
+
122
+ after { middleware.call(env) }
123
+ end
124
+
125
+ context "with route_param" do
126
+ let(:app) do
127
+ Class.new(::Grape::API) do
128
+ format :json
129
+ resource :users do
130
+ route_param :id do
131
+ get do
132
+ { :name => "Tom" }
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+ let(:env) do
139
+ http_request_env_with_data \
140
+ "api.endpoint" => api_endpoint,
141
+ "REQUEST_METHOD" => "GET",
142
+ :path => ""
143
+ end
144
+
145
+ it "sets non-unique route_param path" do
146
+ expect(transaction).to receive(:set_action_if_nil).with("GET::GrapeExample::Api#/users/:id/")
147
+ expect(transaction).to receive(:set_metadata).with("path", "/users/:id/")
148
+ expect(transaction).to receive(:set_metadata).with("method", "GET")
149
+ end
150
+
151
+ after { middleware.call(env) }
152
+ end
153
+
154
+ context "with namespaced path" do
155
+ context "with symbols" do
156
+ let(:app) do
157
+ Class.new(::Grape::API) do
158
+ format :json
159
+ namespace :v1 do
160
+ namespace :beta do
161
+ post :ping do
162
+ { :message => "Hello namespaced world!" }
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
168
+
169
+ it "sets namespaced path" do
170
+ expect(transaction).to receive(:set_action_if_nil).with("POST::GrapeExample::Api#/v1/beta/ping")
171
+ expect(transaction).to receive(:set_metadata).with("path", "/v1/beta/ping")
172
+ expect(transaction).to receive(:set_metadata).with("method", "POST")
173
+ end
174
+ end
175
+
176
+ context "with strings" do
177
+ context "without / prefix" do
178
+ let(:app) do
179
+ Class.new(::Grape::API) do
180
+ format :json
181
+ namespace "v1" do
182
+ namespace "beta" do
183
+ post "ping" do
184
+ { :message => "Hello namespaced world!" }
185
+ end
186
+ end
187
+ end
188
+ end
189
+ end
190
+
191
+ it "sets namespaced path" do
192
+ expect(transaction).to receive(:set_action_if_nil).with("POST::GrapeExample::Api#/v1/beta/ping")
193
+ expect(transaction).to receive(:set_metadata).with("path", "/v1/beta/ping")
194
+ expect(transaction).to receive(:set_metadata).with("method", "POST")
195
+ end
196
+ end
197
+
198
+ context "with / prefix" do
199
+ let(:app) do
200
+ Class.new(::Grape::API) do
201
+ format :json
202
+ namespace "/v1" do
203
+ namespace "/beta" do
204
+ post "/ping" do
205
+ { :message => "Hello namespaced world!" }
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
211
+
212
+ it "sets namespaced path" do
213
+ expect(transaction).to receive(:set_action_if_nil).with("POST::GrapeExample::Api#/v1/beta/ping")
214
+ expect(transaction).to receive(:set_metadata).with("path", "/v1/beta/ping")
215
+ expect(transaction).to receive(:set_metadata).with("method", "POST")
216
+ end
217
+ end
218
+ end
219
+
220
+ after { middleware.call(env) }
221
+ end
222
+ end
223
+ end
224
+ end
225
+ end