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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 012b200a89f80f3b02f9914a8f527b9e54f7b440
4
- data.tar.gz: b7c5c523bae9a95a6eb9fa0d5f29b976163142fa
3
+ metadata.gz: a8d354800e9781d6efd1a2f52be4515971519468
4
+ data.tar.gz: fa3a415522bcd7dd52db147d92aa68e75f373a09
5
5
  SHA512:
6
- metadata.gz: e7537ed7eb7f4888d3ee4ada2dda6e8dca0791e3f9173ba804383748b627915c076c3c6c1663cfd95a9d05e7004d63ab9bd2f5f520816342323318b847dad2ba
7
- data.tar.gz: 2561238aef1065a629d69034f1f787043f3c82ffa85cdaa0789f10f8bf4ed9827ac8418e8337d617e5617e349fa21747acf5fde8ad1cbcf2b30830b5cae644e7
6
+ metadata.gz: d526d61caca01c60a7d3dbcda9d23a25391fbfeca8a630d03c620ca229a6d63dfe89e7728d8e501042d67cf70f312e5f9a7d4483277567659cc4e4f0a5845684
7
+ data.tar.gz: 4a5bf45846b35bbc1bda5d9f7bf5511cfbb6e5dc793e848dae5f94a6f09972d82673f5639fade3cebdcb2d9bf16ed0ecae7e9adee008cdb83dc2f16f016619a7
@@ -1,11 +1,15 @@
1
1
  # 1.1
2
- * Collect global metrics for GC durations
2
+ * Collect global metrics for GC durations (in beta, disabled by default)
3
3
  * Collect params from Delayed Job in a reliable way
4
4
  * Collect perams for Delayed Job and Sidekiq when using ActiveJob
5
5
  * Official Grape support
6
+ * Easier installation using `bundle exec appsignal install`
7
+
8
+ # 1.0.7
9
+ * Another multibyte bugfix in sql sanizitation
6
10
 
7
11
  # 1.0.6
8
- * Bugfix in background thread when using heavy sanization
12
+ * Bugfix in sql sanitization when using multibyte utf-8 characters
9
13
 
10
14
  # 1.0.5
11
15
  * Improved sql sanitization
data/Rakefile CHANGED
@@ -1,6 +1,4 @@
1
1
  require 'rspec/core/rake_task'
