newrelic_rpm 3.6.1.85.beta → 3.6.1.86.beta

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig CHANGED
Binary file
data/CHANGELOG CHANGED
@@ -28,6 +28,13 @@
28
28
  IP address of New Relic server to which it is sending data, since DNS may not
29
29
  be available in some environments. Thanks to Bill Kirtley for the contribution
30
30
 
31
+ * Added NewRelic::Agent.set_transaction_name and NewRelic::Agent.get_transaction_name
32
+
33
+ Ordinarily the name of your transaction is defined up-front, but if you'd like to
34
+ change the name of a transaction while it is still running you can use
35
+ **NewRelic::Agent.set_transaction_name()**. Similarly, if you need to know the name
36
+ of the currently running transaction, you can use **NewRelic::Agent.get_transaction_name()**.
37
+
31
38
  ## v3.6.0 ##
32
39
 
33
40
  * Sidekiq supprt
@@ -138,6 +138,9 @@ module NewRelic
138
138
 
139
139
  class BackgroundLoadingError < StandardError; end
140
140
 
141
+ # placeholder name used when we cannot determine a transaction's name
142
+ UNKNOWN_METRIC = '(unknown)'.freeze
143
+
141
144
  @agent = nil
142
145
 
143
146
  # The singleton Agent instance. Used internally.
@@ -405,6 +408,7 @@ module NewRelic
405
408
  #
406
409
  def notice_error(exception, options={})
407
410
  Transaction.notice_error(exception, options)
411
+ nil # don't return a noticed error datastructure. it can only hurt.
408
412
  end
409
413
 
410
414
  # Add parameters to the current transaction trace (and traced error if any)
@@ -44,7 +44,7 @@ module NewRelic
44
44
 
45
45
  def in_blacklisted_rake_task?
46
46
  tasks = begin
47
- Rake.application.top_level_tasks
47
+ ::Rake.application.top_level_tasks
48
48
  rescue => e
49
49
  ::NewRelic::Agent.logger.debug("Not in Rake environment so skipping blacklisted_rake_tasks check: #{e}")
50
50
  []
@@ -23,7 +23,7 @@ module NewRelic
23
23
  end
24
24
 
25
25
  def name
26
- '(unknown)'
26
+ ::NewRelic::Agent::UNKNOWN_METRIC
27
27
  end
28
28
  end
29
29
 
@@ -78,7 +78,7 @@ module NewRelic
78
78
  end
79
79
 
80
80
  def browser_monitoring_transaction_name
81
- current_transaction.name || '(unknown)'
81
+ current_transaction.name || ::NewRelic::Agent::UNKNOWN_METRIC
82
82
  end
83
83
 
84
84
  def browser_monitoring_queue_time
@@ -29,7 +29,7 @@ module NewRelic
29
29
  license_key = ''
30
30
 
31
31
  erb = ERB.new(file).result(binding)
32
- confighash = YAML.load(erb)
32
+ confighash = with_yaml_engine { YAML.load(erb) }
33
33
  ::NewRelic::Agent.logger.error("Config (#{path}) doesn't include a '#{env}' environment!") unless
34
34
  confighash.key?(env)
35
35
 
@@ -51,6 +51,16 @@ module NewRelic
51
51
 
52
52
  protected
53
53
 
54
+ def with_yaml_engine
55
+ return yield unless NewRelic::LanguageSupport.needs_syck?
56
+
57
+ yamler = ::YAML::ENGINE.yamler
58
+ ::YAML::ENGINE.yamler = 'syck'
59
+ result = yield
60
+ ::YAML::ENGINE.yamler = yamler
61
+ result
62
+ end
63
+
54
64
  def booleanify_values(config, *keys)
55
65
  # auto means defer ro default
56
66
  keys.each do |option|
@@ -108,6 +108,17 @@ module NewRelic
108
108
  exception.instance_variable_set(EXCEPTION_TAG_IVAR, true)
109
109
  end
110
110
 
111
+ def blamed_metric_name(options)
112
+ if options[:metric] && options[:metric] != ::NewRelic::Agent::UNKNOWN_METRIC
113
+ "Errors/#{options[:metric]}"
114
+ else
115
+ txn_info = TransactionInfo.get
116
+ if txn_info && txn_info.transaction
117
+ "Errors/#{txn_info.transaction.name}"
118
+ end
119
+ end
120
+ end
121
+
111
122
  # Increments a statistic that tracks total error rate
112
123
  # Be sure not to double-count same exception. This clears per harvest.
113
124
  def increment_error_count!(exception, options={})
@@ -115,9 +126,9 @@ module NewRelic
115
126
  tag_as_seen(exception)
116
127
 
117
128
  metric_names = ["Errors/all"]
