newrelic_rpm 3.8.0.218 → 3.8.1.221

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +32 -0
  3. data/README.md +4 -7
  4. data/Rakefile +3 -0
  5. data/lib/new_relic/agent.rb +3 -7
  6. data/lib/new_relic/agent/agent.rb +4 -14
  7. data/lib/new_relic/agent/agent_logger.rb +19 -11
  8. data/lib/new_relic/agent/autostart.rb +1 -1
  9. data/lib/new_relic/agent/configuration/default_source.rb +25 -12
  10. data/lib/new_relic/agent/configuration/manager.rb +14 -7
  11. data/lib/new_relic/agent/configuration/yaml_source.rb +39 -8
  12. data/lib/new_relic/agent/cross_app_monitor.rb +9 -7
  13. data/lib/new_relic/agent/cross_app_tracing.rb +6 -6
  14. data/lib/new_relic/agent/datastores/mongo.rb +6 -7
  15. data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +32 -13
  16. data/lib/new_relic/agent/datastores/mongo/statement_formatter.rb +4 -3
  17. data/lib/new_relic/agent/error_collector.rb +2 -2
  18. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +10 -69
  19. data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +5 -7
  20. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +2 -2
  21. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +77 -93
  22. data/lib/new_relic/agent/instrumentation/evented_subscriber.rb +1 -1
  23. data/lib/new_relic/agent/instrumentation/mongo.rb +26 -42
  24. data/lib/new_relic/agent/instrumentation/rubyprof.rb +1 -1
  25. data/lib/new_relic/agent/instrumentation/sinatra.rb +4 -1
  26. data/lib/new_relic/agent/javascript_instrumentor.rb +15 -6
  27. data/lib/new_relic/agent/method_tracer.rb +41 -92
  28. data/lib/new_relic/agent/request_sampler.rb +0 -1
  29. data/lib/new_relic/agent/rules_engine.rb +36 -12
  30. data/lib/new_relic/agent/shim_agent.rb +0 -1
  31. data/lib/new_relic/agent/sql_sampler.rb +8 -15
  32. data/lib/new_relic/agent/stats_engine.rb +2 -6
  33. data/lib/new_relic/agent/stats_engine/metric_stats.rb +8 -2
  34. data/lib/new_relic/agent/stats_engine/stats_hash.rb +1 -1
  35. data/lib/new_relic/agent/supported_versions.rb +1 -1
  36. data/lib/new_relic/agent/traced_method_stack.rb +87 -0
  37. data/lib/new_relic/agent/transaction.rb +277 -107
  38. data/lib/new_relic/agent/transaction_sample_builder.rb +2 -2
  39. data/lib/new_relic/agent/transaction_sampler.rb +18 -27
  40. data/lib/new_relic/agent/transaction_state.rb +15 -40
  41. data/lib/new_relic/control/instance_methods.rb +8 -4
  42. data/lib/new_relic/recipes.rb +3 -3
  43. data/lib/new_relic/transaction_sample.rb +3 -7
  44. data/lib/new_relic/version.rb +1 -1
  45. data/lib/sequel/extensions/newrelic_instrumentation.rb +3 -3
  46. data/newrelic_rpm.gemspec +15 -9
  47. data/test/agent_helper.rb +71 -36
  48. data/test/environments/norails/Gemfile +2 -0
  49. data/test/environments/rails21/Gemfile +2 -0
  50. data/test/environments/rails22/Gemfile +2 -0
  51. data/test/environments/rails23/Gemfile +2 -0
  52. data/test/environments/rails30/Gemfile +2 -0
  53. data/test/environments/rails31/Gemfile +2 -0
  54. data/test/environments/rails32/Gemfile +2 -0
  55. data/test/environments/rails40/Gemfile +2 -0
  56. data/test/environments/rails41/Gemfile +1 -0
  57. data/test/helpers/mongo_metric_builder.rb +1 -1
  58. data/test/multiverse/suites/agent_only/audit_log_test.rb +2 -2
  59. data/test/multiverse/suites/agent_only/cross_application_tracing_test.rb +9 -1
  60. data/test/multiverse/suites/agent_only/encoding_handling_test.rb +1 -1
  61. data/test/multiverse/suites/agent_only/logging_test.rb +2 -2
  62. data/test/multiverse/suites/agent_only/marshaling_test.rb +8 -9
  63. data/test/multiverse/suites/agent_only/rum_instrumentation_test.rb +14 -1
  64. data/test/multiverse/suites/agent_only/set_transaction_name_test.rb +30 -13
  65. data/test/multiverse/suites/agent_only/thread_profiling_test.rb +9 -8
  66. data/test/multiverse/suites/agent_only/transaction_ignoring_test.rb +43 -0
  67. data/test/multiverse/suites/config_file_loading/config_file_loading_test.rb +77 -5
  68. data/test/multiverse/suites/excon/excon_test.rb +1 -1
  69. data/test/multiverse/suites/mongo/Envfile +4 -7
  70. data/test/multiverse/suites/mongo/helpers/mongo_operation_tests.rb +55 -16
  71. data/test/multiverse/suites/mongo/helpers/mongo_server.rb +6 -4
  72. data/test/multiverse/suites/rails/bad_instrumentation_test.rb +2 -2
  73. data/test/multiverse/suites/rails/error_tracing_test.rb +3 -1
  74. data/test/multiverse/suites/rails/request_statistics_test.rb +14 -14
  75. data/test/multiverse/suites/rails/transaction_ignoring_test.rb +45 -0
  76. data/test/multiverse/suites/sequel/sequel_instrumentation_test.rb +1 -1
  77. data/test/new_relic/agent/agent/connect_test.rb +4 -4
  78. data/test/new_relic/agent/agent_logger_test.rb +32 -0
  79. data/test/new_relic/agent/configuration/manager_test.rb +12 -4
  80. data/test/new_relic/agent/configuration/yaml_source_test.rb +2 -2
  81. data/test/new_relic/agent/cross_app_monitor_test.rb +6 -2
  82. data/test/new_relic/agent/cross_app_tracing_test.rb +5 -5
  83. data/test/new_relic/agent/datastores/mongo/statement_formatter_test.rb +7 -6
  84. data/test/new_relic/agent/error_collector_test.rb +1 -2
  85. data/test/new_relic/agent/instrumentation/action_controller_subscriber_test.rb +24 -11
  86. data/test/new_relic/agent/instrumentation/action_view_subscriber_test.rb +2 -2
  87. data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +12 -17
  88. data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +43 -32
  89. data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +3 -4
  90. data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +36 -20
  91. data/test/new_relic/agent/javascript_instrumentor_test.rb +1 -2
  92. data/test/new_relic/agent/method_tracer/class_methods/add_method_tracer_test.rb +15 -26
  93. data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +66 -103
  94. data/test/new_relic/agent/method_tracer_test.rb +2 -2
  95. data/test/new_relic/agent/mock_scope_listener.rb +3 -6
  96. data/test/new_relic/agent/pipe_channel_manager_test.rb +4 -4
  97. data/test/new_relic/agent/rules_engine_test.rb +13 -0
  98. data/test/new_relic/agent/sql_sampler_test.rb +8 -10
  99. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +18 -0
  100. data/test/new_relic/agent/stats_engine_test.rb +0 -173
  101. data/test/new_relic/agent/threading/agent_thread_test.rb +27 -26
  102. data/test/new_relic/agent/traced_method_stack_test.rb +139 -0
  103. data/test/new_relic/agent/transaction_sample_builder_test.rb +2 -12
  104. data/test/new_relic/agent/transaction_sampler_test.rb +98 -107
  105. data/test/new_relic/agent/transaction_state_test.rb +52 -61
  106. data/test/new_relic/agent/transaction_test.rb +209 -140
  107. data/test/new_relic/agent_test.rb +3 -2
  108. data/test/new_relic/control_test.rb +10 -9
  109. data/test/new_relic/fake_collector.rb +34 -2
  110. data/test/new_relic/http_client_test_cases.rb +0 -5
  111. data/test/new_relic/license_test.rb +4 -2
  112. data/test/new_relic/local_environment_test.rb +14 -28
  113. data/test/new_relic/multiverse_helpers.rb +2 -2
  114. data/test/new_relic/rack/developer_mode_test.rb +4 -5
  115. data/test/new_relic/transaction_ignoring_test_cases.rb +104 -0
  116. data/test/new_relic/transaction_sample_test.rb +14 -7
  117. data/test/performance/lib/performance/instrumentation/gc_stats.rb +6 -3
  118. data/test/performance/suites/transaction_tracing.rb +4 -1
  119. data/test/test_helper.rb +31 -60
  120. data/ui/views/newrelic/show_sample.rhtml +1 -1
  121. metadata +46 -101
  122. metadata.gz.sig +0 -0
  123. data/lib/new_relic/agent/stats_engine/transactions.rb +0 -114
  124. data/lib/new_relic/agent/transaction/pop.rb +0 -52
  125. data/test/new_relic/agent/transaction/pop_test.rb +0 -79
