appsignal 4.0.5 → 4.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/Rakefile +9 -9
  4. data/appsignal.gemspec +22 -1
  5. data/build_matrix.yml +2 -1
  6. data/ext/agent.rb +27 -27
  7. data/lib/appsignal/check_in/scheduler.rb +3 -4
  8. data/lib/appsignal/check_in.rb +1 -1
  9. data/lib/appsignal/config.rb +1 -3
  10. data/lib/appsignal/integrations/que.rb +8 -2
  11. data/lib/appsignal/integrations/resque.rb +1 -6
  12. data/lib/appsignal/utils/hash_sanitizer.rb +4 -0
  13. data/lib/appsignal/version.rb +1 -1
  14. metadata +2 -191
  15. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -31
  16. data/.github/ISSUE_TEMPLATE/chore.md +0 -14
  17. data/.github/workflows/ci.yml +0 -3150
  18. data/.github/workflows/create_release_from_tag.yml +0 -62
  19. data/.gitignore +0 -35
  20. data/.gitmodules +0 -3
  21. data/.rspec +0 -4
  22. data/.yardopts +0 -8
  23. data/benchmark.rake +0 -139
  24. data/gemfiles/capistrano2.gemfile +0 -6
  25. data/gemfiles/capistrano3.gemfile +0 -7
  26. data/gemfiles/dry-monitor.gemfile +0 -5
  27. data/gemfiles/grape.gemfile +0 -5
  28. data/gemfiles/hanami-2.0.gemfile +0 -7
  29. data/gemfiles/hanami-2.1.gemfile +0 -7
  30. data/gemfiles/http5.gemfile +0 -5
  31. data/gemfiles/no_dependencies.gemfile +0 -10
  32. data/gemfiles/padrino.gemfile +0 -7
  33. data/gemfiles/psych-3.gemfile +0 -5
  34. data/gemfiles/psych-4.gemfile +0 -5
  35. data/gemfiles/que.gemfile +0 -5
  36. data/gemfiles/rails-6.0.gemfile +0 -10
  37. data/gemfiles/rails-6.1.gemfile +0 -11
  38. data/gemfiles/rails-7.0.gemfile +0 -11
  39. data/gemfiles/rails-7.1.gemfile +0 -11
  40. data/gemfiles/rails-7.2.gemfile +0 -11
  41. data/gemfiles/redis-4.gemfile +0 -5
  42. data/gemfiles/redis-5.gemfile +0 -6
  43. data/gemfiles/resque-2.gemfile +0 -6
  44. data/gemfiles/sequel.gemfile +0 -10
  45. data/gemfiles/sinatra.gemfile +0 -5
  46. data/gemfiles/webmachine1.gemfile +0 -7
  47. data/gemfiles/webmachine2.gemfile +0 -6
  48. data/mono.yml +0 -16
  49. data/spec/.rubocop.yml +0 -7
  50. data/spec/lib/appsignal/auth_check_spec.rb +0 -84
  51. data/spec/lib/appsignal/capistrano2_spec.rb +0 -227
  52. data/spec/lib/appsignal/capistrano3_spec.rb +0 -284
  53. data/spec/lib/appsignal/check_in/cron_spec.rb +0 -202
  54. data/spec/lib/appsignal/check_in/scheduler_spec.rb +0 -443
  55. data/spec/lib/appsignal/cli/demo_spec.rb +0 -46
  56. data/spec/lib/appsignal/cli/diagnose/paths_spec.rb +0 -16
  57. data/spec/lib/appsignal/cli/diagnose/utils_spec.rb +0 -86
  58. data/spec/lib/appsignal/cli/diagnose_spec.rb +0 -1553
  59. data/spec/lib/appsignal/cli/helpers_spec.rb +0 -179
  60. data/spec/lib/appsignal/cli/install_spec.rb +0 -848
  61. data/spec/lib/appsignal/cli_spec.rb +0 -56
  62. data/spec/lib/appsignal/config_spec.rb +0 -1380
  63. data/spec/lib/appsignal/demo_spec.rb +0 -83
  64. data/spec/lib/appsignal/environment_spec.rb +0 -190
  65. data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +0 -60
  66. data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +0 -21
  67. data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +0 -21
  68. data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +0 -52
  69. data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +0 -21
  70. data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +0 -84
  71. data/spec/lib/appsignal/event_formatter/rom/sql_formatter_spec.rb +0 -22
  72. data/spec/lib/appsignal/event_formatter/sequel/sql_formatter_spec.rb +0 -30
  73. data/spec/lib/appsignal/event_formatter/view_component/render_formatter_spec.rb +0 -41
  74. data/spec/lib/appsignal/event_formatter_spec.rb +0 -193
  75. data/spec/lib/appsignal/extension/jruby_spec.rb +0 -46
  76. data/spec/lib/appsignal/extension_install_failure_spec.rb +0 -20
  77. data/spec/lib/appsignal/extension_spec.rb +0 -178
  78. data/spec/lib/appsignal/garbage_collection_spec.rb +0 -98
  79. data/spec/lib/appsignal/hooks/action_cable_spec.rb +0 -345
  80. data/spec/lib/appsignal/hooks/action_mailer_spec.rb +0 -55
  81. data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +0 -23
  82. data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +0 -99
  83. data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +0 -47
  84. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +0 -47
  85. data/spec/lib/appsignal/hooks/activejob_spec.rb +0 -650
  86. data/spec/lib/appsignal/hooks/at_exit_spec.rb +0 -105
  87. data/spec/lib/appsignal/hooks/celluloid_spec.rb +0 -40
  88. data/spec/lib/appsignal/hooks/data_mapper_spec.rb +0 -40
  89. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +0 -38
  90. data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +0 -83
  91. data/spec/lib/appsignal/hooks/excon_spec.rb +0 -67
  92. data/spec/lib/appsignal/hooks/gvl_spec.rb +0 -145
  93. data/spec/lib/appsignal/hooks/http_spec.rb +0 -37
  94. data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +0 -46
  95. data/spec/lib/appsignal/hooks/mri_spec.rb +0 -23
  96. data/spec/lib/appsignal/hooks/net_http_spec.rb +0 -18
  97. data/spec/lib/appsignal/hooks/passenger_spec.rb +0 -30
  98. data/spec/lib/appsignal/hooks/puma_spec.rb +0 -80
  99. data/spec/lib/appsignal/hooks/que_spec.rb +0 -19
  100. data/spec/lib/appsignal/hooks/rake_spec.rb +0 -144
  101. data/spec/lib/appsignal/hooks/redis_client_spec.rb +0 -218
  102. data/spec/lib/appsignal/hooks/redis_spec.rb +0 -124
  103. data/spec/lib/appsignal/hooks/resque_spec.rb +0 -27
  104. data/spec/lib/appsignal/hooks/sequel_spec.rb +0 -44
  105. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +0 -29
  106. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +0 -115
  107. data/spec/lib/appsignal/hooks/unicorn_spec.rb +0 -63
  108. data/spec/lib/appsignal/hooks/webmachine_spec.rb +0 -24
  109. data/spec/lib/appsignal/hooks_spec.rb +0 -124
  110. data/spec/lib/appsignal/integrations/data_mapper_spec.rb +0 -74
  111. data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +0 -454
  112. data/spec/lib/appsignal/integrations/http_spec.rb +0 -111
  113. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +0 -154
  114. data/spec/lib/appsignal/integrations/net_http_spec.rb +0 -33
  115. data/spec/lib/appsignal/integrations/object_spec.rb +0 -347
  116. data/spec/lib/appsignal/integrations/puma_spec.rb +0 -150
  117. data/spec/lib/appsignal/integrations/que_spec.rb +0 -152
  118. data/spec/lib/appsignal/integrations/railtie_spec.rb +0 -457
  119. data/spec/lib/appsignal/integrations/resque_spec.rb +0 -155
  120. data/spec/lib/appsignal/integrations/shoryuken_spec.rb +0 -165
  121. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +0 -640
  122. data/spec/lib/appsignal/integrations/webmachine_spec.rb +0 -136
  123. data/spec/lib/appsignal/loaders/grape_spec.rb +0 -12
  124. data/spec/lib/appsignal/loaders/hanami_spec.rb +0 -92
  125. data/spec/lib/appsignal/loaders/padrino_spec.rb +0 -273
  126. data/spec/lib/appsignal/loaders/sinatra_spec.rb +0 -44
  127. data/spec/lib/appsignal/loaders_spec.rb +0 -144
  128. data/spec/lib/appsignal/logger_spec.rb +0 -205
  129. data/spec/lib/appsignal/marker_spec.rb +0 -51
  130. data/spec/lib/appsignal/probes/gvl_spec.rb +0 -164
  131. data/spec/lib/appsignal/probes/mri_spec.rb +0 -162
  132. data/spec/lib/appsignal/probes/sidekiq_spec.rb +0 -333
  133. data/spec/lib/appsignal/probes_spec.rb +0 -411
  134. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +0 -370
  135. data/spec/lib/appsignal/rack/body_wrapper_spec.rb +0 -319
  136. data/spec/lib/appsignal/rack/event_handler_spec.rb +0 -441
  137. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +0 -201
  138. data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +0 -36
  139. data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +0 -38
  140. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +0 -126
  141. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +0 -217
  142. data/spec/lib/appsignal/rack_spec.rb +0 -243
  143. data/spec/lib/appsignal/sample_data_spec.rb +0 -238
  144. data/spec/lib/appsignal/span_spec.rb +0 -141
  145. data/spec/lib/appsignal/system_spec.rb +0 -126
  146. data/spec/lib/appsignal/transaction_spec.rb +0 -2111
  147. data/spec/lib/appsignal/transmitter_spec.rb +0 -198
  148. data/spec/lib/appsignal/utils/data_spec.rb +0 -166
  149. data/spec/lib/appsignal/utils/hash_sanitizer_spec.rb +0 -182
  150. data/spec/lib/appsignal/utils/integration_logger_spec.rb +0 -21
  151. data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +0 -153
  152. data/spec/lib/appsignal/utils/json_spec.rb +0 -44
  153. data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +0 -192
  154. data/spec/lib/appsignal_spec.rb +0 -1919
  155. data/spec/lib/puma/appsignal_spec.rb +0 -334
  156. data/spec/spec_helper.rb +0 -173
  157. data/spec/support/fixtures/generated_config.yml +0 -24
  158. data/spec/support/fixtures/projects/broken/config/appsignal.yml +0 -1
  159. data/spec/support/fixtures/projects/valid/config/appsignal.yml +0 -57
  160. data/spec/support/fixtures/projects/valid/log/.gitkeep +0 -0
  161. data/spec/support/fixtures/projects/valid_with_rails_app/config/application.rb +0 -16
  162. data/spec/support/fixtures/projects/valid_with_rails_app/config/appsignal.yml +0 -56
  163. data/spec/support/fixtures/projects/valid_with_rails_app/config/environment.rb +0 -10
  164. data/spec/support/fixtures/projects/valid_with_rails_app/log/.gitkeep +0 -0
  165. data/spec/support/fixtures/uploaded_file.txt +0 -0
  166. data/spec/support/hanami/hanami_app.rb +0 -29
  167. data/spec/support/helpers/action_mailer_helpers.rb +0 -25
  168. data/spec/support/helpers/activejob_helpers.rb +0 -27
  169. data/spec/support/helpers/api_request_helper.rb +0 -20
  170. data/spec/support/helpers/cli_helpers.rb +0 -40
  171. data/spec/support/helpers/config_helpers.rb +0 -66
  172. data/spec/support/helpers/dependency_helper.rb +0 -150
  173. data/spec/support/helpers/directory_helper.rb +0 -27
  174. data/spec/support/helpers/env_helpers.rb +0 -41
  175. data/spec/support/helpers/environment_metdata_helper.rb +0 -16
  176. data/spec/support/helpers/example_exception.rb +0 -13
  177. data/spec/support/helpers/example_standard_error.rb +0 -13
  178. data/spec/support/helpers/loader_helper.rb +0 -21
  179. data/spec/support/helpers/log_helpers.rb +0 -36
  180. data/spec/support/helpers/rails_helper.rb +0 -28
  181. data/spec/support/helpers/std_streams_helper.rb +0 -94
  182. data/spec/support/helpers/system_helpers.rb +0 -8
  183. data/spec/support/helpers/take_at_most_helper.rb +0 -21
  184. data/spec/support/helpers/time_helpers.rb +0 -11
  185. data/spec/support/helpers/transaction_helpers.rb +0 -122
  186. data/spec/support/helpers/wait_for_helper.rb +0 -39
  187. data/spec/support/matchers/contains_log.rb +0 -26
  188. data/spec/support/matchers/have_colorized_text.rb +0 -28
  189. data/spec/support/matchers/transaction.rb +0 -200
  190. data/spec/support/mocks/appsignal_mock.rb +0 -18
  191. data/spec/support/mocks/dummy_app.rb +0 -20
  192. data/spec/support/mocks/fake_gc_profiler.rb +0 -19
  193. data/spec/support/mocks/fake_gvl_tools.rb +0 -28
  194. data/spec/support/mocks/hash_like.rb +0 -10
  195. data/spec/support/mocks/mock_probe.rb +0 -13
  196. data/spec/support/mocks/puma_mock.rb +0 -43
  197. data/spec/support/shared_examples/instrument.rb +0 -48
  198. data/spec/support/stubs/appsignal/loaders/loader_stub.rb +0 -7
  199. data/spec/support/stubs/delayed_job.rb +0 -0
  200. data/spec/support/stubs/sidekiq/api.rb +0 -4
  201. data/spec/support/testing.rb +0 -194
  202. data/support/bundler_wrapper +0 -12
  203. 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