newrelic_rpm 3.9.5.251 → 3.9.6.257

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +74 -3
  3. data/GUIDELINES_FOR_CONTRIBUTING.md +19 -15
  4. data/README.md +1 -1
  5. data/Rakefile +22 -1
  6. data/lib/new_relic/agent/agent.rb +17 -5
  7. data/lib/new_relic/agent/agent_logger.rb +4 -0
  8. data/lib/new_relic/agent/configuration/default_source.rb +45 -1
  9. data/lib/new_relic/agent/configuration/manager.rb +43 -7
  10. data/lib/new_relic/agent/cross_app_monitor.rb +0 -3
  11. data/lib/new_relic/agent/cross_app_tracing.rb +8 -5
  12. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +4 -1
  13. data/lib/new_relic/agent/instrumentation/active_job.rb +93 -0
  14. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +2 -1
  15. data/lib/new_relic/agent/instrumentation/middleware_tracing.rb +2 -2
  16. data/lib/new_relic/agent/instrumentation/sinatra.rb +1 -2
  17. data/lib/new_relic/agent/new_relic_service.rb +1 -1
  18. data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +20 -1
  19. data/lib/new_relic/agent/new_relic_service/pruby_marshaller.rb +5 -1
  20. data/lib/new_relic/agent/pipe_channel_manager.rb +32 -11
  21. data/lib/new_relic/agent/threading/agent_thread.rb +1 -1
  22. data/lib/new_relic/agent/threading/backtrace_node.rb +4 -3
  23. data/lib/new_relic/agent/transaction.rb +27 -6
  24. data/lib/new_relic/agent/transaction_state.rb +3 -3
  25. data/lib/new_relic/agent/vm/mri_vm.rb +3 -3
  26. data/lib/new_relic/control/frameworks/rails3.rb +1 -16
  27. data/lib/new_relic/control/instance_methods.rb +2 -0
  28. data/lib/new_relic/json_wrapper.rb +18 -3
  29. data/lib/new_relic/rack/browser_monitoring.rb +7 -5
  30. data/lib/new_relic/rack/developer_mode.rb +2 -0
  31. data/lib/new_relic/rack/error_collector.rb +12 -51
  32. data/lib/new_relic/transaction_sample.rb +0 -4
  33. data/lib/new_relic/transaction_sample/segment.rb +0 -4
  34. data/lib/new_relic/version.rb +1 -1
  35. data/newrelic_rpm.gemspec +3 -2
  36. data/test/agent_helper.rb +1 -1
  37. data/test/config/test.cert.crt +16 -12
  38. data/test/config/test.cert.key +13 -13
  39. data/test/environments/lib/environments/runner.rb +3 -0
  40. data/test/environments/rails30/Gemfile +2 -2
  41. data/test/environments/rails31/Gemfile +2 -2
  42. data/test/environments/rails32/Gemfile +2 -2
  43. data/test/environments/rails40/Gemfile +2 -4
  44. data/test/environments/rails41/Gemfile +2 -4
  45. data/test/environments/rails42/Gemfile +2 -4
  46. data/test/fixtures/cross_agent_tests/attribute_configuration.json +349 -0
  47. data/test/fixtures/cross_agent_tests/labels.json +31 -2
  48. data/test/fixtures/cross_agent_tests/postgres_explain_obfuscation/README.md +16 -0
  49. data/test/fixtures/cross_agent_tests/rum_client_config.json +9 -9
  50. data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/empty_head +4 -0
  51. data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/no_end_header.html +6 -0
  52. data/test/fixtures/cross_agent_tests/rum_loader_insertion_location/x_ua_meta_tag_multiple_tags.html +12 -0
  53. data/test/multiverse/lib/multiverse/runner.rb +33 -1
  54. data/test/multiverse/lib/multiverse/suite.rb +79 -7
  55. data/test/multiverse/suites/active_record/Envfile +1 -1
  56. data/test/multiverse/suites/agent_only/encoding_handling_test.rb +1 -1
  57. data/test/multiverse/suites/agent_only/labels_test.rb +2 -1
  58. data/test/multiverse/suites/agent_only/set_transaction_name_test.rb +2 -3
  59. data/test/multiverse/suites/agent_only/thread_profiling_test.rb +6 -6
  60. data/test/multiverse/suites/capistrano/Envfile +2 -2
  61. data/test/multiverse/suites/capistrano2/Envfile +4 -0
  62. data/test/multiverse/suites/curb/Envfile +4 -0
  63. data/test/multiverse/suites/high_security/config/newrelic.yml +5 -2
  64. data/test/multiverse/suites/high_security/high_security_test.rb +10 -8
  65. data/test/multiverse/suites/json/Envfile +23 -0
  66. data/test/multiverse/suites/json/config/newrelic.yml +22 -0
  67. data/test/multiverse/suites/json/json_test.rb +17 -0
  68. data/test/multiverse/suites/marshalling/marshalling_test.rb +2 -45
  69. data/test/multiverse/suites/rails/Envfile +3 -3
  70. data/test/multiverse/suites/rails/activejob_test.rb +137 -0
  71. data/test/multiverse/suites/rails/error_tracing_test.rb +15 -8
  72. data/test/multiverse/suites/rails/parameter_capture_test.rb +39 -19
  73. data/test/multiverse/suites/sequel/Envfile +5 -5
  74. data/test/multiverse/suites/sidekiq/Envfile +2 -2
  75. data/test/multiverse/suites/sinatra/Envfile +2 -1
  76. data/test/multiverse/suites/yajl/Envfile +13 -0
  77. data/test/multiverse/suites/yajl/config/newrelic.yml +21 -0
  78. data/test/multiverse/suites/yajl/yajl_test.rb +19 -0
  79. data/test/new_relic/agent/agent_logger_test.rb +10 -0
  80. data/test/new_relic/agent/agent_test.rb +7 -1
  81. data/test/new_relic/agent/configuration/default_source_test.rb +24 -0
  82. data/test/new_relic/agent/configuration/manager_test.rb +60 -2
  83. data/test/new_relic/agent/configuration/orphan_configuration_test.rb +25 -13
  84. data/test/new_relic/agent/cross_app_tracing_test.rb +10 -1
  85. data/test/new_relic/agent/instrumentation/active_job_test.rb +20 -0
  86. data/test/new_relic/agent/instrumentation/active_record_test.rb +10 -17
  87. data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +15 -0
  88. data/test/new_relic/agent/instrumentation/sinatra_test.rb +1 -1
  89. data/test/new_relic/agent/new_relic_service_test.rb +24 -0
  90. data/test/new_relic/agent/pipe_channel_manager_test.rb +44 -2
  91. data/test/new_relic/agent/threading/agent_thread_test.rb +1 -2
  92. data/test/new_relic/agent/threading/backtrace_node_test.rb +12 -0
  93. data/test/new_relic/agent/transaction_state_test.rb +3 -6
  94. data/test/new_relic/agent/transaction_test.rb +163 -0
  95. data/test/new_relic/agent_test.rb +13 -1
  96. data/test/new_relic/fake_collector.rb +5 -5
  97. data/test/new_relic/fake_server.rb +5 -3
  98. data/test/new_relic/http_client_test_cases.rb +0 -4
  99. data/test/new_relic/marshalling_test_cases.rb +54 -0
  100. data/test/new_relic/multiverse_helpers.rb +2 -2
  101. data/test/new_relic/rack/browser_monitoring_test.rb +6 -0
  102. data/test/new_relic/rack/developer_mode_test.rb +8 -0
  103. data/test/new_relic/rack/error_collector_test.rb +0 -41
  104. data/test/new_relic/transaction_sample/segment_test.rb +0 -13
  105. data/test/new_relic/transaction_sample_test.rb +1 -11
  106. data/test/performance/lib/performance/instrumentation/perf_tools.rb +1 -1
  107. data/test/performance/lib/performance/runner.rb +1 -1
  108. data/test/performance/script/runner +2 -1
  109. data/test/performance/suites/rum_autoinsertion.rb +12 -2
  110. metadata +24 -11
  111. metadata.gz.sig +0 -0
  112. data/test/config/test.cert.csr +0 -11
  113. data/test/config/testing-privkey.pem +0 -18
