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

Sign up to get free protection for your applications and to get access to all the features.
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