appsignal 1.4.0.alpha.2 → 1.4.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +3 -1
  3. data/.travis.yml +3 -1
  4. data/CHANGELOG.md +38 -1
  5. data/Rakefile +29 -12
  6. data/benchmark.rake +3 -7
  7. data/ext/agent.yml +11 -11
  8. data/ext/appsignal_extension.c +364 -72
  9. data/ext/extconf.rb +2 -4
  10. data/gemfiles/resque.gemfile +1 -0
  11. data/lib/appsignal.rb +40 -30
  12. data/lib/appsignal/auth_check.rb +1 -1
  13. data/lib/appsignal/cli/diagnose.rb +4 -3
  14. data/lib/appsignal/cli/install.rb +16 -15
  15. data/lib/appsignal/config.rb +31 -31
  16. data/lib/appsignal/event_formatter.rb +1 -1
  17. data/lib/appsignal/extension.rb +6 -0
  18. data/lib/appsignal/garbage_collection_profiler.rb +47 -0
  19. data/lib/appsignal/hooks.rb +1 -0
  20. data/lib/appsignal/hooks/active_support_notifications.rb +43 -0
  21. data/lib/appsignal/integrations/capistrano/appsignal.cap +1 -1
  22. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +2 -2
  23. data/lib/appsignal/integrations/mongo_ruby_driver.rb +1 -1
  24. data/lib/appsignal/integrations/object.rb +4 -4
  25. data/lib/appsignal/integrations/padrino.rb +1 -1
  26. data/lib/appsignal/integrations/sinatra.rb +1 -1
  27. data/lib/appsignal/integrations/webmachine.rb +2 -2
  28. data/lib/appsignal/js_exception_transaction.rb +7 -10
  29. data/lib/appsignal/marker.rb +3 -2
  30. data/lib/appsignal/rack/generic_instrumentation.rb +1 -1
  31. data/lib/appsignal/rack/sinatra_instrumentation.rb +13 -6
  32. data/lib/appsignal/rack/streaming_listener.rb +5 -3
  33. data/lib/appsignal/system.rb +36 -0
  34. data/lib/appsignal/transaction.rb +20 -20
  35. data/lib/appsignal/transmitter.rb +11 -7
  36. data/lib/appsignal/utils.rb +76 -2
  37. data/lib/appsignal/version.rb +1 -1
  38. data/spec/lib/appsignal/auth_check_spec.rb +0 -2
  39. data/spec/lib/appsignal/capistrano2_spec.rb +99 -79
  40. data/spec/lib/appsignal/capistrano3_spec.rb +57 -78
  41. data/spec/lib/appsignal/cli/diagnose_spec.rb +17 -15
  42. data/spec/lib/appsignal/cli/install_spec.rb +38 -20
  43. data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +2 -5
  44. data/spec/lib/appsignal/cli_spec.rb +2 -5
  45. data/spec/lib/appsignal/config_spec.rb +385 -158
  46. data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +1 -3
  47. data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +0 -2
  48. data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +0 -2
  49. data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +0 -2
  50. data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +0 -2
  51. data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +0 -2
  52. data/spec/lib/appsignal/event_formatter/moped/query_formatter_spec.rb +0 -2
  53. data/spec/lib/appsignal/event_formatter_spec.rb +0 -2
  54. data/spec/lib/appsignal/extension_spec.rb +7 -8
  55. data/spec/lib/appsignal/garbage_collection_profiler_spec.rb +71 -0
  56. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +42 -0
  57. data/spec/lib/appsignal/hooks/celluloid_spec.rb +0 -2
  58. data/spec/lib/appsignal/hooks/data_mapper_spec.rb +0 -2
  59. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +0 -2
  60. data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +0 -2
  61. data/spec/lib/appsignal/hooks/net_http_spec.rb +0 -2
  62. data/spec/lib/appsignal/hooks/passenger_spec.rb +0 -2
  63. data/spec/lib/appsignal/hooks/puma_spec.rb +0 -2
  64. data/spec/lib/appsignal/hooks/rake_spec.rb +1 -2
  65. data/spec/lib/appsignal/hooks/redis_spec.rb +0 -2
  66. data/spec/lib/appsignal/hooks/sequel_spec.rb +19 -21
  67. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +1 -4
  68. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +2 -3
  69. data/spec/lib/appsignal/hooks/unicorn_spec.rb +0 -2
  70. data/spec/lib/appsignal/hooks/webmachine_spec.rb +4 -11
  71. data/spec/lib/appsignal/hooks_spec.rb +0 -2
  72. data/spec/lib/appsignal/integrations/data_mapper_spec.rb +0 -1
  73. data/spec/lib/appsignal/integrations/grape_spec.rb +1 -3
  74. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +1 -2
  75. data/spec/lib/appsignal/integrations/object_spec.rb +32 -3
  76. data/spec/lib/appsignal/integrations/padrino_spec.rb +4 -11
  77. data/spec/lib/appsignal/integrations/railtie_spec.rb +1 -3
  78. data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +1 -3
  79. data/spec/lib/appsignal/integrations/resque_spec.rb +2 -4
  80. data/spec/lib/appsignal/integrations/sinatra_spec.rb +33 -8
  81. data/spec/lib/appsignal/integrations/webmachine_spec.rb +6 -15
  82. data/spec/lib/appsignal/js_exception_transaction_spec.rb +3 -5
  83. data/spec/lib/appsignal/marker_spec.rb +35 -48
  84. data/spec/lib/appsignal/minutely_spec.rb +0 -2
  85. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +0 -2
  86. data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +0 -2
  87. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +3 -5
  88. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +47 -11
  89. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +6 -7
  90. data/spec/lib/appsignal/system/container_spec.rb +67 -0
  91. data/spec/lib/appsignal/system_spec.rb +49 -0
  92. data/spec/lib/appsignal/transaction_spec.rb +30 -13
  93. data/spec/lib/appsignal/transmitter_spec.rb +53 -20
  94. data/spec/lib/appsignal/utils/gzip_spec.rb +10 -0
  95. data/spec/lib/appsignal/utils/params_sanitizer_spec.rb +0 -2
  96. data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +0 -2
  97. data/spec/lib/appsignal/utils_spec.rb +59 -3
  98. data/spec/lib/appsignal_spec.rb +132 -58
  99. data/spec/spec_helper.rb +24 -116
  100. data/spec/support/fixtures/containers/cgroups/docker +14 -0
  101. data/spec/support/fixtures/containers/cgroups/docker_systemd +8 -0
  102. data/spec/support/fixtures/containers/cgroups/lxc +10 -0
  103. data/spec/support/fixtures/containers/cgroups/no_permission +0 -0
  104. data/spec/support/fixtures/containers/cgroups/none +1 -0
  105. data/spec/support/helpers/api_request_helper.rb +22 -0
  106. data/spec/support/helpers/dependency_helper.rb +61 -0
  107. data/spec/support/helpers/directory_helper.rb +27 -0
  108. data/spec/support/helpers/std_streams_helper.rb +35 -0
  109. data/spec/support/helpers/system_helpers.rb +24 -0
  110. data/spec/support/helpers/transaction_helpers.rb +7 -64
  111. data/spec/support/helpers/very_specific_error.rb +8 -0
  112. data/spec/support/mocks/fake_gc_profiler.rb +19 -0
  113. data/spec/support/project_fixture/config/appsignal.yml +10 -1
  114. metadata +60 -35
  115. data/circle.yml +0 -12
  116. data/lib/appsignal/subscriber.rb +0 -55
  117. data/lib/appsignal/update_active_support.rb +0 -20
  118. data/lib/vendor/active_support/notifications.rb +0 -212
  119. data/lib/vendor/active_support/notifications/fanout.rb +0 -157
  120. data/lib/vendor/active_support/notifications/instrumenter.rb +0 -73
  121. data/lib/vendor/active_support/per_thread_registry.rb +0 -53
  122. data/spec/lib/appsignal/subscriber_spec.rb +0 -160
  123. data/spec/lib/appsignal/update_active_support_spec.rb +0 -17
  124. data/spec/support/helpers/notification_helpers.rb +0 -14
