appsignal 1.1.0.beta.12 → 1.1.0.beta.13

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -2
  3. data/Rakefile +0 -2
  4. data/gemfiles/grape.gemfile +0 -2
  5. data/gemfiles/padrino.gemfile +0 -2
  6. data/gemfiles/rails-3.2.gemfile +0 -2
  7. data/gemfiles/rails-4.0.gemfile +1 -1
  8. data/gemfiles/rails-4.1.gemfile +1 -1
  9. data/gemfiles/rails-4.2.gemfile +1 -1
  10. data/gemfiles/rails-5.0.gemfile +0 -2
  11. data/lib/appsignal/auth_check.rb +1 -1
  12. data/lib/appsignal/cli.rb +13 -42
  13. data/lib/appsignal/cli/diagnose.rb +72 -0
  14. data/lib/appsignal/cli/install.rb +296 -0
  15. data/lib/appsignal/cli/notify_of_deploy.rb +41 -0
  16. data/lib/appsignal/config.rb +6 -1
  17. data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +1 -5
  18. data/lib/appsignal/integrations/capistrano/careful_logger.rb +1 -0
  19. data/lib/appsignal/integrations/railtie.rb +0 -4
  20. data/lib/appsignal/version.rb +1 -1
  21. data/{lib/generators/appsignal/templates/appsignal.yml → resources/appsignal.yml.erb} +4 -4
  22. data/spec/lib/appsignal/cli/diagnose_spec.rb +27 -0
  23. data/spec/lib/appsignal/cli/install_spec.rb +438 -0
  24. data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +128 -0
  25. data/spec/lib/appsignal/cli_spec.rb +23 -126
  26. data/spec/lib/appsignal/config_spec.rb +7 -2
  27. data/spec/lib/appsignal/integrations/sinatra_spec.rb +1 -12
  28. data/spec/lib/appsignal_spec.rb +14 -7
  29. data/spec/spec_helper.rb +16 -4
  30. data/spec/support/project_fixture/config/application.rb +0 -0
  31. data/spec/support/project_fixture/config/environments/development.rb +0 -0
  32. data/spec/support/project_fixture/config/environments/production.rb +0 -0
  33. data/spec/support/project_fixture/config/environments/test.rb +0 -0
  34. metadata +19 -6
  35. data/lib/generators/appsignal/USAGE +0 -8
  36. data/lib/generators/appsignal/appsignal_generator.rb +0 -64
  37. data/spec/lib/generators/appsignal/appsignal_generator_spec.rb +0 -156
@@ -0,0 +1,41 @@
1
+ module Appsignal
2
+ class CLI
3
+ class NotifyOfDeploy
4
+ class << self
5
+ def run(options, config)
6
+ validate_active_config(config)
7
+ validate_required_options(options, [:revision, :user, :environment])
8
+
9
+ Appsignal::Marker.new(
10
+ {
11
+ :revision => options[:revision],
12
+ :user => options[:user]
13
+ },
14
+ config,
15
+ nil
16
+ ).transmit
17
+ end
18
+
19
+ protected
20
+
21
+ def validate_required_options(options, required_options)
22
+ missing = required_options.select do |required_option|
23
+ val = options[required_option]
24
+ val.nil? || (val.respond_to?(:empty?) && val.empty?)
25
+ end
26
+ if missing.any?
27
+ puts "Missing options: #{missing.join(', ')}"
28
+ exit(1)
29
+ end
30
+ end
31
+
32
+ def validate_active_config(config)
33
+ unless config.active?
34
+ puts 'Exiting: No config file or push api key env var found'
35
+ exit(1)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -20,7 +20,7 @@ module Appsignal
20
20
  :enable_frontend_error_catching => false,
21
21
  :frontend_error_catching_path => '/appsignal_error_catcher',
22
22
  :enable_allocation_tracking => true,
23
- :enable_gc_instrumentation => true,
23
+ :enable_gc_instrumentation => false,
24
24
  :running_in_container => false
25
25
  }.freeze
26
26
 
@@ -47,6 +47,7 @@ module Appsignal
47
47
  }.freeze
48
48
 
49
49
  attr_reader :root_path, :env, :initial_config, :config_hash
50
+ attr_accessor :logger
50
51
 
51
52
  def initialize(root_path, env, initial_config={}, logger=Appsignal.logger)
52
53
  @root_path = root_path
@@ -74,6 +75,10 @@ module Appsignal
74
75
  config_hash[key]
75
76
  end
76
77
 
78
+ def []=(key, value)
79
+ config_hash[key] = value
80
+ end
81
+
77
82
  def log_file_path
78
83
  path = config_hash[:log_path] || root_path