data.tar.gz.sig CHANGED
Binary file
data/CHANGELOG CHANGED
@@ -1,5 +1,76 @@
1
1
  # New Relic Ruby Agent Release Notes #
2
2
 
3
+ ## v3.9.6 ##
4
+
5
+ * Rails 4.2 ActiveJob support
6
+
7
+ A new version of Rails is coming! One of the highlight features is
8
+ ActiveJob, a framework for interacting with background job processors. This
9
+ release of the Ruby agent adds instrumentation to give you insight into
10
+ ActiveJob, whether you're just testing it out or running it for real.
11
+
12
+ Metrics are recorded around enqueuing ActiveJobs, and background transactions
13
+ are started for any ActiveJob performed where the agent didn't already
14
+ provide specific instrumentation (such as DelayedJob, Resque and Sidekiq).
15
+
16
+ Since Rails 4.2 is still in beta we'd love to hear any feedback on this
17
+ instrumentation so it'll be rock solid for the general release!
18
+
19
+ * Ruby 2.2.0-preview1 updates
20
+
21
+ Ruby 2.2.0 is on its way later in the year, and the Ruby agent is ready for
22
+ it. Updates to the GC stats and various other small changes have already been
23
+ applied, and our automated tests are running against 2.2.0 so the agent will
24
+ be ready on release day.
25
+
26
+ * Ignoring transactions by URL
27
+
28
+ While you could always ignore transactions by controller and action, the
29
+ Ruby agent previously lacked a way to ignore by specific URLs or patterns
30
+ without code changes. This release adds the config setting,
31
+ `rules.ignore_url_regexes` to ignore specific transactions based on the
32
+ request URL as well. For more information, see the documentation at:
33
+ https://docs.newrelic.com/docs/agents/ruby-agent/installation-configuration/ignoring-specific-transactions#config-ignoring
34
+
35
+ * Better dependency detection in non-Rack applications
36
+
37
+ The Ruby agent runs dependency detection at key points in the Rack and Rails
38
+ lifecycle, but non-Rails apps could occasionally miss out instrumenting late
39
+ loaded libraries. The agent now runs an additional dependency detection
40
+ during manual_start to more seamlessly install instrumentation in any app.
41
+
42
+ * Excluding /newrelic routes from developer mode
43
+
44
+ Recent changes to track time in middleware resulted in New Relic's developer
45
+ mode capturing its own page views in the list. This has been fixed. Thanks
46
+ to Ignatius Reza Lesmana for the report!
47
+
48
+ * Spikes in external time
49
+
50
+ Timeouts during certain external HTTP requests could result in incorrect
51
+ large spikes in the time recorded by the agent. This has been fixed.
52
+
53
+ * Recognize browser_monitoring.auto_instrument setting in non-Rails apps
54
+
55
+ The `browser_monitoring.auto_instrument` config setting disables
56
+ auto-injection of JavaScript into your pages, but was not properly obeyed in
57
+ Sinatra and other non-Rails contexts. This has been fixed.
58
+
59
+ * Failures to gather CPU thread time on JRuby
60
+
61
+ JRuby running on certain JVM's and operating systems (FreeBSD in particular)
62
+ did not always support the method being used to gather CPU burn metrics.
63
+ This would result in a failure during those transactions. This has been
64
+ fixed.
65
+
66
+ * Fix for rare race condition in Resque instrumentation
67
+
68
+ A race condition in the agent's Resque instrumentation that could cause rare
69
+ Resque job failures in high-throughput Resque setups has been fixed. This bug
70
+ would manifest as an exception with the following error message:
71
+ "RuntimeError: can't add a new key into hash during iteration" and a backtrace
72
+ leading through the PipeChannelManager class in the agent.
73
+
3
74
  ## v3.9.5 ##
