appsignal 2.1.2 → 2.2.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +14 -0
  3. data/.rubocop_todo.yml +16 -171
  4. data/.travis.yml +14 -1
  5. data/.yardopts +8 -0
  6. data/CHANGELOG.md +21 -3
  7. data/README.md +20 -2
  8. data/Rakefile +60 -62
  9. data/appsignal.gemspec +24 -23
  10. data/ext/agent.yml +11 -11
  11. data/ext/appsignal_extension.c +43 -12
  12. data/ext/extconf.rb +9 -9
  13. data/gemfiles/padrino.gemfile +1 -1
  14. data/lib/appsignal.rb +403 -26
  15. data/lib/appsignal/auth_check.rb +28 -1
  16. data/lib/appsignal/cli.rb +1 -0
  17. data/lib/appsignal/cli/demo.rb +40 -0
  18. data/lib/appsignal/cli/diagnose.rb +345 -89
  19. data/lib/appsignal/cli/helpers.rb +9 -4
  20. data/lib/appsignal/cli/install.rb +6 -6
  21. data/lib/appsignal/cli/notify_of_deploy.rb +58 -0
  22. data/lib/appsignal/config.rb +40 -38
  23. data/lib/appsignal/demo.rb +20 -0
  24. data/lib/appsignal/event_formatter.rb +4 -0
  25. data/lib/appsignal/event_formatter/action_view/render_formatter.rb +1 -0
  26. data/lib/appsignal/event_formatter/active_record/instantiation_formatter.rb +1 -0
  27. data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +1 -0
  28. data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +1 -0
  29. data/lib/appsignal/event_formatter/faraday/request_formatter.rb +1 -0
  30. data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +2 -1
  31. data/lib/appsignal/event_formatter/moped/query_formatter.rb +1 -0
  32. data/lib/appsignal/extension.rb +1 -0
  33. data/lib/appsignal/garbage_collection_profiler.rb +20 -19
  34. data/lib/appsignal/hooks.rb +1 -0
  35. data/lib/appsignal/hooks/active_support_notifications.rb +1 -0
  36. data/lib/appsignal/hooks/celluloid.rb +1 -0
  37. data/lib/appsignal/hooks/data_mapper.rb +1 -0
  38. data/lib/appsignal/hooks/delayed_job.rb +1 -0
  39. data/lib/appsignal/hooks/mongo_ruby_driver.rb +1 -0
  40. data/lib/appsignal/hooks/net_http.rb +1 -0
  41. data/lib/appsignal/hooks/passenger.rb +1 -0
  42. data/lib/appsignal/hooks/puma.rb +1 -0
  43. data/lib/appsignal/hooks/rake.rb +1 -0
  44. data/lib/appsignal/hooks/redis.rb +1 -0
  45. data/lib/appsignal/hooks/sequel.rb +1 -0
  46. data/lib/appsignal/hooks/shoryuken.rb +1 -0
  47. data/lib/appsignal/hooks/sidekiq.rb +1 -0
  48. data/lib/appsignal/hooks/unicorn.rb +1 -0
  49. data/lib/appsignal/hooks/webmachine.rb +1 -0
  50. data/lib/appsignal/integrations/capistrano/appsignal.cap +4 -4
  51. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +2 -0
  52. data/lib/appsignal/integrations/data_mapper.rb +1 -1
  53. data/lib/appsignal/integrations/delayed_job_plugin.rb +1 -0
  54. data/lib/appsignal/integrations/grape.rb +3 -1
  55. data/lib/appsignal/integrations/mongo_ruby_driver.rb +1 -0
  56. data/lib/appsignal/integrations/padrino.rb +36 -21
  57. data/lib/appsignal/integrations/railtie.rb +2 -2
  58. data/lib/appsignal/integrations/resque.rb +1 -0
  59. data/lib/appsignal/integrations/resque_active_job.rb +1 -0
  60. data/lib/appsignal/integrations/webmachine.rb +27 -24
  61. data/lib/appsignal/js_exception_transaction.rb +8 -8
  62. data/lib/appsignal/marker.rb +41 -4
  63. data/lib/appsignal/minutely.rb +1 -0
  64. data/lib/appsignal/rack/generic_instrumentation.rb +3 -2
  65. data/lib/appsignal/rack/js_exception_catcher.rb +55 -15
  66. data/lib/appsignal/rack/rails_instrumentation.rb +2 -1
  67. data/lib/appsignal/rack/sinatra_instrumentation.rb +4 -2
  68. data/lib/appsignal/rack/streaming_listener.rb +4 -2
  69. data/lib/appsignal/system.rb +5 -31
  70. data/lib/appsignal/transaction.rb +71 -6
  71. data/lib/appsignal/transmitter.rb +24 -13
  72. data/lib/appsignal/utils.rb +18 -11
  73. data/lib/appsignal/utils/params_sanitizer.rb +2 -1
  74. data/lib/appsignal/utils/query_params_sanitizer.rb +1 -0
  75. data/lib/appsignal/version.rb +1 -1
  76. data/resources/appsignal.yml.erb +1 -1
  77. data/spec/lib/appsignal/auth_check_spec.rb +64 -22
  78. data/spec/lib/appsignal/cli/diagnose_spec.rb +539 -81
  79. data/spec/lib/appsignal/cli/helpers_spec.rb +74 -2
  80. data/spec/lib/appsignal/cli/install_spec.rb +3 -3
  81. data/spec/lib/appsignal/config_spec.rb +38 -72
  82. data/spec/lib/appsignal/demo_spec.rb +2 -2
  83. data/spec/lib/appsignal/event_formatter_spec.rb +2 -2
  84. data/spec/lib/appsignal/extension_spec.rb +4 -0
  85. data/spec/lib/appsignal/garbage_collection_profiler_spec.rb +18 -21
  86. data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +1 -1
  87. data/spec/lib/appsignal/hooks/redis_spec.rb +34 -44
  88. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +2 -2
  89. data/spec/lib/appsignal/integrations/grape_spec.rb +6 -6
  90. data/spec/lib/appsignal/integrations/padrino_spec.rb +241 -122
  91. data/spec/lib/appsignal/integrations/railtie_spec.rb +34 -16
  92. data/spec/lib/appsignal/integrations/resque_spec.rb +1 -1
  93. data/spec/lib/appsignal/integrations/sinatra_spec.rb +38 -10
  94. data/spec/lib/appsignal/integrations/webmachine_spec.rb +2 -2
  95. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +7 -6
  96. data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +95 -58
  97. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +9 -6
  98. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +11 -10
  99. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +20 -13
  100. data/spec/lib/appsignal/system_spec.rb +2 -32
  101. data/spec/lib/appsignal/transaction_spec.rb +48 -7
  102. data/spec/lib/appsignal/transmitter_spec.rb +52 -33
  103. data/spec/lib/appsignal/utils/params_sanitizer_spec.rb +3 -1
  104. data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +3 -3
  105. data/spec/lib/appsignal/utils_spec.rb +49 -6
  106. data/spec/lib/appsignal_spec.rb +60 -5
  107. data/spec/spec_helper.rb +4 -3
  108. data/spec/support/helpers/api_request_helper.rb +1 -4
  109. data/spec/support/helpers/dependency_helper.rb +4 -0
  110. data/spec/support/helpers/system_helpers.rb +1 -17
  111. data/spec/support/helpers/time_helpers.rb +1 -1
  112. metadata +19 -8
  113. data/spec/lib/appsignal/system/container_spec.rb +0 -67
  114. data/spec/lib/appsignal/utils/gzip_spec.rb +0 -10