@@ -78,12 +78,10 @@ def install
78
78
 
79
79
  logger.info "Creating makefile"
80
80
  require 'mkmf'
81
- if !find_library('appsignal', 'appsignal_start', EXT_PATH)
82
- installation_failed 'Aborting installation, libappsignal not found'
81
+ if !have_library('appsignal', 'appsignal_start', 'appsignal.h')
82
+ installation_failed 'Aborting installation, libappsignal.a or appsignal.h not found'
83
83
  elsif !find_executable('appsignal-agent', EXT_PATH)
84
84
  installation_failed 'Aborting installation, appsignal-agent not found'
85
- elsif !find_header('appsignal.h', EXT_PATH)
86
- installation_failed 'Aborting installation, appsignal.h not found'
87
85
  else
88
86
  create_makefile 'appsignal_extension'
89
87
  logger.info 'Successfully created Makefile for appsignal extension'
@@ -2,6 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  gem 'resque'
4
4
  gem 'rails', '~> 4.2.0'
5
+ gem 'sinatra'
5
6
  gem 'mime-types', '~> 2.6'
6
7
 
7
8
  gemspec :path => '../'
@@ -2,20 +2,9 @@ require 'json'
2
2
  require 'logger'
3
3
  require 'securerandom'
4
4
 
5
- # Make sure we have the notification system
6
- begin
7
- require 'active_support/notifications'
8
- ActiveSupport::Notifications::Fanout::Subscribers::Timed # See it it's recent enough
9
- rescue LoadError
10
- require 'vendor/active_support/notifications'
11
- rescue NameError
12
- require 'appsignal/update_active_support'
13
- Appsignal::UpdateActiveSupport.run
14
- end
15
-
16
5
  module Appsignal