data.tar.gz.sig CHANGED
Binary file
data/CHANGELOG CHANGED
@@ -1,5 +1,37 @@
1
1
  # New Relic Ruby Agent Release Notes #
2
2
 
3
+ ## v3.8.1 ##
4
+
5
+ * Better handling for Rack applications implemented as middlewares
6
+
7
+ When using a Sinatra application as a middleware around another app (for
8
+ example, a Rails app), or manually instrumenting a Rack middleware wrapped
9
+ around another application, the agent would previously generate two separate
10
+ transaction names in the New Relic UI (one for the middleware, and one for
11
+ the inner application).
12
+
13
+ As of this release, the agent will instead unify these two parts into a single
14
+ transaction in the UI. The unified name will be the name assigned to the
15
+ inner-most traced transaction by default. Calls to
16
+ NewRelic::Agent.set_transaction_name will continue to override the default
17
+ names assigned by the agent's instrumentation code.
18
+
19
+ This change also makes it possible to run X-Ray sessions against transactions
20
+ of the 'inner' application in cases where one instrumented app is wrapped in
21
+ another that's implemented as a middleware.
22
+
23
+ * Support for mongo-1.10.0
24
+
25
+ The Ruby agent now instruments version 1.10.0 of the mongo gem (versions 1.8.x
26
+ and 1.9.x were already supported, and continue to be).
27
+
28
+ * Allow setting configuration file path via an option to manual_start
29
+
30
+ Previously, passing the :config_path option to NewRelic::Agent.manual_start
31
+ would not actually affect the location that the agent would use to look for
32
+ its configuration file. This has been fixed, and the log messages emitted when
33
+ a configuration file is not found should now be more helpful.
34
+
3
35
  ## v3.8.0 ##