79
84
  File.join(File.realpath(path), 'appsignal.log')
@@ -5,11 +5,7 @@ module Appsignal
5
5
  register 'sql.active_record'
6
6
 
7
7
  def format(payload)
8
- [
9
- payload[:name],
10
- Appsignal::Utils.encode_utf8(payload[:sql]),
11
- SQL_BODY_FORMAT
12
- ]
8
+ [payload[:name], payload[:sql], SQL_BODY_FORMAT]
13
9
  end
14
10
  end
15
11
  end
@@ -3,6 +3,7 @@ module Appsignal
3
3
  # Because Capistrano 2's logger uses the term important
4
4
  # instead of error.
5
5
  def carefully_log_error(message)
6
+ return unless @logger
6
7
  if @logger.respond_to?(:important)
7
8
  @logger.important(message)
8
9
  else
@@ -36,10 +36,6 @@ module Appsignal
36
36
 
37
37
  Appsignal.start
38
38
  end
39
-
40
- rake_tasks do
41
- load 'tasks/diag.rake'
42
- end
43
39
  end
44
40
  end
45
41
  end
@@ -1,5 +1,5 @@
1
1
  require 'yaml'
2
2
 
3
3
  module Appsignal
4
- VERSION = '1.1.0.beta.12'
4
+ VERSION = '1.1.0.beta.13'
5
5
  end
@@ -4,15 +4,15 @@ default: &defaults
4
4
  push_api_key: "<%= push_api_key %>"
5
5
 
6
6
  # Your app's name
7
- name: "<%= Rails.application.class.parent_name %>"
8
-
9
- # The cuttoff point in ms above which a request is considered slow, default is 200
10
- # slow_request_threshold: 200
7
+ name: "<%= app_name %>"
11
8
 
12
9
  # Actions that should not be monitored by AppSignal
13
10
  # ignore_actions:
14
11
  # - ApplicationController#isup
15
12
 
13
+ # See http://docs.appsignal.com/gem-settings/configuration.html for
14
+ # all configuration options.
15
+
16
16
  # Configuration per environment, leave out an environment or set active
17
17
  # to false to not push metrics for that environment.
