appsignal 2.5.0.alpha.1-java

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 (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