2
- import 'lib/tasks/diag.rake'
3
-
4
2
  GEMFILES = %w(
5
3
  capistrano2
6
4
  capistrano3
@@ -2,6 +2,4 @@ source 'https://rubygems.org'
2
2
 
3
3
  gem 'grape', '0.14.0'
4
4
 
5
- gem 'generator_spec'
6
-
7
5
  gemspec :path => '../'
@@ -2,6 +2,4 @@ source 'https://rubygems.org'
2
2
 
3
3
  gem 'padrino', '~> 0.12.0'
4
4
 
5
- gem 'generator_spec'
6
-
7
5
  gemspec :path => '../'
@@ -4,6 +4,4 @@ gem 'rails', '~> 3.2.14'
4
4
 
5
5
  gem 'test-unit'
6
6
 
7
- gem 'generator_spec'
8
-
9
7
  gemspec :path => '../'
@@ -2,6 +2,6 @@ source 'https://rubygems.org'
2
2
 
3
3
  gem 'rails', '~> 4.0.0'
4
4
 
5
- gem 'generator_spec'
5
+ gem 'mime-types', '~> 2.6'
6
6
 
7
7
  gemspec :path => '../'
@@ -2,6 +2,6 @@ source 'https://rubygems.org'
2
2
 
3
3
  gem 'rails', '~> 4.1.0'
4
4
 
5
- gem 'generator_spec'
5
+ gem 'mime-types', '~> 2.6'
6
6
 
7
7
  gemspec :path => '../'
@@ -2,6 +2,6 @@ source 'https://rubygems.org'
2
2
 
3
3
  gem 'rails', '~> 4.2.0'
4
4
 
5
- gem 'generator_spec'
5
+ gem 'mime-types', '~> 2.6'
6
6
 
7
7
  gemspec :path => '../'
@@ -2,6 +2,4 @@ source 'https://rubygems.org'
2
2
 
3
3
  gem 'rails', '~> 5.0.0.beta'
4
4
 
5
- gem 'generator_spec'
6
-
7
5
  gemspec :path => '../'
@@ -4,7 +4,7 @@ module Appsignal
4
4
 
5
5
  attr_reader :config, :logger
6
6
 
7
- def initialize(config, logger)
7
+ def initialize(config, logger=Appsignal.logger)
8
8
  @config = config
9
9
  @logger = logger
10
10
  end
@@ -2,10 +2,13 @@ require 'optparse'
2
2
  require 'logger'
3
3
  require 'yaml'
4
4
  require 'appsignal'
5
+ require 'appsignal/cli/diagnose'
6
+ require 'appsignal/cli/install'
7
+ require 'appsignal/cli/notify_of_deploy'
5
8
 
6
9
  module Appsignal
7
10
  class CLI
8
- AVAILABLE_COMMANDS = %w(notify_of_deploy).freeze
11
+ AVAILABLE_COMMANDS = %w(diagnose install notify_of_deploy).freeze
9
12
 
10
13
  class << self
11
14
  attr_accessor :options, :config, :initial_config
@@ -21,8 +24,12 @@ module Appsignal
21
24
  if AVAILABLE_COMMANDS.include?(command)
22
25
  commands[command].parse!(argv)
23
26
  case command.to_sym
27
+ when :diagnose
28
+ Appsignal::CLI::Diagnose.run
29
+ when :install
30
+ Appsignal::CLI::Install.run(argv.shift, config(nil))
24
31
  when :notify_of_deploy
25
- notify_of_deploy
32
+ Appsignal::CLI::NotifyOfDeploy.run(options, config)
26
33
  end
27
34
  else
28
35
  puts "Command '#{command}' does not exist, run appsignal -h to "\
@@ -36,12 +43,8 @@ module Appsignal
36
43
  end
37
44
  end
38
45
 
39
- def logger
40
- Logger.new($stdout)
41
- end
42
-
43
- def config
44
- @config ||= Appsignal::Config.new(
46
+ def config(logger=Logger.new($stdout))
47
+ Appsignal::Config.new(
45
48
  ENV['PWD'],
46
49
  options[:environment],
47
50
  initial_config,
@@ -70,6 +73,8 @@ module Appsignal
70
73
 
71
74
  def command_option_parser
72
75
  {
76
+ 'diagnose' => OptionParser.new,
77
+ 'install' => OptionParser.new,
73
78
  'notify_of_deploy' => OptionParser.new do |o|
74
79
  o.banner = 'Usage: appsignal notify_of_deploy [options]'
75
80
 
@@ -91,40 +96,6 @@ module Appsignal
91
96
  end
92
97
  }
93
98
  end
94
-
95
- def notify_of_deploy
96
- validate_active_config
97
- validate_required_options([:revision, :user, :environment])
98
-
99
- Appsignal::Marker.new(
100
- {
101
- :revision => options[:revision],
102
- :user => options[:user]
103
- },
104
- config,
105
- logger
106
- ).transmit
107
- end
108
-
109
- protected
110
-
111
- def validate_required_options(required_options)
112
- missing = required_options.select do |required_option|
113
- val = options[required_option]
114
- val.nil? || (val.respond_to?(:empty?) && val.empty?)
115
- end
116
- if missing.any?
117
- puts "Missing options: #{missing.join(', ')}"
118
- exit(1)
119
- end
120
- end
121
-
122
- def validate_active_config
123
- unless config.active?
124
- puts 'Exiting: No config file or push api key env var found'
125
- exit(1)
126
- end
127
- end
128
99
  end
129
100
  end
130
101
  end
@@ -0,0 +1,72 @@
1
+ module Appsignal
2
+ class CLI
3
+ class Diagnose
4
+ class << self
5
+ def run
6
+ gem_version
7
+ agent_version
8
+ start_appsignal
9
+ config
10
+ check_api_key
11
+ paths_writable
12
+ check_ext_install
13
+ end
14
+
15
+ def gem_version
16
+ puts "Gem version: #{Appsignal::VERSION}"
17
+ end
18
+
19
+ def agent_version
20
+ puts "Agent version: #{Appsignal::Extension.agent_version}"
21
+ end
22
+
23
+ def start_appsignal
24
+ Appsignal.start
25
+ end
26
+
27
+ def config
28
+ start_appsignal
29
+ Appsignal.config.config_hash.each do |key, val|
30
+ puts "Config #{key}: #{val}"
31
+ end
32
+ end
33
+
34
+ def paths_writable
35
+ start_appsignal
36
+ possible_paths = [
37
+ Appsignal.config.root_path,
38
+ Appsignal.config.log_file_path
39
+ ]
40
+
41
+ puts "Checking if required paths are writable:"
42
+ possible_paths.each do |path|
43
+ result = File.writable?(path) ? 'Ok' : 'Failed'
44
+ puts "#{path} ...#{result}"
45
+ end
46
+ puts "\n"
47
+ end
48
+
49
+ def check_api_key
50
+ start_appsignal
51
+ auth_check = ::Appsignal::AuthCheck.new(Appsignal.config, Appsignal.logger)
52
+ status, result = auth_check.perform_with_result
53
+ if status == '200'
54
+ puts "Checking API key: Ok"
55
+ else
56
+ puts "Checking API key: Failed"
57
+ end
58
+ end
59
+
60
+ def check_ext_install
61
+ require 'bundler/cli'
62
+ require "bundler/cli/common"
63
+ path = Bundler::CLI::Common.select_spec('appsignal').full_gem_path
64
+ log_path = "#{path.strip}/ext/install.log"
65
+ puts "Showing last lines of extension install log: #{log_path}"
66
+ puts File.read(log_path)
67
+ puts "\n"
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,296 @@
1
+ require 'erb'
2
+ require 'ostruct'
3
+ require 'io/console'
4
+
5
+ module Appsignal
6
+ class CLI
7
+ class Install
8
+ EXCLUDED_ENVIRONMENTS = ['test'].freeze
9
+
10
+ class << self
11
+ def run(push_api_key, config)
12
+ puts
13
+ puts colorize "#######################################", :green
14
+ puts colorize "## Starting AppSignal Installer ##", :green
15
+ puts colorize "## --------------------------------- ##", :green
16
+ puts colorize "## Need help? support@appsignal.com ##", :green
17
+ puts colorize "## Docs? docs.appsignal.com ##", :green
18
+ puts colorize "#######################################", :green
19
+ puts
20
+ unless push_api_key
21
+ puts colorize 'Problem encountered:', :red
22
+ puts ' No push api key entered.'
23
+ puts ' - Sign up for AppSignal and follow the instructions'
24
+ puts " - Already signed up? Click 'new app' on the account overview"
25
+ puts
26
+ puts colorize 'Exiting installer...', :red
27
+ return false
28
+ end
29
+
30
+ config[:push_api_key] = push_api_key
31
+
32
+ print 'Validating api key'
33
+ periods
34
+ puts
35
+ begin
36
+ auth_check = Appsignal::AuthCheck.new(config)
37
+ unless auth_check.perform == '200'
38
+ puts "\n Api key '#{config[:push_api_key]}' is not valid, please get a new one on https://appsignal.com"
39
+ return false
40
+ end
41
+ rescue Exception => e
42
+ puts " There was an error validating your api key:"
43
+ puts colorize "'#{e}'", :red
44
+ puts " Please try again"
45
+ return false
46
+ end
47
+ puts colorize ' Api key valid!', :green
48
+ puts
49
+
50
+ if installed_frameworks.include?(:rails)
51
+ install_for_rails(config)
52
+ elsif installed_frameworks.include?(:sinatra) && !installed_frameworks.include?(:padrino)
53
+ install_for_sinatra(config)
54
+ elsif installed_frameworks.include?(:padrino)
55
+ install_for_padrino(config)
56
+ elsif installed_frameworks.include?(:grape)
57
+ install_for_grape(config)
58
+ else
59
+ puts "We could not detect which framework you are using. We'll be very grateful if you e-mail ons on support@appsignal.com with information about your setup."
60
+ return false
61
+ end
62
+
63
+ true
64
+ end
65
+
66
+ def install_for_rails(config)
67
+ require File.expand_path(File.join(ENV['PWD'], 'config/application.rb'))
68
+
69
+ puts 'Installing for Ruby on Rails'
70
+
71
+ config[:name] = Rails.application.class.parent_name
72
+
73
+ name_overwritten = yes_or_no(" Your app's name is: '#{config[:name]}' \n Do you want to change how this is displayed in AppSignal? (y/n): ")
74
+ puts
75
+ if name_overwritten
76
+ config[:name] = required_input(" Choose app's display name: ")
77
+ puts
78
+ end
79
+
80
+ configure(config, rails_environments, name_overwritten)
81
+ done_notice
82
+ end
83
+
84
+ def install_for_sinatra(config)
85
+ puts 'Installing for Sinatra'
86
+ config[:name] = required_input(' Enter application name: ')
87
+ puts
88
+ configure(config, ['production', 'staging'], true)
89
+
90
+ puts "Finish Sinatra configuration"
91
+ puts " Sinatra requires some manual configuration."
92
+ puts " Add this line beneath require 'sinatra':"
93
+ puts
94
+ puts " require 'appsignal/integrations/sinatra'"
95
+ press_any_key
96
+ puts "Configure subclass apps"
97
+ puts " If your app is a subclass of Sinatra::Base you need to use this middleware:"
98
+ puts
99
+ puts " use Appsignal::Rack::SinatraInstrumentation"
100
+ press_any_key
101
+ done_notice
102
+ end
103
+
104
+ def install_for_padrino(config)
105
+ puts 'Installing for Padrino'
106
+
107
+ config[:name] = required_input(' Enter application name: ')
108
+ puts
109
+
110
+ configure(config, ['production', 'staging'], true)
111
+
112
+ puts "Finish Padrino installation"
113
+ puts " Padrino requires some manual configuration."
114
+ puts " After installing the gem, add the following line to /config/boot.rb:"
115
+ puts
116
+ puts " require 'appsignal/integrations/padrino"
117
+ puts
118
+ puts " You can find more information in the documentation:"
119
+ puts " http://docs.appsignal.com/getting-started/supported-frameworks.html#padrino"
120
+ press_any_key
121
+ done_notice
122
+ end
123
+
124
+ def install_for_grape(config)
125
+ puts 'Installing for Grape'
126
+
127
+ config[:name] = required_input(' Enter application name: ')
128
+ puts
129
+
130
+ configure(config, ['production', 'staging'], true)
131
+
132
+ puts "Manual Grape configuration needed"
133
+ puts " See the installation instructions here:"
134
+ puts " http://docs.appsignal.com/getting-started/supported-frameworks.html#grape"
135
+ press_any_key
136
+ done_notice
137
+ end
138
+
139
+ def colorize(text, color)
140
+ return text if Gem.win_platform?
141
+ color_code = case color
142
+ when :red then 31
143
+ when :green then 32
144
+ when :yellow then 33
145
+ when :blue then 34
146
+ when :pink then 35
147
+ else 0
148
+ end
149
+ "\e[#{color_code}m#{text}\e[0m"
150
+ end
151
+
152
+ def periods
153
+ 3.times do
154
+ print "."
155
+ sleep(0.5)
156
+ end
157
+ end
158
+
159
+ def press_any_key
160
+ puts
161
+ print " Ready? Press any key:"
162
+ STDIN.getch
163
+ puts
164
+ puts
165
+ end
166
+
167
+ def yes_or_no(prompt)
168
+ loop do
169
+ print prompt
170
+ input = gets.chomp
171
+ if input == 'y'
172
+ return true
173
+ elsif input == 'n'
174
+ return false
175
+ end
176
+ end
177
+ end
178
+
179
+ def required_input(prompt)
180
+ loop do
181
+ print prompt
182
+ input = gets.chomp
183
+ if input.length > 0
184
+ return input
185
+ end
186
+ end
187
+ end
188
+
189
+ def configure(config, environments, name_overwritten)
190
+ puts "How do you want to configure AppSignal?"
191
+ puts " (1) a config file"
192
+ puts " (2) environment variables?"
193
+ loop do
194
+ print " Choose (1/2): "
195
+ input = gets.chomp
196
+ if input == '1'
197
+ puts
198
+ print "Writing config file"
199
+ periods
200
+ puts
201
+ puts colorize " Config file written to config/appsignal.yml", :green
202
+ write_config_file(
203
+ :push_api_key => config[:push_api_key],
204
+ :app_name => config[:name],
205
+ :environments => environments
206
+ )
207
+ puts
208
+ break
209
+ elsif input == '2'
210
+ puts
211
+ puts "Add the following environment variables to configure AppSignal:"
212
+ puts " export APPSIGNAL_ACTIVE=true"
213
+ puts " export APPSIGNAL_PUSH_API_KEY=#{config[:push_api_key]}"
214
+ if name_overwritten
215
+ puts " export APPSIGNAL_APP_NAME=#{config[:name]}"
216
+ end
217
+ puts
218
+ puts " See the documentation for more configuration options:"
219
+ puts " http://docs.appsignal.com/gem-settings/configuration.html"
220
+ press_any_key
221
+ break
222
+ end
223
+ end
224
+ end
225
+
226
+ def done_notice
227
+ sleep 0.3
228
+ puts colorize "#####################################", :green
229
+ puts colorize "## AppSignal installation complete ##", :green
230
+ puts colorize "#####################################", :green
231
+ sleep 0.3
232
+ puts
233
+ puts ' Now you need to send us some data!'
234
+ puts
235
+ if Gem.win_platform?
236
+ puts 'The AppSignal agent currently does not work on Windows, please push these changes to your test/staging/production environment'
237
+ else
238
+ puts " Run your app with AppSignal activated:"
239
+ puts " - You can do this on your dev environment"
240
+ puts " - Or deploy to staging or production"
241
+ puts
242
+ puts " Test if AppSignal is receiving data:"
243
+ puts " - Requests > 200ms are shown in AppSignal"
244
+ puts " - Generate an error to test (add .xml to any path!)"
245
+ puts
246
+ puts "Return to your browser and follow the instructions!"
247
+ end
248
+ end
249
+
250
+ def installed_frameworks
251
+ [].tap do |out|
252
+ begin
253
+ require 'rails'
254
+ out << :rails
255
+ rescue LoadError
256
+ end
257
+ begin
258
+ require 'sinatra'
259
+ out << :sinatra
260
+ rescue LoadError
261
+ end
262
+ begin
263
+ require 'padrino'
264
+ out << :padrino
265
+ rescue LoadError
266
+ end
267
+ begin
268
+ require 'grape'
269
+ out << :grape
270
+ rescue LoadError
271
+ end
272
+ end
273
+ end
274
+
275
+ def rails_environments
276
+ @environments ||= Dir.glob(
277
+ File.join(ENV['PWD'], 'config/environments/*.rb')
278
+ ).map { |o| File.basename(o, ".rb") }.sort - EXCLUDED_ENVIRONMENTS
279
+ end
280
+
281
+ def write_config_file(data)
282
+ template = ERB.new(
283
+ File.read(File.join(File.dirname(__FILE__), "../../../resources/appsignal.yml.erb")),
284
+ nil,
285
+ '-'
286
+ )
287
+
288
+ config = template.result(OpenStruct.new(data).instance_eval { binding })
289
+
290
+ FileUtils.mkdir_p(File.join(ENV['PWD'], 'config'))
291
+ File.write(File.join(ENV['PWD'], 'config/appsignal.yml'), config)
292
+ end
293
+ end
294
+ end
295
+ end
296
+ end