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
@@ -89,6 +89,7 @@ module Appsignal
89
89
  end
90
90
  end
91
91
 
92
+ require 'appsignal/hooks/active_support_notifications'
92
93
  require 'appsignal/hooks/celluloid'
93
94
  require 'appsignal/hooks/delayed_job'
94
95
  require 'appsignal/hooks/net_http'
@@ -0,0 +1,43 @@
1
+ module Appsignal
2
+ class Hooks
3
+ class ActiveSupportNotificationsHook < Appsignal::Hooks::Hook
4
+ register :active_support_notifications
5
+
6
+ BANG = '!'.freeze
7
+
8
+ def dependencies_present?
9
+ defined?(::ActiveSupport::Notifications::Instrumenter)
10
+ end
11
+
12
+ def install
13
+ ::ActiveSupport::Notifications::Instrumenter.class_eval do
14
+ alias instrument_without_appsignal instrument
15
+
16
+ def instrument(name, payload={}, &block)
17
+ # Events that start with a bang are internal to Rails
18
+ instrument_this = name[0] != BANG
19
+
20
+ if instrument_this
21
+ transaction = Appsignal::Transaction.current
22
+ transaction.start_event
23
+ end
24
+
25
+ return_value = instrument_without_appsignal(name, payload, &block)
26
+
27
+ if instrument_this
28
+ title, body, body_format = Appsignal::EventFormatter.format(name, payload)
29
+ transaction.finish_event(
30
+ name,
31
+ title,
32
+ body,
33
+ body_format
34
+ )
35
+ end
36
+
37
+ return_value
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -20,7 +20,7 @@ namespace :appsignal do
20
20
  marker = Appsignal::Marker.new(marker_data, appsignal_config)
21
21
  marker.transmit
22
22
  else
23
- puts 'Not notifying of deploy, config is not active'
23
+ puts "Not notifying of deploy, config is not active for environment: #{env}"
24
24
  end
25
25
  end
26
26
  end
@@ -7,7 +7,7 @@ module Appsignal
7
7
 
8
8
  namespace :appsignal do
9
9
  task :deploy do
10
- env = fetch(:rails_env, fetch(:rack_env, 'production'))
10
+ env = fetch(:appsignal_env, fetch(:stage, fetch(:rails_env, fetch(:rack_env, 'production'))))
11
11
  user = ENV['USER'] || ENV['USERNAME']
12
12
  revision = fetch(:appsignal_revision, fetch(:current_revision))
13
13
 
@@ -31,7 +31,7 @@ module Appsignal
31
31
  marker.transmit
32
32
  end
33
33
  else
34
- puts 'Not notifying of deploy, config is not active'
34
+ puts "Not notifying of deploy, config is not active for environment: #{env}"
35
35
  end
36
36
  end
37
37
  end
@@ -45,7 +45,7 @@ module Appsignal
45
45
  transaction.finish_event(
46
46
  'query.mongodb',
47
47
  "#{event.command_name.to_s} | #{event.database_name} | #{result}",
48
- Appsignal::Utils.json_generate(command),
48
+ Appsignal::Utils.data_generate(command),
49
49
  Appsignal::EventFormatter::DEFAULT
50
50
  )
51
51
  end
@@ -2,24 +2,24 @@ class Object
2
2
  def self.appsignal_instrument_class_method(method_name, options = {})
3
3
  singleton_class.send \
4
4
  :alias_method, "appsignal_uninstrumented_#{method_name}", method_name
5
- singleton_class.send(:define_method, method_name) do |*args|
5
+ singleton_class.send(:define_method, method_name) do |*args, &block|
6
6
  name = options.fetch(:name) do
7
7
  "#{method_name}.class_method.#{appsignal_reverse_class_name}.other"
8
8
  end
9
9
  Appsignal.instrument name do
10
- send "appsignal_uninstrumented_#{method_name}", *args
10
+ send "appsignal_uninstrumented_#{method_name}", *args, &block
11
11
  end