118
- if options[:metric] && options[:metric] != '(unknown)'
119
- metric_names << "Errors/#{options[:metric]}"
120
- end
129
+ blamed_metric = blamed_metric_name(options)
130
+ metric_names << blamed_metric if blamed_metric
131
+
121
132
  stats_engine = NewRelic::Agent.agent.stats_engine
122
133
  stats_engine.record_metrics(metric_names) do |stats|
123
134
  stats.increment_count
@@ -44,7 +44,7 @@ module NewRelic
44
44
  def recordable?
45
45
  name[0] == '!' ||
46
46
  metric_name == 'View/text template/Rendering' ||
47
- metric_name == 'View/(unknown)/Partial'
47
+ metric_name == "View/#{::NewRelic::Agent::UNKNOWN_METRIC}/Partial"
48
48
  end
49
49
 
50
50
  def metric_name
@@ -70,7 +70,7 @@ module NewRelic
70
70
  elsif (parts = identifier.split('/')).size > 1
71
71
  parts[-2..-1].join('/')
72
72
  else
73
- '(unknown)'
73
+ ::NewRelic::Agent::UNKNOWN_METRIC
74
74
  end
75
75
  end
76
76
 
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ # This is a legacy support shim now that the MetricFrame functionality has
6
+ # moved over to the Transaction class instead.
7
+ #
8
+ # This class is deprecated and will be removed in a future agent version.
9
+ #
10
+ # This class is not part of the public API. Avoid making calls on it directly.
11
+ #
12
+ module NewRelic
13
+ module Agent
14
+ module Instrumentation
15
+ class MetricFrame
16
+
17
+ def self.recording_web_transaction?
18
+ Transaction.recording_web_transaction?
19
+ end
20
+
21
+ def self.abort_transaction!
22
+ Transaction.abort_transaction!
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+ end
@@ -48,7 +48,7 @@ module NewRelic
48
48
  if options[:file]
49
49
  "file"
50
50
  elsif identifier.nil?
51
- "(unknown)"
51
+ ::NewRelic::Agent::UNKNOWN_METRIC
52
52
  elsif identifier.include? '/' # this is a filepath
53
53
  identifier.split('/')[-2..-1].join('/')
54
54
  else
@@ -81,7 +81,7 @@ module NewRelic
81
81
  end
82
82
 
83
83
  def transaction_name(routes, request)
84
- name = '(unknown)'
84
+ name = ::NewRelic::Agent::UNKNOWN_METRIC
85
85
  verb = http_verb(request)
86
86
 
87
87
  Array(routes[verb]).each do |pattern, keys, conditions, block|
@@ -94,7 +94,7 @@ module NewRelic
94
94
  end
95
95
  end
96
96
 
97
- name.gsub!(%r{^[/^]*(.*?)[/\$\?]*$}, '\1')
97
+ name = name.gsub(%r{^[/^]*(.*?)[/\$\?]*$}, '\1')
98
98
  if verb
99
99
  name = verb + ' ' + name
100
100
  end
@@ -102,7 +102,7 @@ module NewRelic
102
102
  name
103
103
  rescue => e
104
104
  ::NewRelic::Agent.logger.debug("#{e.class} : #{e.message} - Error encountered trying to identify Sinatra transaction name")
105
- '(unknown)'
105
+ ::NewRelic::Agent::UNKNOWN_METRIC
106
106
  end
107
107
  end
108
108
  end
@@ -159,7 +159,7 @@ module NewRelic
159
159
 
160
160
  # Unwind one stack level. It knows if it's back at the outermost caller and
161
161
  # does the appropriate wrapup of the context.
162
- def stop(metric='(unknown)')
162
+ def stop(metric=::NewRelic::Agent::UNKNOWN_METRIC)
163
163
  @name ||= metric unless name_frozen?
164
164
  freeze_name
165
165
  log_underflow if @type.nil?
@@ -8,7 +8,6 @@ require 'new_relic/agent/agent_logger'
8
8
 
9
9
  module NewRelic
10
10
  class Control
11
- include NewRelic::LanguageSupport::Control
12
11
 
13
12
  # Contains methods that relate to the runtime usage of the control
14
13
  # object. Note that these are subject to override in the
@@ -5,25 +5,10 @@
5
5
  module NewRelic::LanguageSupport
6
6
  extend self
7
7
 