@@ -37,6 +37,9 @@ module Appsignal
37
37
  def ask_for_input
38
38
  value = stdin.gets
39
39
  value ? value.chomp : ""
40
+ rescue Interrupt
41
+ puts "\nExiting..."
42
+ exit 1
40
43
  end
41
44
 
42
45
  def required_input(prompt)
@@ -47,13 +50,15 @@ module Appsignal
47
50
  end
48
51
  end
49
52
 
50
- def yes_or_no(prompt)
53
+ def yes_or_no(prompt, options = {})
51
54
  loop do
52
55
  print prompt
53
- case ask_for_input
54
- when "y"
56
+ input = ask_for_input.strip
57
+ input = options[:default] if input.empty? && options[:default]
58
+ case input
59
+ when "y", "Y", "yes"
55
60
  return true
56
- when "n"
61
+ when "n", "N", "no"
57
62
  return false
58
63
  end
59
64
  end
@@ -85,7 +85,7 @@ module Appsignal
85
85
  puts "Installing for Sinatra"
86
86
  config[:name] = required_input(" Enter application name: ")
87
87
  puts
88
- configure(config, ["development", "production", "staging"], true)
88
+ configure(config, %w(development production staging), true)
89
89
 
90
90
  puts "Finish Sinatra configuration"