17
6
  class << self
18
- attr_accessor :config, :subscriber, :agent, :extension_loaded
7
+ attr_accessor :config, :agent, :extension_loaded
19
8
  attr_writer :logger, :in_memory_log
20
9
 
21
10
  def extensions
@@ -58,13 +47,17 @@ module Appsignal
58
47
  Appsignal::Hooks.load_hooks
59
48
  Appsignal::EventFormatter.initialize_formatters
60
49
  initialize_extensions
61
- Appsignal::Extension.install_allocation_event_hook if config[:enable_allocation_tracking]
50
+
51
+ if config[:enable_allocation_tracking]
52
+ Appsignal::Extension.install_allocation_event_hook
53
+ end
54
+
62
55
  if config[:enable_gc_instrumentation]
63
- Appsignal::Extension.install_gc_event_hooks
56
+ GC::Profiler.enable
64
57
  Appsignal::Minutely.add_gc_probe
65
58
  end
59
+
66
60
  Appsignal::Minutely.start if config[:enable_minutely_probes]
67
- @subscriber = Appsignal::Subscriber.new
68
61
  else
69
62
  logger.info("Not starting, not active for #{config.env}")
70
63
  end
@@ -95,7 +88,6 @@ module Appsignal
95
88
  Appsignal.start_logger
96
89
  logger.debug('Forked process, resubscribing and restarting extension')
97
90
  Appsignal::Extension.start
98
- @subscriber.resubscribe
99
91
  end
100
92
 
101
93
  def get_server_state(key)
@@ -123,7 +115,7 @@ module Appsignal
123
115
  request
124
116
  )
125
117
  begin
126
- ActiveSupport::Notifications.instrument(name) do
118
+ Appsignal.instrument(name) do
127
119
  yield