8
- module Control
9
- def self.included(base)
10
- # need to use syck rather than psych when possible
11
- if defined?(::YAML::ENGINE)
12
- if !NewRelic::LanguageSupport.using_engine?('jruby') &&
13
- (NewRelic::LanguageSupport.using_version?('1.9.1') ||
14
- NewRelic::LanguageSupport.using_version?('1.9.2'))
15
- base.class_eval do
16
- def load_newrelic_yml(*args)
17
- yamler = ::YAML::ENGINE.yamler
18
- ::YAML::ENGINE.yamler = 'syck'
19
- val = super
20
- ::YAML::ENGINE.yamler = yamler
21
- val
22
- end
23
- end
24
- end
25
- end
26
- end
8
+ # need to use syck rather than psych when possible
9
+ def needs_syck?
10
+ !NewRelic::LanguageSupport.using_engine?('jruby') &&
11
+ NewRelic::LanguageSupport.using_version?('1.9.2')
27
12
  end
28
13
 
29
14
  @@forkable = nil
@@ -23,12 +23,10 @@ module NewRelic::Rack
23
23
  {'error' => warning}
24
24
  end
25
25
 
26
- transaction_name = NewRelic::Agent::TransactionInfo.get.transaction.name
27
- NewRelic::Agent::Transaction.notice_error(exception,
28
- :uri => request.path,
29
- :referer => request.referer,
30
- :metric => transaction_name,
31
- :request_params => params)
26
+ NewRelic::Agent.notice_error(exception,
27
+ :uri => request.path,
28
+ :referer => request.referer,
29
+ :request_params => params)
32
30
  end
33
31
  raise exception
34
32
  end
@@ -12,10 +12,27 @@ if !defined?(MyApp)
12
12
 
13
13
  ENV['NEW_RELIC_DISPATCHER'] = 'test'
14
14
 
15
+ class ErrorMiddleware
16
+ def initialize(app, options={})
17
+ @app = app
18
+ end
19
+
20
+ def call(env)
21
+ path = ::Rack::Request.new(env).path_info
22
+ raise "middleware error" if path.match(/\/middleware_error\/before/)
23
+ result = @app.call(env)
24
+ raise "middleware error" if path.match(/\/middleware_error\/after/)
25
+ result
26
+ end
27
+ end
28
+
15
29
  class MyApp < Rails::Application
16
30
  # We need a secret token for session, cookies, etc.
17
31
  config.active_support.deprecation = :log
18
32
  config.secret_token = "49837489qkuweoiuoqwehisuakshdjksadhaisdy78o34y138974xyqp9rmye8yrpiokeuioqwzyoiuxftoyqiuxrhm3iou1hrzmjk"
33
+ initializer "install_error_middleware" do
34
+ config.middleware.use ErrorMiddleware
35
+ end
19
36
  end
20
37
  MyApp.initialize!
21
38
 
@@ -38,6 +38,10 @@ class ErrorController < ApplicationController
38
38
  newrelic_notice_error(RuntimeError.new('this error should be noticed'))
39
39
  render :text => "Shoulda noticed an error"
40
40
  end
41
+
42
+ def middleware_error
43
+ render :text => 'everything went great'
44
+ end
41
45
  end
42
46
 
43
47
  class IgnoredError < StandardError; end
@@ -56,6 +60,7 @@ class ErrorsWithoutSSCTest < ActionDispatch::IntegrationTest
56
60
  NewRelic::Agent.instance_variable_set(:@agent, nil)
57
61
  NewRelic::Agent::Agent.instance_variable_set(:@instance, nil)
58
62
  NewRelic::Agent.manual_start
63
+ NewRelic::Agent::TransactionInfo.reset
59
64
 
60
65
  reset_error_collector
61
66
  end
@@ -166,6 +171,16 @@ class ErrorsWithoutSSCTest < ActionDispatch::IntegrationTest
166
171
  assert_error_reported_once('this is a server ignored error')
167
172
  end
168
173
 
174
+ def test_should_capture_errors_raised_in_middleware_before_call
175
+ get '/error/middleware_error/before'
176
+ assert_error_reported_once('middleware error')
177
+ end
178
+
179
+ def test_should_capture_errors_raised_in_middleware_after_call
180
+ get '/error/middleware_error/after'
181
+ assert_error_reported_once('middleware error')
182
+ end
183
+
169
184
  protected
170
185
 
171
186
  def assert_errors_reported(message, queued_count, total_count=queued_count, txn_name=nil)
@@ -182,7 +197,7 @@ class ErrorsWithoutSSCTest < ActionDispatch::IntegrationTest
182
197
 
183
198
  assert_equal(queued_count,
184
199
  @error_collector.errors.select{|error| error.message == message}.size,
185
- "Wrong number of errors with message '#{message} found'")
200
+ "Wrong number of errors with message #{message.inspect} found")
186
201
  end
187
202
 