12
12
  end
13
13
  end
14
14
 
15
15
  def self.appsignal_instrument_method(method_name, options = {})
16
16
  alias_method "appsignal_uninstrumented_#{method_name}", method_name
17
- define_method method_name do |*args|
17
+ define_method method_name do |*args, &block|
18
18
  name = options.fetch(:name) do
19
19
  "#{method_name}.#{appsignal_reverse_class_name}.other"
20
20
  end
21
21
  Appsignal.instrument name do
22
- send "appsignal_uninstrumented_#{method_name}", *args
22
+ send "appsignal_uninstrumented_#{method_name}", *args, &block
23
23
  end
24
24
  end
25
25
  end
@@ -33,7 +33,7 @@ module Padrino::Routing::InstanceMethods
33
33
  request
34
34
  )
35
35
  begin
36
- ActiveSupport::Notifications.instrument('process_action.padrino') do
36
+ Appsignal.instrument('process_action.padrino') do
37
37
  route_without_appsignal(base, pass_block)
38
38
  end
39
39
  rescue => error
@@ -6,7 +6,7 @@ Appsignal.logger.info("Loading Sinatra (#{Sinatra::VERSION}) integration")
6
6
  app_settings = ::Sinatra::Application.settings
7
7
  Appsignal.config = Appsignal::Config.new(
8
8
  app_settings.root || Dir.pwd,
9
- app_settings.environment
9
+ ENV.fetch('APPSIGNAL_APP_ENV'.freeze, app_settings.environment)
10
10
  )
11
11
 
12
12
  Appsignal.start_logger
@@ -12,7 +12,7 @@ module Appsignal::Integrations
12
12
 
13
13
  transaction.set_action("#{resource.class.name}##{request.method}")
14
14
 
15
- ActiveSupport::Notifications.instrument('process_action.webmachine') do
15
+ Appsignal.instrument('process_action.webmachine') do
16
16
  run_without_appsignal
17
17
  end
18
18
 
@@ -25,7 +25,7 @@ module Appsignal::Integrations
25
25
  handle_exceptions_without_appsignal do
26
26
  begin
27
27
  yield
28
- rescue Exception => e
28
+ rescue => e
29
29
  Appsignal.set_error(e)
30
30
  raise e
31
31
  end
@@ -5,7 +5,7 @@ module Appsignal
5
5
  def initialize(data)
6
6
  @data = data
7
7
  @uuid = SecureRandom.uuid
8
- @ext = Appsignal::Extension.start_transaction(@uuid, Appsignal::Transaction::FRONTEND)
8
+ @ext = Appsignal::Extension.start_transaction(@uuid, Appsignal::Transaction::FRONTEND, 0)
9
9
 
10
10
  set_action
11
11
  set_metadata
@@ -27,25 +27,22 @@ module Appsignal
27
27
  @ext.set_error(
28
28
  @data['name'],
29
29
  @data['message'],
30
- Appsignal::Utils.json_generate(@data['backtrace'])
30
+ Appsignal::Utils.data_generate(@data['backtrace'])
31
31
  )
32
32
  end
33
33
 
34
34
  def set_sample_data
35
35
  {
36
36
  :params => @data['params'],
37
+ :session_data => @data['session_data'],
37
38
  :environment => @data['environment'],
38
39
  :tags => @data['tags']
39
40
  }.each do |key, data|
40
41
  next unless data.is_a?(Array) || data.is_a?(Hash)
41
- begin
42
- @ext.set_sample_data(
43
- key.to_s,
44
- Appsignal::Utils.json_generate(data)
45
- )
46
- rescue *Appsignal::Transaction::JSON_EXCEPTIONS => e
47
- Appsignal.logger.error("Error generating JSON (#{e.class}: #{e.message}) for '#{backtrace.inspect}'")
48
- end
42
+ @ext.set_sample_data(
43
+ key.to_s,
44
+ Appsignal::Utils.data_generate(data)
45
+ )
49
46
  end