91
91
  puts " Sinatra requires some manual configuration."
@@ -94,7 +94,7 @@ module Appsignal
94
94
  puts " require 'appsignal/integrations/sinatra'"
95
95
  puts
96
96
  puts " You can find more information in the documentation:"
97
- puts " http://docs.appsignal.com/getting-started/supported-frameworks.html#sinatra"
97
+ puts " http://docs.appsignal.com/ruby/integrations/sinatra.html"
98
98
  press_any_key
99
99
  done_notice
100
100
  end
@@ -103,7 +103,7 @@ module Appsignal
103
103
  puts "Installing for Padrino"
104
104
  config[:name] = required_input(" Enter application name: ")
105
105
  puts
106
- configure(config, ["development", "production", "staging"], true)
106
+ configure(config, %w(development production staging), true)
107
107
 
108
108
  puts "Finish Padrino installation"
109
109
  puts " Padrino requires some manual configuration."
@@ -112,7 +112,7 @@ module Appsignal
112
112
  puts " require 'appsignal/integrations/padrino"
113
113
  puts
114
114
  puts " You can find more information in the documentation:"
115
- puts " http://docs.appsignal.com/getting-started/supported-frameworks.html#padrino"
115
+ puts " http://docs.appsignal.com/ruby/integrations/padrino.html"
116
116
  press_any_key
117
117
  done_notice
118
118
  end
@@ -123,11 +123,11 @@ module Appsignal
123
123
  config[:name] = required_input(" Enter application name: ")
124
124
  puts
125
125
 
126
- configure(config, ["development", "production", "staging"], true)
126
+ configure(config, %w(development production staging), true)
127
127
 
128
128
  puts "Manual Grape configuration needed"
129
129
  puts " See the installation instructions at:"
130
- puts " http://docs.appsignal.com/getting-started/supported-frameworks.html#grape"
130
+ puts " http://docs.appsignal.com/ruby/integrations/grape.html"
131
131
  press_any_key
132
132
  done_notice
133
133
  end
@@ -1,7 +1,65 @@
1
1
  module Appsignal
2
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
3
53
  class NotifyOfDeploy
4
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]
5
63
  def run(options)
6
64
  config = config_for(options[:environment])
7
65
  config[:name] = options[:name] if options[:name]
@@ -22,11 +22,11 @@ module Appsignal
22
22
  :frontend_error_catching_path => "/appsignal_error_catcher",
23
23
  :enable_allocation_tracking => true,
24
24
  :enable_gc_instrumentation => false,
25
- :running_in_container => false,
26
25
  :enable_host_metrics => true,
27
26
  :enable_minutely_probes => false,
28
27
  :hostname => ::Socket.gethostname,
29
- :ca_file_path => File.expand_path(File.join("../../../resources/cacert.pem"), __FILE__)
28
+ :ca_file_path => File.expand_path(File.join("../../../resources/cacert.pem"), __FILE__),
29
+ :dns_servers => []
30
30
  }.freeze
31
31
 
