newrelic_rpm 3.9.6.257 → 3.9.7.266
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +45 -0
- data/lib/new_relic/agent.rb +0 -1
- data/lib/new_relic/agent/agent.rb +61 -22
- data/lib/new_relic/agent/agent_logger.rb +11 -9
- data/lib/new_relic/agent/configuration/default_source.rb +25 -2
- data/lib/new_relic/agent/cross_app_monitor.rb +15 -53
- data/lib/new_relic/agent/cross_app_tracing.rb +11 -3
- data/lib/new_relic/agent/custom_event_aggregator.rb +98 -0
- data/lib/new_relic/agent/event_buffer.rb +84 -0
- data/lib/new_relic/agent/harvester.rb +4 -15
- data/lib/new_relic/agent/hostname.rb +1 -9
- data/lib/new_relic/agent/inbound_request_monitor.rb +41 -0
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +2 -2
- data/lib/new_relic/agent/instrumentation/queue_time.rb +0 -5
- data/lib/new_relic/agent/instrumentation/resque.rb +4 -9
- data/lib/new_relic/agent/javascript_instrumentor.rb +0 -12
- data/lib/new_relic/agent/method_tracer_helpers.rb +3 -1
- data/lib/new_relic/agent/new_relic_service.rb +1 -1
- data/lib/new_relic/agent/sampled_buffer.rb +13 -41
- data/lib/new_relic/agent/samplers/delayed_job_sampler.rb +52 -24
- data/lib/new_relic/agent/sized_buffer.rb +23 -0
- data/lib/new_relic/agent/synthetics_monitor.rb +50 -0
- data/lib/new_relic/agent/system_info.rb +28 -0
- data/lib/new_relic/agent/transaction.rb +78 -9
- data/lib/new_relic/agent/transaction/synthetics_sample_buffer.rb +25 -0
- data/lib/new_relic/agent/{request_sampler.rb → transaction_event_aggregator.rb} +53 -19
- data/lib/new_relic/agent/transaction_sample_builder.rb +3 -1
- data/lib/new_relic/agent/transaction_sampler.rb +10 -0
- data/lib/new_relic/agent/transaction_state.rb +1 -9
- data/lib/new_relic/coerce.rb +8 -2
- data/lib/new_relic/control.rb +0 -1
- data/lib/new_relic/local_environment.rb +12 -8
- data/lib/new_relic/metric_spec.rb +11 -2
- data/lib/new_relic/rack/developer_mode.rb +9 -1
- data/lib/new_relic/transaction_sample.rb +4 -10
- data/lib/new_relic/version.rb +1 -1
- data/newrelic_rpm.gemspec +1 -0
- data/test/agent_helper.rb +15 -2
- data/test/environments/norails/Gemfile +1 -0
- data/test/environments/rails21/Gemfile +1 -0
- data/test/environments/rails22/Gemfile +1 -0
- data/test/environments/rails23/Gemfile +1 -0
- data/test/environments/rails30/Gemfile +1 -0
- data/test/environments/rails31/Gemfile +1 -0
- data/test/environments/rails32/Gemfile +2 -1
- data/test/environments/rails40/Gemfile +2 -1
- data/test/environments/rails41/Gemfile +3 -1
- data/test/environments/rails42/Gemfile +3 -1
- data/test/fixtures/cross_agent_tests/README.md +6 -2
- data/test/fixtures/cross_agent_tests/docker_container_id/README.md +6 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/cases.json +22 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/docker-0.9.1.txt +10 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/docker-1.0.0.txt +10 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/docker-1.3.txt +9 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/empty.txt +0 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/lxc-containers-without-docker.txt +10 -0
- data/test/fixtures/cross_agent_tests/proc_meminfo/README.md +7 -0
- data/test/fixtures/cross_agent_tests/proc_meminfo/meminfo_4096MB.txt +47 -0
- data/test/fixtures/cross_agent_tests/rum_client_config.json +0 -80
- data/test/fixtures/cross_agent_tests/synthetics/synthetics.json +317 -0
- data/test/multiverse/lib/multiverse/runner.rb +1 -1
- data/test/multiverse/lib/multiverse/suite.rb +1 -0
- data/test/multiverse/suites/active_record/Envfile +42 -8
- data/test/multiverse/suites/active_record/ar_method_aliasing.rb +8 -4
- data/test/multiverse/suites/agent_only/audit_log_test.rb +0 -2
- data/test/multiverse/suites/agent_only/collector_exception_handling_test.rb +1 -2
- data/test/multiverse/suites/agent_only/cross_application_tracing_test.rb +5 -5
- data/test/multiverse/suites/agent_only/encoding_handling_test.rb +2 -0
- data/test/multiverse/suites/agent_only/harvest_timestamps_test.rb +8 -0
- data/test/multiverse/suites/agent_only/synthetics_test.rb +139 -0
- data/test/multiverse/suites/delayed_job/Envfile +79 -0
- data/test/multiverse/suites/delayed_job/before_suite.rb +33 -0
- data/test/multiverse/suites/delayed_job/config/newrelic.yml +18 -0
- data/test/multiverse/suites/delayed_job/delayed_job_sampler_test.rb +131 -0
- data/test/multiverse/suites/delayed_job/unsupported_backend_test.rb +24 -0
- data/test/multiverse/suites/high_security/high_security_test.rb +3 -10
- data/test/multiverse/suites/rails/Envfile +4 -4
- data/test/multiverse/suites/rails/request_statistics_test.rb +4 -4
- data/test/new_relic/agent/agent_test.rb +32 -4
- data/test/new_relic/agent/configuration/default_source_test.rb +6 -0
- data/test/new_relic/agent/cross_app_monitor_test.rb +23 -29
- data/test/new_relic/agent/custom_event_aggregator_test.rb +88 -0
- data/test/new_relic/agent/event_buffer_test_cases.rb +152 -0
- data/test/new_relic/agent/harvester_test.rb +5 -25
- data/test/new_relic/agent/hostname_test.rb +1 -1
- data/test/new_relic/agent/inbound_request_monitor_test.rb +49 -0
- data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +9 -9
- data/test/new_relic/agent/instrumentation/queue_time_test.rb +0 -19
- data/test/new_relic/agent/javascript_instrumentor_test.rb +0 -45
- data/test/new_relic/agent/new_relic_service_test.rb +17 -12
- data/test/new_relic/agent/pipe_channel_manager_test.rb +4 -4
- data/test/new_relic/agent/sampled_buffer_test.rb +73 -145
- data/test/new_relic/agent/sized_buffer_test.rb +29 -0
- data/test/new_relic/agent/synthetics_monitor_test.rb +96 -0
- data/test/new_relic/agent/system_info_test.rb +19 -3
- data/test/new_relic/agent/transaction/developer_mode_sample_buffer_test.rb +14 -8
- data/test/new_relic/agent/transaction/synthetics_sample_buffer_test.rb +38 -0
- data/test/new_relic/agent/{request_sampler_test.rb → transaction_event_aggregator_test.rb} +55 -4
- data/test/new_relic/agent/transaction_sampler_test.rb +33 -11
- data/test/new_relic/agent/transaction_state_test.rb +0 -1
- data/test/new_relic/agent/transaction_test.rb +121 -19
- data/test/new_relic/coerce_test.rb +38 -3
- data/test/new_relic/control_test.rb +1 -0
- data/test/new_relic/fake_collector.rb +6 -2
- data/test/new_relic/fake_external_server.rb +2 -6
- data/test/new_relic/fake_server.rb +46 -29
- data/test/new_relic/http_client_test_cases.rb +71 -2
- data/test/new_relic/local_environment_test.rb +78 -0
- data/test/new_relic/metric_parser/metric_parser_test.rb +2 -0
- data/test/new_relic/metric_spec_test.rb +43 -0
- data/test/new_relic/multiverse_helpers.rb +11 -18
- data/test/new_relic/rack/browser_monitoring_test.rb +1 -18
- data/test/new_relic/rack/developer_mode_test.rb +1 -1
- data/test/new_relic/transaction_sample_test.rb +14 -4
- data/test/performance/suites/rack_middleware.rb +3 -1
- data/test/test_helper.rb +33 -0
- metadata +48 -7
- metadata.gz.sig +0 -0
- data/lib/new_relic/agent/browser_token.rb +0 -41
- data/test/multiverse/suites/agent_only/before_suite.rb +0 -7
- data/test/new_relic/agent/browser_token_test.rb +0 -56
@@ -19,6 +19,9 @@ module NewRelic
|
|
19
19
|
# The cross app transaction header for "outgoing" calls
|
20
20
|
NR_TXN_HEADER = 'X-NewRelic-Transaction'
|
21
21
|
|
22
|
+
# The cross app synthetics header
|
23
|
+
NR_SYNTHETICS_HEADER = 'X-NewRelic-Synthetics'
|
24
|
+
|
22
25
|
# The index of the transaction GUID in the appdata header of responses
|
23
26
|
APPDATA_TXN_GUID_INDEX = 5
|
24
27
|
|
@@ -169,9 +172,14 @@ module NewRelic
|
|
169
172
|
|
170
173
|
state.is_cross_app_caller = true
|
171
174
|
txn_guid = state.request_guid
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
+
txn = state.current_transaction
|
176
|
+
if txn
|
177
|
+
trip_id = txn.cat_trip_id(state)
|
178
|
+
path_hash = txn.cat_path_hash(state)
|
179
|
+
|
180
|
+
if txn.raw_synthetics_header
|
181
|
+
request[NR_SYNTHETICS_HEADER] = txn.raw_synthetics_header
|
182
|
+
end
|
175
183
|
end
|
176
184
|
txn_data = NewRelic::JSONWrapper.dump([txn_guid, false, trip_id, path_hash])
|
177
185
|
|
@@ -0,0 +1,98 @@
|
|
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 'new_relic/agent/sized_buffer'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
class CustomEventAggregator
|
10
|
+
include NewRelic::Coerce
|
11
|
+
|
12
|
+
TYPE = 'type'.freeze
|
13
|
+
TIMESTAMP = 'timestamp'.freeze
|
14
|
+
SOURCE = 'source'.freeze
|
15
|
+
AGENT_SOURCE = 'Agent'.freeze
|
16
|
+
EVENT_PARAMS_CTX = 'recording custom event'.freeze
|
17
|
+
EVENT_TYPE_REGEX = /^[a-zA-Z0-9:_ ]+$/.freeze
|
18
|
+
|
19
|
+
DEFAULT_CAPACITY_KEY = :'custom_insights_events.max_samples_stored'
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@lock = Mutex.new
|
23
|
+
@buffer = SampledBuffer.new(NewRelic::Agent.config[DEFAULT_CAPACITY_KEY])
|
24
|
+
@type_strings = Hash.new { |hash, key| hash[key] = key.to_s.freeze }
|
25
|
+
register_config_callbacks
|
26
|
+
end
|
27
|
+
|
28
|
+
def register_config_callbacks
|
29
|
+
NewRelic::Agent.config.register_callback(DEFAULT_CAPACITY_KEY) do |max_samples|
|
30
|
+
NewRelic::Agent.logger.debug "CustomEventAggregator max_samples set to #{max_samples}"
|
31
|
+
@lock.synchronize do
|
32
|
+
@buffer.capacity = max_samples
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def record(type, attributes, source=AGENT_SOURCE)
|
38
|
+
type = @type_strings[type]
|
39
|
+
unless type =~ EVENT_TYPE_REGEX
|
40
|
+
note_dropped_event(type)
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
|
44
|
+
event = [
|
45
|
+
{ TYPE => type, TIMESTAMP => Time.now.to_i, SOURCE => source },
|
46
|
+
event_params(attributes, EVENT_PARAMS_CTX)
|
47
|
+
]
|
48
|
+
|
49
|
+
stored = @lock.synchronize do
|
50
|
+
@buffer.append(event)
|
51
|
+
end
|
52
|
+
stored
|
53
|
+
end
|
54
|
+
|
55
|
+
def harvest!
|
56
|
+
results = []
|
57
|
+
drop_count = 0
|
58
|
+
@lock.synchronize do
|
59
|
+
results.concat(@buffer.to_a)
|
60
|
+
drop_count += @buffer.num_dropped
|
61
|
+
@buffer.reset!
|
62
|
+
end
|
63
|
+
note_dropped_events(results.size, drop_count)
|
64
|
+
results
|
65
|
+
end
|
66
|
+
|
67
|
+
def note_dropped_events(captured_count, dropped_count)
|
68
|
+
total_count = captured_count + dropped_count
|
69
|
+
if dropped_count > 0
|
70
|
+
NewRelic::Agent.logger.warn("Dropped #{dropped_count} custom events out of #{total_count}.")
|
71
|
+
end
|
72
|
+
engine = NewRelic::Agent.instance.stats_engine
|
73
|
+
engine.tl_record_supportability_metric_count("Events/Customer/Seen" , total_count)
|
74
|
+
engine.tl_record_supportability_metric_count("Events/Customer/Sent" , captured_count)
|
75
|
+
engine.tl_record_supportability_metric_count("Events/Customer/Dropped", dropped_count)
|
76
|
+
end
|
77
|
+
|
78
|
+
def merge!(events)
|
79
|
+
@lock.synchronize do
|
80
|
+
events.each do |event|
|
81
|
+
@buffer.append(event)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def reset!
|
87
|
+
@lock.synchronize { @buffer.reset! }
|
88
|
+
end
|
89
|
+
|
90
|
+
def note_dropped_event(type)
|
91
|
+
::NewRelic::Agent.logger.log_once(:warn, "dropping_event_of_type:#{type}",
|
92
|
+
"Invalid event type name '#{type}', not recording.")
|
93
|
+
@buffer.note_dropped
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,84 @@
|
|
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
|
+
# EventBuffer is intended to be an abstract base class. It should not be
|
6
|
+
# instantiated directly. Subclasses should define an `append_event` method
|
7
|
+
# looking something like this:
|
8
|
+
#
|
9
|
+
# def append_event(x)
|
10
|
+
# <attempt to append>
|
11
|
+
# if append_success?
|
12
|
+
# return x
|
13
|
+
# else
|
14
|
+
# return nil
|
15
|
+
# end
|
16
|
+
# end
|
17
|
+
|
18
|
+
module NewRelic
|
19
|
+
module Agent
|
20
|
+
class EventBuffer
|
21
|
+
attr_reader :capacity
|
22
|
+
|
23
|
+
def initialize(capacity)
|
24
|
+
@capacity = capacity
|
25
|
+
@items = []
|
26
|
+
@seen = 0
|
27
|
+
end
|
28
|
+
|
29
|
+
def reset!
|
30
|
+
@items = []
|
31
|
+
@seen = 0
|
32
|
+
end
|
33
|
+
|
34
|
+
def capacity=(new_capacity)
|
35
|
+
@capacity = new_capacity
|
36
|
+
old_items = @items
|
37
|
+
@items = []
|
38
|
+
old_seen = @seen
|
39
|
+
old_items.each { |i| append(i) }
|
40
|
+
@seen = old_seen
|
41
|
+
end
|
42
|
+
|
43
|
+
def append(x)
|
44
|
+
@seen += 1
|
45
|
+
append_event(x)
|
46
|
+
end
|
47
|
+
|
48
|
+
def <<(x)
|
49
|
+
append(x)
|
50
|
+
self # return self for method chaining
|
51
|
+
end
|
52
|
+
|
53
|
+
def full?
|
54
|
+
@items.size >= @capacity
|
55
|
+
end
|
56
|
+
|
57
|
+
def size
|
58
|
+
@items.size
|
59
|
+
end
|
60
|
+
|
61
|
+
def note_dropped
|
62
|
+
@seen += 1
|
63
|
+
end
|
64
|
+
|
65
|
+
def num_seen
|
66
|
+
@seen
|
67
|
+
end
|
68
|
+
|
69
|
+
def num_dropped
|
70
|
+
@seen - @items.size
|
71
|
+
end
|
72
|
+
|
73
|
+
def sample_rate
|
74
|
+
@seen > 0 ? (size.to_f / @seen) : 0.0
|
75
|
+
end
|
76
|
+
|
77
|
+
def to_a
|
78
|
+
@items.dup
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
@@ -13,9 +13,7 @@ module NewRelic
|
|
13
13
|
# We intentionally don't set our pid as started at this point.
|
14
14
|
# Startup routines must call mark_started when they consider us set!
|
15
15
|
@starting_pid = nil
|
16
|
-
|
17
16
|
@after_forker = after_forker
|
18
|
-
@lock = Mutex.new
|
19
17
|
|
20
18
|
if events
|
21
19
|
events.subscribe(:start_transaction, &method(:on_transaction))
|
@@ -23,17 +21,11 @@ module NewRelic
|
|
23
21
|
end
|
24
22
|
|
25
23
|
def on_transaction(*_)
|
26
|
-
return unless restart_in_children_enabled? &&
|
27
|
-
|
28
|
-
|
29
|
-
@lock.synchronize do
|
30
|
-
needs_thread_start = needs_restart?
|
31
|
-
mark_started
|
32
|
-
end
|
24
|
+
return unless restart_in_children_enabled? &&
|
25
|
+
needs_restart? &&
|
26
|
+
harvest_thread_enabled?
|
33
27
|
|
34
|
-
|
35
|
-
restart_harvest_thread
|
36
|
-
end
|
28
|
+
restart_harvest_thread
|
37
29
|
end
|
38
30
|
|
39
31
|
def mark_started(pid = Process.pid)
|
@@ -53,11 +45,8 @@ module NewRelic
|
|
53
45
|
end
|
54
46
|
|
55
47
|
def restart_harvest_thread
|
56
|
-
# Daemonize reports thread as still alive when it isn't... whack!
|
57
|
-
NewRelic::Agent.instance.instance_variable_set(:@worker_thread, nil)
|
58
48
|
@after_forker.after_fork(:force_reconnect => true)
|
59
49
|
end
|
60
|
-
|
61
50
|
end
|
62
51
|
end
|
63
52
|
end
|
@@ -22,16 +22,8 @@ module NewRelic
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
# TODO: Once config transforms are in, use those instead of handcoding
|
26
25
|
def self.get_dyno_prefixes
|
27
|
-
|
28
|
-
if dyno_prefixes.is_a?(String)
|
29
|
-
dyno_prefixes = dyno_prefixes.split(',')
|
30
|
-
elsif !dyno_prefixes.respond_to?(:find)
|
31
|
-
::NewRelic::Agent.logger.warn("Ignoring invalid setting found for 'heroku.dyno_name_prefixes_to_shorten', #{dyno_prefixes}.")
|
32
|
-
dyno_prefixes = []
|
33
|
-
end
|
34
|
-
dyno_prefixes
|
26
|
+
::NewRelic::Agent.config[:'heroku.dyno_name_prefixes_to_shorten']
|
35
27
|
end
|
36
28
|
end
|
37
29
|
end
|
@@ -0,0 +1,41 @@
|
|
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 class serves as the base for objects wanting to monitor and respond to
|
6
|
+
# incoming web requests. Examples include cross application tracing and
|
7
|
+
# synthetics.
|
8
|
+
#
|
9
|
+
# Subclasses are expected to define on_finished_configuring(events) which will
|
10
|
+
# be called when the agent is fully configured. That method is expected to
|
11
|
+
# subscribe to the necessary request events, such as before_call and after_call
|
12
|
+
# for the monitor to do its work.
|
13
|
+
module NewRelic
|
14
|
+
module Agent
|
15
|
+
class InboundRequestMonitor
|
16
|
+
|
17
|
+
attr_reader :obfuscator
|
18
|
+
|
19
|
+
def initialize(events)
|
20
|
+
events.subscribe(:finished_configuring) do
|
21
|
+
# This requires :encoding_key, so must wait until :finished_configuring
|
22
|
+
setup_obfuscator
|
23
|
+
on_finished_configuring(events)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def setup_obfuscator
|
28
|
+
@obfuscator = NewRelic::Agent::Obfuscator.new(NewRelic::Agent.config[:encoding_key])
|
29
|
+
end
|
30
|
+
|
31
|
+
def deserialize_header(encoded_header, key)
|
32
|
+
decoded_header = obfuscator.deobfuscate(encoded_header)
|
33
|
+
NewRelic::JSONWrapper.load(decoded_header)
|
34
|
+
rescue => err
|
35
|
+
# If we have a failure of any type here, just return nil and carry on
|
36
|
+
NewRelic::Agent.logger.debug("Failure deserializing encoded header '#{key}' in #{self.class}, #{err.class}, #{err.message}")
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -213,7 +213,7 @@ module NewRelic
|
|
213
213
|
end
|
214
214
|
|
215
215
|
class TransactionNamer
|
216
|
-
def self.
|
216
|
+
def self.name_for(txn, traced_obj, category, options={})
|
217
217
|
"#{prefix_for_category(txn, category)}#{path_name(traced_obj, options)}"
|
218
218
|
end
|
219
219
|
|
@@ -354,7 +354,7 @@ module NewRelic
|
|
354
354
|
|
355
355
|
category = trace_options[:category] || :controller
|
356
356
|
txn_options = create_transaction_options(trace_options, available_params)
|
357
|
-
txn_options[:transaction_name] = TransactionNamer.
|
357
|
+
txn_options[:transaction_name] = TransactionNamer.name_for(nil, self, category, trace_options)
|
358
358
|
txn_options[:apdex_start_time] = detect_queue_start_time(state)
|
359
359
|
|
360
360
|
begin
|
@@ -49,11 +49,6 @@ module NewRelic
|
|
49
49
|
earliest
|
50
50
|
end
|
51
51
|
|
52
|
-
def record_frontend_metrics(start_time, now=Time.now) #THREAD_LOCAL_ACCESS
|
53
|
-
NewRelic::Agent.instance.stats_engine.tl_record_unscoped_metrics(
|
54
|
-
ALL_QUEUE_METRIC, (now - start_time).to_f)
|
55
|
-
end
|
56
|
-
|
57
52
|
def timestamp_string_from_header_value(value)
|
58
53
|
case value
|
59
54
|
when /^\s*([\d+\.]+)\s*$/ then $1
|
@@ -15,12 +15,6 @@ DependencyDetection.defer do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
executes do
|
18
|
-
# == Resque Instrumentation
|
19
|
-
#
|
20
|
-
# Installs a hook to ensure the agent starts manually when the worker
|
21
|
-
# starts and also adds the tracer to the process method which executes
|
22
|
-
# in the forked task.
|
23
|
-
|
24
18
|
module Resque
|
25
19
|
module Plugins
|
26
20
|
module NewRelicInstrumentation
|
@@ -40,8 +34,7 @@ DependencyDetection.defer do
|
|
40
34
|
yield(*args)
|
41
35
|
end
|
42
36
|
ensure
|
43
|
-
NewRelic::Agent.
|
44
|
-
(!Resque.respond_to?(:inline) || !Resque.inline)
|
37
|
+
NewRelic::Agent.agent.flush_pipe_data
|
45
38
|
end
|
46
39
|
end
|
47
40
|
end
|
@@ -97,7 +90,9 @@ DependencyDetection.defer do
|
|
97
90
|
end
|
98
91
|
|
99
92
|
::Resque.before_fork do |job|
|
100
|
-
|
93
|
+
if ENV['FORK_PER_JOB'] != 'false'
|
94
|
+
NewRelic::Agent.register_report_channel(job.object_id)
|
95
|
+
end
|
101
96
|
end
|
102
97
|
|
103
98
|
::Resque.after_fork do |job|
|
@@ -125,8 +125,6 @@ module NewRelic
|
|
125
125
|
TRANSACTION_NAME_KEY = "transactionName".freeze
|
126
126
|
QUEUE_TIME_KEY = "queueTime".freeze
|
127
127
|
APPLICATION_TIME_KEY = "applicationTime".freeze
|
128
|
-
TT_GUID_KEY = "ttGuid".freeze
|
129
|
-
AGENT_TOKEN_KEY = "agentToken".freeze
|
130
128
|
AGENT_KEY = "agent".freeze
|
131
129
|
USER_ATTRIBUTES_KEY = "userAttributes".freeze
|
132
130
|
SSL_FOR_HTTP_KEY = "sslForHttp".freeze
|
@@ -143,14 +141,9 @@ module NewRelic
|
|
143
141
|
TRANSACTION_NAME_KEY => obfuscator.obfuscate(timings.transaction_name_or_unknown),
|
144
142
|
QUEUE_TIME_KEY => timings.queue_time_in_millis,
|
145
143
|
APPLICATION_TIME_KEY => timings.app_time_in_millis,
|
146
|
-
AGENT_TOKEN_KEY => state.request_token,
|
147
144
|
AGENT_KEY => NewRelic::Agent.config[:js_agent_file]
|
148
145
|
}
|
149
146
|
|
150
|
-
if include_guid?(state, timings)
|
151
|
-
data[TT_GUID_KEY] = state.request_guid
|
152
|
-
end
|
153
|
-
|
154
147
|
add_ssl_for_http(data)
|
155
148
|
add_user_attributes(data, state.current_transaction)
|
156
149
|
|
@@ -172,11 +165,6 @@ module NewRelic
|
|
172
165
|
data[USER_ATTRIBUTES_KEY] = obfuscator.obfuscate(json)
|
173
166
|
end
|
174
167
|
|
175
|
-
def include_guid?(state, timings)
|
176
|
-
state.current_transaction &&
|
177
|
-
state.current_transaction.include_guid?(state, timings.app_time_in_seconds)
|
178
|
-
end
|
179
|
-
|
180
168
|
# Still support deprecated capture_attributes.page_view_events for
|
181
169
|
# clients that use it. Could potentially be removed if we don't have
|
182
170
|
# anymore users with it set according to zeitgeist.
|
@@ -5,6 +5,8 @@
|
|
5
5
|
module NewRelic
|
6
6
|
module Agent
|
7
7
|
module MethodTracerHelpers
|
8
|
+
MAX_ALLOWED_METRIC_DURATION = 1_000_000_000 # roughly 31 years
|
9
|
+
|
8
10
|
extend self
|
9
11
|
|
10
12
|
# helper for logging errors to the newrelic_agent.log
|
@@ -43,7 +45,7 @@ module NewRelic
|
|
43
45
|
duration = t1 - t0
|
44
46
|
exclusive = duration - frame.children_time
|
45
47
|
|
46
|
-
if duration <
|
48
|
+
if duration < MAX_ALLOWED_METRIC_DURATION
|
47
49
|
if duration < 0
|
48
50
|
::NewRelic::Agent.logger.log_once(:warn, "metric_duration_negative:#{first_name}",
|
49
51
|
"Metric #{first_name} has negative duration: #{duration} s")
|
@@ -414,7 +414,7 @@ module NewRelic
|
|
414
414
|
end
|
415
415
|
case response
|
416
416
|
when Net::HTTPSuccess
|
417
|
-
true #
|
417
|
+
true # do nothing
|
418
418
|
when Net::HTTPUnauthorized
|
419
419
|
raise LicenseException, 'Invalid license key, please visit support.newrelic.com'
|
420
420
|
when Net::HTTPServiceUnavailable
|
@@ -7,67 +7,39 @@
|
|
7
7
|
# in the Array is equal. It uses reservoir sampling in order to achieve this:
|
8
8
|
# http://xlinux.nist.gov/dads/HTML/reservoirSampling.html
|
9
9
|
|
10
|
+
require 'new_relic/agent/event_buffer'
|
11
|
+
|
10
12
|
module NewRelic
|
11
13
|
module Agent
|
12
|
-
class SampledBuffer
|
13
|
-
attr_reader :
|
14
|
+
class SampledBuffer < EventBuffer
|
15
|
+
attr_reader :seen_lifetime, :captured_lifetime
|
14
16
|
|
15
17
|
def initialize(capacity)
|
16
|
-
|
17
|
-
@capacity = capacity
|
18
|
+
super
|
18
19
|
@captured_lifetime = 0
|
19
|
-
@
|
20
|
-
@seen_lifetime = 0
|
20
|
+
@seen_lifetime = 0
|
21
21
|
end
|
22
22
|
|
23
|
-
def reset
|
23
|
+
def reset!
|
24
24
|
@captured_lifetime += @items.size
|
25
|
-
@seen_lifetime
|
26
|
-
|
27
|
-
@seen = 0
|
28
|
-
end
|
29
|
-
|
30
|
-
def full?
|
31
|
-
@items.size >= @capacity
|
25
|
+
@seen_lifetime += @seen
|
26
|
+
super
|
32
27
|
end
|
33
28
|
|
34
|
-
|
35
|
-
def append(x)
|
36
|
-
(self << x).full?
|
37
|
-
end
|
38
|
-
|
39
|
-
def <<(x)
|
40
|
-
@seen += 1
|
29
|
+
def append_event(x)
|
41
30
|
if @items.size < @capacity
|
42
31
|
@items << x
|
32
|
+
return x
|
43
33
|
else
|
44
34
|
m = rand(@seen) # [0, @seen)
|
45
35
|
if m < @capacity
|
46
36
|
@items[m] = x
|
37
|
+
return x
|
47
38
|
else
|
48
39
|
# discard current sample
|
40
|
+
return nil
|
49
41
|
end
|
50
42
|
end
|
51
|
-
return self
|
52
|
-
end
|
53
|
-
|
54
|
-
def size
|
55
|
-
@items.size
|
56
|
-
end
|
57
|
-
|
58
|
-
def to_a
|
59
|
-
@items.dup
|
60
|
-
end
|
61
|
-
|
62
|
-
def capacity=(new_capacity)
|
63
|
-
@capacity = new_capacity
|
64
|
-
old_items = @items
|
65
|
-
@items = []
|
66
|
-
old_items.each { |i| self << i }
|
67
|
-
end
|
68
|
-
|
69
|
-
def sample_rate
|
70
|
-
@seen > 0 ? (size.to_f / @seen) : 0.0
|
71
43
|
end
|
72
44
|
|
73
45
|
def sample_rate_lifetime
|