50
47
  end
51
48
 
@@ -10,14 +10,15 @@ module Appsignal
10
10
 
11
11
  def transmit
12
12
  transmitter = Transmitter.new(ACTION, config)
13
- puts "Notifying Appsignal of deploy with: revision: #{marker_data[:revision]}, user: #{marker_data[:user]}"
13
+ puts "Notifying Appsignal of deploy with: "\
14
+ "revision: #{marker_data[:revision]}, user: #{marker_data[:user]}"
14
15
  result = transmitter.transmit(marker_data)
15
16
  if result == '200'
16
17
  puts 'Appsignal has been notified of this deploy!'
17
18
  else
18
19
  raise "#{result} at #{transmitter.uri}"
19
20
  end
20
- rescue Exception => e
21
+ rescue => e
21
22
  puts "Something went wrong while trying to notify Appsignal: #{e}"
22
23
  end
23
24
  end
@@ -24,7 +24,7 @@ module Appsignal
24
24
  request
25
25
  )
26
26
  begin
27
- ActiveSupport::Notifications.instrument('process_action.generic') do
27
+ Appsignal.instrument('process_action.generic') do
28
28
  @app.call(env)
29
29
  end
30
30
  rescue => error
@@ -29,7 +29,7 @@ module Appsignal
29
29
  def initialize(app, options = {})
30
30
  Appsignal.logger.debug 'Initializing Appsignal::Rack::SinatraInstrumentation'
31
31
  @app, @options = app, options
32
- @raise_errors_on = @app.settings.raise_errors
32
+ @raise_errors_on = raise_errors?(@app)
33
33
  end
34
34
 
35
35
  def call(env)
@@ -52,7 +52,7 @@ module Appsignal
52
52
  {:force => @options.include?(:force) && @options[:force]}
53
53
  )
54
54
  begin
55
- ActiveSupport::Notifications.instrument('process_action.sinatra') do
55
+ Appsignal.instrument('process_action.sinatra') do
56
56
  @app.call(env)
57
57
  end
58
58
  rescue => error
@@ -73,16 +73,23 @@ module Appsignal
73
73
  end
74
74
 
75
75
  def action_name(env)
76
- if @options.fetch(:mounted_at, nil)
77
- method, route = env['sinatra.route'].split(" ")
78
- "#{method} #{@options[:mounted_at]}#{route}"
79
- elsif env['SCRIPT_NAME']
76
+ return unless env['sinatra.route']
77
+
78
+ if env['SCRIPT_NAME']
80
79
  method, route = env['sinatra.route'].split(" ")
81
80
  "#{method} #{env['SCRIPT_NAME']}#{route}"
82
81
  else
83
82
  env['sinatra.route']
84
83
  end
85
84
  end
85
+
86
+ private
87
+
88
+ def raise_errors?(app)
89
+ app.respond_to?(:settings) &&
90
+ app.settings.respond_to?(:raise_errors) &&
91
+ app.settings.raise_errors
92
+ end
86
93
  end
87
94
  end
88
95
  end
@@ -25,7 +25,7 @@ module Appsignal
25
25
 
26
26
  # Instrument a `process_action`, to set params/action name
27
27
  status, headers, body =
28
- ActiveSupport::Notifications.instrument('process_action.rack') do
28
+ Appsignal.instrument('process_action.rack') do
29
29
  begin
30
30
  @app.call(env)
31
31
  rescue Exception => e
@@ -54,13 +54,15 @@ module Appsignal
54
54
  def each
55
55
  @stream.each { |c| yield(c) }
56
56
  rescue Exception => e
57
- @transaction.set_error(e); raise e
57
+ @transaction.set_error(e)
58
+ raise e
58
59
  end
59
60
 
60
61
  def close
61
62
  @stream.close if @stream.respond_to?(:close)
62
63
  rescue Exception => e
63
- @transaction.set_error(e); raise e
64
+ @transaction.set_error(e)
65
+ raise e
64
66
  ensure