32
32
  ENV_TO_KEY_MAPPING = {
@@ -55,7 +55,8 @@ module Appsignal
55
55
  "APPSIGNAL_ENABLE_HOST_METRICS" => :enable_host_metrics,
56
56
  "APPSIGNAL_ENABLE_MINUTELY_PROBES" => :enable_minutely_probes,
57
57
  "APPSIGNAL_HOSTNAME" => :hostname,
58
- "APPSIGNAL_CA_FILE_PATH" => :ca_file_path
58
+ "APPSIGNAL_CA_FILE_PATH" => :ca_file_path,
59
+ "APPSIGNAL_DNS_SERVERS" => :dns_servers
59
60
  }.freeze
60
61
 
61
62
  attr_reader :root_path, :env, :initial_config, :config_hash
@@ -115,33 +116,35 @@ module Appsignal
115
116
  @valid && config_hash[:active]
116
117
  end
117
118
 
118
- def write_to_environment
119
- ENV["APPSIGNAL_ACTIVE"] = active?.to_s
120
- ENV["APPSIGNAL_APP_PATH"] = root_path.to_s
121
- ENV["APPSIGNAL_AGENT_PATH"] = File.expand_path("../../../ext", __FILE__).to_s
122
- ENV["APPSIGNAL_ENVIRONMENT"] = env
123
- ENV["APPSIGNAL_AGENT_VERSION"] = Appsignal::Extension.agent_version
124
- ENV["APPSIGNAL_LANGUAGE_INTEGRATION_VERSION"] = "ruby-#{Appsignal::VERSION}"
125
- ENV["APPSIGNAL_DEBUG_LOGGING"] = config_hash[:debug].to_s
126
- ENV["APPSIGNAL_LOG_FILE_PATH"] = log_file_path.to_s if log_file_path
127
- ENV["APPSIGNAL_PUSH_API_ENDPOINT"] = config_hash[:endpoint]
128
- ENV["APPSIGNAL_PUSH_API_KEY"] = config_hash[:push_api_key]
129
- ENV["APPSIGNAL_APP_NAME"] = config_hash[:name]
130
- ENV["APPSIGNAL_HTTP_PROXY"] = config_hash[:http_proxy]
131
- ENV["APPSIGNAL_IGNORE_ACTIONS"] = config_hash[:ignore_actions].join(",")
132
- ENV["APPSIGNAL_IGNORE_ERRORS"] = config_hash[:ignore_errors].join(",")
133
- ENV["APPSIGNAL_FILTER_PARAMETERS"] = config_hash[:filter_parameters].join(",")
134
- ENV["APPSIGNAL_SEND_PARAMS"] = config_hash[:send_params].to_s
135
- ENV["APPSIGNAL_RUNNING_IN_CONTAINER"] = config_hash[:running_in_container].to_s
136
- ENV["APPSIGNAL_WORKING_DIR_PATH"] = config_hash[:working_dir_path] if config_hash[:working_dir_path]
137
- ENV["APPSIGNAL_ENABLE_HOST_METRICS"] = config_hash[:enable_host_metrics].to_s
138
- ENV["APPSIGNAL_ENABLE_MINUTELY_PROBES"] = config_hash[:enable_minutely_probes].to_s
139
- ENV["APPSIGNAL_HOSTNAME"] = config_hash[:hostname].to_s
140
- ENV["APPSIGNAL_PROCESS_NAME"] = $0
141
- ENV["APPSIGNAL_CA_FILE_PATH"] = config_hash[:ca_file_path].to_s
119
+ def write_to_environment # rubocop:disable Metrics/AbcSize
120
+ ENV["_APPSIGNAL_ACTIVE"] = active?.to_s
121
+ ENV["_APPSIGNAL_APP_PATH"] = root_path.to_s
122
+ ENV["_APPSIGNAL_AGENT_PATH"] = File.expand_path("../../../ext", __FILE__).to_s
123
+ ENV["_APPSIGNAL_ENVIRONMENT"] = env
124
+ ENV["_APPSIGNAL_AGENT_VERSION"] = Appsignal::Extension.agent_version
125
+ ENV["_APPSIGNAL_LANGUAGE_INTEGRATION_VERSION"] = "ruby-#{Appsignal::VERSION}"
126
+ ENV["_APPSIGNAL_DEBUG_LOGGING"] = config_hash[:debug].to_s
127
+ ENV["_APPSIGNAL_LOG"] = config_hash[:log]
128
+ ENV["_APPSIGNAL_LOG_FILE_PATH"] = log_file_path.to_s if log_file_path
129
+ ENV["_APPSIGNAL_PUSH_API_ENDPOINT"] = config_hash[:endpoint]
130
+ ENV["_APPSIGNAL_PUSH_API_KEY"] = config_hash[:push_api_key]
131
+ ENV["_APPSIGNAL_APP_NAME"] = config_hash[:name]
132
+ ENV["_APPSIGNAL_HTTP_PROXY"] = config_hash[:http_proxy]
133
+ ENV["_APPSIGNAL_IGNORE_ACTIONS"] = config_hash[:ignore_actions].join(",")
134
+ ENV["_APPSIGNAL_IGNORE_ERRORS"] = config_hash[:ignore_errors].join(",")
135
+ ENV["_APPSIGNAL_FILTER_PARAMETERS"] = config_hash[:filter_parameters].join(",")
136
+ ENV["_APPSIGNAL_SEND_PARAMS"] = config_hash[:send_params].to_s
137
+ ENV["_APPSIGNAL_RUNNING_IN_CONTAINER"] = config_hash[:running_in_container].to_s
138
+ ENV["_APPSIGNAL_WORKING_DIR_PATH"] = config_hash[:working_dir_path] if config_hash[:working_dir_path]
139
+ ENV["_APPSIGNAL_ENABLE_HOST_METRICS"] = config_hash[:enable_host_metrics].to_s
140
+ ENV["_APPSIGNAL_ENABLE_MINUTELY_PROBES"] = config_hash[:enable_minutely_probes].to_s
141
+ ENV["_APPSIGNAL_HOSTNAME"] = config_hash[:hostname].to_s
142
+ ENV["_APPSIGNAL_PROCESS_NAME"] = $PROGRAM_NAME
143
+ ENV["_APPSIGNAL_CA_FILE_PATH"] = config_hash[:ca_file_path].to_s
144
+ ENV["_APPSIGNAL_DNS_SERVERS"] = config_hash[:dns_servers].join(",")
142
145
  end
