appsignal 2.5.0.alpha.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (211) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +33 -0
  3. data/.rspec +4 -0
  4. data/.rubocop.yml +66 -0
  5. data/.rubocop_todo.yml +124 -0
  6. data/.travis.yml +72 -0
  7. data/.yardopts +8 -0
  8. data/CHANGELOG.md +639 -0
  9. data/Gemfile +3 -0
  10. data/LICENSE +20 -0
  11. data/README.md +264 -0
  12. data/Rakefile +214 -0
  13. data/appsignal.gemspec +42 -0
  14. data/benchmark.rake +77 -0
  15. data/bin/appsignal +13 -0
  16. data/ext/Rakefile +27 -0
  17. data/ext/agent.yml +64 -0
  18. data/ext/appsignal_extension.c +692 -0
  19. data/ext/base.rb +79 -0
  20. data/ext/extconf.rb +35 -0
  21. data/gemfiles/capistrano2.gemfile +7 -0
  22. data/gemfiles/capistrano3.gemfile +7 -0
  23. data/gemfiles/grape.gemfile +7 -0
  24. data/gemfiles/no_dependencies.gemfile +5 -0
  25. data/gemfiles/padrino.gemfile +7 -0
  26. data/gemfiles/que.gemfile +5 -0
  27. data/gemfiles/rails-3.2.gemfile +6 -0
  28. data/gemfiles/rails-4.0.gemfile +6 -0
  29. data/gemfiles/rails-4.1.gemfile +6 -0
  30. data/gemfiles/rails-4.2.gemfile +10 -0
  31. data/gemfiles/rails-5.0.gemfile +5 -0
  32. data/gemfiles/rails-5.1.gemfile +5 -0
  33. data/gemfiles/resque.gemfile +12 -0
  34. data/gemfiles/sequel-435.gemfile +11 -0
  35. data/gemfiles/sequel.gemfile +11 -0
  36. data/gemfiles/sinatra.gemfile +6 -0
  37. data/gemfiles/webmachine.gemfile +5 -0
  38. data/lib/appsignal.rb +804 -0
  39. data/lib/appsignal/auth_check.rb +65 -0
  40. data/lib/appsignal/capistrano.rb +10 -0
  41. data/lib/appsignal/cli.rb +108 -0
  42. data/lib/appsignal/cli/demo.rb +63 -0
  43. data/lib/appsignal/cli/diagnose.rb +500 -0
  44. data/lib/appsignal/cli/helpers.rb +72 -0
  45. data/lib/appsignal/cli/install.rb +277 -0
  46. data/lib/appsignal/cli/notify_of_deploy.rb +113 -0
  47. data/lib/appsignal/config.rb +287 -0
  48. data/lib/appsignal/demo.rb +107 -0
  49. data/lib/appsignal/event_formatter.rb +74 -0
  50. data/lib/appsignal/event_formatter/action_view/render_formatter.rb +24 -0
  51. data/lib/appsignal/event_formatter/active_record/instantiation_formatter.rb +14 -0
  52. data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +14 -0
  53. data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +32 -0
  54. data/lib/appsignal/event_formatter/faraday/request_formatter.rb +19 -0
  55. data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +89 -0
  56. data/lib/appsignal/event_formatter/moped/query_formatter.rb +80 -0
  57. data/lib/appsignal/extension.rb +63 -0
  58. data/lib/appsignal/extension/jruby.rb +460 -0
  59. data/lib/appsignal/garbage_collection_profiler.rb +48 -0
  60. data/lib/appsignal/hooks.rb +105 -0
  61. data/lib/appsignal/hooks/action_cable.rb +113 -0
  62. data/lib/appsignal/hooks/active_support_notifications.rb +52 -0
  63. data/lib/appsignal/hooks/celluloid.rb +30 -0
  64. data/lib/appsignal/hooks/data_mapper.rb +18 -0
  65. data/lib/appsignal/hooks/delayed_job.rb +19 -0
  66. data/lib/appsignal/hooks/mongo_ruby_driver.rb +21 -0
  67. data/lib/appsignal/hooks/net_http.rb +29 -0
  68. data/lib/appsignal/hooks/passenger.rb +22 -0
  69. data/lib/appsignal/hooks/puma.rb +35 -0
  70. data/lib/appsignal/hooks/que.rb +21 -0
  71. data/lib/appsignal/hooks/rake.rb +39 -0
  72. data/lib/appsignal/hooks/redis.rb +30 -0
  73. data/lib/appsignal/hooks/sequel.rb +60 -0
  74. data/lib/appsignal/hooks/shoryuken.rb +43 -0
  75. data/lib/appsignal/hooks/sidekiq.rb +144 -0
  76. data/lib/appsignal/hooks/unicorn.rb +40 -0
  77. data/lib/appsignal/hooks/webmachine.rb +23 -0
  78. data/lib/appsignal/integrations/capistrano/appsignal.cap +39 -0
  79. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +52 -0
  80. data/lib/appsignal/integrations/data_mapper.rb +33 -0
  81. data/lib/appsignal/integrations/delayed_job_plugin.rb +54 -0
  82. data/lib/appsignal/integrations/grape.rb +53 -0
  83. data/lib/appsignal/integrations/mongo_ruby_driver.rb +55 -0
  84. data/lib/appsignal/integrations/object.rb +35 -0
  85. data/lib/appsignal/integrations/padrino.rb +84 -0
  86. data/lib/appsignal/integrations/que.rb +43 -0
  87. data/lib/appsignal/integrations/railtie.rb +41 -0
  88. data/lib/appsignal/integrations/rake.rb +2 -0
  89. data/lib/appsignal/integrations/resque.rb +20 -0
  90. data/lib/appsignal/integrations/resque_active_job.rb +30 -0
  91. data/lib/appsignal/integrations/sinatra.rb +17 -0
  92. data/lib/appsignal/integrations/webmachine.rb +38 -0
  93. data/lib/appsignal/js_exception_transaction.rb +54 -0
  94. data/lib/appsignal/marker.rb +63 -0
  95. data/lib/appsignal/minutely.rb +42 -0
  96. data/lib/appsignal/rack/generic_instrumentation.rb +49 -0
  97. data/lib/appsignal/rack/js_exception_catcher.rb +70 -0
  98. data/lib/appsignal/rack/rails_instrumentation.rb +51 -0
  99. data/lib/appsignal/rack/sinatra_instrumentation.rb +99 -0
  100. data/lib/appsignal/rack/streaming_listener.rb +73 -0
  101. data/lib/appsignal/system.rb +81 -0
  102. data/lib/appsignal/transaction.rb +498 -0
  103. data/lib/appsignal/transmitter.rb +107 -0
  104. data/lib/appsignal/utils.rb +127 -0
  105. data/lib/appsignal/utils/params_sanitizer.rb +59 -0
  106. data/lib/appsignal/utils/query_params_sanitizer.rb +55 -0
  107. data/lib/appsignal/version.rb +3 -0
  108. data/lib/sequel/extensions/appsignal_integration.rb +3 -0
  109. data/resources/appsignal.yml.erb +39 -0
  110. data/resources/cacert.pem +3866 -0
  111. data/spec/.rubocop.yml +7 -0
  112. data/spec/lib/appsignal/auth_check_spec.rb +80 -0
  113. data/spec/lib/appsignal/capistrano2_spec.rb +224 -0
  114. data/spec/lib/appsignal/capistrano3_spec.rb +237 -0
  115. data/spec/lib/appsignal/cli/demo_spec.rb +67 -0
  116. data/spec/lib/appsignal/cli/diagnose_spec.rb +988 -0
  117. data/spec/lib/appsignal/cli/helpers_spec.rb +171 -0
  118. data/spec/lib/appsignal/cli/install_spec.rb +632 -0
  119. data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +168 -0
  120. data/spec/lib/appsignal/cli_spec.rb +56 -0
  121. data/spec/lib/appsignal/config_spec.rb +637 -0
  122. data/spec/lib/appsignal/demo_spec.rb +87 -0
  123. data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +44 -0
  124. data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +21 -0
  125. data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +21 -0
  126. data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +52 -0
  127. data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +21 -0
  128. data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +113 -0
  129. data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +112 -0
  130. data/spec/lib/appsignal/event_formatter_spec.rb +100 -0
  131. data/spec/lib/appsignal/extension/jruby_spec.rb +43 -0
  132. data/spec/lib/appsignal/extension_spec.rb +137 -0
  133. data/spec/lib/appsignal/garbage_collection_profiler_spec.rb +66 -0
  134. data/spec/lib/appsignal/hooks/action_cable_spec.rb +370 -0
  135. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +92 -0
  136. data/spec/lib/appsignal/hooks/celluloid_spec.rb +35 -0
  137. data/spec/lib/appsignal/hooks/data_mapper_spec.rb +39 -0
  138. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +358 -0
  139. data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +44 -0
  140. data/spec/lib/appsignal/hooks/net_http_spec.rb +53 -0
  141. data/spec/lib/appsignal/hooks/passenger_spec.rb +30 -0
  142. data/spec/lib/appsignal/hooks/puma_spec.rb +80 -0
  143. data/spec/lib/appsignal/hooks/que_spec.rb +19 -0
  144. data/spec/lib/appsignal/hooks/rake_spec.rb +73 -0
  145. data/spec/lib/appsignal/hooks/redis_spec.rb +55 -0
  146. data/spec/lib/appsignal/hooks/sequel_spec.rb +46 -0
  147. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +192 -0
  148. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +419 -0
  149. data/spec/lib/appsignal/hooks/unicorn_spec.rb +52 -0
  150. data/spec/lib/appsignal/hooks/webmachine_spec.rb +35 -0
  151. data/spec/lib/appsignal/hooks_spec.rb +195 -0
  152. data/spec/lib/appsignal/integrations/data_mapper_spec.rb +65 -0
  153. data/spec/lib/appsignal/integrations/grape_spec.rb +225 -0
  154. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +127 -0
  155. data/spec/lib/appsignal/integrations/object_spec.rb +249 -0
  156. data/spec/lib/appsignal/integrations/padrino_spec.rb +323 -0
  157. data/spec/lib/appsignal/integrations/que_spec.rb +174 -0
  158. data/spec/lib/appsignal/integrations/railtie_spec.rb +129 -0
  159. data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +83 -0
  160. data/spec/lib/appsignal/integrations/resque_spec.rb +92 -0
  161. data/spec/lib/appsignal/integrations/sinatra_spec.rb +73 -0
  162. data/spec/lib/appsignal/integrations/webmachine_spec.rb +69 -0
  163. data/spec/lib/appsignal/js_exception_transaction_spec.rb +128 -0
  164. data/spec/lib/appsignal/marker_spec.rb +51 -0
  165. data/spec/lib/appsignal/minutely_spec.rb +50 -0
  166. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +90 -0
  167. data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +147 -0
  168. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +117 -0
  169. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +213 -0
  170. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +161 -0
  171. data/spec/lib/appsignal/system_spec.rb +131 -0
  172. data/spec/lib/appsignal/transaction_spec.rb +1146 -0
  173. data/spec/lib/appsignal/transmitter_spec.rb +152 -0
  174. data/spec/lib/appsignal/utils/params_sanitizer_spec.rb +136 -0
  175. data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +192 -0
  176. data/spec/lib/appsignal/utils_spec.rb +150 -0
  177. data/spec/lib/appsignal_spec.rb +1049 -0
  178. data/spec/spec_helper.rb +116 -0
  179. data/spec/support/fixtures/containers/cgroups/docker +14 -0
  180. data/spec/support/fixtures/containers/cgroups/docker_systemd +8 -0
  181. data/spec/support/fixtures/containers/cgroups/lxc +10 -0
  182. data/spec/support/fixtures/containers/cgroups/no_permission +0 -0
  183. data/spec/support/fixtures/containers/cgroups/none +1 -0
  184. data/spec/support/fixtures/generated_config.yml +24 -0
  185. data/spec/support/fixtures/uploaded_file.txt +0 -0
  186. data/spec/support/helpers/api_request_helper.rb +19 -0
  187. data/spec/support/helpers/cli_helpers.rb +26 -0
  188. data/spec/support/helpers/config_helpers.rb +21 -0
  189. data/spec/support/helpers/dependency_helper.rb +73 -0
  190. data/spec/support/helpers/directory_helper.rb +27 -0
  191. data/spec/support/helpers/env_helpers.rb +33 -0
  192. data/spec/support/helpers/example_exception.rb +13 -0
  193. data/spec/support/helpers/example_standard_error.rb +13 -0
  194. data/spec/support/helpers/log_helpers.rb +22 -0
  195. data/spec/support/helpers/std_streams_helper.rb +66 -0
  196. data/spec/support/helpers/system_helpers.rb +8 -0
  197. data/spec/support/helpers/time_helpers.rb +11 -0
  198. data/spec/support/helpers/transaction_helpers.rb +37 -0
  199. data/spec/support/matchers/contains_log.rb +7 -0
  200. data/spec/support/mocks/fake_gc_profiler.rb +19 -0
  201. data/spec/support/mocks/mock_extension.rb +6 -0
  202. data/spec/support/project_fixture/config/application.rb +0 -0
  203. data/spec/support/project_fixture/config/appsignal.yml +32 -0
  204. data/spec/support/project_fixture/config/environments/development.rb +0 -0
  205. data/spec/support/project_fixture/config/environments/production.rb +0 -0
  206. data/spec/support/project_fixture/config/environments/test.rb +0 -0
  207. data/spec/support/project_fixture/log/.gitkeep +0 -0
  208. data/spec/support/rails/my_app.rb +6 -0
  209. data/spec/support/shared_examples/instrument.rb +43 -0
  210. data/spec/support/stubs/delayed_job.rb +0 -0
  211. metadata +483 -0
