newrelic_rpm 3.9.7.266 → 3.9.8.273
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 +44 -1
- data/lib/new_relic/agent.rb +31 -0
- data/lib/new_relic/agent/agent.rb +34 -5
- data/lib/new_relic/agent/configuration/default_source.rb +25 -1
- data/lib/new_relic/agent/configuration/high_security_source.rb +1 -0
- data/lib/new_relic/agent/cross_app_monitor.rb +1 -1
- data/lib/new_relic/agent/custom_event_aggregator.rb +2 -4
- data/lib/new_relic/agent/error_collector.rb +17 -12
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +9 -8
- data/lib/new_relic/agent/instrumentation/grape.rb +67 -0
- data/lib/new_relic/agent/new_relic_service.rb +93 -43
- data/lib/new_relic/agent/pipe_service.rb +4 -0
- data/lib/new_relic/agent/synthetics_event_buffer.rb +42 -0
- data/lib/new_relic/agent/system_info.rb +44 -18
- data/lib/new_relic/agent/transaction_event_aggregator.rb +9 -2
- data/lib/new_relic/agent/utilization_data.rb +77 -0
- data/lib/new_relic/agent/vm/mri_vm.rb +3 -3
- data/lib/new_relic/rack/agent_hooks.rb +15 -15
- data/lib/new_relic/recipes/capistrano3.rb +2 -2
- data/lib/new_relic/version.rb +1 -1
- data/newrelic_rpm.gemspec +0 -1
- data/test/agent_helper.rb +13 -3
- data/test/environments/lib/environments/runner.rb +3 -19
- data/test/environments/rails42/Gemfile +5 -1
- data/test/fixtures/cross_agent_tests/README.md +1 -1
- data/test/fixtures/cross_agent_tests/cat_map.json +154 -88
- data/test/fixtures/cross_agent_tests/docker_container_id/cases.json +30 -6
- data/test/fixtures/cross_agent_tests/docker_container_id/docker-1.1.2-lxc-driver.txt +10 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/docker-1.1.2-native-driver-fs.txt +10 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/docker-1.1.2-native-driver-systemd.txt +10 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/heroku.txt +1 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/ubuntu-14.04-lxc-container.txt +10 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/{lxc-containers-without-docker.txt → ubuntu-14.04-no-container.txt} +0 -0
- data/test/fixtures/cross_agent_tests/docker_container_id/ubuntu-14.10-no-container.txt +10 -0
- data/test/multiverse/lib/multiverse/runner.rb +1 -0
- data/test/multiverse/lib/multiverse/suite.rb +6 -2
- data/test/multiverse/suites/active_record/.gitignore +1 -0
- data/test/multiverse/suites/active_record/Envfile +25 -7
- data/test/multiverse/suites/active_record/Rakefile +9 -0
- data/test/{new_relic/agent/instrumentation → multiverse/suites/active_record}/active_record_test.rb +82 -88
- data/test/multiverse/suites/active_record/app/models/models.rb +27 -0
- data/test/multiverse/suites/active_record/ar_method_aliasing.rb +5 -46
- data/test/multiverse/suites/active_record/before_suite.rb +23 -0
- data/test/multiverse/suites/active_record/config/database.rb +79 -0
- data/test/multiverse/suites/active_record/config/database.yml +19 -0
- data/test/multiverse/suites/active_record/db/migrate/20141105131800_create_users_and_aliases.rb +21 -0
- data/test/multiverse/suites/active_record/db/migrate/20141106082200_create_orders_and_shipments.rb +25 -0
- data/test/multiverse/suites/agent_only/cross_application_tracing_test.rb +4 -1
- data/test/multiverse/suites/agent_only/custom_analytics_events_test.rb +53 -0
- data/test/multiverse/suites/agent_only/keepalive_test.rb +3 -7
- data/test/multiverse/suites/agent_only/utilization_data_collection_test.rb +170 -0
- data/test/multiverse/suites/grape/Envfile +15 -0
- data/test/multiverse/suites/grape/config/newrelic.yml +18 -0
- data/test/multiverse/suites/grape/grape_test.rb +60 -0
- data/test/multiverse/suites/grape/grape_test_api.rb +43 -0
- data/test/multiverse/suites/grape/unsupported_version_test.rb +31 -0
- data/test/multiverse/suites/json/Envfile +3 -1
- data/test/multiverse/suites/rack/rack_env_mutation_test.rb +54 -0
- data/test/multiverse/suites/rails/Envfile +1 -1
- data/test/multiverse/suites/rails/view_instrumentation_test.rb +2 -1
- data/test/multiverse/suites/resque/resque_marshalling_test.rb +54 -0
- data/test/multiverse/suites/typhoeus/Envfile +4 -4
- data/test/new_relic/agent/agent_test.rb +37 -0
- data/test/new_relic/agent/configuration/default_source_test.rb +14 -0
- data/test/new_relic/agent/custom_event_aggregator_test.rb +3 -3
- data/test/new_relic/agent/error_collector/notice_error_test.rb +4 -4
- data/test/new_relic/agent/error_collector_test.rb +27 -4
- data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +23 -0
- data/test/new_relic/agent/new_relic_service_test.rb +208 -103
- data/test/new_relic/agent/pipe_service_test.rb +7 -0
- data/test/new_relic/agent/synthetics_event_buffer_test.rb +54 -0
- data/test/new_relic/agent/synthetics_monitor_test.rb +0 -3
- data/test/new_relic/agent/system_info_test.rb +6 -6
- data/test/new_relic/agent/transaction_event_aggregator_test.rb +43 -2
- data/test/new_relic/agent/utilization_data_test.rb +18 -0
- data/test/new_relic/collection_helper_test.rb +0 -1
- data/test/new_relic/data_container_tests.rb +11 -7
- data/test/new_relic/fake_collector.rb +23 -0
- data/test/new_relic/fake_instance_metadata_service.rb +45 -0
- data/test/new_relic/license_test.rb +2 -0
- data/test/new_relic/marshalling_test_cases.rb +89 -4
- data/test/new_relic/transaction_sample_test.rb +1 -0
- data/test/test_helper.rb +1 -0
- metadata +33 -6
- metadata.gz.sig +1 -2
- data/test/active_record_fixtures.rb +0 -79
- data/test/new_relic/rack/all_test.rb +0 -14
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG
CHANGED
@@ -1,12 +1,55 @@
|
|
1
1
|
# New Relic Ruby Agent Release Notes #
|
2
2
|
|
3
|
+
## v3.9.8 ##
|
4
|
+
|
5
|
+
* Custom Insights events API
|
6
|
+
|
7
|
+
In addition to attaching custom parameters to the events that the Ruby agent
|
8
|
+
generates automatically for each transaction, you can now record custom event
|
9
|
+
types into Insights with the new NewRelic::Agent.record_custom_event API.
|
10
|
+
|
11
|
+
For details, see https://docs.newrelic.com/docs/insights/new-relic-insights/adding-querying-data/inserting-custom-events-new-relic-agents
|
12
|
+
|
13
|
+
* Reduced memory usage for idling applications
|
14
|
+
|
15
|
+
Idling applications using the agent could previously appear to leak memory
|
16
|
+
because of native allocations during creation of new SSL connections to our
|
17
|
+
servers. These native allocations didn't factor into triggering Ruby's
|
18
|
+
garbage collector.
|
19
|
+
|
20
|
+
The agent will now re-use a single TCP connection to our servers for as long
|
21
|
+
as possible, resulting in improved memory usage for applications that are
|
22
|
+
idling and not having GC triggered for other reasons.
|
23
|
+
|
24
|
+
* Don't write to stderr during CPU sampling
|
25
|
+
|
26
|
+
The Ruby agent's code for gathering CPU information would write error
|
27
|
+
messages to stderr on some FreeBSD systems. This has been fixed.
|
28
|
+
|
29
|
+
* LocalJumpError on Rails 2.x
|
30
|
+
|
31
|
+
Under certain conditions, Rails 2.x controller instrumentation could fail
|
32
|
+
with a LocalJumpError when an action was not being traced. This has been
|
33
|
+
fixed.
|
34
|
+
|
35
|
+
* Fixed config lookup in warbler packaged apps
|
36
|
+
|
37
|
+
When running a Ruby application from a standalone warbler .jar file on
|
38
|
+
JRuby, the packaged config/newrelic.yml was not properly found. This has
|
39
|
+
been fixed, and thanks to Bob Beaty for the help getting it fixed!
|
40
|
+
|
41
|
+
* Hash iteration failure in middleware
|
42
|
+
|
43
|
+
If a background thread iterated over the keys in the Rack env hash, it could
|
44
|
+
cause failures in New Relic's AgentHooks middleware. This has been fixed.
|
45
|
+
|
3
46
|
## v3.9.7 ##
|
4
47
|
|
5
48
|
* Support for New Relic Synthetics
|
6
49
|
|
7
50
|
The Ruby agent now gives you additional information for requests from New
|
8
51
|
Relic Synthetics. More transaction traces and events give you a clearer look
|
9
|
-
into how your
|
52
|
+
into how your application is performing around the world.
|
10
53
|
|
11
54
|
For more details, see https://docs.newrelic.com/docs/synthetics/new-relic-synthetics/getting-started/new-relic-synthetics
|
12
55
|
|
data/lib/new_relic/agent.rb
CHANGED
@@ -455,6 +455,37 @@ module NewRelic
|
|
455
455
|
agent.pop_trace_execution_flag
|
456
456
|
end
|
457
457
|
|
458
|
+
# Record a custom event to be sent to New Relic Insights.
|
459
|
+
# The recorded event will be buffered in memory until the next time the
|
460
|
+
# agent sends data to New Relic's servers.
|
461
|
+
#
|
462
|
+
# If you want to be able to tie the information recorded via this call back
|
463
|
+
# to the web request or background job that it happened in, you may want to
|
464
|
+
# instead use the add_custom_parameters API call to attach attributes to
|
465
|
+
# the Transaction event that will automatically be generated for the
|
466
|
+
# request.
|
467
|
+
#
|
468
|
+
# A timestamp will be automatically added to the recorded event when this
|
469
|
+
# method is called.
|
470
|
+
#
|
471
|
+
# @param [Symbol or String] event_type The name of the event type to record. Event
|
472
|
+
# types must consist of only alphanumeric
|
473
|
+
# characters, '_', ':', or ' '.
|
474
|
+
#
|
475
|
+
# @param [Hash] event_attrs A Hash of attributes to be attached to the event.
|
476
|
+
# Keys should be strings or symbols, and values
|
477
|
+
# may be strings, symbols, numeric values or
|
478
|
+
# booleans.
|
479
|
+
#
|
480
|
+
# @api public
|
481
|
+
#
|
482
|
+
def record_custom_event(event_type, event_attrs)
|
483
|
+
if agent && NewRelic::Agent.config[:'custom_insights_events.enabled']
|
484
|
+
agent.custom_event_aggregator.record(event_type, event_attrs)
|
485
|
+
end
|
486
|
+
nil
|
487
|
+
end
|
488
|
+
|
458
489
|
# Check to see if we are capturing metrics currently on this thread.
|
459
490
|
def tl_is_execution_traced?
|
460
491
|
NewRelic::Agent::TransactionState.tl_get.is_execution_traced?
|
@@ -20,11 +20,13 @@ require 'new_relic/agent/commands/agent_command_router'
|
|
20
20
|
require 'new_relic/agent/event_listener'
|
21
21
|
require 'new_relic/agent/cross_app_monitor'
|
22
22
|
require 'new_relic/agent/synthetics_monitor'
|
23
|
+
require 'new_relic/agent/synthetics_event_buffer'
|
23
24
|
require 'new_relic/agent/transaction_event_aggregator'
|
24
25
|
require 'new_relic/agent/custom_event_aggregator'
|
25
26
|
require 'new_relic/agent/sampler_collection'
|
26
27
|
require 'new_relic/agent/javascript_instrumentor'
|
27
28
|
require 'new_relic/agent/vm/monotonic_gc_profiler'
|
29
|
+
require 'new_relic/agent/utilization_data'
|
28
30
|
require 'new_relic/environment_report'
|
29
31
|
|
30
32
|
module NewRelic
|
@@ -52,10 +54,11 @@ module NewRelic
|
|
52
54
|
@cross_app_monitor = NewRelic::Agent::CrossAppMonitor.new(@events)
|
53
55
|
@synthetics_monitor = NewRelic::Agent::SyntheticsMonitor.new(@events)
|
54
56
|
@error_collector = NewRelic::Agent::ErrorCollector.new
|
57
|
+
@utilization_data = NewRelic::Agent::UtilizationData.new
|
55
58
|
@transaction_rules = NewRelic::Agent::RulesEngine.new
|
56
59
|
@harvest_samplers = NewRelic::Agent::SamplerCollection.new(@events)
|
57
|
-
@javascript_instrumentor = NewRelic::Agent::JavascriptInstrumentor.new(@events)
|
58
60
|
@monotonic_gc_profiler = NewRelic::Agent::VM::MonotonicGCProfiler.new
|
61
|
+
@javascript_instrumentor = NewRelic::Agent::JavascriptInstrumentor.new(@events)
|
59
62
|
|
60
63
|
@harvester = NewRelic::Agent::Harvester.new(@events)
|
61
64
|
@after_fork_lock = Mutex.new
|
@@ -583,6 +586,7 @@ module NewRelic
|
|
583
586
|
# Never allow any data type to be reported more frequently than once
|
584
587
|
# per second.
|
585
588
|
MIN_ALLOWED_REPORT_PERIOD = 1.0
|
589
|
+
UTILIZATION_REPORT_PERIOD = 30 * 60 # every half hour
|
586
590
|
|
587
591
|
def report_period_for(method)
|
588
592
|
config_key = "data_report_periods.#{method}".to_sym
|
@@ -614,6 +618,15 @@ module NewRelic
|
|
614
618
|
@event_loop.fire_every(Agent.config[:data_report_period], :report_data)
|
615
619
|
@event_loop.fire_every(report_period_for(:analytic_event_data), :report_event_data)
|
616
620
|
@event_loop.fire_every(LOG_ONCE_KEYS_RESET_PERIOD, :reset_log_once_keys)
|
621
|
+
|
622
|
+
if Agent.config[:collect_utilization] && !in_resque_child_process?
|
623
|
+
@event_loop.on(:report_utilization_data) do
|
624
|
+
transmit_utilization_data
|
625
|
+
end
|
626
|
+
@event_loop.fire(:report_utilization_data)
|
627
|
+
@event_loop.fire_every(UTILIZATION_REPORT_PERIOD, :report_utilization_data)
|
628
|
+
end
|
629
|
+
|
617
630
|
@event_loop.run
|
618
631
|
end
|
619
632
|
|
@@ -882,6 +895,7 @@ module NewRelic
|
|
882
895
|
when :transaction_sample_data then @transaction_sampler
|
883
896
|
when :error_data then @error_collector
|
884
897
|
when :analytic_event_data then @transaction_event_aggregator
|
898
|
+
when :custom_event_data then @custom_event_aggregator
|
885
899
|
when :sql_trace_data then @sql_sampler
|
886
900
|
end
|
887
901
|
end
|
@@ -1043,7 +1057,11 @@ module NewRelic
|
|
1043
1057
|
|
1044
1058
|
def harvest_and_send_analytic_event_data
|
1045
1059
|
harvest_and_send_from_container(@transaction_event_aggregator, :analytic_event_data)
|
1046
|
-
harvest_and_send_from_container(@custom_event_aggregator, :
|
1060
|
+
harvest_and_send_from_container(@custom_event_aggregator, :custom_event_data)
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
def harvest_and_send_utilization_data
|
1064
|
+
harvest_and_send_from_container(@utilization_data, :utilization_data)
|
1047
1065
|
end
|
1048
1066
|
|
1049
1067
|
def check_for_and_handle_agent_commands
|
@@ -1071,17 +1089,27 @@ module NewRelic
|
|
1071
1089
|
end
|
1072
1090
|
|
1073
1091
|
def transmit_event_data
|
1092
|
+
transmit_single_data_type(:harvest_and_send_analytic_event_data, "TransactionEvent")
|
1093
|
+
end
|
1094
|
+
|
1095
|
+
def transmit_utilization_data
|
1096
|
+
transmit_single_data_type(:harvest_and_send_utilization_data, "UtilizationData")
|
1097
|
+
end
|
1098
|
+
|
1099
|
+
def transmit_single_data_type(harvest_method, supportability_name)
|
1074
1100
|
now = Time.now
|
1075
|
-
|
1101
|
+
|
1102
|
+
msg = "Sending #{harvest_method.to_s.gsub("harvest_and_send_", "")} to New Relic Service"
|
1103
|
+
::NewRelic::Agent.logger.debug msg
|
1076
1104
|
|
1077
1105
|
harvest_lock.synchronize do
|
1078
1106
|
@service.session do # use http keep-alive
|
1079
|
-
|
1107
|
+
self.send(harvest_method)
|
1080
1108
|
end
|
1081
1109
|
end
|
1082
1110
|
ensure
|
1083
1111
|
duration = (Time.now - now).to_f
|
1084
|
-
NewRelic::Agent.record_metric(
|
1112
|
+
NewRelic::Agent.record_metric("Supportability/#{supportability_name}Harvest", duration)
|
1085
1113
|
end
|
1086
1114
|
|
1087
1115
|
# This method is expected to only be called with the harvest_lock
|
@@ -1123,6 +1151,7 @@ module NewRelic
|
|
1123
1151
|
@events.notify(:before_shutdown)
|
1124
1152
|
transmit_data
|
1125
1153
|
transmit_event_data
|
1154
|
+
transmit_utilization_data if NewRelic::Agent.config[:collect_utilization]
|
1126
1155
|
|
1127
1156
|
if @connected_pid == $$ && !@service.kind_of?(NewRelic::Agent::NewRelicService)
|
1128
1157
|
::NewRelic::Agent.logger.debug "Sending New Relic service agent run shutdown message"
|
@@ -49,6 +49,12 @@ module NewRelic
|
|
49
49
|
paths << File.join(ENV["HOME"], "newrelic.yml")
|
50
50
|
end
|
51
51
|
|
52
|
+
# If we're packaged for warbler, we can tell from GEM_HOME
|
53
|
+
if ENV["GEM_HOME"] && ENV["GEM_HOME"].end_with?(".jar!")
|
54
|
+
app_name = File.basename(ENV["GEM_HOME"], ".jar!")
|
55
|
+
paths << File.join(ENV["GEM_HOME"], app_name, "config", "newrelic.yml")
|
56
|
+
end
|
57
|
+
|
52
58
|
paths
|
53
59
|
}
|
54
60
|
end
|
@@ -1092,7 +1098,7 @@ module NewRelic
|
|
1092
1098
|
:description => 'A dictionary of label names and values that will be applied to the data sent from this agent. May also be expressed as a semi-colon delimited string of colon-separated pairs (e.g. "Server:One;Data Center:Primary".'
|
1093
1099
|
},
|
1094
1100
|
:aggressive_keepalive => {
|
1095
|
-
:default =>
|
1101
|
+
:default => true,
|
1096
1102
|
:public => false,
|
1097
1103
|
:type => Boolean,
|
1098
1104
|
:description => 'If true, attempt to keep the TCP connection to the collector alive between harvests.'
|
@@ -1110,6 +1116,12 @@ module NewRelic
|
|
1110
1116
|
:type => String,
|
1111
1117
|
: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."
|
1112
1118
|
},
|
1119
|
+
:collect_utilization => {
|
1120
|
+
:default => false,
|
1121
|
+
:public => false,
|
1122
|
+
:type => Boolean,
|
1123
|
+
:description => "Controls whether to collect processor and instance sizing data and send it to New Relic"
|
1124
|
+
},
|
1113
1125
|
:'rules.ignore_url_regexes' => {
|
1114
1126
|
:default => [],
|
1115
1127
|
:public => true,
|
@@ -1129,12 +1141,24 @@ module NewRelic
|
|
1129
1141
|
:type => Fixnum,
|
1130
1142
|
:description => 'Maximum number of synthetics transaction events to hold for a given harvest'
|
1131
1143
|
},
|
1144
|
+
:'custom_insights_events.enabled' => {
|
1145
|
+
:default => true,
|
1146
|
+
:public => true,
|
1147
|
+
:type => Boolean,
|
1148
|
+
:description => 'Enable or disable custom Insights event recording.'
|
1149
|
+
},
|
1132
1150
|
:'custom_insights_events.max_samples_stored' => {
|
1133
1151
|
:default => 1000,
|
1134
1152
|
:public => true,
|
1135
1153
|
:type => Fixnum,
|
1136
1154
|
:description => 'Maximum number of custom Insights events buffered in memory at a time.',
|
1137
1155
|
:dynamic_name => true
|
1156
|
+
},
|
1157
|
+
:disable_grape => {
|
1158
|
+
:default => false,
|
1159
|
+
:public => true,
|
1160
|
+
:type => Boolean,
|
1161
|
+
:description => 'Disables installation of Grape instrumentation.'
|
1138
1162
|
}
|
1139
1163
|
}.freeze
|
1140
1164
|
|
@@ -11,8 +11,6 @@ module NewRelic
|
|
11
11
|
|
12
12
|
TYPE = 'type'.freeze
|
13
13
|
TIMESTAMP = 'timestamp'.freeze
|
14
|
-
SOURCE = 'source'.freeze
|
15
|
-
AGENT_SOURCE = 'Agent'.freeze
|
16
14
|
EVENT_PARAMS_CTX = 'recording custom event'.freeze
|
17
15
|
EVENT_TYPE_REGEX = /^[a-zA-Z0-9:_ ]+$/.freeze
|
18
16
|
|
@@ -34,7 +32,7 @@ module NewRelic
|
|
34
32
|
end
|
35
33
|
end
|
36
34
|
|
37
|
-
def record(type, attributes
|
35
|
+
def record(type, attributes)
|
38
36
|
type = @type_strings[type]
|
39
37
|
unless type =~ EVENT_TYPE_REGEX
|
40
38
|
note_dropped_event(type)
|
@@ -42,7 +40,7 @@ module NewRelic
|
|
42
40
|
end
|
43
41
|
|
44
42
|
event = [
|
45
|
-
{ TYPE => type, TIMESTAMP => Time.now.to_i
|
43
|
+
{ TYPE => type, TIMESTAMP => Time.now.to_i },
|
46
44
|
event_params(attributes, EVENT_PARAMS_CTX)
|
47
45
|
]
|
48
46
|
|
@@ -121,7 +121,8 @@ module NewRelic
|
|
121
121
|
error_ids.include?(exception.object_id)
|
122
122
|
end
|
123
123
|
|
124
|
-
def tag_as_seen(
|
124
|
+
def tag_as_seen(state, exception)
|
125
|
+
txn = state.current_transaction
|
125
126
|
txn.noticed_error_ids << exception.object_id if txn
|
126
127
|
end
|
127
128
|
|
@@ -147,14 +148,9 @@ module NewRelic
|
|
147
148
|
end
|
148
149
|
|
149
150
|
# Increments a statistic that tracks total error rate
|
150
|
-
|
151
|
-
def increment_error_count!(exception, options={}) #THREAD_LOCAL_ACCESS
|
152
|
-
state = ::NewRelic::Agent::TransactionState.tl_get
|
151
|
+
def increment_error_count!(state, exception, options={})
|
153
152
|
txn = state.current_transaction
|
154
153
|
|
155
|
-
return if seen?(txn, exception)
|
156
|
-
tag_as_seen(txn, exception)
|
157
|
-
|
158
154
|
metric_names = aggregated_metric_names(txn)
|
159
155
|
blamed_metric = blamed_metric_name(txn, options)
|
160
156
|
metric_names << blamed_metric if blamed_metric
|
@@ -165,8 +161,11 @@ module NewRelic
|
|
165
161
|
end
|
166
162
|
end
|
167
163
|
|
168
|
-
def skip_notice_error?(exception)
|
169
|
-
disabled? ||
|
164
|
+
def skip_notice_error?(state, exception)
|
165
|
+
disabled? ||
|
166
|
+
error_is_ignored?(exception) ||
|
167
|
+
exception.nil? ||
|
168
|
+
seen?(state.current_transaction, exception)
|
170
169
|
end
|
171
170
|
|
172
171
|
# acts just like Hash#fetch, but deletes the key from the hash
|
@@ -278,13 +277,19 @@ module NewRelic
|
|
278
277
|
#
|
279
278
|
# If anything is left over, it's added to custom params
|
280
279
|
# If exception is nil, the error count is bumped and no traced error is recorded
|
281
|
-
def notice_error(exception, options={})
|
282
|
-
|
283
|
-
|
280
|
+
def notice_error(exception, options={}) #THREAD_LOCAL_ACCESS
|
281
|
+
state = ::NewRelic::Agent::TransactionState.tl_get
|
282
|
+
|
283
|
+
return if skip_notice_error?(state, exception)
|
284
|
+
tag_as_seen(state, exception)
|
285
|
+
|
286
|
+
increment_error_count!(state, exception, options)
|
284
287
|
NewRelic::Agent.instance.events.notify(:notice_error, exception, options)
|
288
|
+
|
285
289
|
action_path = fetch_from_options(options, :metric, "")
|
286
290
|
exception_options = error_params_from_options(options).merge(exception_info(exception))
|
287
291
|
add_to_error_queue(NewRelic::NoticedError.new(action_path, exception_options, exception))
|
292
|
+
|
288
293
|
exception
|
289
294
|
rescue => e
|
290
295
|
::NewRelic::Agent.logger.warn("Failure when capturing error '#{exception}':", e)
|
@@ -330,17 +330,18 @@ module NewRelic
|
|
330
330
|
state = NewRelic::Agent::TransactionState.tl_get
|
331
331
|
state.request = newrelic_request(args)
|
332
332
|
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
333
|
+
skip_tracing = do_not_trace? || !state.is_execution_traced?
|
334
|
+
if skip_tracing
|
335
|
+
if block_given?
|
336
|
+
return yield
|
337
|
+
else
|
338
|
+
state.current_transaction.ignore! if state.current_transaction
|
339
|
+
NewRelic::Agent.disable_all_tracing do
|
340
|
+
return perform_action_without_newrelic_trace(*args)
|
341
|
+
end
|
339
342
|
end
|
340
343
|
end
|
341
344
|
|
342
|
-
return yield unless state.is_execution_traced?
|
343
|
-
|
344
345
|
# If a block was passed in, then the arguments represent options for
|
345
346
|
# the instrumentation, not app method arguments.
|
346
347
|
trace_options = NR_DEFAULT_OPTIONS
|
@@ -0,0 +1,67 @@
|
|
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
|
+
module NewRelic
|
6
|
+
module Agent
|
7
|
+
module GrapeInstrumentation
|
8
|
+
API_ENDPOINT = 'api.endpoint'.freeze
|
9
|
+
FORMAT = '(.:format)'.freeze
|
10
|
+
EMPTY_STRING = ''.freeze
|
11
|
+
MIN_VERSION = ::NewRelic::VersionNumber.new("0.2.0")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
DependencyDetection.defer do
|
17
|
+
named :grape
|
18
|
+
|
19
|
+
depends_on do
|
20
|
+
defined?(::Grape::VERSION) &&
|
21
|
+
::NewRelic::VersionNumber.new(::Grape::VERSION) >= ::NewRelic::Agent::GrapeInstrumentation::MIN_VERSION
|
22
|
+
end
|
23
|
+
|
24
|
+
depends_on do
|
25
|
+
false
|
26
|
+
end
|
27
|
+
|
28
|
+
executes do
|
29
|
+
NewRelic::Agent.logger.info 'Installing Grape instrumentation'
|
30
|
+
instrument_call
|
31
|
+
end
|
32
|
+
|
33
|
+
def instrument_call
|
34
|
+
::Grape::API.class_eval do
|
35
|
+
def call_with_new_relic(env)
|
36
|
+
begin
|
37
|
+
response = call_without_new_relic(env)
|
38
|
+
ensure
|
39
|
+
# We don't want an error in our transaction naming to kill the request.
|
40
|
+
begin
|
41
|
+
endpoint = env[::NewRelic::Agent::GrapeInstrumentation::API_ENDPOINT]
|
42
|
+
|
43
|
+
if endpoint
|
44
|
+
route_obj = endpoint.route
|
45
|
+
if route_obj
|
46
|
+
action_name = route_obj.route_path.sub(::NewRelic::Agent::GrapeInstrumentation::FORMAT,
|
47
|
+
::NewRelic::Agent::GrapeInstrumentation::EMPTY_STRING)
|
48
|
+
method_name = route_obj.route_method
|
49
|
+
|
50
|
+
txn_name = "#{self.class.name}#{action_name} (#{method_name})"
|
51
|
+
::NewRelic::Agent.set_transaction_name(txn_name)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
rescue => e
|
55
|
+
::NewRelic::Agent.logger.warn("Error in Grape transaction naming", e)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
response
|
60
|
+
end
|
61
|
+
|
62
|
+
alias_method :call_without_new_relic, :call
|
63
|
+
alias_method :call, :call_with_new_relic
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|