128
120
  end
129
121
  rescue => error
@@ -192,9 +184,13 @@ module Appsignal
192
184
 
193
185
  def instrument(name, title=nil, body=nil, body_format=Appsignal::EventFormatter::DEFAULT)
194
186
  Appsignal::Transaction.current.start_event
195
- r = yield
187
+ return_value = yield
196
188
  Appsignal::Transaction.current.finish_event(name, title, body, body_format)
197
- r
189
+ return_value
190
+ end
191
+
192
+ def instrument_sql(name, title=nil, body=nil, &block)
193
+ instrument(name, title, body, Appsignal::EventFormatter::SQL_BODY_FORMAT, &block)
198
194
  end
199
195
 
200
196
  def set_gauge(key, value)
@@ -235,22 +231,26 @@ module Appsignal
235
231
  end
236
232
 
237
233
  def log_formatter
238
- proc do |severity, datetime, progname, msg|
239
- "[#{datetime.strftime('%Y-%m-%dT%H:%M:%S')} (process) ##{Process.pid}][#{severity}] #{msg}\n"
240
- end
234
+ proc do |severity, datetime, progname, msg|
235
+ "[#{datetime.strftime('%Y-%m-%dT%H:%M:%S')} (process) ##{Process.pid}][#{severity}] #{msg}\n"
236
+ end
241
237
  end
242
238
 
243
239
  def start_logger(path_arg=nil)
244
240
  path = Appsignal.config ? Appsignal.config.log_file_path : nil
245
- if path && !ENV['DYNO']
246
- @logger = Logger.new(path)
247
- @logger.formatter = log_formatter
248
- else
249
- @logger = Logger.new($stdout)
250
- @logger.formatter = lambda do |severity, datetime, progname, msg|
251
- "appsignal: #{msg}\n"
241
+ if path && !Appsignal::System.heroku?
242
+ begin
243
+ @logger = Logger.new(path)
244
+ @logger.formatter = log_formatter
245
+ rescue SystemCallError => error
246
+ start_stdout_logger
247
+ logger.warn "appsignal: Unable to start logger with log path '#{path}'."
248
+ logger.warn "appsignal: #{error}"
252
249
  end
250
+ else
251
+ start_stdout_logger
253
252
  end
253
+
254
254
  if config && config[:debug]
255
255
  @logger.level = Logger::DEBUG
256
256
  else
@@ -292,6 +292,15 @@ module Appsignal
292
292
  ensure
293
293
  Appsignal::Transaction.current.resume! if Appsignal::Transaction.current
294
294
  end
295
+
296
+ private
297
+
298
+ def start_stdout_logger
299
+ @logger = Logger.new($stdout)
300
+ @logger.formatter = lambda do |severity, datetime, progname, msg|
301
+ "appsignal: #{msg}\n"
302
+ end
303
+ end
295
304
  end
296
305
  end
297
306
 
@@ -304,13 +313,14 @@ require 'appsignal/hooks'
304
313
  require 'appsignal/marker'
305
314
  require 'appsignal/minutely'
306
315
  require 'appsignal/params_sanitizer'
316
+ require 'appsignal/garbage_collection_profiler'
307
317
  require 'appsignal/integrations/railtie' if defined?(::Rails)
308
318
  require 'appsignal/integrations/resque'
309
319
  require 'appsignal/integrations/resque_active_job'
310
- require 'appsignal/subscriber'
311
320
  require 'appsignal/transaction'
312
321
  require 'appsignal/version'
313
322
  require 'appsignal/rack/generic_instrumentation'
314
323
  require 'appsignal/rack/js_exception_catcher'
315
324
  require 'appsignal/js_exception_transaction'
316
325
  require 'appsignal/transmitter'
326
+ require 'appsignal/system'
@@ -26,7 +26,7 @@ module Appsignal
26
26
  "#{status.nil? ? 'nil' : status}"