18
18
  <% environments.each do |environment| -%>
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+ require 'appsignal/cli'
3
+
4
+ describe Appsignal::CLI::Diagnose do
5
+ let(:out_stream) { StringIO.new }
6
+ let(:cli) { Appsignal::CLI::Diagnose }
7
+ before do
8
+ @original_stdout = $stdout
9
+ $stdout = out_stream
10
+ end
11
+ after do
12
+ $stdout = @original_stdout
13
+ end
14
+
15
+ describe ".run" do
16
+ it "should output diagnostic information" do
17
+ cli.run
18
+
19
+ out_stream.string.should include('Gem version')
20
+ out_stream.string.should include('Agent version')
21
+ out_stream.string.should include('Config')
22
+ out_stream.string.should include('Checking API key')
23
+ out_stream.string.should include('Checking if required paths are writable')
24
+ out_stream.string.should include('Showing last lines of extension install log')
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,438 @@
1
+ require 'spec_helper'
2
+ require 'appsignal/cli'
3
+
4
+ begin
5
+ require 'sinatra'
6
+ rescue LoadError
7
+ end
8
+
9
+ describe Appsignal::CLI::Install do
10
+ let(:out_stream) { StringIO.new }
11
+ let(:cli) { Appsignal::CLI::Install }
12
+ let(:config) { Appsignal::Config.new(nil, {}) }
13
+ let(:auth_check) { double }
14
+
15
+ before do
16
+ ENV['PWD'] = project_fixture_path
17
+ @original_stdout = $stdout
18
+ $stdout = out_stream
19
+ Appsignal::AuthCheck.stub(:new => auth_check)
20
+ auth_check.stub(:perform => '200')
21
+ cli.stub(:sleep)
22
+ cli.stub(:press_any_key)
23
+ end
24
+ after do
25
+ $stdout = @original_stdout
26
+ end
27
+
28
+ describe ".run" do
29
+ it "should not continue if there is no key" do
30
+ cli.run(nil, config)
31
+
32
+ out_stream.string.should include('Problem encountered:')
33
+ out_stream.string.should include('No push api key entered')
34
+ end
35
+
36
+ context "auth check" do
37
+ it "should exit if the key is invalid" do
38
+ auth_check.stub(:perform => '402')
39
+
40
+ cli.run('key', config)
41
+
42
+ out_stream.string.should include("Api key 'key' is not valid")
43
+ end
44
+
45
+ it "should exit if there was an error" do
46
+ auth_check.stub(:perform).and_raise(StandardError.new)
47
+
48
+ cli.run('key', config)
49
+
50
+ out_stream.string.should include("There was an error validating your api key")
51
+ end
52
+ end
53
+ end
54
+
55
+ context "with rails" do
56
+ if rails_present?
57
+ describe ".run" do
58
+ it "should install with environment variables" do
59
+ cli.should_receive(:gets).once.and_return('n')
60
+ cli.should_receive(:gets).once.and_return('2')
61
+
62
+ cli.run('key', config)
63
+
64
+ out_stream.string.should include("Validating api key...")
65
+ out_stream.string.should include("Api key valid")
66
+ out_stream.string.should include("Installing for Ruby on Rails")
67
+ out_stream.string.should include("export APPSIGNAL_PUSH_API_KEY=key")
68
+ out_stream.string.should include("AppSignal installation complete")
69
+ end
70
+
71
+ it "should install with config file" do
72
+ cli.should_receive(:gets).once.and_return('n')
73
+ cli.should_receive(:gets).once.and_return('1')
74
+ cli.should_receive(:write_config_file)
75
+
76
+ cli.run('key', config)
77
+
78
+ out_stream.string.should include("Validating api key...")
79
+ out_stream.string.should include("Api key valid")
80
+ out_stream.string.should include("Installing for Ruby on Rails")
81
+ out_stream.string.should include("AppSignal installation complete")
82
+ end
83
+
84
+ it "should install with an overridden app name and environment variables" do
85
+ cli.should_receive(:gets).once.and_return('y')
86
+ cli.should_receive(:gets).once.and_return('Appname')
87
+ cli.should_receive(:gets).once.and_return('2')
88
+
89
+ cli.run('key', config)
90
+
91
+ out_stream.string.should include("Validating api key...")
92
+ out_stream.string.should include("Api key valid")
93
+ out_stream.string.should include("Installing for Ruby on Rails")
94
+ out_stream.string.should include("export APPSIGNAL_PUSH_API_KEY=key")
95
+ out_stream.string.should include("export APPSIGNAL_APP_NAME=Appname")
96
+ out_stream.string.should include("AppSignal installation complete")
97
+ end
98
+
99
+ it "should install with an overridden app name and a config file" do
100
+ cli.should_receive(:gets).once.and_return('y')
101
+ cli.should_receive(:gets).once.and_return('Appname')
102
+ cli.should_receive(:gets).once.and_return('1')
103
+ cli.should_receive(:write_config_file)
104
+
105
+ cli.run('key', config)
106
+
107
+ out_stream.string.should include("Validating api key...")
108
+ out_stream.string.should include("Api key valid")
109
+ out_stream.string.should include("Installing for Ruby on Rails")
110
+ out_stream.string.should include("AppSignal installation complete")
111
+ end
112
+ end
113
+
114
+ describe ".rails_environments" do
115
+ before do
116
+ ENV['PWD'] = project_fixture_path
117
+ end
118
+
119
+ subject { cli.rails_environments }
120
+
121
+ it { should == ['development', 'production'] }
122
+ end
123
+
124
+ describe ".installed_frameworks" do
125
+ subject { cli.installed_frameworks }
126
+
127
+ it { should include(:rails) }
128
+ end
129
+ end
130
+ end
131
+
132
+ context "with sinatra" do
133
+ if sinatra_present? && !padrino_present?
134
+ describe ".install" do
135
+ it "should install with environment variables" do
136
+ cli.should_receive(:gets).once.and_return('Appname')
137
+ cli.should_receive(:gets).once.and_return('2')
138
+
139
+ cli.run('key', config)
140
+
141
+ out_stream.string.should include("Validating api key...")
142
+ out_stream.string.should include("Api key valid")
143
+ out_stream.string.should include("Installing for Sinatra")
144
+ out_stream.string.should include("export APPSIGNAL_PUSH_API_KEY=key")
145
+ out_stream.string.should include("AppSignal installation complete")
146
+ end
147
+
148
+ it "should install with a config file" do
149
+ cli.should_receive(:gets).once.and_return('Appname')
150
+ cli.should_receive(:gets).once.and_return('1')
151
+ cli.should_receive(:write_config_file)
152
+
153
+ cli.run('key', config)
154
+
155
+ out_stream.string.should include("Validating api key...")
156
+ out_stream.string.should include("Api key valid")
157
+ out_stream.string.should include("Installing for Sinatra")
158
+ out_stream.string.should include("AppSignal installation complete")
159
+ end
160
+ end
161
+
162
+ describe ".installed_frameworks" do
163
+ subject { cli.installed_frameworks }
164
+
165
+ it { should include(:sinatra) }
166
+ end
167
+ end
168
+ end
169
+
170
+ context "with padrino" do
171
+ if padrino_present?
172
+ describe ".install" do
173
+ it "should install with environment variables" do
174
+ cli.should_receive(:gets).once.and_return('Appname')
175
+ cli.should_receive(:gets).once.and_return('2')
176
+
177
+ cli.run('key', config)
178
+
179
+ out_stream.string.should include("Validating api key...")
180
+ out_stream.string.should include("Api key valid")
181
+ out_stream.string.should include("Installing for Padrino")
182
+ out_stream.string.should include("export APPSIGNAL_PUSH_API_KEY=key")
183
+ out_stream.string.should include("AppSignal installation complete")
184
+ end
185
+
186
+ it "should install with a config file" do
187
+ cli.should_receive(:gets).once.and_return('Appname')
188
+ cli.should_receive(:gets).once.and_return('1')
189
+ cli.should_receive(:write_config_file)
190
+
191
+ cli.run('key', config)
192
+
193
+ out_stream.string.should include("Validating api key...")
194
+ out_stream.string.should include("Api key valid")
195
+ out_stream.string.should include("Installing for Padrino")
196
+ out_stream.string.should include("AppSignal installation complete")
197
+ end
198
+ end
199
+
200
+ describe ".installed_frameworks" do
201
+ subject { cli.installed_frameworks }
202
+
203
+ it { should include(:padrino) }
204
+ end
205
+ end
206
+ end
207
+
208
+ context "with grape" do
209
+ if grape_present?
210
+ describe ".install" do
211
+ it "should install with environment variables" do
212
+ cli.should_receive(:gets).once.and_return('Appname')
213
+ cli.should_receive(:gets).once.and_return('2')
214
+
215
+ cli.run('key', config)
216
+
217
+ out_stream.string.should include("Validating api key...")
218
+ out_stream.string.should include("Api key valid")
219
+ out_stream.string.should include("Installing for Grape")
220
+ out_stream.string.should include("export APPSIGNAL_PUSH_API_KEY=key")
221
+ out_stream.string.should include("AppSignal installation complete")
222
+ end
223
+
224
+ it "should install with a config file" do
225
+ cli.should_receive(:gets).once.and_return('Appname')
226
+ cli.should_receive(:gets).once.and_return('1')
227
+ cli.should_receive(:write_config_file)
228
+
229
+ cli.run('key', config)
230
+
231
+ out_stream.string.should include("Validating api key...")
232
+ out_stream.string.should include("Api key valid")
233
+ out_stream.string.should include("Installing for Grape")
234
+ out_stream.string.should include("AppSignal installation complete")
235
+ end
236
+ end
237
+
238
+ describe ".installed_frameworks" do
239
+ subject { cli.installed_frameworks }
240
+
241
+ it { should include(:grape) }
242
+ end
243
+ end
244
+ end
245
+
246
+ context "with unknown framework" do
247
+ if !rails_present? && !sinatra_present? && !padrino_present? && !grape_present?
248
+ describe ".install" do
249
+ it "should give a message about unknown framework" do
250
+ cli.run('key', config)
251
+
252
+ out_stream.string.should include("Validating api key...")
253
+ out_stream.string.should include("Api key valid")
254
+ out_stream.string.should include("We could not detect which framework you are using.")
255
+ end
256
+ end
257
+
258
+ describe ".installed_frameworks" do
259
+ subject { cli.installed_frameworks }
260
+
261
+ it { should be_empty }
262
+ end
263
+ end
264
+ end
265
+
266
+ describe ".colorize" do
267
+ subject { cli.colorize('text', :green) }
268
+
269
+ context "on windows" do
270
+ before do
271
+ Gem.stub(:win_platform? => true)
272
+ end
273
+
274
+ it { should == 'text' }
275
+ end
276
+
277
+ context "not on windows" do
278
+ before do
279
+ Gem.stub(:win_platform? => false)
280
+ end
281
+
282
+ it { should == "\e[32mtext\e[0m" }
283
+ end
284
+ end
285
+
286
+ describe ".periods" do
287
+ it "should output three periods" do
288
+ cli.periods
289
+ out_stream.string.should include('...')
290
+ end
291
+ end
292
+
293
+ describe ".press_any_key" do
294
+ before do
295
+ cli.unstub(:press_any_key)
296
+ STDIN.stub(:getch)
297
+ end
298
+
299
+ it "should continue" do
300
+ cli.press_any_key
301
+ out_stream.string.should include('Press any key')
302
+ end
303
+ end
304
+
305
+ describe ".yes_or_no" do
306
+ it "should take yes for an answer" do
307
+ cli.should_receive(:gets).once.and_return('')
308
+ cli.should_receive(:gets).once.and_return('nonsense')
309
+ cli.should_receive(:gets).once.and_return('y')
310
+
311
+ cli.yes_or_no('yes or no?: ').should be_true
312
+ end
313
+
314
+ it "should take no for an answer" do
315
+ cli.should_receive(:gets).once.and_return('')
316
+ cli.should_receive(:gets).once.and_return('nonsense')
317
+ cli.should_receive(:gets).once.and_return('n')
318
+
319
+ cli.yes_or_no('yes or no?: ').should be_false
320
+ end
321
+ end
322
+
323
+ describe ".required_input" do
324
+ it "should collect required input" do
325
+ cli.should_receive(:gets).once.and_return('')
326
+ cli.should_receive(:gets).once.and_return('value')
327
+
328
+ cli.required_input('provide: ').should == 'value'
329
+ end
330
+ end
331
+
332
+ describe ".configure" do
333
+ before do
334
+ config[:push_api_key] = 'key'
335
+ config[:name] = 'Appname'
336
+ end
337
+
338
+ context "environment variables" do
339
+ it "should output the environment variables" do
340
+ cli.should_receive(:gets).once.and_return('2')
341
+
342
+ cli.configure(config, [], false)
343
+
344
+ out_stream.string.should include("Add the following environment variables to configure AppSignal")
345
+ out_stream.string.should include("export APPSIGNAL_ACTIVE=true")
346
+ out_stream.string.should include("export APPSIGNAL_PUSH_API_KEY=key")
347
+ end
348
+
349
+ it "should output the environment variables with name overwritten" do
350
+ cli.should_receive(:gets).once.and_return('2')
351
+
352
+ cli.configure(config, [], true)
353
+
354
+ out_stream.string.should include("Add the following environment variables to configure AppSignal")
355
+ out_stream.string.should include("export APPSIGNAL_ACTIVE=true")
356
+ out_stream.string.should include("export APPSIGNAL_PUSH_API_KEY=key")
357
+ out_stream.string.should include("export APPSIGNAL_APP_NAME=Appname")
358
+ end
359
+ end
360
+
361
+ context "config file" do
362
+ it "should write the config file" do
363
+ cli.should_receive(:gets).once.and_return('1')
364
+
365
+ cli.should_receive(:write_config_file).with(
366
+ :push_api_key => 'key',
367
+ :app_name => config[:name],
368
+ :environments => []
369
+ )
370
+
371
+ cli.configure(config, [], false)
372
+
373
+ out_stream.string.should include("Writing config file")
374
+ out_stream.string.should include("Config file written to config/appsignal.yml")
375
+ end
376
+ end
377
+ end
378
+
379
+ describe ".done_notice" do
380
+ subject { out_stream.string }
381
+
382
+ context "on windows" do
383
+ before do
384
+ Gem.stub(:win_platform? => true)
385
+ cli.done_notice
386
+ end
387
+
388
+ it { should include('The AppSignal agent currently does not work on Windows') }
389
+ it { should include('test/staging/production environment') }
390
+ end
391
+
392
+ context "not on windows" do
393
+ before do
394
+ Gem.stub(:win_platform? => false)
395
+ cli.done_notice
396
+ end
397
+
398
+ it { should include('You can do this on your dev environment') }
399
+ it { should include('Or deploy to staging or production') }
400
+ end
401
+ end
402
+
403
+ context ".write_config_file" do
404
+ before do
405
+ ENV['PWD'] = tmp_dir
406
+ end
407
+
408
+ it "should write a config file with environments" do
409
+ cli.write_config_file(
410
+ :push_api_key => 'key',
411
+ :app_name => 'App name',
412
+ :environments => [:staging, :production]
413
+ )
414
+
415
+ config = File.read(File.join(tmp_dir, 'config/appsignal.yml'))
416
+
417
+ config.should include('name: "App name"')
418
+ config.should include('push_api_key: "key"')
419
+ config.should include('staging:')
420
+ config.should include('production:')
421
+ end
422
+
423
+ it "should write a config file without environments" do
424
+ cli.write_config_file(
425
+ :push_api_key => 'key',
426
+ :app_name => 'App name',
427
+ :environments => []
428
+ )
429
+
430
+ config = File.read(File.join(tmp_dir, 'config/appsignal.yml'))
431
+
432
+ config.should include('name: "App name"')
433
+ config.should include('push_api_key: "key"')
434
+ config.should_not include('staging:')
435
+ config.should_not include('production:')
436
+ end
437
+ end
438
+ end