appsignal 0.12.beta.31 → 0.12.beta.32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/Rakefile +1 -0
  4. data/benchmark.rake +20 -20
  5. data/ext/appsignal_extension.c +31 -23
  6. data/gemfiles/padrino.gemfile +7 -0
  7. data/lib/appsignal.rb +50 -27
  8. data/lib/appsignal/capistrano.rb +2 -1
  9. data/lib/appsignal/config.rb +94 -39
  10. data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +12 -17
  11. data/lib/appsignal/integrations/padrino.rb +65 -0
  12. data/lib/appsignal/integrations/rails.rb +4 -2
  13. data/lib/appsignal/integrations/rake.rb +30 -0
  14. data/lib/appsignal/integrations/sidekiq.rb +2 -2
  15. data/lib/appsignal/integrations/sinatra.rb +0 -1
  16. data/lib/appsignal/js_exception_transaction.rb +4 -9
  17. data/lib/appsignal/params_sanitizer.rb +8 -5
  18. data/lib/appsignal/rack/rails_instrumentation.rb +41 -0
  19. data/lib/appsignal/rack/sinatra_instrumentation.rb +31 -24
  20. data/lib/appsignal/subscriber.rb +2 -9
  21. data/lib/appsignal/transaction.rb +86 -75
  22. data/lib/appsignal/transmitter.rb +30 -3
  23. data/lib/appsignal/version.rb +2 -2
  24. data/spec/lib/appsignal/cli_spec.rb +1 -1
  25. data/spec/lib/appsignal/config_spec.rb +38 -131
  26. data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +27 -29
  27. data/spec/lib/appsignal/extension_spec.rb +11 -29
  28. data/spec/lib/appsignal/integrations/padrino_spec.rb +191 -0
  29. data/spec/lib/appsignal/integrations/rails_spec.rb +3 -4
  30. data/spec/lib/appsignal/integrations/rake_spec.rb +78 -0
  31. data/spec/lib/appsignal/integrations/resque_spec.rb +2 -2
  32. data/spec/lib/appsignal/integrations/sequel_spec.rb +2 -3
  33. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +22 -5
  34. data/spec/lib/appsignal/integrations/sinatra_spec.rb +0 -6
  35. data/spec/lib/appsignal/js_exception_transaction_spec.rb +4 -6
  36. data/spec/lib/appsignal/params_sanitizer_spec.rb +27 -11
  37. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +79 -0
  38. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +71 -71
  39. data/spec/lib/appsignal/subscriber_spec.rb +3 -37
  40. data/spec/lib/appsignal/transaction_spec.rb +290 -155
  41. data/spec/lib/appsignal/transmitter_spec.rb +10 -0
  42. data/spec/lib/appsignal_spec.rb +80 -47
  43. data/spec/spec_helper.rb +21 -2
  44. data/spec/support/helpers/env_helpers.rb +31 -0
  45. data/spec/support/helpers/notification_helpers.rb +1 -30
  46. data/spec/support/helpers/transaction_helpers.rb +7 -7
  47. data/spec/support/project_fixture/config/appsignal.yml +2 -0
  48. metadata +14 -8
  49. data/lib/appsignal/rack/instrumentation.rb +0 -32
  50. data/lib/appsignal/rack/listener.rb +0 -32
  51. data/spec/lib/appsignal/rack/instrumentation_spec.rb +0 -72
  52. data/spec/lib/appsignal/rack/listener_spec.rb +0 -104
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eb6deacd3b946d7291c5ea4b1e7a98a4268e2867
4
- data.tar.gz: cf0d403fefc46f4957264e0b33f2b148e8ad7ae8
3
+ metadata.gz: 3904c5300ef30db2a6f5c8eaadce8e7a1ac7a5b6
4
+ data.tar.gz: dc5d9e98c1eaabaf84eacb629e490f6494819bf0
5
5
  SHA512:
6
- metadata.gz: ebd6b18c154977fb7cf24b9f6c441627f06df556676fd6dd22b8c6617ec3509a379b2ac301d187e7d49c699f7d93807ef5e3bd55d7f9b10ab0af2cc2df8840cd
7
- data.tar.gz: 7646f9ec281d26c0075bd313f2c9d1a2ff1c65ed6d60b167276d928c9796090a4082ba138bafe278047c9a335704c20305f3c80ab54f266a25260c5ff2b5b10c
6
+ metadata.gz: 66c82fe27b587026438c1608735dbd29e80ba2d475fb9057d33bb7b66b60a55c8347ee4fe92544a2b8bb74d0f8adb4e446bd392f59fb139a1ec48e715f7bf89b
7
+ data.tar.gz: 2e67ade5b8bb20aa9c28728590f0bf490f90806420804151c66f9952c11105e300c08e2467cf98199448738455e89a5d2217b40b81dc23e3167a873d07412408
@@ -3,6 +3,29 @@
3
3
  * Use native library and agent
4
4
  * Use API V2
5
5
 
6
+ # 0.11.15
7
+ * Improve Sinatra support
8
+
9
+ # 0.11.14
10
+ * Support ActiveJob wrapped jobs
11
+ * Improve proxy support
12
+ * Improve rake support
13
+
14
+ # 0.11.13
15
+ * Add Padrino support
16
+ * Add Rake task monitoring
17
+ * Add http proxy support
18
+ * Configure Net::HTTP to only use TLS
19
+ * Don't send queue if there is no content
20
+ * Don't retry transmission when response code is 400 (no content)
21
+ * Don't start Resque IPC server when AppSignal is not active
22
+ * Display warning message when attempting to send a non-exception to `send_exception`
23
+ * Fix capistrano 2 detection
24
+ * Fix issue with Sinatra integration attempting to attach an exception to a transaction that doesn't exist.
25
+
26
+ # 0.11.12
27
+ * Sanitizer will no longer inspect unknown objects, since implementations of inspect sometimes trigger unexpected behavior.
28
+
6
29
  # 0.11.11
7
30
  * Reliably get errors in production for Sinatra
8
31
 