@@ -0,0 +1,72 @@
1
+ module Appsignal
2
+ class CLI
3
+ module Helpers
4
+ private
5
+
6
+ def colorize(text, color)
7
+ return text if Gem.win_platform?
8
+
9
+ color_code =
10
+ case color
11
+ when :red then 31
12
+ when :green then 32
13
+ when :yellow then 33
14
+ when :blue then 34
15
+ when :pink then 35
16
+ else 0
17
+ end
18
+
19
+ "\e[#{color_code}m#{text}\e[0m"
20
+ end
21
+
22
+ def periods
23
+ 3.times do
24
+ print "."
25
+ sleep 0.5
26
+ end
27
+ end
28
+
29
+ def press_any_key
30
+ puts
31
+ print " Ready? Press any key:"
32
+ stdin.getc
33
+ puts
34
+ puts
35
+ end
36
+
37
+ def ask_for_input
38
+ value = stdin.gets
39
+ value ? value.chomp : ""
40
+ rescue Interrupt
41
+ puts "\nExiting..."
42
+ exit 1
43
+ end
44
+
45
+ def required_input(prompt)
46
+ loop do
47
+ print prompt
48
+ value = ask_for_input
49
+ return value unless value.empty?
50
+ end
51
+ end
52
+
53
+ def yes_or_no(prompt, options = {})
54
+ loop do
55
+ print prompt
56
+ input = ask_for_input.strip
57
+ input = options[:default] if input.empty? && options[:default]
58
+ case input
59
+ when "y", "Y", "yes"
60
+ return true
61
+ when "n", "N", "no"
62
+ return false
63
+ end
64
+ end
65
+ end
66
+
67
+ def stdin
68
+ $stdin
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,277 @@
1
+ require "erb"
2
+ require "ostruct"
3
+ require "io/console"
4
+ require "appsignal/demo"
5
+
6
+ module Appsignal
7
+ class CLI
8
+ class Install
9
+ extend CLI::Helpers
10
+
11
+ EXCLUDED_ENVIRONMENTS = ["test"].freeze
12
+
13
+ class << self
14
+ def run(push_api_key)
15
+ $stdout.sync = true
16
+
17
+ puts
18
+ puts colorize "#######################################", :green
19
+ puts colorize "## Starting AppSignal Installer ##", :green
20
+ puts colorize "## --------------------------------- ##", :green
21
+ puts colorize "## Need help? support@appsignal.com ##", :green
22
+ puts colorize "## Docs? docs.appsignal.com ##", :green
23
+ puts colorize "#######################################", :green
24
+ puts
25
+ unless push_api_key
26
+ puts colorize "Problem encountered:", :red
27
+ puts " No push API key entered."
28
+ puts " - Sign up for AppSignal and follow the instructions"
29
+ puts " - Already signed up? Click 'Add app' on the account overview page"
30
+ puts
31
+ puts colorize "Exiting installer...", :red
32
+ return
33
+ end
34
+ config = new_config
35
+ config[:push_api_key] = push_api_key
36
+
37
+ print "Validating API key"
38
+ periods
39
+ puts
40
+ begin
41
+ auth_check = Appsignal::AuthCheck.new(config)
42
+ unless auth_check.perform == "200"
43
+ puts "\n API key '#{config[:push_api_key]}' is not valid, please get a new one on https://appsignal.com"
44
+ return
45
+ end
46
+ rescue => e
47
+ puts " There was an error validating your API key:"
48
+ puts colorize "'#{e}'", :red
49
+ puts " Please try again"
50
+ return
51
+ end
52
+ puts colorize " API key valid!", :green
53
+ puts
54
+
55
+ if installed_frameworks.include?(:rails)
56
+ install_for_rails(config)
57
+ elsif installed_frameworks.include?(:padrino)
58
+ install_for_padrino(config)
59
+ elsif installed_frameworks.include?(:grape)
60
+ install_for_grape(config)
61
+ elsif installed_frameworks.include?(:sinatra)
62
+ install_for_sinatra(config)
63
+ else
64
+ print colorize "Warning:", :red
65
+ puts " We could not detect which framework you are using. "\
66
+ "We'd be very grateful if you email us on support@appsignal.com "\
67
+ "with information about your setup."
68
+ puts
69
+ done_notice
70
+ end
71
+ end
72
+
73
+ def install_for_rails(config)
74
+ require File.expand_path(File.join(Dir.pwd, "config/application.rb"))
75
+
76
+ puts "Installing for Ruby on Rails"
77
+
78
+ config[:name] = Rails.application.class.parent_name
79
+
80
+ 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): ")
81
+ puts
82
+ if name_overwritten
83
+ config[:name] = required_input(" Choose app's display name: ")
84
+ puts
85
+ end
86
+
87
+ configure(config, rails_environments, name_overwritten)
88
+ done_notice
89
+ end
90
+
91
+ def install_for_sinatra(config)
92
+ puts "Installing for Sinatra"
93
+ config[:name] = required_input(" Enter application name: ")
94
+ puts
95
+ configure(config, %w[development production staging], true)
96
+
97
+ puts "Finish Sinatra configuration"
98
+ puts " Sinatra requires some manual configuration."
99
+ puts " Add this line beneath require 'sinatra':"
100
+ puts
101
+ puts " require 'appsignal/integrations/sinatra'"
102
+ puts
103
+ puts " You can find more information in the documentation:"
104
+ puts " http://docs.appsignal.com/ruby/integrations/sinatra.html"
105
+ press_any_key
106
+ done_notice
107
+ end
108
+
109
+ def install_for_padrino(config)
110
+ puts "Installing for Padrino"
111
+ config[:name] = required_input(" Enter application name: ")
112
+ puts
113
+ configure(config, %w[development production staging], true)
114
+
115
+ puts "Finish Padrino installation"
116
+ puts " Padrino requires some manual configuration."
117
+ puts " After installing the gem, add the following line to /config/boot.rb:"
118
+ puts
119
+ puts " require 'appsignal/integrations/padrino"
120
+ puts
121
+ puts " You can find more information in the documentation:"
122
+ puts " http://docs.appsignal.com/ruby/integrations/padrino.html"
123
+ press_any_key
124
+ done_notice
125
+ end
126
+
127
+ def install_for_grape(config)
128
+ puts "Installing for Grape"
129
+
130
+ config[:name] = required_input(" Enter application name: ")
131
+ puts
132
+
133
+ configure(config, %w[development production staging], true)
134
+
135
+ puts "Manual Grape configuration needed"
136
+ puts " See the installation instructions at:"
137
+ puts " http://docs.appsignal.com/ruby/integrations/grape.html"
138
+ press_any_key
139
+ done_notice
140
+ end
141
+
142
+ def install_for_capistrano
143
+ capfile = File.join(Dir.pwd, "Capfile")
144
+ return unless File.exist?(capfile)
145
+ return if File.read(capfile) =~ %r{require ['|"]appsignal/capistrano}
146
+
147
+ puts "Installing for Capistrano"
148
+ print " Adding AppSignal integration to Capfile"
149
+ File.open(capfile, "a") do |f|
150
+ f.write "\nrequire 'appsignal/capistrano'\n"
151
+ end
152
+ periods
153
+ puts
154
+ puts
155
+ end
156
+
157
+ def configure(config, environments, name_overwritten)
158
+ install_for_capistrano
159
+
160
+ ENV["APPSIGNAL_APP_ENV"] = "development"
161
+
162
+ puts "How do you want to configure AppSignal?"
163
+ puts " (1) a config file"
164
+ puts " (2) environment variables"
165
+ loop do
166
+ print " Choose (1/2): "
167
+ case ask_for_input
168
+ when "1"
169
+ puts
170
+ print "Writing config file"
171
+ periods
172
+ puts
173
+ puts colorize " Config file written to config/appsignal.yml", :green
174
+ write_config_file(
175
+ :push_api_key => config[:push_api_key],
176
+ :app_name => config[:name],
177
+ :environments => environments
178
+ )
179
+ puts
180
+ break
181
+ when "2"
182
+ ENV["APPSIGNAL_ACTIVE"] = "true"
183
+ ENV["APPSIGNAL_PUSH_API_KEY"] = config[:push_api_key]
184
+ ENV["APPSIGNAL_APP_NAME"] = config[:name]
185
+
186
+ puts
187
+ puts "Add the following environment variables to configure AppSignal:"
188
+ puts " export APPSIGNAL_PUSH_API_KEY=#{config[:push_api_key]}"
189
+ if name_overwritten
190
+ puts " export APPSIGNAL_APP_NAME=#{config[:name]}"
191
+ end
192
+ puts
193
+ puts " See the documentation for more configuration options:"
194
+ puts " http://docs.appsignal.com/gem-settings/configuration.html"
195
+ press_any_key
196
+ break
197
+ end
198
+ end
199
+ end
200
+
201
+ def done_notice
202
+ sleep 0.3
203
+ puts colorize "#####################################", :green
204
+ puts colorize "## AppSignal installation complete ##", :green
205
+ puts colorize "#####################################", :green
206
+ sleep 0.3
207
+ puts
208
+ if Gem.win_platform?
209
+ puts "The AppSignal agent currently does not work on Microsoft " \
210
+ "Windows. Please push these changes to your staging/production " \
211
+ "environment and make sure some actions are performed. " \
212
+ "AppSignal should pick up your app after a few minutes."
213
+ else
214
+ puts " Sending example data to AppSignal..."
215
+ if Appsignal::Demo.transmit
216
+ puts " Example data sent!"
217
+ puts " It may take about a minute for the data to appear on https://appsignal.com/accounts"
218
+ puts
219
+ puts " Please return to your browser and follow the instructions."
220
+ else
221
+ puts " Couldn't start the AppSignal agent and send example data to AppSignal.com"
222
+ puts " Please use `appsignal diagnose` to debug your configuration."
223
+ end
224
+ end
225
+ end
226
+
227
+ def installed_frameworks
228
+ [].tap do |out|
229
+ begin
230
+ require "rails"
231
+ out << :rails
232
+ rescue LoadError
233
+ end
234
+ begin
235
+ require "sinatra"
236
+ out << :sinatra
237
+ rescue LoadError
238
+ end
239
+ begin
240
+ require "padrino"
241
+ out << :padrino
242
+ rescue LoadError
243
+ end
244
+ begin
245
+ require "grape"
246
+ out << :grape
247
+ rescue LoadError
248
+ end
249
+ end
250
+ end
251
+
252
+ def rails_environments
253
+ Dir.glob(
254
+ File.join(Dir.pwd, "config/environments/*.rb")
255
+ ).map { |o| File.basename(o, ".rb") }.sort - EXCLUDED_ENVIRONMENTS
256
+ end
257
+
258
+ def write_config_file(data)
259
+ template = ERB.new(
260
+ File.read(File.join(File.dirname(__FILE__), "../../../resources/appsignal.yml.erb")),
261
+ nil,
262
+ "-"
263
+ )
264
+
265
+ config = template.result(OpenStruct.new(data).instance_eval { binding })
266
+
267
+ FileUtils.mkdir_p(File.join(Dir.pwd, "config"))
268
+ File.write(File.join(Dir.pwd, "config/appsignal.yml"), config)
269
+ end
270
+
271
+ def new_config
272
+ Appsignal::Config.new(Dir.pwd, "")
273
+ end
274
+ end
275
+ end
276
+ end
277
+ end
@@ -0,0 +1,113 @@
1
+ module Appsignal
2
+ class CLI
3
+ # Command line tool to send a "Deploy Marker" for an application to
4
+ # AppSignal.
5
+ #
6
+ # Deploy markers are used on AppSignal.com to indicate changes in an
7
+ # application, "Deploy markers" indicate a deploy of an application.
8
+ #
9
+ # Incidents for exceptions and performance issues will be closed and
10
+ # reopened if they occur again in the new deploy.
11
+ #
12
+ # @note The same logic is used in the Capistrano integration. A deploy
13
+ # marker is created on each deploy.
14
+ #
15
+ # ## Options
16
+ #
17
+ # - `--environment` required. The environment of the application being
18
+ # deployed.
19
+ # - `--user` required. User that triggered the deploy.
20
+ # - `--revision` required. Git commit SHA or other identifiable revision id.
21
+ # - `--name` If no "name" config can be found in a `config/appsignal.yml`
22
+ # file or based on the `APPSIGNAL_APP_NAME` environment variable, this
23
+ # option is required.
24
+ #
25
+ # ## Exit codes
26
+ #
27
+ # - Exits with status code `0` if the deploy marker is sent.
28
+ # - Exits with status code `1` if the configuration is not valid and active.
29
+ # - Exits with status code `1` if the required options aren't present.
30
+ #
31
+ # @example basic example
32
+ # appsignal notify_of_deploy \
33
+ # --user=tom \
34
+ # --environment=production \
35
+ # --revision=abc1234
36
+ #
37
+ # @example using a custom app name
38
+ # appsignal notify_of_deploy \
39
+ # --user=tom \
40
+ # --environment=production \
41
+ # --revision=abc1234 \
42
+ # --name="My app"
43
+ #
44
+ # @example help command
45
+ # appsignal notify_of_deploy --help
46
+ #
47
+ # @since 0.2.5
48
+ # @see Appsignal::Marker Appsignal::Marker
49
+ # @see http://docs.appsignal.com/ruby/command-line/notify_of_deploy.html
50
+ # AppSignal notify_of_deploy documentation
51
+ # @see http://docs.appsignal.com/appsignal/terminology.html#markers
52
+ # Terminology: Deploy marker
53
+ class NotifyOfDeploy
54
+ class << self
55
+ # @param options [Hash]
56
+ # @option options :environment [String] environment to load
57
+ # configuration for.
58
+ # @option options :name [String] custom name of the application.
59
+ # @option options :user [String] user who triggered the deploy.
60
+ # @option options :revision [String] the revision that has been
61
+ # deployed. E.g. a git commit SHA.
62
+ # @return [void]
63
+ def run(options)
64
+ config = config_for(options[:environment])
65
+ config[:name] = options[:name] if options[:name]
66
+
67
+ validate_active_config(config)
68
+ required_config = [:revision, :user]
69
+ required_config << :environment if config.env.empty?
70
+ required_config << :name if !config[:name] || config[:name].empty?
71
+ validate_required_options(options, required_config)
72
+
73
+ Appsignal::Marker.new(
74
+ {
75
+ :revision => options[:revision],
76
+ :user => options[:user]
77
+ },
78
+ config
79
+ ).transmit
80
+ end
81
+
82
+ private
83
+
84
+ def validate_required_options(options, required_options)
85
+ missing = required_options.select do |required_option|
86
+ val = options[required_option]
87
+ val.nil? || (val.respond_to?(:empty?) && val.empty?)
88
+ end
89
+ return unless missing.any?
90
+
91
+ puts "Error: Missing options: #{missing.join(", ")}"
92
+ exit 1
93
+ end
94
+
95
+ def validate_active_config(config)
96
+ return if config.active?
97
+
98
+ puts "Error: No valid config found."
99
+ exit 1
100
+ end
101
+
102
+ def config_for(environment)
103
+ Appsignal::Config.new(
104
+ Dir.pwd,
105
+ environment,
106
+ {},
107
+ Logger.new(StringIO.new)
108
+ )
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end