143
146
 
144
- protected
147
+ private
145
148
 
146
149
  def config_file
147
150
  @config_file ||=
@@ -149,7 +152,6 @@ module Appsignal
149
152
  end
150
153
 
151
154
  def detect_from_system
152
- config_hash[:running_in_container] = true if Appsignal::System.container?
153
155
  config_hash[:log] = "stdout" if Appsignal::System.heroku?
154
156
 
155
157
  # Make active by default if APPSIGNAL_PUSH_API_KEY is present
@@ -189,9 +191,9 @@ module Appsignal
189
191
  APPSIGNAL_FRONTEND_ERROR_CATCHING_PATH APPSIGNAL_HTTP_PROXY
190
192
  APPSIGNAL_LOG APPSIGNAL_LOG_PATH APPSIGNAL_WORKING_DIR_PATH
191
193
  APPSIGNAL_HOSTNAME APPSIGNAL_CA_FILE_PATH).each do |var|
192
- if env_var = ENV[var]
193
- config[ENV_TO_KEY_MAPPING[var]] = env_var
194
- end
194
+ env_var = ENV[var]
195
+ next unless env_var
196
+ config[ENV_TO_KEY_MAPPING[var]] = env_var
195
197
  end
196
198
 
197
199
  # Configuration with boolean type
@@ -201,17 +203,17 @@ module Appsignal
201
203
  APPSIGNAL_ENABLE_ALLOCATION_TRACKING APPSIGNAL_ENABLE_GC_INSTRUMENTATION
