appsignal 4.0.6 → 4.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (201) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/Rakefile +9 -9
  4. data/appsignal.gemspec +22 -1
  5. data/ext/agent.rb +27 -27
  6. data/lib/appsignal/check_in.rb +1 -1
  7. data/lib/appsignal/config.rb +1 -3
  8. data/lib/appsignal/integrations/resque.rb +1 -6
  9. data/lib/appsignal/utils/hash_sanitizer.rb +4 -0
  10. data/lib/appsignal/version.rb +1 -1
  11. metadata +2 -192
  12. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -31
  13. data/.github/ISSUE_TEMPLATE/chore.md +0 -14
  14. data/.github/workflows/ci.yml +0 -3285
  15. data/.github/workflows/create_release_from_tag.yml +0 -62
  16. data/.gitignore +0 -35
  17. data/.gitmodules +0 -3
  18. data/.rspec +0 -4
  19. data/.yardopts +0 -8
  20. data/benchmark.rake +0 -139
  21. data/gemfiles/capistrano2.gemfile +0 -6
  22. data/gemfiles/capistrano3.gemfile +0 -7
  23. data/gemfiles/dry-monitor.gemfile +0 -5
  24. data/gemfiles/grape.gemfile +0 -5
  25. data/gemfiles/hanami-2.0.gemfile +0 -7
  26. data/gemfiles/hanami-2.1.gemfile +0 -7
  27. data/gemfiles/http5.gemfile +0 -5
  28. data/gemfiles/no_dependencies.gemfile +0 -10
  29. data/gemfiles/padrino.gemfile +0 -7
  30. data/gemfiles/psych-3.gemfile +0 -5
  31. data/gemfiles/psych-4.gemfile +0 -5
  32. data/gemfiles/que-1.gemfile +0 -5
  33. data/gemfiles/que-2.gemfile +0 -5
  34. data/gemfiles/rails-6.0.gemfile +0 -10
  35. data/gemfiles/rails-6.1.gemfile +0 -11
  36. data/gemfiles/rails-7.0.gemfile +0 -11
  37. data/gemfiles/rails-7.1.gemfile +0 -11
  38. data/gemfiles/rails-7.2.gemfile +0 -11
  39. data/gemfiles/redis-4.gemfile +0 -5
  40. data/gemfiles/redis-5.gemfile +0 -6
  41. data/gemfiles/resque-2.gemfile +0 -6
  42. data/gemfiles/sequel.gemfile +0 -10
  43. data/gemfiles/sinatra.gemfile +0 -5
  44. data/gemfiles/webmachine1.gemfile +0 -7
  45. data/gemfiles/webmachine2.gemfile +0 -6
  46. data/mono.yml +0 -16
  47. data/spec/.rubocop.yml +0 -7
  48. data/spec/lib/appsignal/auth_check_spec.rb +0 -84
  49. data/spec/lib/appsignal/capistrano2_spec.rb +0 -227
  50. data/spec/lib/appsignal/capistrano3_spec.rb +0 -284
  51. data/spec/lib/appsignal/check_in/cron_spec.rb +0 -210
  52. data/spec/lib/appsignal/check_in/scheduler_spec.rb +0 -557
  53. data/spec/lib/appsignal/cli/demo_spec.rb +0 -46
  54. data/spec/lib/appsignal/cli/diagnose/paths_spec.rb +0 -16
  55. data/spec/lib/appsignal/cli/diagnose/utils_spec.rb +0 -86
  56. data/spec/lib/appsignal/cli/diagnose_spec.rb +0 -1553
  57. data/spec/lib/appsignal/cli/helpers_spec.rb +0 -179
  58. data/spec/lib/appsignal/cli/install_spec.rb +0 -848
  59. data/spec/lib/appsignal/cli_spec.rb +0 -56
  60. data/spec/lib/appsignal/config_spec.rb +0 -1380
  61. data/spec/lib/appsignal/demo_spec.rb +0 -83
  62. data/spec/lib/appsignal/environment_spec.rb +0 -190
  63. data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +0 -60
  64. data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +0 -21
  65. data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +0 -21
  66. data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +0 -52
  67. data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +0 -21
  68. data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +0 -84
  69. data/spec/lib/appsignal/event_formatter/rom/sql_formatter_spec.rb +0 -22
  70. data/spec/lib/appsignal/event_formatter/sequel/sql_formatter_spec.rb +0 -30
  71. data/spec/lib/appsignal/event_formatter/view_component/render_formatter_spec.rb +0 -41
  72. data/spec/lib/appsignal/event_formatter_spec.rb +0 -193
  73. data/spec/lib/appsignal/extension/jruby_spec.rb +0 -46
  74. data/spec/lib/appsignal/extension_install_failure_spec.rb +0 -20
  75. data/spec/lib/appsignal/extension_spec.rb +0 -178
  76. data/spec/lib/appsignal/garbage_collection_spec.rb +0 -98
  77. data/spec/lib/appsignal/hooks/action_cable_spec.rb +0 -345
  78. data/spec/lib/appsignal/hooks/action_mailer_spec.rb +0 -55
  79. data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +0 -23
  80. data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +0 -99
  81. data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +0 -47
  82. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +0 -47
  83. data/spec/lib/appsignal/hooks/activejob_spec.rb +0 -650
  84. data/spec/lib/appsignal/hooks/at_exit_spec.rb +0 -105
  85. data/spec/lib/appsignal/hooks/celluloid_spec.rb +0 -40
  86. data/spec/lib/appsignal/hooks/data_mapper_spec.rb +0 -40
  87. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +0 -38
  88. data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +0 -83
  89. data/spec/lib/appsignal/hooks/excon_spec.rb +0 -67
  90. data/spec/lib/appsignal/hooks/gvl_spec.rb +0 -145
  91. data/spec/lib/appsignal/hooks/http_spec.rb +0 -37
  92. data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +0 -46
  93. data/spec/lib/appsignal/hooks/mri_spec.rb +0 -23
  94. data/spec/lib/appsignal/hooks/net_http_spec.rb +0 -18
  95. data/spec/lib/appsignal/hooks/passenger_spec.rb +0 -30
  96. data/spec/lib/appsignal/hooks/puma_spec.rb +0 -80
  97. data/spec/lib/appsignal/hooks/que_spec.rb +0 -19
  98. data/spec/lib/appsignal/hooks/rake_spec.rb +0 -144
  99. data/spec/lib/appsignal/hooks/redis_client_spec.rb +0 -218
  100. data/spec/lib/appsignal/hooks/redis_spec.rb +0 -124
  101. data/spec/lib/appsignal/hooks/resque_spec.rb +0 -27
  102. data/spec/lib/appsignal/hooks/sequel_spec.rb +0 -44
  103. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +0 -29
  104. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +0 -115
  105. data/spec/lib/appsignal/hooks/unicorn_spec.rb +0 -63
  106. data/spec/lib/appsignal/hooks/webmachine_spec.rb +0 -24
  107. data/spec/lib/appsignal/hooks_spec.rb +0 -124
  108. data/spec/lib/appsignal/integrations/data_mapper_spec.rb +0 -74
  109. data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +0 -454
  110. data/spec/lib/appsignal/integrations/http_spec.rb +0 -111
  111. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +0 -154
  112. data/spec/lib/appsignal/integrations/net_http_spec.rb +0 -33
  113. data/spec/lib/appsignal/integrations/object_spec.rb +0 -347
  114. data/spec/lib/appsignal/integrations/puma_spec.rb +0 -150
  115. data/spec/lib/appsignal/integrations/que_spec.rb +0 -187
  116. data/spec/lib/appsignal/integrations/railtie_spec.rb +0 -457
  117. data/spec/lib/appsignal/integrations/resque_spec.rb +0 -155
  118. data/spec/lib/appsignal/integrations/shoryuken_spec.rb +0 -165
  119. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +0 -640
  120. data/spec/lib/appsignal/integrations/webmachine_spec.rb +0 -136
  121. data/spec/lib/appsignal/loaders/grape_spec.rb +0 -12
  122. data/spec/lib/appsignal/loaders/hanami_spec.rb +0 -92
  123. data/spec/lib/appsignal/loaders/padrino_spec.rb +0 -273
  124. data/spec/lib/appsignal/loaders/sinatra_spec.rb +0 -44
  125. data/spec/lib/appsignal/loaders_spec.rb +0 -144
  126. data/spec/lib/appsignal/logger_spec.rb +0 -205
  127. data/spec/lib/appsignal/marker_spec.rb +0 -51
  128. data/spec/lib/appsignal/probes/gvl_spec.rb +0 -164
  129. data/spec/lib/appsignal/probes/mri_spec.rb +0 -162
  130. data/spec/lib/appsignal/probes/sidekiq_spec.rb +0 -333
  131. data/spec/lib/appsignal/probes_spec.rb +0 -414
  132. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +0 -370
  133. data/spec/lib/appsignal/rack/body_wrapper_spec.rb +0 -319
  134. data/spec/lib/appsignal/rack/event_handler_spec.rb +0 -441
  135. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +0 -201
  136. data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +0 -36
  137. data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +0 -38
  138. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +0 -126
  139. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +0 -217
  140. data/spec/lib/appsignal/rack_spec.rb +0 -243
  141. data/spec/lib/appsignal/sample_data_spec.rb +0 -238
  142. data/spec/lib/appsignal/span_spec.rb +0 -141
  143. data/spec/lib/appsignal/system_spec.rb +0 -126
  144. data/spec/lib/appsignal/transaction_spec.rb +0 -2115
  145. data/spec/lib/appsignal/transmitter_spec.rb +0 -198
  146. data/spec/lib/appsignal/utils/data_spec.rb +0 -166
  147. data/spec/lib/appsignal/utils/hash_sanitizer_spec.rb +0 -182
  148. data/spec/lib/appsignal/utils/integration_logger_spec.rb +0 -21
  149. data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +0 -153
  150. data/spec/lib/appsignal/utils/json_spec.rb +0 -44
  151. data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +0 -192
  152. data/spec/lib/appsignal_spec.rb +0 -1919
  153. data/spec/lib/puma/appsignal_spec.rb +0 -334
  154. data/spec/spec_helper.rb +0 -179
  155. data/spec/support/fixtures/generated_config.yml +0 -24
  156. data/spec/support/fixtures/projects/broken/config/appsignal.yml +0 -1
  157. data/spec/support/fixtures/projects/valid/config/appsignal.yml +0 -57
  158. data/spec/support/fixtures/projects/valid/log/.gitkeep +0 -0
  159. data/spec/support/fixtures/projects/valid_with_rails_app/config/application.rb +0 -16
  160. data/spec/support/fixtures/projects/valid_with_rails_app/config/appsignal.yml +0 -56
  161. data/spec/support/fixtures/projects/valid_with_rails_app/config/environment.rb +0 -10
  162. data/spec/support/fixtures/projects/valid_with_rails_app/log/.gitkeep +0 -0
  163. data/spec/support/fixtures/uploaded_file.txt +0 -0
  164. data/spec/support/hanami/hanami_app.rb +0 -29
  165. data/spec/support/helpers/action_mailer_helpers.rb +0 -25
  166. data/spec/support/helpers/activejob_helpers.rb +0 -27
  167. data/spec/support/helpers/api_request_helper.rb +0 -60
  168. data/spec/support/helpers/cli_helpers.rb +0 -40
  169. data/spec/support/helpers/config_helpers.rb +0 -66
  170. data/spec/support/helpers/dependency_helper.rb +0 -155
  171. data/spec/support/helpers/directory_helper.rb +0 -27
  172. data/spec/support/helpers/env_helpers.rb +0 -41
  173. data/spec/support/helpers/environment_metdata_helper.rb +0 -16
  174. data/spec/support/helpers/example_exception.rb +0 -13
  175. data/spec/support/helpers/example_standard_error.rb +0 -13
  176. data/spec/support/helpers/loader_helper.rb +0 -21
  177. data/spec/support/helpers/log_helpers.rb +0 -36
  178. data/spec/support/helpers/rails_helper.rb +0 -28
  179. data/spec/support/helpers/std_streams_helper.rb +0 -94
  180. data/spec/support/helpers/system_helpers.rb +0 -8
  181. data/spec/support/helpers/take_at_most_helper.rb +0 -21
  182. data/spec/support/helpers/time_helpers.rb +0 -11
  183. data/spec/support/helpers/transaction_helpers.rb +0 -122
  184. data/spec/support/helpers/wait_for_helper.rb +0 -39
  185. data/spec/support/matchers/contains_log.rb +0 -26
  186. data/spec/support/matchers/have_colorized_text.rb +0 -28
  187. data/spec/support/matchers/transaction.rb +0 -200
  188. data/spec/support/mocks/appsignal_mock.rb +0 -18
  189. data/spec/support/mocks/dummy_app.rb +0 -20
  190. data/spec/support/mocks/fake_gc_profiler.rb +0 -19
  191. data/spec/support/mocks/fake_gvl_tools.rb +0 -28
  192. data/spec/support/mocks/hash_like.rb +0 -10
  193. data/spec/support/mocks/mock_probe.rb +0 -13
  194. data/spec/support/mocks/puma_mock.rb +0 -43
  195. data/spec/support/shared_examples/instrument.rb +0 -48
  196. data/spec/support/stubs/appsignal/loaders/loader_stub.rb +0 -7
  197. data/spec/support/stubs/delayed_job.rb +0 -0
  198. data/spec/support/stubs/sidekiq/api.rb +0 -4
  199. data/spec/support/testing.rb +0 -203
  200. data/support/bundler_wrapper +0 -12
  201. data/support/install_deps +0 -33