27
27
  end
28
28
  [status, result]
29
- rescue Exception => e
29
+ rescue => e
30
30
  result = 'Something went wrong while trying to '\
31
31
  "authenticate with AppSignal: #{e}"
32
32
  [nil, result]
@@ -26,6 +26,7 @@ module Appsignal
26
26
 
27
27
  def config
28
28
  start_appsignal
29
+ puts "Environment: #{Appsignal.config.env}"
29
30
  Appsignal.config.config_hash.each do |key, val|
30
31
  puts "Config #{key}: #{val}"
31
32
  end
@@ -60,12 +61,12 @@ module Appsignal
60
61
  def check_ext_install
61
62
  require 'bundler/cli'
62
63
  require "bundler/cli/common"
63
- path = Bundler::CLI::Common.select_spec('appsignal').full_gem_path
64
- install_log_path = "#{path.strip}/ext/install.log"
64
+ path = Bundler::CLI::Common.select_spec('appsignal').full_gem_path.strip
65
+ install_log_path = "#{path}/ext/install.log"
65
66
  puts "Showing last lines of extension install log: #{install_log_path}"
66
67
  puts File.read(install_log_path)
67
68
  puts "\n"
68
- mkmf_log_path = "#{path.strip}/ext/mkmf.log"
69
+ mkmf_log_path = "#{path}/ext/mkmf.log"
69
70
  if File.exist?(mkmf_log_path)
70
71
  puts "Showing last lines of extension compilation log: #{mkmf_log_path}"
71
72
  puts File.read(mkmf_log_path)
@@ -93,11 +93,6 @@ module Appsignal
93
93
  puts
94
94
  puts " require 'appsignal/integrations/sinatra'"
95
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
96
  done_notice
102
97
  end
103
98
 
@@ -136,6 +131,21 @@ module Appsignal
136
131
  done_notice
137
132
  end
138
133
 