202
204
  APPSIGNAL_RUNNING_IN_CONTAINER APPSIGNAL_ENABLE_HOST_METRICS
203
205
  APPSIGNAL_SEND_PARAMS APPSIGNAL_ENABLE_MINUTELY_PROBES).each do |var|
204
- if env_var = ENV[var]
205
- config[ENV_TO_KEY_MAPPING[var]] = env_var == "true"
206
- end
206
+ env_var = ENV[var]
207
+ next unless env_var
208
+ config[ENV_TO_KEY_MAPPING[var]] = env_var == "true"
207
209
  end
208
210
 
209
211
  # Configuration with array of strings type
210
212
  %w(APPSIGNAL_IGNORE_ERRORS APPSIGNAL_IGNORE_ACTIONS
211
213
  APPSIGNAL_FILTER_PARAMETERS).each do |var|
212
- if env_var = ENV[var]
213
- config[ENV_TO_KEY_MAPPING[var]] = env_var.split(",")
214
- end
214
+ env_var = ENV[var]
215
+ next unless env_var
216
+ config[ENV_TO_KEY_MAPPING[var]] = env_var.split(",")
215
217
  end
216
218
 
217
219
  merge(@config_hash, config)
@@ -1,10 +1,30 @@
1
1
  require "rack/mock"
2
2
 
3
3
  module Appsignal
4
+ # {Appsignal::Demo} is a way to send demonstration / test samples for a
5
+ # exception and a performance issue.
6
+ #
7
+ # @example Loading config automatically
8
+ # Appsignal::Demo.transmit
9
+ #
10
+ # @example With custom config
11
+ # # If another configuration should be used, set it beforehand.
12
+ # Appsignal.config = Appsignal::Config.new(Dir.pwd, "production")
13
+ # Appsignal::Demo.transmit
14
+ #
15
+ # @since 2.0.0
16
+ # @see Appsignal::CLI::Demo
17
+ # @api private
4
18
  class Demo
19
+ # Error type used to create demonstration exception.
5
20
  class TestError < StandardError; end
6
21
 
7
22
  class << self
23
+ # Starts AppSignal and transmits the demonstration samples to AppSignal
24
+ # using the loaded configuration.
25
+ #
26
+ # @return [Boolean]
27
+ # - returns `false` if Appsignal is not active.
8
28
  def transmit
9
29
  Appsignal.start
10
30
  Appsignal.start_logger
@@ -8,6 +8,8 @@ module Appsignal
8
8
  # event, the same object will be called intermittently in a threaded environment.
9
9
  # So only keep global configuration as state and pass the payload around as an
10
10
  # argument if you need to use helper methods.
11
+ #
12
+ # @api private
11
13
  class EventFormatter
12
14
  class << self
13
15
  def formatters
@@ -60,7 +62,9 @@ module Appsignal
60
62
  end
61
63
  end
62
64
 
65
+ # @api public
63
66
  DEFAULT = 0
67
+ # @api public
64
68
  SQL_BODY_FORMAT = 1
65
69
  end
66
70
  end
@@ -1,5 +1,6 @@
1
1
  module Appsignal
2
2
  class EventFormatter
3
+ # @api private
3
4
  module ActionView
4
5
  class RenderFormatter < Appsignal::EventFormatter
5
6
  register "render_partial.action_view"
@@ -1,5 +1,6 @@
1
1
  module Appsignal
2
2
  class EventFormatter
3
+ # @api private
3
4
  module ActiveRecord
4
5
  class InstantiationFormatter < Appsignal::EventFormatter
5
6
  register "instantiation.active_record"
@@ -1,5 +1,6 @@
1
1
  module Appsignal
2
2
  class EventFormatter
3
+ # @api private
3
4
  module ActiveRecord
4
5
  class SqlFormatter < Appsignal::EventFormatter
5
6
  register "sql.active_record"
@@ -1,5 +1,6 @@
1
1
  module Appsignal
2
2
  class EventFormatter