4
75
 
5
76
  * Per-dyno data on Heroku
@@ -22,10 +93,10 @@
22
93
  (including Rails and Sinatra apps) and include them under the httpResponseCode
23
94
  attribute on events sent to Insights.
24
95
 
25
- * Stricter limits on memory usage of metrics and SQL traces
96
+ * Stricter limits on memory usage of SQL traces
26
97
 
27
- The agent now imposes stricter limits on the number of distinct SQL traces and
28
- metrics that it will buffer in memory at any point in time, leading to more
98
+ The agent now imposes stricter limits on the number of distinct SQL traces
99
+ that it will buffer in memory at any point in time, leading to more
29
100
  predictable memory consumption even in exceptional circumstances.
30
101
 
31
102
  * Improved reliability of thread profiling
@@ -1,18 +1,19 @@
1
1
  # Guidelines for Contributing Code
2
2
 
3
- At New Relic we welcome community code contributions to the Ruby Agent, and have
3
+ At New Relic we welcome community code contributions to the Ruby agent, and have
4
4
  taken effort to make this process easy for both contributors and our development
5
5
  team.
6
6
 
7
- When contributing keep in mind that the agent runs in a wide variety of ruby
8
- language implementations (e.g. 1.8.6, 1.8.7, 1.9.x, jruby, etc.) as well as a
9
- wide variety of application environments (e.g. rails, sinatra, roll-your-own,
10
- etc., etc.)
7
+ When contributing, keep in mind that the agent runs in a wide variety of Ruby
8
+ language implementations (e.g. 1.8.7, 1.9.x, 2.x.x, jruby, rbx, etc.) as well as
9
+ a wide variety of application environments (e.g. Rails, Sinatra, roll-your-own,
10
+ etc.) See https://docs.newrelic.com/docs/agents/ruby-agent/getting-started/new-relic-ruby#compat
11
+ for the current full list.
11
12
 