65
67
  Appsignal::Transaction.complete_current!
66
68
  end
@@ -0,0 +1,36 @@
1
+ module Appsignal
2
+ module System
3
+ def self.container?
4
+ heroku? || Container.id
5
+ end
6
+
7
+ def self.heroku?
8
+ ENV.key? 'DYNO'.freeze
9
+ end
10
+
11
+ module Container
12
+ CGROUP_FILE = '/proc/self/cgroup'.freeze
13
+
14
+ def self.id
15
+ case cgroups
16
+ when %r{docker[-|/]([0-9a-f]+)}
17
+ $1
18
+ when %r{lxc/([0-9a-f-]+)$} # LXC / Heroku
19
+ $1
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def self.cgroups
26
+ file = CGROUP_FILE
27
+ return unless File.exist? file
28
+
29
+ File.read(file)
30
+ rescue SystemCallError => e
31
+ Appsignal.logger.debug "Unable to read '#{file}' to determine cgroup"
32
+ Appsignal.logger.debug e
33
+ end
34
+ end
35
+ end
36
+ end
@@ -19,13 +19,6 @@ module Appsignal
19
19
  HTTP_PRAGMA HTTP_REFERER HTTP_X_FORWARDED_FOR HTTP_CLIENT_IP HTTP_RANGE
20
20
  HTTP_X_AUTH_TOKEN)
21
21
 
22
- JSON_EXCEPTIONS = [
23
- IOError,
24
- NotImplementedError,
25
- JSON::GeneratorError,
26
- Encoding::UndefinedConversionError
27
- ].freeze
28
-
29
22
  class << self
30
23
  def create(id, namespace, request, options={})
31
24
  # Allow middleware to force a new transaction
@@ -52,11 +45,15 @@ module Appsignal
52
45
 
53
46
  def complete_current!
54
47
  current.complete
55
- rescue Exception => e
48
+ rescue => e
56
49
  Appsignal.logger.error("Failed to complete transaction ##{current.transaction_id}. #{e.message}")
57
50
  ensure
58
51
  Thread.current[:appsignal_transaction] = nil
59
52
  end
53
+
54
+ def garbage_collection_profiler
55
+ @garbage_collection_profiler ||= Appsignal::GarbageCollectionProfiler.new
56
+ end
60
57
  end
61
58
 
62
59
  attr_reader :ext, :transaction_id, :namespace, :request, :paused, :tags, :options, :discarded
@@ -72,7 +69,11 @@ module Appsignal
72
69
  @options = options
73
70
  @options[:params_method] ||= :params
74
71
 
75
- @ext = Appsignal::Extension.start_transaction(@transaction_id, @namespace)
72
+ @ext = Appsignal::Extension.start_transaction(
73
+ @transaction_id,
74
+ @namespace,
75
+ self.class.garbage_collection_profiler.total_time
76
+ )
76
77
  end
77
78
 
78
79
  def nil_transaction?
@@ -84,7 +85,7 @@ module Appsignal
84
85
  Appsignal.logger.debug('Skipping transaction because it was manually discarded.'.freeze)
85
86
  return
86
87
  end
87
- if @ext.finish
88
+ if @ext.finish(self.class.garbage_collection_profiler.total_time)
88
89
  sample_data
89
90
  end
90
91
  @ext.complete
@@ -160,10 +161,10 @@ module Appsignal
160
161
  return unless key && data && (data.is_a?(Array) || data.is_a?(Hash))
161
162
  @ext.set_sample_data(
162
163
  key.to_s,
163
- Appsignal::Utils.json_generate(data)
164
+ Appsignal::Utils.data_generate(data)
164
165
  )
165
- rescue *JSON_EXCEPTIONS => e
166
- Appsignal.logger.error("Error generating JSON (#{e.class}: #{e.message}) for '#{data.inspect}'")
166
+ rescue RuntimeError => e
167
+ Appsignal.logger.error("Error generating data (#{e.class}: #{e.message}) for '#{data.inspect}'")
167
168
  end