@@ -1,1919 +0,0 @@
1
- describe Appsignal do
2
- include EnvironmentMetadataHelper
3
- around { |example| keep_transactions { example.run } }
4
-
5
- let(:transaction) { http_request_transaction }
6
-
7
- describe ".configure" do
8
- context "when active" do
9
- it "doesn't update the config" do
10
- start_agent
11
- Appsignal::Testing.store[:config_called] = false
12
- expect do
13
- Appsignal.configure do |_config|
14
- Appsignal::Testing.store[:config_called] = true
15
- end
16
- end.to_not(change { [Appsignal.config, Appsignal.active?] })
17
- expect(Appsignal::Testing.store[:config_called]).to be(false)
18
- end
19
-
20
- it "logs a warning" do
21
- start_agent
22
- logs =
23
- capture_logs do
24
- Appsignal.configure do |_config|
25
- # Do something
26
- end
27
- end
28
- expect(logs).to contains_log(
29
- :warn,
30
- "AppSignal is already started. Ignoring `Appsignal.configure` call."
31
- )
32
- end
33
- end
34
-
35
- context "with config but not started" do
36
- it "reuses the already loaded config if no env arg is given" do
37
- Appsignal.configure(:my_env, :root_path => project_fixture_path) do |config|
38
- config.ignore_actions = ["My action"]
39
- end
40
-
41
- Appsignal.configure do |config|
42
- expect(config.env).to eq("my_env")
43
- expect(config.ignore_actions).to eq(["My action"])
44
-
45
- config.active = true
46
- config.name = "My app"
47
- config.push_api_key = "key"
48
- end
49
- Appsignal.start
50
-
51
- expect(Appsignal.config.valid?).to be(true)
52
- expect(Appsignal.config.env).to eq("my_env")
53
- expect(Appsignal.config[:name]).to eq("My app")
54
- expect(Appsignal.config[:push_api_key]).to eq("key")
55
- expect(Appsignal.config[:ignore_actions]).to eq(["My action"])
56
- end
57
-
58
- it "reuses the already loaded config if the env is the same" do
59
- Appsignal.configure(:my_env, :root_path => project_fixture_path) do |config|
60
- config.ignore_actions = ["My action"]
61
- end
62
-
63
- Appsignal.configure(:my_env) do |config|
64
- expect(config.ignore_actions).to eq(["My action"])
65
- config.active = true
66
- config.name = "My app"
67
- config.push_api_key = "key"
68
- end
69
- Appsignal.start
70
-
71
- expect(Appsignal.config.valid?).to be(true)
72
- expect(Appsignal.config.env).to eq("my_env")
73
- expect(Appsignal.config[:active]).to be(true)
74
- expect(Appsignal.config[:name]).to eq("My app")
75
- expect(Appsignal.config[:push_api_key]).to eq("key")
76
- end
77
-
78
- it "loads a new config if the env is not the same" do
79
- Appsignal.configure(:my_env, :root_path => project_fixture_path) do |config|
80
- config.name = "Some name"
81
- config.push_api_key = "Some key"
82
- config.ignore_actions = ["My action"]
83
- end
84
-
85
- Appsignal.configure(:my_env2) do |config|
86
- expect(config.ignore_actions).to be_empty
87
- config.active = true
88
- config.name = "My app"
89
- config.push_api_key = "key"
90
- end
91
- Appsignal.start
92
-
93
- expect(Appsignal.config.valid?).to be(true)
94
- expect(Appsignal.config.env).to eq("my_env2")
95
- expect(Appsignal.config[:active]).to be(true)
96
- expect(Appsignal.config[:name]).to eq("My app")
97
- expect(Appsignal.config[:push_api_key]).to eq("key")
98
- end
99
-
100
- it "loads a new config if the path is not the same" do
101
- Appsignal.configure(:my_env, :root_path => "/some/path") do |config|
102
- config.name = "Some name"
103
- config.push_api_key = "Some key"
104
- config.ignore_actions = ["My action"]
105
- end
106
-
107
- Appsignal.configure(:my_env, :root_path => project_fixture_path) do |config|
108
- expect(config.ignore_actions).to be_empty
109
- config.active = true
110
- config.name = "My app"
111
- config.push_api_key = "key"
112
- end
113
- Appsignal.start
114
-
115
- expect(Appsignal.config.valid?).to be(true)
116
- expect(Appsignal.config.env).to eq("my_env")
117
- expect(Appsignal.config[:active]).to be(true)
118
- expect(Appsignal.config[:name]).to eq("My app")
119
- expect(Appsignal.config[:push_api_key]).to eq("key")
120
- end
121
-
122
- it "calls configure if not started yet" do
123
- Appsignal.configure(:my_env) do |config|
124
- config.active = false
125
- config.name = "Some name"
126
- end
127
- Appsignal.start
128
- expect(Appsignal.started?).to be_falsy
129
-
130
- Appsignal.configure(:my_env) do |config|
131
- expect(config.ignore_actions).to be_empty
132
- config.active = true
133
- config.name = "My app"
134
- config.push_api_key = "key"
135
- end
136
- Appsignal.start
137
-
138
- expect(Appsignal.config.valid?).to be(true)
139
- expect(Appsignal.config.env).to eq("my_env")
140
- expect(Appsignal.config[:active]).to be(true)
141
- expect(Appsignal.config[:name]).to eq("My app")
142
- expect(Appsignal.config[:push_api_key]).to eq("key")
143
- end
144
- end
145
-
146
- context "when not active" do
147
- it "starts with the configured config" do
148
- Appsignal.configure(:test) do |config|
149
- config.push_api_key = "key"
150
- end
151
- Appsignal.start
152
-
153
- expect(Appsignal.config[:push_api_key]).to eq("key")
154
- end
155
-
156
- it "uses the given env" do
157
- ENV["APPSIGNAL_APP_ENV"] = "env_env"
158
- Appsignal.configure(:env_arg)
159
- Appsignal.start
160
-
161
- expect(Appsignal.config.env).to eq("env_arg")
162
- end
163
-
164
- it "uses the given root path to read the config file" do
165
- Appsignal.configure(:test, :root_path => project_fixture_path)
166
- Appsignal.start
167
-
168
- expect(Appsignal.config.env).to eq("test")
169
- expect(Appsignal.config[:push_api_key]).to eq("abc")
170
- # Ensure it loads from the config file in the given path
171
- expect(Appsignal.config.file_config).to_not be_empty
172
- end
173
-
174
- it "loads the config without a block being given" do
175
- Dir.chdir project_fixture_path do
176
- Appsignal.configure(:test)
177
- end
178
- Appsignal.start
179
-
180
- expect(Appsignal.config.env).to eq("test")
181
- expect(Appsignal.config[:push_api_key]).to eq("abc")
182
- # Ensure it loads from the config file in the current working directory
183
- expect(Appsignal.config.file_config).to_not be_empty
184
- end
185
-
186
- it "allows customization of config in the block" do
187
- Appsignal.configure(:test) do |config|
188
- config.push_api_key = "key"
189
- end
190
- Appsignal.start
191
-
192
- expect(Appsignal.config.valid?).to be(true)
193
- expect(Appsignal.config.env).to eq("test")
194
- expect(Appsignal.config[:push_api_key]).to eq("key")
195
- end
196
-
197
- it "loads the default config" do
198
- Appsignal.configure do |config|
199
- Appsignal::Config::DEFAULT_CONFIG.each do |option, value|
200
- expect(config.send(option)).to eq(value)
201
- end
202
- end
203
- end
204
-
205
- it "loads the config from the YAML file" do
206
- Dir.chdir project_fixture_path do
207
- Appsignal.configure(:test) do |config|
208
- expect(config.name).to eq("TestApp")
209
- end
210
- end
211
- end
212
-
213
- it "recognizes valid config" do
214
- Appsignal.configure(:my_env) do |config|
215
- config.push_api_key = "key"
216
- end
217
- Appsignal.start
218
-
219
- expect(Appsignal.config.valid?).to be(true)
220
- end
221
-
222
- it "recognizes invalid config" do
223
- Appsignal.configure(:my_env) do |config|
224
- config.push_api_key = ""
225
- end
226
- Appsignal.start
227
-
228
- expect(Appsignal.config.valid?).to be(false)
229
- end
230
-
231
- it "sets the environment when given as an argument" do
232
- Appsignal.configure(:my_env)
233
-
234
- expect(Appsignal.config.env).to eq("my_env")
235
- end
236
-
237
- it "reads the environment from the environment" do
238
- ENV["APPSIGNAL_APP_ENV"] = "env_env"
239
- Appsignal.configure do |config|
240
- expect(config.env).to eq("env_env")
241
- end
242
-
243
- expect(Appsignal.config.env).to eq("env_env")
244
- end
245
-
246
- it "reads the environment from a loader default" do
247
- clear_integration_env_vars!
248
- define_loader(:loader_env) do
249
- def on_load
250
- register_config_defaults(
251
- :env => "loader_env"
252
- )
253
- end
254
- end
255
- load_loader(:loader_env)
256
-
257
- Appsignal.configure do |config|
258
- expect(config.env).to eq("loader_env")
259
- end
260
-
261
- expect(Appsignal.config.env).to eq("loader_env")
262
- end
263
-
264
- it "reads the root_path from a loader default" do
265
- clear_integration_env_vars!
266
- define_loader(:loader_path) do
267
- def on_load
268
- register_config_defaults(
269
- :root_path => "/loader_path"
270
- )
271
- end
272
- end
273
- load_loader(:loader_path)
274
-
275
- Appsignal.configure do |config|
276
- expect(config.app_path).to eq("/loader_path")
277
- end
278
-
279
- expect(Appsignal.config.root_path).to eq("/loader_path")
280
- end
281
-
282
- it "considers the given env leading above APPSIGNAL_APP_ENV" do
283
- ENV["APPSIGNAL_APP_ENV"] = "env_env"
284
-
285
- Appsignal.configure(:dsl_env) do |config|
286
- expect(config.env).to eq("dsl_env")
287
- end
288
-
289
- expect(Appsignal.config.env).to eq("dsl_env")
290
- end
291
-
292
- it "allows modification of previously unset config options" do
293
- expect do
294
- Appsignal.configure do |config|
295
- config.ignore_actions << "My action"
296
- config.request_headers << "My allowed header"
297
- end
298
- end.to_not(change { Appsignal::Config::DEFAULT_CONFIG })
299
-
300
- expect(Appsignal.config[:ignore_actions]).to eq(["My action"])
301
- expect(Appsignal.config[:request_headers])
302
- .to eq(Appsignal::Config::DEFAULT_CONFIG[:request_headers] + ["My allowed header"])
303
- end
304
- end
305
- end
306
-
307
- describe ".start" do
308
- context "with no config set beforehand" do
309
- let(:stdout_stream) { std_stream }
310
- let(:stdout) { stdout_stream.read }
311
- let(:stderr_stream) { std_stream }
312
- let(:stderr) { stderr_stream.read }
313
- before { ENV["APPSIGNAL_LOG"] = "stdout" }
314
-
315
- it "does nothing when config is not set and there is no valid config in the env" do
316
- expect(Appsignal::Extension).to_not receive(:start)
317
- capture_std_streams(stdout_stream, stderr_stream) { Appsignal.start }
318
-
319
- expect(stdout).to contains_log(
320
- :error,
321
- "appsignal: Not starting, no valid config for this environment"
322
- )
323
- end
324
-
325
- it "should create a config from the env" do
326
- ENV["APPSIGNAL_PUSH_API_KEY"] = "something"
327
- expect(Appsignal::Extension).to receive(:start)
328
- capture_std_streams(stdout_stream, stderr_stream) { Appsignal.start }
329
-
330
- expect(Appsignal.config[:push_api_key]).to eq("something")
331
- expect(stderr).to_not include("[ERROR]")
332
- expect(stdout).to_not include("[ERROR]")
333
- end
334
-
335
- it "reads the environment from the loader defaults" do
336
- clear_integration_env_vars!
337
- define_loader(:loader_env) do
338
- def on_load
339
- register_config_defaults(:env => "loader_env")
340
- end
341
- end
342
- load_loader(:loader_env)
343
-
344
- Appsignal.start
345
-
346
- expect(Appsignal.config.env).to eq("loader_env")
347
- end
348
-
349
- it "reads the root_path from the loader defaults" do
350
- define_loader(:loader_path) do
351
- def on_load
352
- register_config_defaults(:root_path => "/loader_path")
353
- end
354
- end
355
- load_loader(:loader_path)
356
-
357
- Appsignal.start
358
-
359
- expect(Appsignal.config.root_path).to eq("/loader_path")
360
- end
361
-
362
- it "chooses APPSIGNAL_APP_ENV over the loader defaults as the default env" do
363
- clear_integration_env_vars!
364
- ENV["APPSIGNAL_APP_ENV"] = "env_env"
365
- define_loader(:loader_env) do
366
- def on_load
367
- register_config_defaults(:env => "loader_env")
368
- end
369
- end
370
- load_loader(:loader_env)
371
-
372
- Appsignal.start
373
-
374
- expect(Appsignal.config.env).to eq("env_env")
375
- end
376
- end
377
-
378
- context "when config is loaded" do
379
- before { Appsignal.configure(:production, :root_path => project_fixture_path) }
380
-
381
- it "should initialize logging" do
382
- Appsignal.start
383
- expect(Appsignal.internal_logger.level).to eq Logger::INFO
384
- end
385
-
386
- it "should start native" do
387
- expect(Appsignal::Extension).to receive(:start)
388
- Appsignal.start
389
- end
390
-
391
- it "freezes the config" do
392
- Appsignal.start
393
-
394
- expect_frozen_error do
395
- Appsignal.config[:ignore_actions] << "my action"
396
- end
397
- expect_frozen_error do
398
- Appsignal.config.config_hash[:ignore_actions] << "my action"
399
- end
400
- expect_frozen_error do
401
- Appsignal.config.config_hash.merge!(:option => :value)
402
- end
403
- expect_frozen_error do
404
- Appsignal.config[:ignore_actions] = "my action"
405
- end
406
- end
407
-
408
- def expect_frozen_error(&block)
409
- expect(&block).to raise_error(FrozenError)
410
- end
411
-
412
- context "when allocation tracking has been enabled" do
413
- before do
414
- Appsignal.config.config_hash[:enable_allocation_tracking] = true
415
- capture_environment_metadata_report_calls
416
- end
417
-
418
- unless DependencyHelper.running_jruby?
419
- it "installs the allocation event hook" do
420
- expect(Appsignal::Extension).to receive(:install_allocation_event_hook)
421
- .and_call_original
422
- Appsignal.start
423
- expect_environment_metadata("ruby_allocation_tracking_enabled", "true")
424
- end
425
- end
426
- end
427
-
428
- context "when allocation tracking has been disabled" do
429
- before do
430
- Appsignal.config.config_hash[:enable_allocation_tracking] = false
431
- capture_environment_metadata_report_calls
432
- end
433
-
434
- it "should not install the allocation event hook" do
435
- expect(Appsignal::Extension).not_to receive(:install_allocation_event_hook)
436
- Appsignal.start
437
- expect_not_environment_metadata("ruby_allocation_tracking_enabled")
438
- end
439
- end
440
-
441
- context "when minutely metrics has been enabled" do
442
- before do
443
- Appsignal.config.config_hash[:enable_minutely_probes] = true
444
- end
445
-
446
- it "should start minutely" do
447
- expect(Appsignal::Probes).to receive(:start)
448
- Appsignal.start
449
- end
450
- end
451
-
452
- context "when minutely metrics has been disabled" do
453
- before do
454
- Appsignal.config.config_hash[:enable_minutely_probes] = false
455
- end
456
-
457
- it "should not start minutely" do
458
- expect(Appsignal::Probes).to_not receive(:start)
459
- Appsignal.start
460
- end
461
- end
462
-
463
- describe "loaders" do
464
- it "starts loaded loaders" do
465
- Appsignal::Testing.store[:loader_loaded] = 0
466
- Appsignal::Testing.store[:loader_started] = 0
467
- define_loader(:start_loader) do
468
- def on_load
469
- Appsignal::Testing.store[:loader_loaded] += 1
470
- end
471
-
472
- def on_start
473
- Appsignal::Testing.store[:loader_started] += 1
474
- end
475
- end
476
- Appsignal::Loaders.load(:start_loader)
477
- Appsignal::Loaders.start
478
-
479
- expect(Appsignal::Testing.store[:loader_loaded]).to eq(1)
480
- expect(Appsignal::Testing.store[:loader_started]).to eq(1)
481
- end
482
- end
483
-
484
- describe "environment metadata" do
485
- before { capture_environment_metadata_report_calls }
486
-
487
- it "collects and reports environment metadata" do
488
- Appsignal.start
489
- expect_environment_metadata("ruby_version", "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}")
490
- expect_environment_metadata("ruby_engine", RUBY_ENGINE)
491
- if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.3.0")
492
- expect_environment_metadata("ruby_engine_version", RUBY_ENGINE_VERSION)
493
- end
494
- end
495
- end
496
- end
497
-
498
- context "when already started" do
499
- it "doesn't start again" do
500
- start_agent
501
-
502
- expect(Appsignal::Extension).to_not receive(:start)
503
- logs = capture_logs { Appsignal.start }
504
- expect(logs).to contains_log(
505
- :warn,
506
- "Ignoring call to Appsignal.start after AppSignal has started"
507
- )
508
- end
509
- end
510
-
511
- context "with debug logging" do
512
- before { Appsignal.configure(:test, :root_path => project_fixture_path) }
513
-
514
- it "should change the log level" do
515
- Appsignal.start
516
- expect(Appsignal.internal_logger.level).to eq Logger::DEBUG
517
- end
518
- end
519
- end
520
-
521
- describe ".load" do
522
- before do
523
- TestLoader = define_loader(:appsignal_loader)
524
- end
525
- after do
526
- Object.send(:remove_const, :TestLoader)
527
- end
528
-
529
- it "loads a loader" do
530
- expect(Appsignal::Loaders.instances).to be_empty
531
- Appsignal.load(:appsignal_loader)
532
- expect(Appsignal::Loaders.instances)
533
- .to include(:appsignal_loader => instance_of(TestLoader))
534
- end
535
- end
536
-
537
- describe ".forked" do
538
- context "when not active" do
539
- it "does nothing" do
540
- expect(Appsignal::Extension).to_not receive(:start)
541
-
542
- Appsignal.forked
543
- end
544
- end
545
-
546
- context "when active" do
547
- before do
548
- Appsignal.configure(:production, :root_path => project_fixture_path)
549
- Appsignal.start
550
- end
551
-
552
- it "starts the logger and extension" do
553
- expect(Appsignal).to receive(:_start_logger)
554
- expect(Appsignal::Extension).to receive(:start)
555
-
556
- Appsignal.forked
557
- end
558
- end
559
- end
560
-
561
- describe ".stop" do
562
- it "calls stop on the extension" do
563
- expect(Appsignal.internal_logger).to receive(:debug).with("Stopping AppSignal")
564
- expect(Appsignal::Extension).to receive(:stop)
565
- Appsignal.stop
566
- expect(Appsignal.active?).to be_falsy
567
- end
568
-
569
- it "stops the minutely probes" do
570
- Appsignal::Probes.start
571
- expect(Appsignal::Probes.started?).to be_truthy
572
- Appsignal.stop
573
- expect(Appsignal::Probes.started?).to be_falsy
574
- end
575
-
576
- context "with context specified" do
577
- it "should log the context" do
578
- expect(Appsignal.internal_logger).to receive(:debug).with("Stopping AppSignal (something)")
579
- expect(Appsignal::Extension).to receive(:stop)
580
- Appsignal.stop("something")
581
- expect(Appsignal.active?).to be_falsy
582
- end
583
- end
584
-
585
- it "calls stop on the check-in scheduler" do
586
- expect(Appsignal::CheckIn.scheduler).to receive(:stop)
587
- Appsignal.stop
588
- end
589
- end
590
-
591
- describe ".started?" do
592
- subject { Appsignal.started? }
593
-
594
- context "when started with active config" do
595
- before { start_agent }
596
-
597
- it { is_expected.to be_truthy }
598
- end
599
-
600
- context "when started with inactive config" do
601
- before { Appsignal.configure(:nonsense, :root_path => project_fixture_path) }
602
-
603
- it { is_expected.to be_falsy }
604
- end
605
- end
606
-
607
- describe ".active?" do
608
- subject { Appsignal.active? }
609
-
610
- context "without config" do
611
- it { is_expected.to be_falsy }
612
- end
613
-
614
- context "with inactive config" do
615
- before do
616
- Appsignal.configure(:nonsense, :root_path => project_fixture_path)
617
- Appsignal.start
618
- end
619
-
620
- it { is_expected.to be_falsy }
621
- end
622
-
623
- context "with active config" do
624
- before do
625
- Appsignal.configure(:production, :root_path => project_fixture_path)
626
- Appsignal.start
627
- end
628
-
629
- it { is_expected.to be_truthy }
630
- end
631
- end
632
-
633
- describe ".add_exception" do
634
- it "should alias this method" do
635
- expect(Appsignal).to respond_to(:add_exception)
636
- end
637
- end
638
-
639
- describe ".get_server_state" do
640
- it "should call server state on the extension" do
641
- expect(Appsignal::Extension).to receive(:get_server_state).with("key")
642
-
643
- Appsignal.get_server_state("key")
644
- end
645
-
646
- it "should get nil by default" do
647
- expect(Appsignal.get_server_state("key")).to be_nil
648
- end
649
- end
650
-
651
- context "not active" do
652
- before do
653
- Appsignal.configure(:not_active, :root_path => project_fixture_path)
654
- Appsignal.start
655
- end
656
-
657
- describe ".send_error" do
658
- let(:error) { ExampleException.new("specific error") }
659
-
660
- it "does not raise an error" do
661
- Appsignal.send_error(error)
662
- end
663
-
664
- it "does not create a transaction" do
665
- expect do
666
- Appsignal.send_error(error)
667
- end.to_not(change { created_transactions.count })
668
- end
669
- end
670
-
671
- describe ".set_error" do
672
- let(:error) { ExampleException.new("specific error") }
673
-
674
- it "does not raise an error" do
675
- Appsignal.set_error(error)
676
- end
677
-
678
- it "does not create a transaction" do
679
- expect do
680
- Appsignal.set_error(error)
681
- end.to_not(change { created_transactions.count })
682
- end
683
- end
684
-
685
- describe ".report_error" do
686
- let(:error) { ExampleException.new("specific error") }
687
-
688
- it "does not raise an error" do
689
- Appsignal.report_error(error)
690
- end
691
-
692
- it "does not create a transaction" do
693
- expect do
694
- Appsignal.report_error(error)
695
- end.to_not(change { created_transactions.count })
696
- end
697
- end
698
-
699
- describe ".set_namespace" do
700
- it "does not raise an error" do
701
- Appsignal.set_namespace("custom")
702
- end
703
- end
704
-
705
- describe ".tag_request" do
706
- it "does not raise an error" do
707
- Appsignal.tag_request(:tag => "tag")
708
- end
709
- end
710
-
711
- describe ".set_custom_data" do
712
- it "does not raise an error" do
713
- Appsignal.set_custom_data(:data => "value")
714
- end
715
- end
716
- end
717
-
718
- context "with config and started" do
719
- before { start_agent }
720
- around { |example| keep_transactions { example.run } }
721
-
722
- describe ".monitor" do
723
- it "creates a transaction" do
724
- expect do
725
- Appsignal.monitor(:action => "MyAction")
726
- end.to(change { created_transactions.count }.by(1))
727
-
728
- transaction = last_transaction
729
- expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
730
- expect(transaction).to have_action("MyAction")
731
- expect(transaction).to_not have_error
732
- expect(transaction).to_not include_events
733
- expect(transaction).to_not have_queue_start
734
- expect(transaction).to be_completed
735
- end
736
-
737
- it "returns the block's return value" do
738
- expect(Appsignal.monitor(:action => nil) { :return_value }).to eq(:return_value)
739
- end
740
-
741
- it "sets a custom namespace via the namespace argument" do
742
- Appsignal.monitor(:namespace => "custom", :action => nil)
743
-
744
- expect(last_transaction).to have_namespace("custom")
745
- end
746
-
747
- it "doesn't overwrite custom namespace set in the block" do
748
- Appsignal.monitor(:namespace => "custom", :action => nil) do
749
- Appsignal.set_namespace("more custom")
750
- end
751
-
752
- expect(last_transaction).to have_namespace("more custom")
753
- end
754
-
755
- it "sets the action via the action argument using a string" do
756
- Appsignal.monitor(:action => "custom")
757
-
758
- expect(last_transaction).to have_action("custom")
759
- end
760
-
761
- it "sets the action via the action argument using a symbol" do
762
- Appsignal.monitor(:action => :custom)
763
-
764
- expect(last_transaction).to have_action("custom")
765
- end
766
-
767
- it "doesn't overwrite custom action set in the block" do
768
- Appsignal.monitor(:action => "custom") do
769
- Appsignal.set_action("more custom")
770
- end
771
-
772
- expect(last_transaction).to have_action("more custom")
773
- end
774
-
775
- it "doesn't set the action when value is nil" do
776
- Appsignal.monitor(:action => nil)
777
-
778
- expect(last_transaction).to_not have_action
779
- end
780
-
781
- it "doesn't set the action when value is :set_later" do
782
- Appsignal.monitor(:action => :set_later)
783
-
784
- expect(last_transaction).to_not have_action
785
- end
786
-
787
- it "reports exceptions that occur in the block" do
788
- expect do
789
- Appsignal.monitor :action => nil do
790
- raise ExampleException, "error message"
791
- end
792
- end.to raise_error(ExampleException, "error message")
793
-
794
- expect(last_transaction).to have_error("ExampleException", "error message")
795
- end
796
-
797
- context "with already active transction" do
798
- let(:err_stream) { std_stream }
799
- let(:stderr) { err_stream.read }
800
- let(:transaction) { http_request_transaction }
801
- before do
802
- set_current_transaction(transaction)
803
- transaction.set_action("My action")
804
- end
805
-
806
- it "doesn't create a new transaction" do
807
- logs = nil
808
- expect do
809
- logs =
810
- capture_logs do
811
- capture_std_streams(std_stream, err_stream) do
812
- Appsignal.monitor(:action => nil)
813
- end
814
- end
815
- end.to_not(change { created_transactions.count })
816
-
817
- warning = "A transaction is active around this 'Appsignal.monitor' call."
818
- expect(logs).to contains_log(:warn, warning)
819
- expect(stderr).to include("appsignal WARNING: #{warning}")
820
- end
821
-
822
- it "does not overwrite the parent transaction's namespace" do
823
- silence { Appsignal.monitor(:namespace => "custom", :action => nil) }
824
-
825
- expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
826
- end
827
-
828
- it "does not overwrite the parent transaction's action" do
829
- silence { Appsignal.monitor(:action => "custom") }
830
-
831
- expect(transaction).to have_action("My action")
832
- end
833
-
834
- it "doesn't complete the parent transaction" do
835
- silence { Appsignal.monitor(:action => nil) }
836
-
837
- expect(transaction).to_not be_completed
838
- end
839
- end
840
- end
841
-
842
- describe ".monitor_and_stop" do
843
- it "calls Appsignal.stop after the block" do
844
- allow(Appsignal).to receive(:stop)
845
- Appsignal.monitor_and_stop(:namespace => "custom", :action => "My Action")
846
-
847
- transaction = last_transaction
848
- expect(transaction).to have_namespace("custom")
849
- expect(transaction).to have_action("My Action")
850
- expect(transaction).to be_completed
851
-
852
- expect(Appsignal).to have_received(:stop).with("monitor_and_stop")
853
- end
854
-
855
- it "passes the block to Appsignal.monitor" do
856
- expect do |blk|
857
- Appsignal.monitor_and_stop(:action => "My action", &blk)
858
- end.to yield_control
859
- end
860
- end
861
-
862
- describe ".tag_request" do
863
- before { start_agent }
864
-
865
- context "with transaction" do
866
- let(:transaction) { http_request_transaction }
867
- before { set_current_transaction(transaction) }
868
-
869
- it "sets tags on the current transaction" do
870
- Appsignal.tag_request("a" => "b")
871
-
872
- transaction._sample
873
- expect(transaction).to include_tags("a" => "b")
874
- end
875
- end
876
-
877
- context "without transaction" do
878
- let(:transaction) { nil }
879
-
880
- it "does not set tags on the transaction" do
881
- expect(Appsignal.tag_request).to be_falsy
882
- Appsignal.tag_request("a" => "b")
883
-
884
- expect_any_instance_of(Appsignal::Transaction).to_not receive(:set_tags)
885
- end
886
- end
887
-
888
- it "also listens to tag_job" do
889
- expect(Appsignal.method(:tag_job)).to eq(Appsignal.method(:tag_request))
890
- end
891
-
892
- it "also listens to set_tags" do
893
- expect(Appsignal.method(:set_tags)).to eq(Appsignal.method(:tag_request))
894
- end
895
- end
896
-
897
- describe ".add_params" do
898
- before { start_agent }
899
-
900
- it "has a .set_params alias" do
901
- expect(Appsignal.method(:add_params)).to eq(Appsignal.method(:set_params))
902
- end
903
-
904
- context "with transaction" do
905
- let(:transaction) { http_request_transaction }
906
- before { set_current_transaction(transaction) }
907
-
908
- it "adds parameters to the transaction" do
909
- Appsignal.add_params("param1" => "value1")
910
-
911
- transaction._sample
912
- expect(transaction).to include_params("param1" => "value1")
913
- end
914
-
915
- it "merges the params if called multiple times" do
916
- Appsignal.add_params("param1" => "value1")
917
- Appsignal.add_params("param2" => "value2")
918
-
919
- transaction._sample
920
- expect(transaction).to include_params(
921
- "param1" => "value1",
922
- "param2" => "value2"
923
- )
924
- end
925
-
926
- it "adds parameters with a block to the transaction" do
927
- Appsignal.add_params { { "param1" => "value1" } }
928
-
929
- transaction._sample
930
- expect(transaction).to include_params("param1" => "value1")
931
- end
932
- end
933
-
934
- context "without transaction" do
935
- it "does not add tags to any transaction" do
936
- Appsignal.add_params("a" => "b")
937
-
938
- expect_any_instance_of(Appsignal::Transaction).to_not receive(:add_params)
939
- end
940
- end
941
- end
942
-
943
- describe ".set_empty_params!" do
944
- before { start_agent }
945
-
946
- context "with transaction" do
947
- let(:transaction) { http_request_transaction }
948
- before { set_current_transaction(transaction) }
949
-
950
- it "marks parameters to be sent as an empty value" do
951
- Appsignal.add_params("key1" => "value")
952
- Appsignal.set_empty_params!
953
-
954
- transaction._sample
955
- expect(transaction).to_not include_params
956
- end
957
- end
958
- end
959
-
960
- describe ".add_session_data" do
961
- before { start_agent }
962
-
963
- it "has a .set_session_data alias" do
964
- expect(Appsignal.method(:add_session_data)).to eq(Appsignal.method(:set_session_data))
965
- end
966
-
967
- context "with transaction" do
968
- let(:transaction) { http_request_transaction }
969
- before { set_current_transaction(transaction) }
970
-
971
- it "adds session data to the transaction" do
972
- Appsignal.add_session_data("data" => "value1")
973
-
974
- transaction._sample
975
- expect(transaction).to include_session_data("data" => "value1")
976
- end
977
-
978
- it "merges the session data if called multiple times" do
979
- Appsignal.set_session_data("data1" => "value1")
980
- Appsignal.set_session_data("data2" => "value2")
981
-
982
- transaction._sample
983
- expect(transaction).to include_session_data(
984
- "data1" => "value1",
985
- "data2" => "value2"
986
- )
987
- end
988
-
989
- it "adds session data with a block to the transaction" do
990
- Appsignal.set_session_data { { "data" => "value1" } }
991
-
992
- transaction._sample
993
- expect(transaction).to include_session_data("data" => "value1")
994
- end
995
- end
996
-
997
- context "without transaction" do
998
- it "does not add session data to any transaction" do
999
- Appsignal.set_session_data("a" => "b")
1000
-
1001
- expect_any_instance_of(Appsignal::Transaction).to_not receive(:add_session_data)
1002
- end
1003
- end
1004
- end
1005
-
1006
- describe ".add_headers" do
1007
- before { start_agent }
1008
-
1009
- it "has a .set_headers alias" do
1010
- expect(Appsignal.method(:add_headers)).to eq(Appsignal.method(:set_headers))
1011
- end
1012
-
1013
- context "with transaction" do
1014
- let(:transaction) { http_request_transaction }
1015
- before { set_current_transaction(transaction) }
1016
-
1017
- it "adds request headers to the transaction" do
1018
- Appsignal.add_headers("PATH_INFO" => "/some-path")
1019
-
1020
- transaction._sample
1021
- expect(transaction).to include_environment("PATH_INFO" => "/some-path")
1022
- end
1023
-
1024
- it "merges the request headers if called multiple times" do
1025
- Appsignal.add_headers("PATH_INFO" => "/some-path")
1026
- Appsignal.add_headers("REQUEST_METHOD" => "GET")
1027
-
1028
- transaction._sample
1029
- expect(transaction).to include_environment(
1030
- "PATH_INFO" => "/some-path",
1031
- "REQUEST_METHOD" => "GET"
1032
- )
1033
- end
1034
-
1035
- it "adds request headers with a block to the transaction" do
1036
- Appsignal.add_headers { { "PATH_INFO" => "/some-path" } }
1037
-
1038
- transaction._sample
1039
- expect(transaction).to include_environment("PATH_INFO" => "/some-path")
1040
- end
1041
- end
1042
-
1043
- context "without transaction" do
1044
- it "does not add request headers to any transaction" do
1045
- Appsignal.add_headers("PATH_INFO" => "/some-path")
1046
-
1047
- expect_any_instance_of(Appsignal::Transaction).to_not receive(:add_headers)
1048
- end
1049
- end
1050
- end
1051
-
1052
- describe ".add_custom_data" do
1053
- before { start_agent }
1054
-
1055
- it "has a .set_custom_data alias" do
1056
- expect(Appsignal.method(:add_custom_data)).to eq(Appsignal.method(:set_custom_data))
1057
- end
1058
-
1059
- context "with transaction" do
1060
- let(:transaction) { http_request_transaction }
1061
- before { set_current_transaction transaction }
1062
-
1063
- it "adds custom data to the current transaction" do
1064
- Appsignal.add_custom_data(
1065
- :user => { :id => 123 },
1066
- :organization => { :slug => "appsignal" }
1067
- )
1068
-
1069
- transaction._sample
1070
- expect(transaction).to include_custom_data(
1071
- "user" => { "id" => 123 },
1072
- "organization" => { "slug" => "appsignal" }
1073
- )
1074
- end
1075
-
1076
- it "merges the custom data if called multiple times" do
1077
- Appsignal.add_custom_data(:abc => "value")
1078
- Appsignal.add_custom_data(:def => "value")
1079
-
1080
- transaction._sample
1081
- expect(transaction).to include_custom_data(
1082
- "abc" => "value",
1083
- "def" => "value"
1084
- )
1085
- end
1086
- end
1087
-
1088
- context "without transaction" do
1089
- it "does not add tags any the transaction" do
1090
- Appsignal.add_custom_data(
1091
- :user => { :id => 123 },
1092
- :organization => { :slug => "appsignal" }
1093
- )
1094
-
1095
- expect_any_instance_of(Appsignal::Transaction).to_not receive(:add_custom_data)
1096
- end
1097
- end
1098
- end
1099
-
1100
- describe ".add_breadcrumb" do
1101
- before { start_agent }
1102
-
1103
- context "with transaction" do
1104
- let(:transaction) { http_request_transaction }
1105
- before { set_current_transaction(transaction) }
1106
-
1107
- it "adds the breadcrumb to the transaction" do
1108
- Appsignal.add_breadcrumb(
1109
- "Network",
1110
- "http",
1111
- "User made network request",
1112
- { :response => 200 },
1113
- fixed_time
1114
- )
1115
-
1116
- transaction._sample
1117
- expect(transaction).to include_breadcrumb(
1118
- "http",
1119
- "Network",
1120
- "User made network request",
1121
- { "response" => 200 },
1122
- fixed_time
1123
- )
1124
- end
1125
- end
1126
-
1127
- context "without transaction" do
1128
- let(:transaction) { nil }
1129
-
1130
- it "does not add a breadcrumb to any transaction" do
1131
- expect(Appsignal.add_breadcrumb("Network", "http")).to be_falsy
1132
- end
1133
- end
1134
- end
1135
-
1136
- describe "custom metrics" do
1137
- let(:tags) { { :foo => "bar" } }
1138
-
1139
- describe ".set_gauge" do
1140
- it "should call set_gauge on the extension with a string key and float" do
1141
- expect(Appsignal::Extension).to receive(:set_gauge)
1142
- .with("key", 0.1, Appsignal::Extension.data_map_new)
1143
- Appsignal.set_gauge("key", 0.1)
1144
- end
1145
-
1146
- it "should call set_gauge with tags" do
1147
- expect(Appsignal::Extension).to receive(:set_gauge)
1148
- .with("key", 0.1, Appsignal::Utils::Data.generate(tags))
1149
- Appsignal.set_gauge("key", 0.1, tags)
1150
- end
1151
-
1152
- it "should call set_gauge on the extension with a symbol key and int" do
1153
- expect(Appsignal::Extension).to receive(:set_gauge)
1154
- .with("key", 1.0, Appsignal::Extension.data_map_new)
1155
- Appsignal.set_gauge(:key, 1)
1156
- end
1157
-
1158
- it "should not raise an exception when out of range" do
1159
- expect(Appsignal::Extension).to receive(:set_gauge).with(
1160
- "key",
1161
- 10,
1162
- Appsignal::Extension.data_map_new
1163
- ).and_raise(RangeError)
1164
- expect(Appsignal.internal_logger).to receive(:warn)
1165
- .with("The gauge value '10' for metric 'key' is too big")
1166
-
1167
- Appsignal.set_gauge("key", 10)
1168
- end
1169
- end
1170
-
1171
- describe ".increment_counter" do
1172
- it "should call increment_counter on the extension with a string key" do
1173
- expect(Appsignal::Extension).to receive(:increment_counter)
1174
- .with("key", 1, Appsignal::Extension.data_map_new)
1175
- Appsignal.increment_counter("key")
1176
- end
1177
-
1178
- it "should call increment_counter with tags" do
1179
- expect(Appsignal::Extension).to receive(:increment_counter)
1180
- .with("key", 1, Appsignal::Utils::Data.generate(tags))
1181
- Appsignal.increment_counter("key", 1, tags)
1182
- end
1183
-
1184
- it "should call increment_counter on the extension with a symbol key" do
1185
- expect(Appsignal::Extension).to receive(:increment_counter)
1186
- .with("key", 1, Appsignal::Extension.data_map_new)
1187
- Appsignal.increment_counter(:key)
1188
- end
1189
-
1190
- it "should call increment_counter on the extension with a count" do
1191
- expect(Appsignal::Extension).to receive(:increment_counter)
1192
- .with("key", 5, Appsignal::Extension.data_map_new)
1193
- Appsignal.increment_counter("key", 5)
1194
- end
1195
-
1196
- it "should not raise an exception when out of range" do
1197
- expect(Appsignal::Extension).to receive(:increment_counter)
1198
- .with("key", 10, Appsignal::Extension.data_map_new).and_raise(RangeError)
1199
- expect(Appsignal.internal_logger).to receive(:warn)
1200
- .with("The counter value '10' for metric 'key' is too big")
1201
-
1202
- Appsignal.increment_counter("key", 10)
1203
- end
1204
- end
1205
-
1206
- describe ".add_distribution_value" do
1207
- it "should call add_distribution_value on the extension with a string key and float" do
1208
- expect(Appsignal::Extension).to receive(:add_distribution_value)
1209
- .with("key", 0.1, Appsignal::Extension.data_map_new)
1210
- Appsignal.add_distribution_value("key", 0.1)
1211
- end
1212
-
1213
- it "should call add_distribution_value with tags" do
1214
- expect(Appsignal::Extension).to receive(:add_distribution_value)
1215
- .with("key", 0.1, Appsignal::Utils::Data.generate(tags))
1216
- Appsignal.add_distribution_value("key", 0.1, tags)
1217
- end
1218
-
1219
- it "should call add_distribution_value on the extension with a symbol key and int" do
1220
- expect(Appsignal::Extension).to receive(:add_distribution_value)
1221
- .with("key", 1.0, Appsignal::Extension.data_map_new)
1222
- Appsignal.add_distribution_value(:key, 1)
1223
- end
1224
-
1225
- it "should not raise an exception when out of range" do
1226
- expect(Appsignal::Extension).to receive(:add_distribution_value)
1227
- .with("key", 10, Appsignal::Extension.data_map_new).and_raise(RangeError)
1228
- expect(Appsignal.internal_logger).to receive(:warn)
1229
- .with("The distribution value '10' for metric 'key' is too big")
1230
-
1231
- Appsignal.add_distribution_value("key", 10)
1232
- end
1233
- end
1234
- end
1235
-
1236
- describe ".internal_logger" do
1237
- subject { Appsignal.internal_logger }
1238
-
1239
- it { is_expected.to be_a Logger }
1240
- end
1241
-
1242
- describe ".log_formatter" do
1243
- subject { Appsignal.log_formatter.call("Debug", Time.parse("2015-07-08"), nil, "log line") }
1244
-
1245
- it "formats a log" do
1246
- expect(subject).to eq "[2015-07-08T00:00:00 (process) ##{Process.pid}][Debug] log line\n"
1247
- end
1248
-
1249
- context "with prefix" do
1250
- subject do
1251
- Appsignal.log_formatter("prefix").call("Debug", Time.parse("2015-07-08"), nil, "log line")
1252
- end
1253
-
1254
- it "adds a prefix" do
1255
- expect(subject)
1256
- .to eq "[2015-07-08T00:00:00 (process) ##{Process.pid}][Debug] prefix: log line\n"
1257
- end
1258
- end
1259
- end
1260
-
1261
- describe ".config" do
1262
- subject { Appsignal.config }
1263
-
1264
- it { is_expected.to be_a Appsignal::Config }
1265
- it "should return configuration" do
1266
- expect(subject[:endpoint]).to eq "https://push.appsignal.com"
1267
- end
1268
- end
1269
-
1270
- describe ".send_error" do
1271
- let(:error) { ExampleException.new("error message") }
1272
- let(:err_stream) { std_stream }
1273
- let(:stderr) { err_stream.read }
1274
- around do |example|
1275
- keep_transactions { example.run }
1276
- end
1277
-
1278
- it "sends the error to AppSignal" do
1279
- expect { Appsignal.send_error(error) }.to(change { created_transactions.count }.by(1))
1280
-
1281
- transaction = last_transaction
1282
- expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
1283
- expect(transaction).to_not have_action
1284
- expect(transaction).to have_error("ExampleException", "error message")
1285
- expect(transaction).to_not include_tags
1286
- expect(transaction).to be_completed
1287
- end
1288
-
1289
- context "when given error is not an Exception" do
1290
- let(:error) { "string value" }
1291
-
1292
- it "logs an error message" do
1293
- logs = capture_logs { Appsignal.send_error(error) }
1294
- expect(logs).to contains_log(
1295
- :error,
1296
- "Appsignal.send_error: Cannot send error. " \
1297
- "The given value is not an exception: #{error.inspect}"
1298
- )
1299
- end
1300
-
1301
- it "does not send the error" do
1302
- expect { Appsignal.send_error(error) }.to_not(change { created_transactions.count })
1303
- end
1304
- end
1305
-
1306
- context "when given a block" do
1307
- it "yields the transaction and allows additional metadata to be set" do
1308
- Appsignal.send_error(StandardError.new("my_error")) do |transaction|
1309
- transaction.set_action("my_action")
1310
- transaction.set_namespace("my_namespace")
1311
- end
1312
-
1313
- expect(last_transaction).to have_namespace("my_namespace")
1314
- expect(last_transaction).to have_action("my_action")
1315
- expect(last_transaction).to have_error("StandardError", "my_error")
1316
- end
1317
-
1318
- it "yields and allows additional metadata to be set with global helpers" do
1319
- Appsignal.send_error(StandardError.new("my_error")) do
1320
- Appsignal.set_action("my_action")
1321
- Appsignal.set_namespace("my_namespace")
1322
- end
1323
-
1324
- expect(last_transaction).to have_namespace("my_namespace")
1325
- expect(last_transaction).to have_action("my_action")
1326
- expect(last_transaction).to have_error("StandardError", "my_error")
1327
- end
1328
-
1329
- it "yields to set metadata and doesn't modify the active transaction" do
1330
- active_transaction = http_request_transaction
1331
- active_transaction.set_action("active action")
1332
- active_transaction.set_namespace("active namespace")
1333
- set_current_transaction(active_transaction)
1334
- expect(current_transaction).to eq(active_transaction)
1335
-
1336
- Appsignal.send_error(StandardError.new("my_error")) do
1337
- Appsignal.set_action("my_action")
1338
- Appsignal.set_namespace("my_namespace")
1339
- end
1340
-
1341
- # Restores the active_transaction as the current transaction
1342
- expect(current_transaction).to eq(active_transaction)
1343
-
1344
- expect(last_transaction).to have_namespace("my_namespace")
1345
- expect(last_transaction).to have_action("my_action")
1346
- expect(last_transaction).to have_error("StandardError", "my_error")
1347
- expect(last_transaction).to be_completed
1348
-
1349
- expect(active_transaction).to have_namespace("active namespace")
1350
- expect(active_transaction).to have_action("active action")
1351
- expect(active_transaction).to_not be_completed
1352
- end
1353
- end
1354
- end
1355
-
1356
- describe ".set_error" do
1357
- let(:err_stream) { std_stream }
1358
- let(:stderr) { err_stream.read }
1359
- let(:error) { ExampleException.new("I am an exception") }
1360
- let(:transaction) { http_request_transaction }
1361
- around { |example| keep_transactions { example.run } }
1362
-
1363
- context "when there is an active transaction" do
1364
- before { set_current_transaction(transaction) }
1365
-
1366
- it "adds the error to the active transaction" do
1367
- Appsignal.set_error(error)
1368
-
1369
- transaction._sample
1370
- expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
1371
- expect(transaction).to have_error("ExampleException", "I am an exception")
1372
- expect(transaction).to_not include_tags
1373
- end
1374
-
1375
- context "when the error is not an Exception" do
1376
- let(:error) { Object.new }
1377
-
1378
- it "does not set an error" do
1379
- silence { Appsignal.set_error(error) }
1380
-
1381
- transaction._sample
1382
- expect(transaction).to_not have_error
1383
- expect(transaction).to_not include_tags
1384
- end
1385
-
1386
- it "logs an error" do
1387
- logs = capture_logs { Appsignal.set_error(error) }
1388
- expect(logs).to contains_log(
1389
- :error,
1390
- "Appsignal.set_error: Cannot set error. " \
1391
- "The given value is not an exception: #{error.inspect}"
1392
- )
1393
- end
1394
- end
1395
-
1396
- context "when given a block" do
1397
- it "yields the transaction and allows additional metadata to be set" do
1398
- Appsignal.set_error(StandardError.new("my_error")) do |t|
1399
- t.set_action("my_action")
1400
- t.set_namespace("my_namespace")
1401
- end
1402
-
1403
- expect(transaction).to have_namespace("my_namespace")
1404
- expect(transaction).to have_action("my_action")
1405
- expect(transaction).to have_error("StandardError", "my_error")
1406
- end
1407
- end
1408
- end
1409
-
1410
- context "when there is no active transaction" do
1411
- it "does nothing" do
1412
- Appsignal.set_error(error)
1413
-
1414
- expect(transaction).to_not have_error
1415
- end
1416
- end
1417
- end
1418
-
1419
- describe ".report_error" do
1420
- let(:err_stream) { std_stream }
1421
- let(:stderr) { err_stream.read }
1422
- let(:error) { ExampleException.new("error message") }
1423
- before { start_agent }
1424
- around { |example| keep_transactions { example.run } }
1425
-
1426
- context "when the error is not an Exception" do
1427
- let(:error) { Object.new }
1428
-
1429
- it "does not set an error" do
1430
- silence { Appsignal.report_error(error) }
1431
-
1432
- expect(last_transaction).to_not have_error
1433
- end
1434
-
1435
- it "logs an error" do
1436
- logs = capture_logs { Appsignal.report_error(error) }
1437
- expect(logs).to contains_log(
1438
- :error,
1439
- "Appsignal.report_error: Cannot add error. " \
1440
- "The given value is not an exception: #{error.inspect}"
1441
- )
1442
- end
1443
- end
1444
-
1445
- context "when there is no active transaction" do
1446
- it "creates a new transaction" do
1447
- expect do
1448
- Appsignal.report_error(error)
1449
- end.to(change { created_transactions.count }.by(1))
1450
- end
1451
-
1452
- it "completes the transaction" do
1453
- Appsignal.report_error(error)
1454
-
1455
- expect(last_transaction).to be_completed
1456
- end
1457
-
1458
- context "when given a block" do
1459
- it "yields the transaction and allows additional metadata to be set" do
1460
- Appsignal.report_error(error) do |t|
1461
- t.set_action("my_action")
1462
- t.set_namespace("my_namespace")
1463
- t.set_tags(:tag1 => "value1")
1464
- end
1465
-
1466
- transaction = last_transaction
1467
- expect(transaction).to have_namespace("my_namespace")
1468
- expect(transaction).to have_action("my_action")
1469
- expect(transaction).to have_error("ExampleException", "error message")
1470
- expect(transaction).to include_tags("tag1" => "value1")
1471
- expect(transaction).to be_completed
1472
- end
1473
-
1474
- it "yields and allows additional metadata to be set with the global helpers" do
1475
- Appsignal.report_error(error) do
1476
- Appsignal.set_action("my_action")
1477
- Appsignal.set_namespace("my_namespace")
1478
- Appsignal.set_tags(:tag1 => "value1")
1479
- end
1480
-
1481
- transaction = last_transaction
1482
- expect(transaction).to have_namespace("my_namespace")
1483
- expect(transaction).to have_action("my_action")
1484
- expect(transaction).to have_error("ExampleException", "error message")
1485
- expect(transaction).to include_tags("tag1" => "value1")
1486
- expect(transaction).to be_completed
1487
- end
1488
- end
1489
- end
1490
-
1491
- context "when there is an active transaction" do
1492
- let(:transaction) { http_request_transaction }
1493
- before { set_current_transaction(transaction) }
1494
-
1495
- it "sets the error in the active transaction" do
1496
- Appsignal.report_error(error)
1497
-
1498
- expect(last_transaction).to eq(transaction)
1499
- transaction._sample
1500
- expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
1501
- expect(transaction).to have_error("ExampleException", "error message")
1502
- end
1503
-
1504
- context "when the active transaction already has an error" do
1505
- let(:previous_error) { ExampleException.new("previous error message") }
1506
-
1507
- before { transaction.set_error(previous_error) }
1508
-
1509
- it "does not overwrite the existing set error" do
1510
- Appsignal.report_error(error)
1511
-
1512
- transaction._sample
1513
- expect(transaction).to have_error("ExampleException", "previous error message")
1514
- end
1515
-
1516
- it "adds the error to the errors" do
1517
- Appsignal.report_error(error)
1518
-
1519
- expect(transaction.error_blocks).to eq({ error => [], previous_error => [] })
1520
- end
1521
-
1522
- context "when given a block" do
1523
- it "only applies the block to the transaction for that error" do
1524
- Appsignal.report_error(error) do |t|
1525
- t.set_action("my_action")
1526
- end
1527
-
1528
- transaction.complete
1529
- expect(transaction).to have_error("ExampleException", "previous error message")
1530
- expect(transaction).not_to have_action("my_action")
1531
-
1532
- expect(last_transaction).to_not be(transaction)
1533
- expect(last_transaction).to have_error("ExampleException", "error message")
1534
- expect(last_transaction).to have_action("my_action")
1535
- end
1536
- end
1537
- end
1538
-
1539
- it "does not complete the transaction" do
1540
- Appsignal.report_error(error)
1541
-
1542
- expect(last_transaction).to_not be_completed
1543
- end
1544
-
1545
- context "when given a block" do
1546
- before do
1547
- Appsignal.report_error(error) do |t|
1548
- t.set_action("my_action")
1549
- t.set_namespace("my_namespace")
1550
- t.set_tags(:tag1 => "value1")
1551
- end
1552
- end
1553
-
1554
- it "applies the block to the error transaction when completed" do
1555
- expect(transaction).not_to have_namespace("my_namespace")
1556
- expect(transaction).not_to have_action("my_action")
1557
- expect(transaction).not_to include_tags("tag1" => "value1")
1558
- expect(transaction).to have_error
1559
- expect(transaction).not_to be_completed
1560
-
1561
- transaction.complete
1562
- expect(transaction).to have_namespace("my_namespace")
1563
- expect(transaction).to have_action("my_action")
1564
- expect(transaction).to include_tags("tag1" => "value1")
1565
- expect(transaction).to have_error
1566
- expect(transaction).to be_completed
1567
- end
1568
-
1569
- it "does not apply the block to other error transactions" do
1570
- Appsignal.report_error(StandardError.new("another error"))
1571
-
1572
- transaction.complete
1573
- expect(created_transactions.count).to eq(2)
1574
-
1575
- expect(transaction).to have_namespace("my_namespace")
1576
- expect(transaction).to have_action("my_action")
1577
- expect(transaction).to include_tags("tag1" => "value1")
1578
- expect(transaction).to have_error("ExampleException", "error message")
1579
- expect(transaction).to be_completed
1580
-
1581
- expect(last_transaction).not_to be(transaction)
1582
- expect(last_transaction).not_to have_namespace("my_namespace")
1583
- expect(last_transaction).not_to have_action("my_action")
1584
- expect(last_transaction).not_to include_tags("tag1" => "value1")
1585
- expect(last_transaction).to have_error("StandardError", "another error")
1586
- expect(last_transaction).to be_completed
1587
- end
1588
-
1589
- it "does not create a new transaction" do
1590
- expect(created_transactions).to eq([transaction])
1591
- end
1592
-
1593
- it "yields and allows additional metadata to be set with the global helpers" do
1594
- Appsignal.report_error(error) do
1595
- Appsignal.set_action("my_action")
1596
- Appsignal.set_namespace("my_namespace")
1597
- Appsignal.set_tags(:tag1 => "value1")
1598
- end
1599
-
1600
- expect(transaction).to_not be_completed
1601
-
1602
- transaction.complete
1603
- expect(transaction).to have_namespace("my_namespace")
1604
- expect(transaction).to have_action("my_action")
1605
- expect(transaction).to have_error("ExampleException", "error message")
1606
- expect(transaction).to include_tags("tag1" => "value1")
1607
- end
1608
- end
1609
- end
1610
- end
1611
-
1612
- describe ".set_action" do
1613
- around { |example| keep_transactions { example.run } }
1614
-
1615
- context "with current transaction" do
1616
- before { set_current_transaction(transaction) }
1617
-
1618
- it "sets the namespace on the current transaction" do
1619
- Appsignal.set_action("custom")
1620
-
1621
- expect(transaction).to have_action("custom")
1622
- end
1623
-
1624
- it "does not set the action if the action is nil" do
1625
- Appsignal.set_action(nil)
1626
-
1627
- expect(transaction).to_not have_action
1628
- end
1629
- end
1630
-
1631
- context "without current transaction" do
1632
- it "does not set ther action" do
1633
- Appsignal.set_action("custom")
1634
-
1635
- expect(transaction).to_not have_action
1636
- end
1637
- end
1638
- end
1639
-
1640
- describe ".set_namespace" do
1641
- around { |example| keep_transactions { example.run } }
1642
-
1643
- context "with current transaction" do
1644
- before { set_current_transaction(transaction) }
1645
-
1646
- it "should set the namespace to the current transaction" do
1647
- Appsignal.set_namespace("custom")
1648
-
1649
- expect(transaction).to have_namespace("custom")
1650
- end
1651
-
1652
- it "does not update the namespace if the namespace is nil" do
1653
- Appsignal.set_namespace(nil)
1654
-
1655
- expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
1656
- end
1657
- end
1658
-
1659
- context "without current transaction" do
1660
- it "does not update the namespace" do
1661
- expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
1662
-
1663
- Appsignal.set_namespace("custom")
1664
-
1665
- expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
1666
- end
1667
- end
1668
- end
1669
-
1670
- describe ".instrument" do
1671
- it_behaves_like "instrument helper" do
1672
- let(:instrumenter) { Appsignal }
1673
- before { set_current_transaction(transaction) }
1674
- end
1675
- end
1676
-
1677
- describe ".instrument_sql" do
1678
- around { |example| keep_transactions { example.run } }
1679
- before { set_current_transaction(transaction) }
1680
-
1681
- it "creates an SQL event on the transaction" do
1682
- result =
1683
- Appsignal.instrument_sql "name", "title", "body" do
1684
- "return value"
1685
- end
1686
-
1687
- expect(result).to eq "return value"
1688
- expect(transaction).to include_event(
1689
- "name" => "name",
1690
- "title" => "title",
1691
- "body" => "body",
1692
- "body_format" => Appsignal::EventFormatter::SQL_BODY_FORMAT
1693
- )
1694
- end
1695
- end
1696
-
1697
- describe ".ignore_instrumentation_events" do
1698
- around { |example| keep_transactions { example.run } }
1699
- let(:transaction) { http_request_transaction }
1700
-
1701
- context "with current transaction" do
1702
- before { set_current_transaction(transaction) }
1703
-
1704
- it "does not record events on the transaction" do
1705
- expect(transaction).to receive(:pause!).and_call_original
1706
- expect(transaction).to receive(:resume!).and_call_original
1707
-
1708
- Appsignal.instrument("register.this.event") { :do_nothing }
1709
- Appsignal.ignore_instrumentation_events do
1710
- Appsignal.instrument("dont.register.this.event") { :do_nothing }
1711
- end
1712
-
1713
- expect(transaction).to include_event("name" => "register.this.event")
1714
- expect(transaction).to_not include_event("name" => "dont.register.this.event")
1715
- end
1716
- end
1717
-
1718
- context "without current transaction" do
1719
- let(:transaction) { nil }
1720
-
1721
- it "does not crash" do
1722
- Appsignal.ignore_instrumentation_events { :do_nothing }
1723
- end
1724
- end
1725
- end
1726
- end
1727
-
1728
- describe "._start_logger" do
1729
- let(:out_stream) { std_stream }
1730
- let(:output) { out_stream.read }
1731
- let(:log_path) { File.join(tmp_dir, "log") }
1732
- let(:log_file) { File.join(log_path, "appsignal.log") }
1733
- let(:log_level) { "debug" }
1734
-
1735
- before do
1736
- FileUtils.mkdir_p(log_path)
1737
- # Clear state from previous test
1738
- Appsignal.internal_logger = nil
1739
- if Appsignal.instance_variable_defined?(:@in_memory_logger)
1740
- Appsignal.remove_instance_variable(:@in_memory_logger)
1741
- end
1742
- end
1743
- after { FileUtils.rm_rf(log_path) }
1744
-
1745
- def initialize_config
1746
- Appsignal.configure(:production, :root_path => project_fixture_path) do |config|
1747
- config.log_path = log_path
1748
- config.log_level = log_level
1749
- end
1750
- Appsignal.internal_logger.error("Log in memory line 1")
1751
- Appsignal.internal_logger.debug("Log in memory line 2")
1752
- expect(Appsignal.in_memory_logger.messages).to_not be_empty
1753
- end
1754
-
1755
- context "when the log path is writable" do
1756
- context "when the log file is writable" do
1757
- let(:log_file_contents) { File.read(log_file) }
1758
-
1759
- before do
1760
- capture_stdout(out_stream) do
1761
- initialize_config
1762
- Appsignal._start_logger
1763
- Appsignal.internal_logger.error("Log to file")
1764
- end
1765
- expect(Appsignal.internal_logger).to be_a(Appsignal::Utils::IntegrationLogger)
1766
- end
1767
-
1768
- it "logs to file" do
1769
- expect(File.exist?(log_file)).to be_truthy
1770
- expect(log_file_contents).to include "[ERROR] Log to file"
1771
- expect(output).to be_empty
1772
- end
1773
-
1774
- context "with log level info" do
1775
- let(:log_level) { "info" }
1776
-
1777
- it "amends info log level and higher memory log messages to log file" do
1778
- expect(log_file_contents).to include "[ERROR] appsignal: Log in memory line 1"
1779
- expect(log_file_contents).to_not include "[DEBUG]"
1780
- end
1781
- end
1782
-
1783
- context "with log level debug" do
1784
- let(:log_level) { "debug" }
1785
-
1786
- it "amends debug log level and higher memory log messages to log file" do
1787
- expect(log_file_contents).to include "[ERROR] appsignal: Log in memory line 1"
1788
- expect(log_file_contents).to include "[DEBUG] appsignal: Log in memory line 2"
1789
- end
1790
- end
1791
-
1792
- it "clears the in memory log after writing to the new logger" do
1793
- expect(Appsignal.instance_variable_get(:@in_memory_logger)).to be_nil
1794
- end
1795
- end
1796
-
1797
- context "when the log file is not writable" do
1798
- before do
1799
- FileUtils.touch log_file
1800
- FileUtils.chmod 0o444, log_file
1801
-
1802
- capture_stdout(out_stream) do
1803
- initialize_config
1804
- Appsignal._start_logger
1805
- Appsignal.internal_logger.error("Log to not writable log file")
1806
- expect(Appsignal.internal_logger).to be_a(Appsignal::Utils::IntegrationLogger)
1807
- end
1808
- end
1809
-
1810
- it "logs to stdout" do
1811
- expect(File.writable?(log_file)).to be_falsy
1812
- expect(output).to include "[ERROR] appsignal: Log to not writable log file"
1813
- end
1814
-
1815
- it "amends in memory log to stdout" do
1816
- expect(output).to include "[ERROR] appsignal: Log in memory"
1817
- end
1818
-
1819
- it "clears the in memory log after writing to the new logger" do
1820
- expect(Appsignal.instance_variable_get(:@in_memory_logger)).to be_nil
1821
- end
1822
-
1823
- it "outputs a warning" do
1824
- expect(output).to include \
1825
- "[WARN] appsignal: Unable to start internal logger with log path '#{log_file}'.",
1826
- "[WARN] appsignal: Permission denied"
1827
- end
1828
- end
1829
- end
1830
-
1831
- context "when the log path and fallback path are not writable" do
1832
- before do
1833
- FileUtils.chmod 0o444, log_path
1834
- FileUtils.chmod 0o444, Appsignal::Config.system_tmp_dir
1835
-
1836
- capture_stdout(out_stream) do
1837
- initialize_config
1838
- Appsignal._start_logger
1839
- Appsignal.internal_logger.error("Log to not writable log path")
1840
- end
1841
- expect(Appsignal.internal_logger).to be_a(Appsignal::Utils::IntegrationLogger)
1842
- end
1843
- after do
1844
- FileUtils.chmod 0o755, Appsignal::Config.system_tmp_dir
1845
- end
1846
-
1847
- it "logs to stdout" do
1848
- expect(File.writable?(log_path)).to be_falsy
1849
- expect(output).to include "[ERROR] appsignal: Log to not writable log path"
1850
- end
1851
-
1852
- it "amends in memory log to stdout" do
1853
- expect(output).to include "[ERROR] appsignal: Log in memory"
1854
- end
1855
-
1856
- it "outputs a warning" do
1857
- expect(output).to include \
1858
- "appsignal: Unable to log to '#{log_path}' " \
1859
- "or the '#{Appsignal::Config.system_tmp_dir}' fallback."
1860
- end
1861
- end
1862
-
1863
- context "when on Heroku" do
1864
- before do
1865
- capture_stdout(out_stream) do
1866
- initialize_config
1867
- Appsignal._start_logger
1868
- Appsignal.internal_logger.error("Log to stdout")
1869
- end
1870
- expect(Appsignal.internal_logger).to be_a(Appsignal::Utils::IntegrationLogger)
1871
- end
1872
- around { |example| recognize_as_heroku { example.run } }
1873
-
1874
- it "logs to stdout" do
1875
- expect(output).to include "[ERROR] appsignal: Log to stdout"
1876
- end
1877
-
1878
- it "amends in memory log to stdout" do
1879
- expect(output).to include "[ERROR] appsignal: Log in memory"
1880
- end
1881
-
1882
- it "clears the in memory log after writing to the new logger" do
1883
- expect(Appsignal.instance_variable_get(:@in_memory_logger)).to be_nil
1884
- end
1885
- end
1886
-
1887
- describe "#logger#level" do
1888
- subject { Appsignal.internal_logger.level }
1889
-
1890
- context "when there is no config" do
1891
- before do
1892
- capture_stdout(out_stream) do
1893
- Appsignal._start_logger
1894
- end
1895
- end
1896
-
1897
- it "sets the log level to info" do
1898
- expect(subject).to eq Logger::INFO
1899
- end
1900
- end
1901
-
1902
- context "when there is a config" do
1903
- context "when log level is configured to debug" do
1904
- before do
1905
- capture_stdout(out_stream) do
1906
- initialize_config
1907
- Appsignal.config[:log_level] = "debug"
1908
- Appsignal._start_logger
1909
- end
1910
- end
1911
-
1912
- it "sets the log level to debug" do
1913
- expect(subject).to eq Logger::DEBUG
1914
- end
1915
- end
1916
- end
1917
- end
1918
- end
1919
- end