3
+ # @api private
3
4
  module ElasticSearch
4
5
  class SearchFormatter < Appsignal::EventFormatter
5
6
  register "search.elasticsearch"
@@ -1,5 +1,6 @@
1
1
  module Appsignal
2
2
  class EventFormatter
3
+ # @api private
3
4
  module Faraday
4
5
  class RequestFormatter < Appsignal::EventFormatter
5
6
  register "request.faraday"
@@ -1,5 +1,6 @@
1
1
  module Appsignal
2
2
  class EventFormatter
3
+ # @api private
3
4
  module MongoRubyDriver
4
5
  class QueryFormatter
5
6
  ALLOWED = {
@@ -44,7 +45,7 @@ module Appsignal
44
45
  "multi" => :allow,
45
46
  "upsert" => :allow
46
47
  }
47
- }
48
+ }.freeze
48
49
 
49
50
  # Format command based on given strategy
50
51
  def self.format(strategy, command)
@@ -1,5 +1,6 @@
1
1
  module Appsignal
2
2
  class EventFormatter
3
+ # @api private
3
4
  module Moped
4
5
  class QueryFormatter < Appsignal::EventFormatter
5
6
  register "query.moped"
@@ -12,6 +12,7 @@ rescue LoadError => err
12
12
  end
13
13
 
14
14
  module Appsignal
15
+ # @api private
15
16
  class Extension
16
17
  class << self
17
18
  def agent_config
@@ -1,41 +1,42 @@
1
1
  module Appsignal
2
- # Appsignal::GarbageCollectionProfiler wraps Ruby's GC::Profiler to be able
3
- # to track garbage collection time for multiple transactions, while
4
- # constantly clearing GC::Profiler's total_time to make sure it doesn't leak
5
- # memory by keeping garbage collection run samples in memory.
6
-
2
+ # {Appsignal::GarbageCollectionProfiler} wraps Ruby's `GC::Profiler` to be
3
+ # able to track garbage collection time for multiple transactions, while
4
+ # constantly clearing `GC::Profiler`'s total_time to make sure it doesn't
5
+ # leak memory by keeping garbage collection run samples in memory.
6
+ #
7
+ # @api private
7
8
  class GarbageCollectionProfiler
9
+ def self.lock
10
+ @lock ||= Mutex.new
11
+ end
12
+
8
13
  def initialize
9
14
  @total_time = 0
10
15
  end
11
16
 
12
- # Whenever #total_time is called, the current GC::Profiler.total_time gets
13
- # added to @total_time, after which GC::Profiler.clear is called to prevent
14
- # it from leaking memory. A class-level lock is used to make sure garbage
15
- # collection time is never counted more than once.
17
+ # Whenever {#total_time} is called, the current `GC::Profiler#total_time`
18
+ # gets added to `@total_time`, after which `GC::Profiler.clear` is called
19
+ # to prevent it from leaking memory. A class-level lock is used to make
20
+ # sure garbage collection time is never counted more than once.
16
21
  #
17
- # Whenever @total_time gets above two billion milliseconds (about 23 days),
18
- # it's reset to make sure the result fits in a signed 32-bit integer.
19
-
22
+ # Whenever `@total_time` gets above two billion milliseconds (about 23
23
+ # days), it's reset to make sure the result fits in a signed 32-bit
24
+ # integer.
25
+ #
26
+ # @return [Integer]
20
27
  def total_time
21
28
  lock.synchronize do
22
29
  @total_time += (internal_profiler.total_time * 1000).round
23
30
  internal_profiler.clear
24
31
  end
25
32
 
26
- if @total_time > 2_000_000_000
27
- @total_time = 0
28
- end
33
+ @total_time = 0 if @total_time > 2_000_000_000
29
34
 
30
35
  @total_time
31
36
  end
32
37
 
33
38
  private
34
39
 
35
- def self.lock
36
- @lock ||= Mutex.new
37
- end
38
-
39
40
  def internal_profiler
40
41
  GC::Profiler
41
42
  end