188
203
  def assert_error_reported_once(message, txn_name=nil)
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','..','..','test_helper'))
6
+
7
+ class NewRelic::Agent::Instrumentation::MetricFrameTest < Test::Unit::TestCase
8
+
9
+ # These tests are just here to make sure that we're maintaining the required
10
+ # old interface for folks. Real testing of the underlying functionality
11
+ # should go with the Transaction methods we invoke, not these tests.
12
+
13
+ def test_recording_web_transaction
14
+ NewRelic::Agent::Transaction.expects(:recording_web_transaction?)
15
+ NewRelic::Agent::Instrumentation::MetricFrame.recording_web_transaction?
16
+ end
17
+
18
+ def test_abort_transaction
19
+ NewRelic::Agent::Transaction.expects(:abort_transaction!)
20
+ NewRelic::Agent::Instrumentation::MetricFrame.abort_transaction!
21
+ end
22
+ end
@@ -369,6 +369,17 @@ module NewRelic
369
369
  assert engine.lookup_stats('OtherTransaction/Background/new_name')
370
370
  end
371
371
 
372
+ # It's not uncommon for customers to conclude a rescue block with a call to
373
+ # notice_error. We should always return nil, which mean less folks
374
+ # unexpectedly get a noticed error Hash returned from their methods.
375
+ def test_notice_error_returns_nil
376
+ begin
377
+ raise "WTF"
378
+ rescue => e
379
+ assert_equal nil, ::NewRelic::Agent.notice_error(e)
380
+ end
381
+ end
382
+
372
383
  private
373
384
 
374
385
  def mocked_agent
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newrelic_rpm
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.6.1.85.beta
4
+ version: 3.6.1.86.beta
5
5
  prerelease: 9
6
6
  platform: ruby
7
7
  authors:
@@ -41,7 +41,7 @@ cert_chain:
41
41
  cHUySWFQWE92bTNUOEc0TzZxWnZobkxoL1VpZW4rK0RqOGVGQmVjVFBvTThw
42
42
  VmpLM3BoNQpuL0V3dVpDY0U2Z2h0Q0NNCi0tLS0tRU5EIENFUlRJRklDQVRF
43
43
  LS0tLS0K
44
- date: 2013-04-16 00:00:00.000000000 Z
44
+ date: 2013-04-18 00:00:00.000000000 Z
45
45
  dependencies: []
46
46
  description: ! 'New Relic is a performance management system, developed by New Relic,
47
47
 
@@ -129,6 +129,7 @@ files:
129
129
  - lib/new_relic/agent/instrumentation/memcache.rb
130
130
  - lib/new_relic/agent/instrumentation/merb/controller.rb
131
131
  - lib/new_relic/agent/instrumentation/merb/errors.rb
132
+ - lib/new_relic/agent/instrumentation/metric_frame.rb
132
133
  - lib/new_relic/agent/instrumentation/net.rb
133
134
  - lib/new_relic/agent/instrumentation/passenger_instrumentation.rb
134
135
  - lib/new_relic/agent/instrumentation/queue_time.rb
@@ -350,6 +351,7 @@ files:
350
351
  - test/new_relic/agent/instrumentation/browser_monitoring_timings_test.rb
351
352
  - test/new_relic/agent/instrumentation/controller_instrumentation_test.rb
352
353
  - test/new_relic/agent/instrumentation/instrumentation_test.rb
354
+ - test/new_relic/agent/instrumentation/metric_frame_test.rb
353
355
  - test/new_relic/agent/instrumentation/net_instrumentation_test.rb
354
356
  - test/new_relic/agent/instrumentation/queue_time_test.rb
355
357
  - test/new_relic/agent/instrumentation/rack_test.rb
@@ -523,7 +525,12 @@ post_install_message: ! "\n# New Relic Ruby Agent Release Notes #\n\n## v3.6.1 #
523
525
  Don't attempt to resolve collector hostname when proxy is in use\n\n When a proxy
524
526
  is configured, the agent will not attempt to lookup and cache the\n IP address
525
527
  of New Relic server to which it is sending data, since DNS may not\n be available
526
- in some environments. Thanks to Bill Kirtley for the contribution\n\nSee https://github.com/newrelic/rpm/blob/master/CHANGELOG
528
+ in some environments. Thanks to Bill Kirtley for the contribution\n\n* Added NewRelic::Agent.set_transaction_name
529
+ and NewRelic::Agent.get_transaction_name\n\n Ordinarily the name of your transaction
530
+ is defined up-front, but if you'd like to \n change the name of a transaction while
531
+ it is still running you can use \n **NewRelic::Agent.set_transaction_name()**.
532
+ \ Similarly, if you need to know the name\n of the currently running transaction,
533
+ you can use **NewRelic::Agent.get_transaction_name()**.\n\nSee https://github.com/newrelic/rpm/blob/master/CHANGELOG
527
534
  for a full list of\nchanges.\n"
528
535
  rdoc_options:
529
536
  - --line-numbers
metadata.gz.sig CHANGED
Binary file