134
+ def install_for_capistrano
135
+ capfile = File.join(Dir.pwd, 'Capfile')
136
+ return unless File.exist?(capfile)
137
+ return if File.read(capfile) =~ %r{require ['|"]appsignal/capistrano}
138
+
139
+ puts 'Installing for Capistrano'
140
+ print ' Adding AppSignal integration to Capfile'
141
+ File.open(capfile, 'a') do |f|
142
+ f.write "\nrequire 'appsignal/capistrano'\n"
143
+ end
144
+ periods
145
+ puts
146
+ puts
147
+ end
148
+
139
149
  def colorize(text, color)
140
150
  return text if Gem.win_platform?
141
151
  color_code = case color
@@ -187,16 +197,7 @@ module Appsignal
187
197
  end
188
198
 
189
199
  def configure(config, environments, name_overwritten)
190
- deploy_rb_file = File.join(Dir.pwd, 'config/deploy.rb')
191
- if File.exist?(deploy_rb_file) && (File.read(deploy_rb_file) =~ /require (\'|\").\/appsignal\/capistrano/).nil?
192
- print 'Adding AppSignal integration to deploy.rb'
193
- File.open(deploy_rb_file, 'a') do |f|
194
- f.write "\nrequire 'appsignal/capistrano'\n"
195
- end
196
- periods
197
- puts
198
- puts
199
- end
200
+ install_for_capistrano
200
201
 
201
202
  puts "How do you want to configure AppSignal?"
202
203
  puts " (1) a config file"
@@ -5,6 +5,7 @@ require 'socket'
5
5
 
6
6
  module Appsignal
7
7
  class Config
8
+ SYSTEM_TMP_DIR = '/tmp'
8
9
  DEFAULT_CONFIG = {
9
10
  :debug => false,
10
11
  :ignore_errors => [],
@@ -23,7 +24,8 @@ module Appsignal
23
24
  :running_in_container => false,
24
25
  :enable_host_metrics => true,
25
26
  :enable_minutely_probes => false,
26
- :hostname => ::Socket.gethostname
27
+ :hostname => ::Socket.gethostname,
28
+ :ca_file_path => File.expand_path(File.join('../../../resources/cacert.pem'), __FILE__)
27
29
  }.freeze
28
30
 
29
31
  ENV_TO_KEY_MAPPING = {
@@ -50,7 +52,8 @@ module Appsignal
50
52
  'APPSIGNAL_WORKING_DIR_PATH' => :working_dir_path,
51
53
  'APPSIGNAL_ENABLE_HOST_METRICS' => :enable_host_metrics,
52
54
  'APPSIGNAL_ENABLE_MINUTELY_PROBES' => :enable_minutely_probes,
53
- 'APPSIGNAL_HOSTNAME' => :hostname
55
+ 'APPSIGNAL_HOSTNAME' => :hostname,
56
+ 'APPSIGNAL_CA_FILE_PATH' => :ca_file_path
54
57
  }.freeze
55
58
 
56
59
  attr_reader :root_path, :env, :initial_config, :config_hash
@@ -62,18 +65,16 @@ module Appsignal
62
65
  @initial_config = initial_config
63
66
  @logger = logger
64
67
  @valid = false
68
+ @config_hash = Hash[DEFAULT_CONFIG]
65
69
 
70
+ # Set config based on the system
71
+ detect_from_system
66
72
  # Initial config
67
- @config_hash = DEFAULT_CONFIG.merge(initial_config)
68
-
73
+ merge(@config_hash, initial_config)
74
+ # Load the config file if it exists
75
+ load_from_disk
69
76
  # Load config from environment variables
70
77
  load_from_environment
71
-
72
- # Load the config file if it exists
73
- if config_file && File.exist?(config_file)
74
- load_from_disk
75
- end
76
-
77
78
  # Validate that we have a correct config
78
79
  validate
79
80
  end
@@ -89,12 +90,19 @@ module Appsignal
89
90
  def log_file_path
90
91
  path = config_hash[:log_path] || root_path
91
92
  if path && File.writable?(path)
92
- File.join(File.realpath(path), 'appsignal.log')
93
+ return File.join(File.realpath(path), 'appsignal.log')
94
+ end
95
+
96
+ if File.writable? SYSTEM_TMP_DIR
97
+ $stdout.puts "appsignal: Unable to log to '#{path}'. Logging to "\
98
+ "'#{SYSTEM_TMP_DIR}' instead. Please check the "\
99
+ "permissions for the application's log directory."
100
+ File.join(SYSTEM_TMP_DIR, 'appsignal.log')
93
101
  else
94
- '/tmp/appsignal.log'
102
+ $stdout.puts "appsignal: Unable to log to '#{path}' or the "\
103
+ "'#{SYSTEM_TMP_DIR}' fallback. Please check the permissions "\
104
+ "for the application's (log) directory."
95
105
  end
96
- rescue Errno::ENOENT
97
- '/tmp/appsignal.log'
98
106
  end
99
107
 
100
108
  def valid?
@@ -102,7 +110,7 @@ module Appsignal
102
110
  end
103
111
 
104
112
  def active?
105
- @valid && self[:active]
113
+ @valid && config_hash[:active]
106
114
  end
107
115
 
108
116
  def write_to_environment
@@ -127,6 +135,7 @@ module Appsignal
127
135
  ENV['APPSIGNAL_ENABLE_MINUTELY_PROBES'] = config_hash[:enable_minutely_probes].to_s
128
136
  ENV['APPSIGNAL_HOSTNAME'] = config_hash[:hostname].to_s
129
137
  ENV['APPSIGNAL_PROCESS_NAME'] = $0
138
+ ENV['APPSIGNAL_CA_FILE_PATH'] = config_hash[:ca_file_path].to_s
130
139
  end
131
140
 
132
141
  protected
@@ -136,7 +145,13 @@ module Appsignal
136
145
  root_path.nil? ? nil : File.join(root_path, 'config', 'appsignal.yml')
137
146
  end
138
147
 
148
+ def detect_from_system
149
+ self[:running_in_container] = true if Appsignal::System.container?
150
+ end
151
+
139
152
  def load_from_disk
153
+ return if !config_file || !File.exist?(config_file)
154
+
140
155
  configurations = YAML.load(ERB.new(IO.read(config_file)).result)
141
156
  config_for_this_env = configurations[env]
142
157
  if config_for_this_env
@@ -167,15 +182,10 @@ module Appsignal
167
182
  config[:active] = true
168
183
  end
169
184
 
170
- # Heroku is a container based system
171
- if ENV['DYNO']
172
- config[:running_in_container] = true
173
- end
174
-
175
185
  # Configuration with string type
176
186
  %w(APPSIGNAL_PUSH_API_KEY APPSIGNAL_APP_NAME APPSIGNAL_PUSH_API_ENDPOINT
177
187
  APPSIGNAL_FRONTEND_ERROR_CATCHING_PATH APPSIGNAL_HTTP_PROXY APPSIGNAL_LOG_PATH
178
- APPSIGNAL_WORKING_DIR_PATH APPSIGNAL_HOSTNAME).each do |var|
188
+ APPSIGNAL_WORKING_DIR_PATH APPSIGNAL_HOSTNAME APPSIGNAL_CA_FILE_PATH).each do |var|
179
189
  if env_var = ENV[var]
180
190
  config[ENV_TO_KEY_MAPPING[var]] = env_var
181
191
  end
@@ -229,15 +239,5 @@ module Appsignal
229
239
  @logger.error "Push api key not set after loading config"
230
240
  end
231
241
  end
232
-
233
- def load_default_config_with_push_api_key_and_name_from_env(key)
234
- # Get base config by doing the default merge and adding the push api key.
235
- @config_hash = merge_config(
236
- :push_api_key => key,
237
- :active => true
238
- )
239
- @config_hash[:name] = ENV['APPSIGNAL_APP_NAME'] if ENV['APPSIGNAL_APP_NAME']
240
- @config_hash[:active] = ENV['APPSIGNAL_ACTIVE'] == 'true' if ENV['APPSIGNAL_ACTIVE']
241
- end
242
242
  end
243
243
  end
@@ -46,7 +46,7 @@ module Appsignal
46
46
  else
47
47
  raise "#{f} does not have a format(payload) method"
48
48
  end
49
- rescue Exception => ex
49
+ rescue => ex
50
50
  formatter_classes.delete(name)
51
51
  formatters.delete(name)
52
52
  Appsignal.logger.debug("'#{ex.message}' when initializing #{name} event formatter")
@@ -28,5 +28,11 @@ module Appsignal
28
28
  # Do nothing if the extension methods are not loaded
29
29
  end
30
30
  end
31
+
32
+ class Data
33
+ def inspect
34
+ "#<#{self.class.name}:#{object_id} #{to_s}>"
35
+ end
36
+ end
31
37
  end
32
38
  end
@@ -0,0 +1,47 @@
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
+
7
+ class GarbageCollectionProfiler
8
+ def initialize
9
+ @total_time = 0
10
+ end
11
+
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.
16
+ #
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
+
20
+ def total_time
21
+ lock.synchronize do
22
+ @total_time += (internal_profiler.total_time * 1000).round
23
+ internal_profiler.clear
24
+ end
25
+
26
+ if @total_time > 2_000_000_000
27
+ @total_time = 0
28
+ end
29
+
30
+ @total_time
31
+ end
32
+
33
+ private
34
+
35
+ def self.lock
36
+ @lock ||= Mutex.new
37
+ end
38
+
39
+ def internal_profiler
40
+ GC::Profiler
41
+ end
42
+
43
+ def lock
44
+ self.class.lock
45
+ end
46
+ end
47
+ end