168
169
 
169
170
  def sample_data
@@ -187,15 +188,13 @@ module Appsignal
187
188
  @ext.set_error(
188
189
  error.class.name,
189
190
  error.message.to_s,
190
- backtrace ? Appsignal::Utils.json_generate(backtrace) : ''
191
+ backtrace ? Appsignal::Utils.data_generate(backtrace) : Appsignal::Extension.data_array_new
191
192
  )
192
- rescue *JSON_EXCEPTIONS => e
193
- Appsignal.logger.error("Error generating JSON (#{e.class}: #{e.message}) for '#{backtrace.inspect}'")
194
193
  end
195
194
  alias_method :add_exception, :set_error
196
195
 
197
196
  def start_event
198
- @ext.start_event
197
+ @ext.start_event(self.class.garbage_collection_profiler.total_time)
199
198
  end
200
199
 
201
200
  def finish_event(name, title, body, body_format=Appsignal::EventFormatter::DEFAULT)
@@ -203,7 +202,8 @@ module Appsignal
203
202
  name,
204
203
  title || BLANK,
205
204
  body || BLANK,
206
- body_format || Appsignal::EventFormatter::DEFAULT
205
+ body_format || Appsignal::EventFormatter::DEFAULT,
206
+ self.class.garbage_collection_profiler.total_time
207
207
  )
208
208
  end
209
209
 
@@ -269,9 +269,9 @@ module Appsignal
269
269
  params =
270
270
  begin
271
271
  request.send options[:params_method]
272
- rescue Exception => ex
272
+ rescue => e
273
273
  # Getting params from the request has been know to fail.
274
- Appsignal.logger.debug "Exception while getting params: #{ex}"
274
+ Appsignal.logger.debug "Exception while getting params: #{e}"
275
275
  nil
276
276
  end
277
277
  return unless params
@@ -8,7 +8,6 @@ module Appsignal
8
8
  class Transmitter
9
9
  CONTENT_TYPE = 'application/json; charset=UTF-8'.freeze
10
10
  CONTENT_ENCODING = 'gzip'.freeze
11
- CA_FILE_PATH = File.expand_path(File.join(__FILE__, '../../../resources/cacert.pem'))
12
11
 
13
12
  HTTP_ERRORS = [
14
13
  EOFError,
@@ -42,7 +41,7 @@ module Appsignal
42
41
  end
43
42
 
44
43
  def transmit(payload)
45
- Appsignal.logger.debug "Transmitting payload to #{uri}"
44
+ config.logger.debug "Transmitting payload to #{uri}"
46
45
  http_client.request(http_post(payload)).code
47
46
  end
48
47
 
@@ -52,10 +51,8 @@ module Appsignal
52
51
  Net::HTTP::Post.new(uri.request_uri).tap do |request|
53
52
  request['Content-Type'] = CONTENT_TYPE
54
53
  request['Content-Encoding'] = CONTENT_ENCODING
55
- request.body = Zlib::Deflate.deflate(
56
- Appsignal::Utils.json_generate(payload),
57
- Zlib::BEST_SPEED
58
- )
54
+ request.body = Appsignal::Utils::Gzip.compress \
55
+ Appsignal::Utils::JSON.generate(payload)
59
56
  end
60
57
  end
61
58
 
@@ -71,7 +68,14 @@ module Appsignal
71
68
  http.use_ssl = true
72
69
  http.ssl_version = :TLSv1
73
70
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
74
- http.ca_file = CA_FILE_PATH
71
+
72
+ ca_file = config[:ca_file_path]
73
+ if ca_file && File.exist?(ca_file) && File.readable?(ca_file)
74
+ http.ca_file = ca_file
75
+ else
76
+ config.logger.warn "Ignoring non-existing or unreadable "\
77
+ "`ca_file_path`: #{ca_file}"
78
+ end
75
79
  end
76
80
  end
77
81
  end