data/Rakefile CHANGED
@@ -2,6 +2,7 @@ GEMFILES = %w(
2
2
  capistrano2
3
3
  capistrano3
4
4
  no_dependencies
5
+ padrino
5
6
  rails-3.0
6
7
  rails-3.1
7
8
  rails-3.2
@@ -7,6 +7,8 @@ end
7
7
 
8
8
  GC.disable
9
9
 
10
+ task :default => :'benchmark:all'
11
+
10
12
  namespace :benchmark do
11
13
  task :all => [:run_inactive, :run_active] do
12
14
  end
@@ -37,33 +39,31 @@ def run_benchmark
37
39
  puts "Running #{no_transactions} normal transactions"
38
40
  puts(Benchmark.measure do
39
41
  no_transactions.times do |i|
40
- transaction_id = "transaction_#{i}"
41
- ActiveSupport::Notifications.instrumenter.instance_variable_set(:@id, transaction_id)
42
- Appsignal::Transaction.create("transaction_#{i}", {})
42
+ request = Appsignal::Transaction::GenericRequest.new(
43
+ :controller => 'HomeController',
44
+ :action => 'show',
45
+ :params => {:id => 1}
46
+ )
47
+ Appsignal::Transaction.create("transaction_#{i}", Appsignal::Transaction::HTTP_REQUEST, request)
43
48
 
44
- ActiveSupport::Notifications.instrument('sql.active_record', :sql => 'SELECT `users`.* FROM `users`
45
- WHERE `users`.`id` = ?')
46
- 10.times do
47
- ActiveSupport::Notifications.instrument('sql.active_record', :sql => 'SELECT `todos`.* FROM `todos` WHERE `todos`.`id` = ?')
48
- end
49
+ ActiveSupport::Notifications.instrument('process_action.action_controller') do
50
+ ActiveSupport::Notifications.instrument('sql.active_record', :sql => 'SELECT `users`.* FROM `users`
51
+ WHERE `users`.`id` = ?')
52
+ 10.times do
53
+ ActiveSupport::Notifications.instrument('sql.active_record', :sql => 'SELECT `todos`.* FROM `todos` WHERE `todos`.`id` = ?')
54
+ end
49
55
 
50
- ActiveSupport::Notifications.instrument('render_template.action_view', :identifier => 'app/views/home/show.html.erb') do
51
- 5.times do
52
- ActiveSupport::Notifications.instrument('render_partial.action_view', :identifier => 'app/views/home/_piece.html.erb') do
53
- 3.times do
54
- ActiveSupport::Notifications.instrument('cache.read')
56
+ ActiveSupport::Notifications.instrument('render_template.action_view', :identifier => 'app/views/home/show.html.erb') do
57
+ 5.times do
58
+ ActiveSupport::Notifications.instrument('render_partial.action_view', :identifier => 'app/views/home/_piece.html.erb') do
59
+ 3.times do
60
+ ActiveSupport::Notifications.instrument('cache.read')
61
+ end
55
62
  end
56
63
  end
57
64
  end
58
65
  end
59
66
 
60
- ActiveSupport::Notifications.instrument(
61
- 'process_action.action_controller',
62
- :controller => 'HomeController',
63
- :action => 'show',
64
- :params => {:id => 1}
65
- )
66
-
67
67
  Appsignal::Transaction.complete_current!
68
68
  end
69
69
  puts 'Finished'
@@ -19,10 +19,10 @@ static VALUE stop_extension(VALUE self) {
19
19
  return Qnil;
20
20
  }
21
21
 
22
- static VALUE start_transaction(VALUE self, VALUE transaction_id) {
22
+ static VALUE start_transaction(VALUE self, VALUE transaction_id, VALUE namespace) {
23
23
  Check_Type(transaction_id, T_STRING);
24
24
 
25
- return INT2FIX(appsignal_start_transaction(StringValueCStr(transaction_id)));
25
+ return INT2FIX(appsignal_start_transaction(StringValueCStr(transaction_id), StringValueCStr(namespace)));
26
26
  }
27
27
 
28
28
  static VALUE start_event(VALUE self, VALUE transaction_index) {
@@ -73,16 +73,23 @@ static VALUE set_transaction_error_data(VALUE self, VALUE transaction_index, VAL
73
73
  return Qnil;
74
74
  }
75
75
 
76
- static VALUE set_transaction_base_data(VALUE self, VALUE transaction_index, VALUE namespace, VALUE action, VALUE queue_start) {
76
+ static VALUE set_transaction_action(VALUE self, VALUE transaction_index, VALUE action) {
77
77
  Check_Type(transaction_index, T_FIXNUM);
78
- Check_Type(namespace, T_STRING);
79
78
  Check_Type(action, T_STRING);
79
+
80
+ appsignal_set_transaction_action(
81
+ FIX2INT(transaction_index),
82
+ StringValueCStr(action)
83
+ );
84
+ return Qnil;
85
+ }
86
+
87
+ static VALUE set_transaction_queue_start(VALUE self, VALUE transaction_index, VALUE queue_start) {
88
+ Check_Type(transaction_index, T_FIXNUM);
80
89
  Check_Type(queue_start, T_FIXNUM);
81
90
 
82
- appsignal_set_transaction_base_data(
91
+ appsignal_set_transaction_queue_start(
83
92
  FIX2INT(transaction_index),
84
- StringValueCStr(namespace),
85
- StringValueCStr(action),
86
93
  FIX2LONG(queue_start)
87
94
  );
88
95
  return Qnil;
@@ -214,24 +221,25 @@ void Init_appsignal_extension(void) {
214
221
  VALUE Extension = rb_define_class_under(Appsignal, "Extension", rb_cObject);
215
222
 
216
223
  // Transaction monitoring
217
- rb_define_singleton_method(Extension, "start", start, 0);
218
- rb_define_singleton_method(Extension, "stop_agent", stop_agent, 0);
219
- rb_define_singleton_method(Extension, "stop_extension", stop_extension, 0);
220
- rb_define_singleton_method(Extension, "start_transaction", start_transaction, 1);
221
- rb_define_singleton_method(Extension, "start_event", start_event, 1);
222
- rb_define_singleton_method(Extension, "finish_event", finish_event, 4);
223
- rb_define_singleton_method(Extension, "set_transaction_error", set_transaction_error, 3);
224
- rb_define_singleton_method(Extension, "set_transaction_error_data", set_transaction_error_data, 3);
225
- rb_define_singleton_method(Extension, "set_transaction_base_data", set_transaction_base_data, 4);
226
- rb_define_singleton_method(Extension, "set_transaction_metadata", set_transaction_metadata, 3);
227
- rb_define_singleton_method(Extension, "finish_transaction", finish_transaction, 1);
224
+ rb_define_singleton_method(Extension, "start", start, 0);
225
+ rb_define_singleton_method(Extension, "stop_agent", stop_agent, 0);
226
+ rb_define_singleton_method(Extension, "stop_extension", stop_extension, 0);
227
+ rb_define_singleton_method(Extension, "start_transaction", start_transaction, 2);
228
+ rb_define_singleton_method(Extension, "start_event", start_event, 1);
229
+ rb_define_singleton_method(Extension, "finish_event", finish_event, 4);
230
+ rb_define_singleton_method(Extension, "set_transaction_error", set_transaction_error, 3);
231
+ rb_define_singleton_method(Extension, "set_transaction_error_data", set_transaction_error_data, 3);
232
+ rb_define_singleton_method(Extension, "set_transaction_action", set_transaction_action, 2);
233
+ rb_define_singleton_method(Extension, "set_transaction_queue_start", set_transaction_queue_start, 2);
234
+ rb_define_singleton_method(Extension, "set_transaction_metadata", set_transaction_metadata, 3);
235
+ rb_define_singleton_method(Extension, "finish_transaction", finish_transaction, 1);
228
236
 
229
237
  // Metrics
230
- rb_define_singleton_method(Extension, "set_gauge", set_gauge, 2);
231
- rb_define_singleton_method(Extension, "set_host_gauge", set_host_gauge, 2);
232
- rb_define_singleton_method(Extension, "set_process_gauge", set_process_gauge, 2);
233
- rb_define_singleton_method(Extension, "increment_counter", increment_counter, 2);
234
- rb_define_singleton_method(Extension, "add_distribution_value", add_distribution_value, 2);
238
+ rb_define_singleton_method(Extension, "set_gauge", set_gauge, 2);
239
+ rb_define_singleton_method(Extension, "set_host_gauge", set_host_gauge, 2);
240
+ rb_define_singleton_method(Extension, "set_process_gauge", set_process_gauge, 2);
241
+ rb_define_singleton_method(Extension, "increment_counter", increment_counter, 2);
242
+ rb_define_singleton_method(Extension, "add_distribution_value", add_distribution_value, 2);
235
243
 
236
244
  // Event hooks
237
245
  install_event_hooks();
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'padrino', '~> 0.12.0'
4
+
5
+ gem 'generator_spec'
6
+
7
+ gemspec :path => '../'
@@ -68,53 +68,74 @@ module Appsignal
68
68
  Appsignal::Extension.stop_extension
69
69
  end
70
70
 
71
-
72
- def monitor_transaction(name, payload={})
71
+ def monitor_transaction(name, env={})
73
72
  unless active?
74
73
  yield
75
74
  return
76
75
  end
77
76
 
77
+ if name.start_with?('perform_job'.freeze)
78
+ namespace = Appsignal::Transaction::BACKGROUND_JOB
79
+ request = Appsignal::Transaction::GenericRequest.new(env)
80
+ elsif name.start_with?('process_action'.freeze)
81
+ namespace = Appsignal::Transaction::HTTP_REQUEST
82
+ request = ::Rack::Request.new(env)
83
+ else
84
+ logger.error("Unrecognized name '#{name}'") and return
85
+ end
86
+ transaction = Appsignal::Transaction.create(
87
+ SecureRandom.uuid,
88
+ namespace,
89
+ request
90
+ )
78
91
  begin
79
- Appsignal::Transaction.create(SecureRandom.uuid, ENV.to_hash)
80
- ActiveSupport::Notifications.instrument(name, payload) do
92
+ ActiveSupport::Notifications.instrument(name) do
81
93
  yield
82
94
  end
83
- rescue => exception
84
- Appsignal.set_exception(exception)
85
- raise exception
95
+ rescue => error
96
+ transaction.set_error(error)
97
+ raise error
86
98
  ensure
99
+ transaction.set_http_or_background_action(request.env)
100
+ transaction.set_http_or_background_queue_start
87
101
  Appsignal::Transaction.complete_current!
88
102
  end
89
103
  end
90
104
 
91
- def listen_for_exception(&block)
105
+ def listen_for_error(&block)
92
106
  yield
93
- rescue Exception => exception
94
- send_exception(exception)
95
- raise exception
107
+ rescue => error
108
+ send_error(error)
109
+ raise error
96
110
  end
111
+ alias :listen_for_exception :listen_for_error
97
112
 
98
- def send_exception(exception, tags=nil)
99
- return if !active? || is_ignored_exception?(exception)
100
- transaction = Appsignal::Transaction.create(SecureRandom.uuid, ENV.to_hash)
113
+ def send_error(error, tags=nil, namespace=Appsignal::Transaction::HTTP_REQUEST)
114
+ return if !active? || is_ignored_error?(error)
115
+ unless error.is_a?(Exception)
116
+ logger.error('Can\'t send error, given value is not an exception')
117
+ return
118
+ end
119
+ transaction = Appsignal::Transaction.create(
120
+ SecureRandom.uuid,
121
+ namespace,
122
+ Appsignal::Transaction::GenericRequest.new({})
123
+ )
101
124
  transaction.set_tags(tags) if tags
102
- transaction.set_error(exception)
125
+ transaction.set_error(error)
103
126
  Appsignal::Transaction.complete_current!
104
127
  end
128
+ alias :send_exception :send_error
105
129
 
106
- def add_exception(exception)
107
- warn '[DEPRECATION] add_exception is deprecated, use set_exception instead'
108
- set_exception(exception)
109
- end
110
-
111
- def set_exception(exception)
130
+ def set_error(exception)
112
131
  return if !active? ||
113
132
  Appsignal::Transaction.current.nil? ||
114
133
  exception.nil? ||
115
- is_ignored_exception?(exception)
134
+ is_ignored_error?(exception)
116
135
  Appsignal::Transaction.current.set_error(exception)
117
136
  end
137
+ alias :set_exception :set_error
138
+ alias :add_exception :set_error
118
139
 
119
140
  def tag_request(params={})
120
141
  return unless active?
@@ -178,9 +199,10 @@ module Appsignal
178
199
  config && config.active?
179
200
  end
180
201
 
181
- def is_ignored_exception?(exception)
182
- Appsignal.config[:ignore_exceptions].include?(exception.class.name)
202
+ def is_ignored_error?(error)
203
+ Appsignal.config[:ignore_errors].include?(error.class.name)
183
204
  end
205
+ alias :is_ignored_exception? :is_ignored_error?
184
206
 
185
207
  def is_ignored_action?(action)
186
208
  Appsignal.config[:ignore_actions].include?(action)
@@ -208,8 +230,9 @@ require 'appsignal/subscriber'
208
230
  require 'appsignal/transaction'
209
231
  require 'appsignal/version'
210
232
  require 'appsignal/rack/js_exception_catcher'
211
- require 'appsignal/rack/listener'
212
- require 'appsignal/rack/instrumentation'
213
- require 'appsignal/integrations/rails'
214
233
  require 'appsignal/js_exception_transaction'
215
234
  require 'appsignal/transmitter'
235
+
236
+ # This needs to be required immediately, that's why it's
237
+ # not in load_integrations
238
+ require 'appsignal/integrations/rails'
@@ -1,6 +1,7 @@
1
1
  require 'appsignal'
2
+ require 'capistrano/version'
2
3
 
3
- if defined?(Capistrano::VERSION)
4
+ if defined?(Capistrano::VERSION) && Gem::Version.new(Capistrano::VERSION) >= Gem::Version.new(3)
4
5
  # Capistrano 3+
5
6
  load File.expand_path('../integrations/capistrano/appsignal.cap', __FILE__)
6
7
  else
@@ -8,7 +8,7 @@ module Appsignal
8
8
 
9
9
  DEFAULT_CONFIG = {
10
10
  :debug => false,
11
- :ignore_exceptions => [],
11
+ :ignore_errors => [],
12
12
  :ignore_actions => [],
13
13
  :send_params => true,
14
14
  :endpoint => 'https://push.appsignal.com',
@@ -18,6 +18,21 @@ module Appsignal
18
18
  :frontend_error_catching_path => '/appsignal_error_catcher'
19
19
  }.freeze
20
20
 
21
+ ENV_TO_KEY_MAPPING = {
22
+ 'APPSIGNAL_ACTIVE' => :active,
23
+ 'APPSIGNAL_PUSH_API_KEY' => :push_api_key,
24
+ 'APPSIGNAL_APP_NAME' => :name,
25
+ 'APPSIGNAL_PUSH_API_ENDPOINT' => :endpoint,
26
+ 'APPSIGNAL_FRONTEND_ERROR_CATCHING_PATH' => :frontend_error_catching_path,
27
+ 'APPSIGNAL_DEBUG' => :debug,
28
+ 'APPSIGNAL_INSTRUMENT_NET_HTTP' => :instrument_net_http,
29
+ 'APPSIGNAL_SKIP_SESSION_DATA' => :skip_session_data,
30
+ 'APPSIGNAL_ENABLE_FRONTEND_ERROR_CATCHING' => :enable_frontend_error_catching,
31
+ 'APPSIGNAL_IGNORE_ERRORS' => :ignore_errors,
32
+ 'APPSIGNAL_IGNORE_ACTIONS' => :ignore_actions,
33
+ 'APPSIGNAL_HTTP_PROXY' => :http_proxy
34
+ }.freeze
35
+
21
36
  attr_reader :root_path, :env, :initial_config, :config_hash
22
37
 
23
38
  def initialize(root_path, env, initial_config={}, logger=Appsignal.logger)
@@ -25,46 +40,33 @@ module Appsignal
25
40
  @env = env.to_s
26
41
  @initial_config = initial_config
27
42
  @logger = logger
43
+ @valid = false
44
+
45
+ # Initial config
46
+ @config_hash = DEFAULT_CONFIG.merge(initial_config)
28
47
 
48
+ # Load config from environment variables
49
+ load_from_environment
50
+
51
+ # Load the config file if it exists
29
52
  if File.exists?(config_file)
30
- load_config_from_disk
31
- elsif ENV['APPSIGNAL_PUSH_API_KEY']
32
- load_default_config_with_push_api_key_and_name_from_env(
33
- ENV['APPSIGNAL_PUSH_API_KEY']
34
- )
35
- elsif ENV['APPSIGNAL_API_KEY']
36
- load_default_config_with_push_api_key_and_name_from_env(
37
- ENV['APPSIGNAL_API_KEY']
38
- )
39
- @logger.info(
40
- 'The APPSIGNAL_API_KEY environment variable has been deprecated, ' \
41
- 'please switch to APPSIGNAL_PUSH_API_KEY'
42
- )
43
- else
44
- carefully_log_error(
45
- "Not loading: No config file found at '#{config_file}' " \
46
- "and no APPSIGNAL_PUSH_API_KEY env var present"
47
- )
53
+ load_from_disk
48
54
  end
49
- if config_hash && !config_hash[:name]
50
- @logger.debug(
51
- "There's no application name set in your config file or in the APPSIGNAL_APP_NAME env var. " \
52
- "You should set one unless your app runs on Heroku."
53
- )
54
- end
55
- end
56
55
 
57
- def loaded?
58
- !! config_hash
56
+ # Validate that we have a correct config
57
+ validate
59
58
  end
60
59
 
61
60
  def [](key)
62
- return unless loaded?
63
61
  config_hash[key]
64
62
  end
65
63
 
64
+ def valid?
65
+ @valid
66
+ end
67
+
66
68
  def active?
67
- !! self[:active]
69
+ @valid && self[:active]
68
70
  end
69
71
 
70
72
  def write_to_environment
@@ -72,12 +74,14 @@ module Appsignal
72
74
  ENV['APPSIGNAL_APP_PATH'] = root_path.to_s
73
75
  ENV['APPSIGNAL_AGENT_PATH'] = File.expand_path('../../../ext', __FILE__).to_s
74
76
  ENV['APPSIGNAL_LOG_PATH'] = File.join(root_path, 'log')
77
+ ENV['APPSIGNAL_ENVIRONMENT'] = env
78
+ ENV['APPSIGNAL_AGENT_VERSION'] = Appsignal::AGENT_VERSION
75
79
  ENV['APPSIGNAL_DEBUG_LOGGING'] = config_hash[:debug].to_s
76
80
  ENV['APPSIGNAL_PUSH_API_ENDPOINT'] = config_hash[:endpoint]
77
81
  ENV['APPSIGNAL_PUSH_API_KEY'] = config_hash[:push_api_key]
78
82
  ENV['APPSIGNAL_APP_NAME'] = config_hash[:name]
79
- ENV['APPSIGNAL_ENVIRONMENT'] = env
80
- ENV['APPSIGNAL_AGENT_VERSION'] = Appsignal::AGENT_VERSION
83
+ ENV['APPSIGNAL_HTTP_PROXY'] = config_hash[:http_proxy]
84
+ ENV['APPSIGNAL_IGNORE_ACTIONS'] = config_hash[:ignore_actions].join(',')
81
85
  end
82
86
 
83
87
  protected
@@ -86,7 +90,7 @@ module Appsignal
86
90
  @config_file ||= File.join(root_path, 'config', 'appsignal.yml')
87
91
  end
88
92
 
89
- def load_config_from_disk
93
+ def load_from_disk
90
94
  configurations = YAML.load(ERB.new(IO.read(config_file)).result)
91
95
  config_for_this_env = configurations[env]
92
96
  if config_for_this_env
@@ -99,10 +103,65 @@ module Appsignal
99
103
  if !config_for_this_env[:push_api_key] && config_for_this_env[:api_key]
100
104
  config_for_this_env[:push_api_key] = config_for_this_env[:api_key]
101
105
  end
106
+ if !config_for_this_env[:ignore_errors] && config_for_this_env[:ignore_exceptions]
107
+ config_for_this_env[:ignore_errors] = config_for_this_env[:ignore_exceptions]
108
+ end
109
+
110
+ merge(@config_hash, config_for_this_env)
111
+ else
112
+ carefully_log_error("Not loading from config file: config for '#{env}' not found")
113
+ end
114
+ end
115
+
116
+ def load_from_environment
117
+ config = {}
118
+
119
+ # Make active by default if APPSIGNAL_PUSH_API_KEY is present
120
+ if ENV['APPSIGNAL_PUSH_API_KEY']
121
+ config[:active] = true
122
+ end
123
+
124
+ # Configuration with string type
125
+ %w(APPSIGNAL_PUSH_API_KEY APPSIGNAL_APP_NAME APPSIGNAL_PUSH_API_ENDPOINT
126
+ APPSIGNAL_FRONTEND_ERROR_CATCHING_PATH APPSIGNAL_HTTP_PROXY).each do |var|
127
+ if env_var = ENV[var]
128
+ config[ENV_TO_KEY_MAPPING[var]] = env_var
129
+ end
130
+ end
131
+
132
+ # Configuration with boolean type
133
+ %w(APPSIGNAL_ACTIVE APPSIGNAL_DEBUG APPSIGNAL_INSTRUMENT_NET_HTTP
134
+ APPSIGNAL_SKIP_SESSION_DATA APPSIGNAL_ENABLE_FRONTEND_ERROR_CATCHING).each do |var|
135
+ if env_var = ENV[var]
136
+ config[ENV_TO_KEY_MAPPING[var]] = env_var == 'true'
137
+ end
138
+ end
102
139
 
103
- @config_hash = merge_config(config_for_this_env)
140
+ # Configuration with array of strings type
141
+ %w(APPSIGNAL_IGNORE_ERRORS APPSIGNAL_IGNORE_ACTIONS).each do |var|
142
+ if env_var = ENV[var]
143
+ config[ENV_TO_KEY_MAPPING[var]] = env_var.split(',')
144
+ end
145
+ end
146
+
147
+ merge(@config_hash, config)
148
+ end
149
+
150
+ def merge(original_config, new_config)
151
+ new_config.each do |key, value|
152
+ unless original_config[key].nil?
153
+ @logger.warn("Config key '#{key}' is being overwritten")
154
+ end
155
+ original_config[key] = value
156
+ end
157
+ end
158
+
159
+ def validate
160
+ if config_hash[:push_api_key]
161
+ @valid = true
104
162
  else
105
- carefully_log_error("Not loading: config for '#{env}' not found")
163
+ @valid = false
164
+ carefully_log_error("Push api key not set after loading config")
106
165
  end
107
166
  end
108
167
 
@@ -115,9 +174,5 @@ module Appsignal
115
174
  @config_hash[:name] = ENV['APPSIGNAL_APP_NAME'] if ENV['APPSIGNAL_APP_NAME']
116
175
  @config_hash[:active] = ENV['APPSIGNAL_ACTIVE'] == 'true' if ENV['APPSIGNAL_ACTIVE']
117
176
  end
118
-
119
- def merge_config(config)
120
- DEFAULT_CONFIG.merge(initial_config).merge(config)
121
- end
122
177
  end
123
178
  end