12
- Because of this we need to be more defensive in our coding practices than most
13
- projects. Syntax must be compatible with all supported ruby implementations
13
+ Because of this, we need to be more defensive in our coding practices than most
14
+ projects. Syntax must be compatible with all supported Ruby implementations
14
15
  (e.g. no 1.9 specific hash syntax) and we can't assume the presence of any
15
- specific libraries such as `ActiveSupport`.
16
+ specific libraries, including `ActiveSupport`, `ActiveRecord`, etc.
16
17
 
17
18
  ## Testing
18
19
 
@@ -31,15 +32,15 @@ Running the test suite is simple. Just invoke:
31
32
  bundle exec rake
32
33
 
33
34
  This will run the unit tests in standalone mode, bootstrapping a basic Rails
34
- 3.2 environment for the agent to instrument then executing the test suite.
35
+ 3.2 environment for the agent to instrument, then executing the test suite.
35
36
 
36
37
  These tests are setup to run automatically in
37
- [travis-ci](https://travis-ci.org/newrelic/rpm) under several Ruby implementations.
38
- When you've pushed your changes to github you can confirm that the travis-ci
39
- build passes for your fork of the codebase.
38
+ [Travis CI](https://travis-ci.org/newrelic/rpm) under several Ruby implementations.
39
+ When you've pushed your changes to GitHub, you can confirm that the Travis
40
+ build passes for your fork.
40
41
 
41
- Additionally, our own CI jobs runs these tests under multiple versions of Rails to
42
- verify compatibility.
42
+ Additionally, our own CI jobs runs these tests under multiple versions of Rails
43
+ to verify compatibility.
43
44
 
44
45
  ### Writing Tests
45
46
 
@@ -57,7 +58,7 @@ chances it will be accepted.
57
58
  ### Functional Testing
58
59
 
59
60
  For cases where the unit test environment is not sufficient for testing a
60
- change (e.g. instrumentation for a non-rails framework, not available in the
61
+ change (e.g. instrumentation for a non-Rails framework, not available in the
61
62
  unit test environment), we have a functional testing suite called multiverse.
62
63
  These tests can be run by invoking:
63
64
 
@@ -74,3 +75,6 @@ that you are granting New Relic a non-exclusive, non-revokable, no-cost license
74
75
  to use the code, algorithms, patents, and ideas in that code in our products if
75
76
  we so choose. You also agree the code is provided as-is and you provide no
76
77
  warranties as to its fitness or correctness for any purpose.
78
+
79
+ If you have any feedback on how we can make contributing easier, please get in
80
+ touch at [support.newrelic.com](http://support.newrelic.com) and let us know!
data/README.md CHANGED
@@ -67,7 +67,7 @@ The initial configuration is done in the `newrelic.yml` file. This file
67
67
  is by default read from the `config` directory of the application root
68
68
  and is subsequently searched for in the application root directory,
69
69
  and then in a `~/.newrelic` directory. Once you're up and running you can
70
- enable Server Side Config and manage your newrelic configuation from the web
70
+ enable Server Side Config and manage your newrelic configuration from the web
71
71
  UI.
72
72
 
73
73
  #### Rails Installation
data/Rakefile CHANGED
@@ -73,7 +73,7 @@ end
73
73
  desc 'Record build number and stage'
74
74
  task :record_build, [ :build_number, :stage ] do |t, args|
75
75
  build_string = args.build_number
76
- build_string << ".#{args.stage}" if args.stage
76
+ build_string << ".#{args.stage}" unless args.stage.nil? || args.stage.empty?
77
77
 
78
78
  gitsha = File.exists?(".git") ? `git rev-parse HEAD` : "Unknown"
79
79
  gitsha.chomp!
@@ -125,6 +125,27 @@ task :update_ca_bundle do |t|
125
125
  puts "Done, please commit your changes to #{bundle_path}"
126
126
  end
127
127
 
128
+ namespace :cross_agent_tests do
129
+ cross_agent_tests_upstream_path = File.expand_path(File.join(File.dirname(__FILE__), '..', 'cross_agent_tests'))
130
+ cross_agent_tests_local_path = File.expand_path(File.join(File.dirname(__FILE__), 'test', 'fixtures', 'cross_agent_tests'))
131
+
132
+ desc 'Pull latest changes from cross_agent_tests repo'
133
+ task :pull do
134
+ puts "Updating embedded cross_agent_tests from #{cross_agent_tests_upstream_path}..."
135
+ cmd = "rsync -avu --exclude .git #{cross_agent_tests_upstream_path}/ #{cross_agent_tests_local_path}/"
136
+ puts cmd
137
+ system(cmd)
138
+ end
139
+
140
+ desc 'Copy changes from embedded cross_agent_tests to official repo working copy'
141
+ task :push do
142
+ puts "Copying changes from embedded cross_agent_tests to #{cross_agent_tests_upstream_path}..."
143
+ cmd = "rsync -avu #{cross_agent_tests_local_path}/ #{cross_agent_tests_upstream_path}/"
144
+ puts cmd
145
+ system(cmd)
146
+ end
147
+ end
148
+
128
149
  task :console do
129
150
  require 'pry'
130
151
  require 'newrelic_rpm'
@@ -298,6 +298,14 @@ module NewRelic
298
298
  ::NewRelic::Agent.logger.info "Application: #{Agent.config.app_names.join(", ")}"
299
299
  end
300
300
 
301
+ def log_ignore_url_regexes
302
+ regexes = NewRelic::Agent.config[:'rules.ignore_url_regexes']
303
+
304
+ unless regexes.empty?
305
+ ::NewRelic::Agent.logger.info "Ignoring URLs that match the following regexes: #{regexes.map(&:inspect).join(", ")}."
306
+ end
307
+ end
308
+
301
309
  # Logs the configured application names
302
310
  def app_name_configured?
303
311
  names = Agent.config.app_names
@@ -495,6 +503,10 @@ module NewRelic
495
503
  log_startup
496
504
  check_config_and_start_agent
497
505
  log_version_and_pid
506
+
507
+ events.subscribe(:finished_configuring) do
508
+ log_ignore_url_regexes
509
+ end
498
510
  end
499
511
 
500
512
  # Clear out the metric data, errors, and transaction traces, etc.
@@ -570,11 +582,11 @@ module NewRelic
570
582
  @event_loop.on(:report_data) do
571
583
  transmit_data
572
584
  end
573
- @event_loop.on(:report_transaction_event_data) do
574
- transmit_transaction_event_data
585
+ @event_loop.on(:report_event_data) do
586
+ transmit_event_data
575
587
  end
576
588
  @event_loop.fire_every(Agent.config[:data_report_period], :report_data)
577
- @event_loop.fire_every(report_period_for(:analytic_event_data), :report_transaction_event_data)
589
+ @event_loop.fire_every(report_period_for(:analytic_event_data), :report_event_data)
578
590
  @event_loop.run
579
591
  end
580
592
 
@@ -1019,7 +1031,7 @@ module NewRelic
1019
1031
  end
1020
1032
  end
1021
1033
 
1022
- def transmit_transaction_event_data
1034
+ def transmit_event_data
1023
1035
  now = Time.now
1024
1036
  ::NewRelic::Agent.logger.debug "Sending analytics data to New Relic Service"
1025
1037
 
@@ -1071,7 +1083,7 @@ module NewRelic
1071
1083
 
1072
1084
  @events.notify(:before_shutdown)
1073
1085
  transmit_data
1074
- transmit_transaction_event_data
1086
+ transmit_event_data
1075
1087
 
1076
1088
  if @connected_pid == $$ && !@service.kind_of?(NewRelic::Agent::NewRelicService)
1077
1089
  ::NewRelic::Agent.logger.debug "Sending New Relic service agent run shutdown message"
@@ -145,6 +145,10 @@ module NewRelic
145
145
  @already_logged
146
146
  end
147
147
 
148
+ def clear_already_logged
149
+ @already_logged = {}
150
+ end
151
+
148
152
  def wants_stdout?
149
153
  ::NewRelic::Agent.config[:log_file_path].upcase == "STDOUT"
150
154
  end
@@ -27,6 +27,11 @@ module NewRelic
27
27
  result
28
28
  end
29
29
 
30
+ def self.transform_for(key)
31
+ default_settings = ::NewRelic::Agent::Configuration::DEFAULTS[key]
32
+ default_settings[:transform] if default_settings
33
+ end
34
+
30
35
  def self.config_search_paths
31
36
  Proc.new {
32
37
  paths = [
@@ -182,6 +187,25 @@ module NewRelic
182
187
  def self.monitor_mode
183
188
  Proc.new { NewRelic::Agent.config[:enabled] }
184
189
  end
190
+
191
+ def self.rules_ignore
192
+ Proc.new do |rules|
193
+ rules = convert_to_list(rules)
194
+
195
+ rules.map do |rule|
196
+ /#{rule}/
197
+ end
198
+ end
199
+ end
200
+
201
+ def self.convert_to_list(value)
202
+ case value
203
+ when String
204
+ value.split(',')
205
+ else
206
+ value
207
+ end
208
+ end
185
209
  end
186
210
 
187
211
  AUTOSTART_BLACKLISTED_RAKE_TASKS = [
@@ -595,6 +619,13 @@ module NewRelic
595
619
  :type => Boolean,
596
620
  :description => 'Enable or disable active record instrumentation.'
597
621
  },
622
+ :disable_activejob => {
623
+ :default => false,
624
+ :public => true,
625
+ :type => Boolean,
626
+ :dynamic_name => true,
627
+ :description => 'Enable or disable ActiveJob instrumentation.'
628
+ },
598
629
  :disable_memcache_instrumentation => {
599
630
  :default => false,
600
631
  :public => true,
@@ -1032,6 +1063,12 @@ module NewRelic
1032
1063
  :type => Boolean,
1033
1064
  :description => 'Defines whether the agent will wrap third-party middlewares in instrumentation (regardless of whether they are installed via Rack::Builder or Rails).'
1034
1065
  },
1066
+ :disable_rails_middleware => {
1067
+ :default => false,
1068
+ :public => false,
1069
+ :type => Boolean,
1070
+ :description => 'Internal name for controlling Rails 3+ middleware instrumentation'
1071
+ },
1035
1072
  :'heroku.use_dyno_names' => {
1036
1073
  :default => true,
1037
1074
  :public => true,
@@ -1068,7 +1105,14 @@ module NewRelic
1068
1105
  :public => true,
1069
1106
  :type => String,
1070
1107
  :description => "Manual override for the path to your local CA bundle. This CA bundle will be used to validate the SSL certificate presented by New Relic's data collection service."
1071
- }
1108
+ },
1109
+ :'rules.ignore_url_regexes' => {
1110
+ :default => [],
1111
+ :public => true,
1112
+ :type => Array,
1113
+ :transform => DefaultSource.rules_ignore,
1114
+ :description => 'A list of patterns that will cause a transaction to be ignored if any of them match the URI.'
1115
+ }
1072
1116
  }.freeze
1073
1117
 
1074
1118
  end
@@ -115,17 +115,46 @@ module NewRelic
115
115
  config_stack.each do |config|
116
116
  next unless config
117
117
  accessor = key.to_sym
118
+
118
119
  if config.has_key?(accessor)
119
- if config[accessor].respond_to?(:call)
120
- return instance_eval(&config[accessor])
121
- else
122
- return config[accessor]
120
+ evaluated = evaluate_procs(config[accessor])
121
+
122
+ begin
123
+ return apply_transformations(accessor, evaluated)
124
+ rescue
125
+ next
123
126
  end
124
127
  end
125
128
  end
129
+
126
130
  nil
127
131
  end
128
132
 
133
+ def evaluate_procs(value)
134
+ if value.respond_to?(:call)
135
+ instance_eval(&value)
136
+ else
137
+ value
138
+ end
139
+ end
140
+
141
+ def apply_transformations(key, value)
142
+ if transform = transform_from_default(key)
143
+ begin
144
+ transform.call(value)
145
+ rescue => e
146
+ ::NewRelic::Agent.logger.error("Error applying transformation for #{key}, falling back to #{value}.", e)
147
+ raise e
148
+ end
149
+ else
150
+ value
151
+ end
152
+ end
153
+
154
+ def transform_from_default(key)
155
+ ::NewRelic::Agent::Configuration::DefaultSource.transform_for(key)
156
+ end
157
+
129
158
  def register_callback(key, &proc)
130
159
  @callbacks[key] << proc
131
160
  proc.call(@cache[key])
@@ -134,6 +163,7 @@ module NewRelic
134
163
  def invoke_callbacks(direction, source)
135
164
  return unless source
136
165
  source.keys.each do |key|
166
+
137
167
  if @cache[key] != source[key]
138
168
  @callbacks[key].each do |proc|
139
169
  if direction == :add
@@ -224,10 +254,9 @@ module NewRelic
224
254
  end
225
255
 
226
256
  def break_label_string_into_pairs(labels)
227
- # Strip whitespaces immediately before and after colons or semicolons
228
- stripped_labels = labels.gsub(/\s*(:|;)\s*/, '\1')
257
+ stripped_labels = labels.strip
229
258
  stripped_labels.split(';').map do |pair|
230
- pair.split(':')
259
+ pair.split(':').map(&:strip)
231
260
  end
232
261
  end
233
262
 
@@ -259,6 +288,7 @@ module NewRelic
259
288
  end
260
289
 
261
290
  pairs = limit_number_of_labels(pairs)
291
+ pairs = remove_duplicates(pairs)
262
292
  pairs.map do |key, value|
263
293
  {
264
294
  'label_type' => truncate(key),
@@ -290,6 +320,12 @@ module NewRelic
290
320
  end
291
321
  end
292
322
 
323
+ # We only take the last value provided for a given label type key
324
+ def remove_duplicates(pairs)
325
+ grouped_by_type = pairs.group_by(&:first)
326
+ grouped_by_type.values.map(&:last)
327
+ end
328
+
293
329
  def parse_labels_from_dictionary
294
330
  make_label_hash(NewRelic::Agent.config[:labels])
295
331
  end
@@ -89,8 +89,6 @@ module NewRelic
89
89
  txn_header = from_headers(request_headers, NEWRELIC_TXN_HEADER_KEYS) or return
90
90
  txn_header = obfuscator.deobfuscate(txn_header)
91
91
  txn_info = NewRelic::JSONWrapper.load(txn_header)
92
- NewRelic::Agent.logger.debug("Referring txn_info: %p" % [txn_info])
93
-
94
92
  state.referring_transaction_info = txn_info
95
93
  end
96
94
 
@@ -170,7 +168,6 @@ module NewRelic
170
168
 
171
169
  referring_guid = client_referring_transaction_guid(state)
172
170
  if referring_guid
173
- NewRelic::Agent.logger.debug "Referring transaction guid: %p" % [referring_guid]
174
171
  NewRelic::Agent.add_custom_parameters(:referring_transaction_guid => referring_guid)
175
172
  end
176
173
  end