4
36
 
5
37
  * Better support for forking and daemonizing dispatchers (e.g. Puma, Unicorn)
data/README.md CHANGED
@@ -4,7 +4,7 @@ New Relic is a performance management system, developed by
4
4
  New Relic, Inc (http://www.newrelic.com). It provides you with deep
5
5
  information about the performance of your Rails or Ruby
6
6
  application as it runs in production. The New Relic Ruby Agent is
7
- dual-purposed as a either a Rails plugin or a Gem, hosted on
7
+ dual-purposed as a either a Gem or a Rails plugin, hosted on
8
8
  [github](http://github.com/newrelic/rpm/tree/master).
9
9
 
10
10
  The New Relic Ruby Agent runs in one of two modes:
@@ -51,11 +51,7 @@ and avoid breaking your code with future changes to the agent.
51
51
 
52
52
  ## Getting Started
53
53
 
54
- Install the Ruby Agent as a gem.
55
-
56
- gem install newrelic_rpm
57
-
58
- Or add it to your project's Gemfile.
54
+ Add the Ruby Agent to your project's Gemfile.
59
55
 
60
56
  gem 'newrelic_rpm'
61
57
 
@@ -182,7 +178,8 @@ You can find more detailed documentation [on our website](http://newrelic.com/do
182
178
  and specifically in the [Ruby category](http://newrelic.com/docs/ruby).
183
179
 
184
180
  If you can't find what you're looking for there, reach out to us on our [support
185
- site](http://support.newrelic.com/) and we'll be happy to help you.
181
+ site](http://support.newrelic.com/) or our [community forum](http://forum.newrelic.com)
182
+ and we'll be happy to help you.
186
183
 
187
184
  Also available is community support on IRC: we generally use #newrelic
188
185
  on irc.freenode.net
data/Rakefile CHANGED
@@ -1,7 +1,10 @@
1
1
  require 'rubygems'
2
2
  require 'rake/testtask'
3
+ require 'yard'
3
4
  require "#{File.dirname(__FILE__)}/lib/tasks/all.rb"
4
5
 
6
+ YARD::Rake::YardocTask.new
7
+
5
8
  task :default => :test
6
9
  task :test => ['test:newrelic']
7
10
 
@@ -505,11 +505,7 @@ module NewRelic
505
505
  # @api public
506
506
  #
507
507
  def set_transaction_name(name, options={})
508
- if Transaction.current
509
- namer = Instrumentation::ControllerInstrumentation::TransactionNamer.new(self)
510
- Transaction.current.type = options[:category] if options[:category]
511
- Transaction.current.name = "#{namer.category_name(options[:category])}/#{name}"
512
- end
508
+ Transaction.set_overriding_transaction_name(name, options)
513
509
  end
514
510
 
515
511
  # Get the name of the current running transaction. This is useful if you
@@ -519,8 +515,8 @@ module NewRelic
519
515
  #
520
516
  def get_transaction_name
521
517
  if Transaction.current
522
- namer = Instrumentation::ControllerInstrumentation::TransactionNamer.new(self)
523
- Transaction.current.name.sub(Regexp.new("\\A#{Regexp.escape(namer.category_name)}/"), '')
518
+ namer = Instrumentation::ControllerInstrumentation::TransactionNamer
519
+ Transaction.current.best_name.sub(Regexp.new("\\A#{Regexp.escape(namer.category_name)}/"), '')
524
520
  end
525
521
  end
526
522
 
@@ -255,16 +255,6 @@ module NewRelic
255
255
  end
256
256
  end
257
257
 
258
- # Tells the statistics engine we are starting a new transaction
259
- def start_transaction
260
- @stats_engine.start_transaction
261
- end
262
-
263
- # Tells the statistics engine we are ending a transaction
264
- def end_transaction
265
- @stats_engine.end_transaction
266
- end
267
-
268
258
  # Sets a thread local variable as to whether we should or
269
259
  # should not record sql in the current thread. Returns the
270
260
  # previous value, if there is one
@@ -419,8 +409,8 @@ module NewRelic
419
409
  if Agent.config[:license_key] && Agent.config[:license_key].length > 0
420
410
  true
421
411
  else
422
- ::NewRelic::Agent.logger.warn("No license key found in newrelic.yml config. " +
423
- "This often means your newrelic.yml is missing a section for the running environment '#{NewRelic::Control.instance.env}'")
412
+ ::NewRelic::Agent.logger.warn("No license key found. " +
413
+ "This often means your newrelic.yml file was not found, or it lacks a section for the running environment, '#{NewRelic::Control.instance.env}'.")
424
414
  false
425
415
  end
426
416
  end
@@ -922,7 +912,7 @@ module NewRelic
922
912
  log_error(e)
923
913
  if opts[:keep_retrying]
924
914
  note_connect_failure
925
- ::NewRelic::Agent.logger.warn "Will re-attempt in #{connect_retry_period} seconds"
915
+ ::NewRelic::Agent.logger.info "Will re-attempt in #{connect_retry_period} seconds"
926
916
  sleep connect_retry_period
927
917
  retry
928
918
  else
@@ -1033,7 +1023,7 @@ module NewRelic
1033
1023
  rescue ForceRestartException, ForceDisconnectException
1034
1024
  raise
1035
1025
  rescue => e
1036
- NewRelic::Agent.logger.warn("Error during check_for_and_handle_agent_commands, will retry later: ", e)
1026
+ NewRelic::Agent.logger.info("Error during check_for_and_handle_agent_commands, will retry later: ", e)
1037
1027
  end
1038
1028
  end
1039
1029
 
@@ -16,24 +16,24 @@ module NewRelic
16
16
  gather_startup_logs
17
17
  end
18
18
 
19
- def fatal(*msgs)
20
- format_and_send(:fatal, msgs)
19
+ def fatal(*msgs, &blk)
20
+ format_and_send(:fatal, msgs, &blk)
21
21
  end
22
22
 
23
- def error(*msgs)
24
- format_and_send(:error, msgs)
23
+ def error(*msgs, &blk)
24
+ format_and_send(:error, msgs, &blk)
25
25
  end
26
26
 
27
- def warn(*msgs)
28
- format_and_send(:warn, msgs)
27
+ def warn(*msgs, &blk)
28
+ format_and_send(:warn, msgs, &blk)
29
29
  end
30
30
 
31
- def info(*msgs)
32
- format_and_send(:info, msgs)
31
+ def info(*msgs, &blk)
32
+ format_and_send(:info, msgs, &blk)
33
33
  end
34
34
 
35
- def debug(*msgs)
36
- format_and_send(:debug, msgs)
35
+ def debug(*msgs, &blk)
36
+ format_and_send(:debug, msgs, &blk)
37
37
  end
38
38
 
39
39
  def log_once(level, key, *msgs)
@@ -74,7 +74,15 @@ module NewRelic
74
74
  end
75
75
 
76
76
  # Allows for passing exceptions in explicitly, which format with backtrace
77
- def format_and_send(level, *msgs)
77
+ def format_and_send(level, *msgs, &block)
78
+ if block
79
+ if @log.send("#{level}?")
80
+ msgs = Array(block.call)
81
+ else
82
+ msgs = []
83
+ end
84
+ end
85
+
78
86
  msgs.flatten.each do |item|
79
87
  case item
80
88
  when Exception then log_exception(level, item, :debug)
@@ -13,7 +13,7 @@ module NewRelic
13
13
  # the console during interactive sessions.
14
14
  #
15
15
  # It should be possible to override Autostart logic with an explicit
16
- # configuration, for example the NEWRELIC_ENABLE environment variable or
16
+ # configuration, for example the NEWRELIC_AGENT_ENABLED environment variable or
17
17
  # agent_enabled key in newrelic.yml
18
18
  module Autostart
19
19
  extend self
@@ -27,16 +27,23 @@ module NewRelic
27
27
  result
28
28
  end
29
29
 
30
- def self.config_path
30
+ def self.config_search_paths
31
31
  Proc.new {
32
- files = []
33
- files << File.join("config","newrelic.yml")
34
- files << File.join("newrelic.yml")
32
+ paths = [
33
+ File.join("config","newrelic.yml"),
34
+ File.join("newrelic.yml")
35
+ ]
35
36
  if ENV["HOME"]
36
- files << File.join(ENV["HOME"], ".newrelic", "newrelic.yml")
37
- files << File.join(ENV["HOME"], "newrelic.yml")
37
+ paths << File.join(ENV["HOME"], ".newrelic", "newrelic.yml")
38
+ paths << File.join(ENV["HOME"], "newrelic.yml")
38
39
  end
39
- found_path = files.detect do |file|
40
+ paths
41
+ }
42
+ end
43
+
44
+ def self.config_path
45
+ Proc.new {
46
+ found_path = NewRelic::Agent.config[:config_search_paths].detect do |file|
40
47
  File.expand_path(file) if File.exists? file
41
48
  end
42
49
  found_path || ""
@@ -227,6 +234,12 @@ module NewRelic
227
234
  :type => String,
228
235
  :description => "Path to newrelic.yml. When omitted the agent will check (in order) 'config/newrelic.yml', 'newrelic.yml', $HOME/.newrelic/newrelic.yml' and $HOME/newrelic.yml."
229
236
  },
237
+ :config_search_paths => {
238
+ :default => DefaultSource.config_search_paths,
239
+ :public => false,
240
+ :type => Array,
241
+ :description => "An array of candidate locations for the agent's configuration file."
242
+ },
230
243
  :app_name => {
231
244
  :default => DefaultSource.app_name,
232
245
  :public => true,
@@ -525,7 +538,7 @@ module NewRelic
525
538
  :default => false,
526
539
  :public => true,
527
540
  :type => Boolean,
528
- :description => 'Enable or disable agent middleware for sinatra. This middleware is responsible for instrumenting advanced feature support for sinatra (e.g. Cross-application tracing, Real User Monitoring, Error collection).'
541
+ :description => 'Enable or disable agent middleware for sinatra. This middleware is responsible for instrumenting advanced feature support for Sinatra; for example, cross application tracing, page load timing (sometimes referred to as real user monitoring or RUM), and error collection.'
529
542
  },
530
543
  :disable_view_instrumentation => {
531
544
  :default => false,
@@ -657,7 +670,7 @@ module NewRelic
657
670
  :default => false,
658
671
  :public => true,
659
672
  :type => Boolean,
660
- :description => 'Enable or disable MongoDB instrumentation.'
673
+ :description => 'Controls whether instrumentation for the mongo gem will be installed by the agent.'
661
674
  },
662
675
  :'slow_sql.enabled' => {
663
676
  :default => DefaultSource.slow_sql_enabled,
@@ -723,7 +736,7 @@ module NewRelic
723
736
  :default => true,
724
737
  :public => true,
725
738
  :type => Boolean,
726
- :description => 'Enable or disable real user monitoring.'
739
+ :description => 'Enable or disable page load timing (sometimes referred to as real user monitoring or RUM).'
727
740
  },
728
741
  :browser_key => {
729
742
  :default => '',
@@ -759,7 +772,7 @@ module NewRelic
759
772
  :default => DefaultSource.browser_monitoring_auto_instrument,
760
773
  :public => true,
761
774
  :type => Boolean,
762
- :description => 'Enable or disable automatic insertion of the real user monitoring header and footer into outgoing responses.'
775
+ :description => 'Enable or disable automatic insertion of the JavaScript header into outgoing responses for page load timing (sometimes referred to as real user monitoring or RUM).'
763
776
  },
764
777
  :'browser_monitoring.loader' => {
765
778
  :default => DefaultSource.browser_monitoring_loader,
@@ -820,7 +833,7 @@ module NewRelic
820
833
  :default => true,
821
834
  :public => true,
822
835
  :type => Boolean,
823
- :description => 'Enable or disable cross-application tracing.'
836
+ :description => 'Enable or disable cross application tracing.'
824
837
  },
825
838
  :cross_application_tracing => {
826
839
  :default => nil,
@@ -42,11 +42,14 @@ module NewRelic
42
42
  end
43
43
 
44
44
  def remove_config(source=nil)
45
- if block_given?
46
- @config_stack.delete_if {|c| yield c }
47
- else
48
- @config_stack.delete(source)
45
+ @config_stack.delete_if do |c|
46
+ if block_given?
47
+ yield c
48
+ else
49
+ c.class == source.class && c == source
50
+ end
49
51
  end
52
+
50
53
  reset_cache
51
54
  invoke_callbacks(:remove, source)
52
55
  log_config(:remove, source)
@@ -159,9 +162,13 @@ module NewRelic
159
162
  end
160
163
 
161
164
  def log_config(direction, source)
162
- ::NewRelic::Agent.logger.debug(
163
- "Updating config (#{direction}) from #{source.class}. Results:",
164
- flattened.inspect)
165
+ # Just generating this log message (specifically calling
166
+ # flattened.inspect) is expensive enough that we don't want to do it
167
+ # unless we're actually going to be logging the message based on our
168
+ # current log level.
169
+ ::NewRelic::Agent.logger.debug do
170
+ "Updating config (#{direction}) from #{source.class}. Results: #{flattened.inspect}"
171
+ end
165
172
  end
166
173
 
167
174
  private
@@ -11,16 +11,13 @@ module NewRelic
11
11
  attr_accessor :file_path
12
12
 
13
13
  def initialize(path, env)
14
- ::NewRelic::Agent.logger.info("Reading configuration from #{path}")
15
-
16
14
  config = {}
15
+
17
16
  begin
18
- @file_path = File.expand_path(path)
19
- if !File.exists?(@file_path)
20
- ::NewRelic::Agent.logger.error("Unable to load configuration from #{path}")
21
- return
22
- end
17
+ @file_path = validate_config_file_path(path)
18
+ return unless @file_path
23
19
 
20
+ ::NewRelic::Agent.logger.info("Reading configuration from #{path}")
24
21
  file = File.read(@file_path)
25
22
 
26
23
  # Next two are for populating the newrelic.yml via erb binding, necessary
@@ -35,7 +32,7 @@ module NewRelic
35
32
 
36
33
  config = merge!(confighash[env] || {})
37
34
  rescue ScriptError, StandardError => e
38
- ::NewRelic::Agent.logger.error("Unable to read configuration file #{path}: #{e}")
35
+ ::NewRelic::Agent.logger.error("Failed to read or parse configuration file at #{path}: #{e}")
39
36
  end
40
37
 
41
38
  if config['transaction_tracer'] &&
@@ -51,6 +48,40 @@ module NewRelic
51
48
 
52
49
  protected
53
50
 
51
+ def validate_config_file_path(path)
52
+ expanded_path = File.expand_path(path)
53
+
54
+ if path.empty? || !File.exists?(expanded_path)
55
+ warn_missing_config_file(expanded_path)
56
+ return
57
+ end
58
+
59
+ expanded_path
60
+ end
61
+
62
+ def warn_missing_config_file(path)
63
+ based_on = 'unknown'
64
+ source = ::NewRelic::Agent.config.source(:config_path)
65
+ candidate_paths = [path]
66
+
67
+ case source
68
+ when DefaultSource
69
+ based_on = 'defaults'
70
+ candidate_paths = NewRelic::Agent.config[:config_search_paths].map do |p|
71
+ File.expand_path(p)
72
+ end
73
+ when EnvironmentSource
74
+ based_on = 'environment variable'
75
+ when ManualSource
76
+ based_on = 'API call'
77
+ end
78
+
79
+ NewRelic::Agent.logger.warn(
80
+ "No configuration file found. Working directory = #{Dir.pwd}",
81
+ "Looked in these locations (based on #{based_on}): #{candidate_paths.join(", ")}"
82
+ )
83
+ end
84
+
54
85
  def with_yaml_engine
55
86
  return yield unless NewRelic::LanguageSupport.needs_syck?
56
87
 
@@ -106,13 +106,15 @@ module NewRelic
106
106
 
107
107
  def insert_response_header(request_headers, response_headers)
108
108
  unless client_cross_app_id.nil?
109
- unless NewRelic::Agent::TransactionState.get.transaction.nil?
110
- NewRelic::Agent::Transaction.freeze_name
111
- timings = NewRelic::Agent::TransactionState.get.timings
112
- content_length = content_length_from_request(request_headers)
113
-
114
- set_response_headers(response_headers, timings, content_length)
115
- set_metrics(client_cross_app_id, timings)
109
+ txn = NewRelic::Agent::TransactionState.get.most_recent_transaction
110
+ unless txn.nil?
111
+ txn.freeze_name_and_execute_if_not_ignored do
112
+ timings = NewRelic::Agent::TransactionState.get.timings
113
+ content_length = content_length_from_request(request_headers)
114
+
115
+ set_response_headers(response_headers, timings, content_length)
116
+ set_metrics(client_cross_app_id, timings)
117
+ end
116
118
  end
117
119
  clear_client_cross_app_id
118
120
  end
@@ -63,11 +63,11 @@ module NewRelic
63
63
  # This method MUST return a pair. The first item always returns the
64
64
  # starting time of the trace, even if an error occurs. The second item is
65
65
  # the transaction segment if it was sucessfully pushed.
66
- def start_trace( request )
66
+ def start_trace(request)
67
67
  t0 = Time.now
68
68
 
69
- inject_request_headers( request ) if cross_app_enabled?
70
- segment = stats_engine.push_scope( :http_request, t0 )
69
+ inject_request_headers(request) if cross_app_enabled?
70
+ segment = NewRelic::Agent::TracedMethodStack.push_frame(:http_request, t0)
71
71
 
72
72
  return t0, segment
73
73
  rescue => err
@@ -109,9 +109,9 @@ module NewRelic
109
109
  end
110
110
  end
111
111
  ensure
112
- # If we have a segment, always pop the scope stack to avoid an
113
- # inconsistent state, which prevents tracing of whole transaction.
114
- stats_engine.pop_scope( segment, scoped_metric, t1 ) if segment
112
+ # If we have a segment, always pop the traced method stack to avoid
113
+ # an inconsistent state, which prevents tracing of whole transaction.
114
+ NewRelic::Agent::TracedMethodStack.pop_frame( segment, scoped_metric, t1 ) if segment
115
115
  end
116
116
  rescue NewRelic::Agent::CrossAppTracing::Error => err
117
117
  NewRelic::Agent.logger.debug "while cross app tracing", err