dolores_rpm 3.2.0.6 → 3.3.4.fork
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +32 -6
- data/dolores_rpm.gemspec +15 -11
- data/lib/new_relic/agent/agent.rb +28 -14
- data/lib/new_relic/agent/beacon_configuration.rb +11 -0
- data/lib/new_relic/agent/browser_monitoring.rb +53 -13
- data/lib/new_relic/agent/database.rb +34 -14
- data/lib/new_relic/agent/error_collector.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_merchant.rb +3 -1
- data/lib/new_relic/agent/instrumentation/active_record.rb +137 -0
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +24 -5
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +4 -36
- data/lib/new_relic/agent/instrumentation/metric_frame.rb +24 -3
- data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +3 -2
- data/lib/new_relic/agent/instrumentation/queue_time.rb +1 -1
- data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +88 -30
- data/lib/new_relic/agent/instrumentation/sinatra.rb +40 -20
- data/lib/new_relic/agent/samplers/memory_sampler.rb +5 -6
- data/lib/new_relic/agent/sql_sampler.rb +35 -16
- data/lib/new_relic/agent/stats_engine/gc_profiler.rb +123 -0
- data/lib/new_relic/agent/stats_engine/samplers.rb +1 -1
- data/lib/new_relic/agent/stats_engine/transactions.rb +2 -85
- data/lib/new_relic/agent/stats_engine.rb +1 -0
- data/lib/new_relic/agent/transaction_info.rb +74 -0
- data/lib/new_relic/agent/transaction_sample_builder.rb +17 -3
- data/lib/new_relic/agent/transaction_sampler.rb +86 -15
- data/lib/new_relic/agent/worker_loop.rb +1 -1
- data/lib/new_relic/agent.rb +15 -2
- data/lib/new_relic/collection_helper.rb +8 -6
- data/lib/new_relic/command.rb +1 -1
- data/lib/new_relic/commands/deployments.rb +1 -1
- data/lib/new_relic/control/configuration.rb +6 -2
- data/lib/new_relic/control/frameworks/merb.rb +1 -1
- data/lib/new_relic/control/frameworks/rails.rb +5 -5
- data/lib/new_relic/control/frameworks/rails3.rb +2 -2
- data/lib/new_relic/control/instance_methods.rb +3 -3
- data/lib/new_relic/control/instrumentation.rb +1 -1
- data/lib/new_relic/control/server_methods.rb +2 -2
- data/lib/new_relic/data_serialization.rb +10 -16
- data/lib/new_relic/delayed_job_injection.rb +6 -1
- data/lib/new_relic/language_support.rb +11 -7
- data/lib/new_relic/local_environment.rb +24 -10
- data/lib/new_relic/metric_spec.rb +7 -6
- data/lib/new_relic/noticed_error.rb +6 -1
- data/lib/new_relic/rack/browser_monitoring.rb +21 -13
- data/lib/new_relic/rack/developer_mode.rb +2 -2
- data/lib/new_relic/recipes.rb +8 -4
- data/lib/new_relic/stats.rb +0 -53
- data/lib/new_relic/transaction_sample/segment.rb +2 -0
- data/lib/new_relic/transaction_sample.rb +39 -23
- data/lib/new_relic/version.rb +3 -3
- data/test/active_record_fixtures.rb +3 -3
- data/test/fixtures/proc_cpuinfo.txt +575 -0
- data/test/new_relic/agent/agent/connect_test.rb +4 -11
- data/test/new_relic/agent/agent_test.rb +1 -0
- data/test/new_relic/agent/agent_test_controller_test.rb +20 -1
- data/test/new_relic/agent/beacon_configuration_test.rb +10 -7
- data/test/new_relic/agent/browser_monitoring_test.rb +90 -45
- data/test/new_relic/agent/database_test.rb +34 -47
- data/test/new_relic/agent/error_collector_test.rb +32 -15
- data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +56 -18
- data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +0 -2
- data/test/new_relic/agent/instrumentation/metric_frame/pop_test.rb +0 -1
- data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +3 -3
- data/test/new_relic/agent/instrumentation/queue_time_test.rb +6 -11
- data/test/new_relic/agent/method_tracer/class_methods/add_method_tracer_test.rb +1 -1
- data/test/new_relic/agent/method_tracer_test.rb +2 -2
- data/test/new_relic/agent/rpm_agent_test.rb +1 -1
- data/test/new_relic/agent/sql_sampler_test.rb +48 -16
- data/test/new_relic/agent/stats_engine_test.rb +41 -6
- data/test/new_relic/agent/transaction_info_test.rb +13 -0
- data/test/new_relic/agent/transaction_sample_builder_test.rb +19 -3
- data/test/new_relic/agent/transaction_sampler_test.rb +49 -37
- data/test/new_relic/agent/worker_loop_test.rb +1 -1
- data/test/new_relic/agent_test.rb +12 -0
- data/test/new_relic/control/configuration_test.rb +12 -0
- data/test/new_relic/control_test.rb +2 -0
- data/test/new_relic/data_serialization_test.rb +12 -12
- data/test/new_relic/local_environment_test.rb +14 -1
- data/test/new_relic/metric_parser/metric_parser_test.rb +11 -0
- data/test/new_relic/rack/browser_monitoring_test.rb +81 -23
- data/test/new_relic/rack/developer_mode_test.rb +31 -0
- data/test/new_relic/stats_test.rb +0 -15
- data/test/new_relic/transaction_sample_test.rb +13 -0
- data/test/script/build_test_gem.sh +51 -0
- data/test/script/ci.sh +94 -0
- data/test/script/ci_bench.sh +52 -0
- data/test/test_helper.rb +1 -0
- data/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection.rb +5 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/metric_parser.rb +17 -4
- metadata +25 -19
- data/dolores_rpm-3.2.0.2.gem +0 -0
- data/dolores_rpm-3.2.0.5.gem +0 -0
- data/dolores_rpm-3.3.4.fork.gem +0 -0
- data/lib/new_relic/agent/instrumentation/rails/active_record_instrumentation.rb +0 -115
- data/lib/new_relic/agent/instrumentation/rails3/active_record_instrumentation.rb +0 -122
data/CHANGELOG
CHANGED
@@ -1,11 +1,37 @@
|
|
1
|
-
v3.
|
2
|
-
*
|
1
|
+
v3.3.4.fork
|
2
|
+
* Roll back to previous version of DataMapper instrumentation (current one does not work for our app)
|
3
3
|
|
4
|
-
v3.
|
5
|
-
*
|
4
|
+
v3.3.4
|
5
|
+
* Rails 3 view instrumentation
|
6
6
|
|
7
|
-
v3.
|
8
|
-
*
|
7
|
+
v3.3.3
|
8
|
+
* Improved Sinatra instrumentation
|
9
|
+
* Limit the number of nodes collected in long running transactions to prevent leaking memory
|
10
|
+
|
11
|
+
v3.3.2.1
|
12
|
+
* [SECURITY] fix for cookie handling by End User Monitoring instrumentation
|
13
|
+
|
14
|
+
v3.3.2
|
15
|
+
* deployments recipe change: truncate git SHAs to 7 characters
|
16
|
+
* Fixes for obfuscation of PostgreSQL and SQLite queries
|
17
|
+
* Fix for lost database connections when using a forking framework
|
18
|
+
* Workaround for RedHat kernel bug which prevented blocking reads of /proc fs
|
19
|
+
* Do not trap signals when handling exceptions
|
20
|
+
|
21
|
+
v3.3.1
|
22
|
+
* improved Ruby 1.8.6 support
|
23
|
+
* fix for issues with RAILS_ROOT deprecation warnings
|
24
|
+
* fixed incorrect 1.9 GC time reporting
|
25
|
+
* obfusction for Slow SQL queries respects transaction trace config
|
26
|
+
* fix for RUM instrumentation repoting bad timing info in some cases
|
27
|
+
* refactored ActiveRecord instrumentation, no longer requires Rails
|
28
|
+
|
29
|
+
v3.3.0
|
30
|
+
* fix for GC instrumentation when using Ruby 1.9
|
31
|
+
* new feature to correlate browser and server transaction traces
|
32
|
+
* new feature to trace slow sql statements
|
33
|
+
* fix to help cope with malformed rack responses
|
34
|
+
* do not try to instrument versions of ActiveMerchant that are too old
|
9
35
|
|
10
36
|
v3.2.0.1
|
11
37
|
* Updated LICENSE
|
data/dolores_rpm.gemspec
CHANGED
@@ -5,14 +5,14 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "dolores_rpm"
|
8
|
-
s.version = "3.
|
8
|
+
s.version = "3.3.4.fork"
|
9
9
|
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Bill Kayser", "Jon Guymon", "Justin George", "Darin Swanson"]
|
12
|
-
s.date = "2012-
|
12
|
+
s.date = "2012-04-27"
|
13
13
|
s.description = "New Relic is a performance management system, developed by New Relic,\nInc (http://www.newrelic.com). This is a fork that uses an older version\nof the DataMapper instrumentation. Newer versions did not work for us.\n"
|
14
14
|
s.email = "support@newrelic.com"
|
15
|
-
s.executables = ["mongrel_rpm", "
|
15
|
+
s.executables = ["mongrel_rpm", "newrelic", "newrelic_cmd"]
|
16
16
|
s.extra_rdoc_files = [
|
17
17
|
"CHANGELOG",
|
18
18
|
"LICENSE",
|
@@ -29,10 +29,6 @@ Gem::Specification.new do |s|
|
|
29
29
|
"cert/cacert.pem",
|
30
30
|
"cert/oldsite.pem",
|
31
31
|
"cert/site.pem",
|
32
|
-
"dolores_rpm-3.2.0.2.gem",
|
33
|
-
"dolores_rpm-3.2.0.5.gem",
|
34
|
-
"dolores_rpm-3.3.4.fork.gem",
|
35
|
-
"dolores_rpm.gemspec",
|
36
32
|
"install.rb",
|
37
33
|
"lib/conditional_vendored_dependency_detection.rb",
|
38
34
|
"lib/conditional_vendored_metric_parser.rb",
|
@@ -46,6 +42,7 @@ Gem::Specification.new do |s|
|
|
46
42
|
"lib/new_relic/agent/error_collector.rb",
|
47
43
|
"lib/new_relic/agent/instrumentation.rb",
|
48
44
|
"lib/new_relic/agent/instrumentation/active_merchant.rb",
|
45
|
+
"lib/new_relic/agent/instrumentation/active_record.rb",
|
49
46
|
"lib/new_relic/agent/instrumentation/acts_as_solr.rb",
|
50
47
|
"lib/new_relic/agent/instrumentation/authlogic.rb",
|
51
48
|
"lib/new_relic/agent/instrumentation/controller_instrumentation.rb",
|
@@ -62,10 +59,8 @@ Gem::Specification.new do |s|
|
|
62
59
|
"lib/new_relic/agent/instrumentation/rack.rb",
|
63
60
|
"lib/new_relic/agent/instrumentation/rails/action_controller.rb",
|
64
61
|
"lib/new_relic/agent/instrumentation/rails/action_web_service.rb",
|
65
|
-
"lib/new_relic/agent/instrumentation/rails/active_record_instrumentation.rb",
|
66
62
|
"lib/new_relic/agent/instrumentation/rails/errors.rb",
|
67
63
|
"lib/new_relic/agent/instrumentation/rails3/action_controller.rb",
|
68
|
-
"lib/new_relic/agent/instrumentation/rails3/active_record_instrumentation.rb",
|
69
64
|
"lib/new_relic/agent/instrumentation/rails3/errors.rb",
|
70
65
|
"lib/new_relic/agent/instrumentation/sinatra.rb",
|
71
66
|
"lib/new_relic/agent/instrumentation/sunspot.rb",
|
@@ -79,9 +74,11 @@ Gem::Specification.new do |s|
|
|
79
74
|
"lib/new_relic/agent/shim_agent.rb",
|
80
75
|
"lib/new_relic/agent/sql_sampler.rb",
|
81
76
|
"lib/new_relic/agent/stats_engine.rb",
|
77
|
+
"lib/new_relic/agent/stats_engine/gc_profiler.rb",
|
82
78
|
"lib/new_relic/agent/stats_engine/metric_stats.rb",
|
83
79
|
"lib/new_relic/agent/stats_engine/samplers.rb",
|
84
80
|
"lib/new_relic/agent/stats_engine/transactions.rb",
|
81
|
+
"lib/new_relic/agent/transaction_info.rb",
|
85
82
|
"lib/new_relic/agent/transaction_sample_builder.rb",
|
86
83
|
"lib/new_relic/agent/transaction_sampler.rb",
|
87
84
|
"lib/new_relic/agent/worker_loop.rb",
|
@@ -132,10 +129,12 @@ Gem::Specification.new do |s|
|
|
132
129
|
"lib/tasks/install.rake",
|
133
130
|
"lib/tasks/tests.rake",
|
134
131
|
"newrelic.yml",
|
132
|
+
"dolores_rpm.gemspec",
|
135
133
|
"recipes/newrelic.rb",
|
136
134
|
"test/active_record_fixtures.rb",
|
137
135
|
"test/config/newrelic.yml",
|
138
136
|
"test/config/test_control.rb",
|
137
|
+
"test/fixtures/proc_cpuinfo.txt",
|
139
138
|
"test/new_relic/agent/agent/connect_test.rb",
|
140
139
|
"test/new_relic/agent/agent/start_test.rb",
|
141
140
|
"test/new_relic/agent/agent/start_worker_thread_test.rb",
|
@@ -171,6 +170,7 @@ Gem::Specification.new do |s|
|
|
171
170
|
"test/new_relic/agent/stats_engine/metric_stats_test.rb",
|
172
171
|
"test/new_relic/agent/stats_engine/samplers_test.rb",
|
173
172
|
"test/new_relic/agent/stats_engine_test.rb",
|
173
|
+
"test/new_relic/agent/transaction_info_test.rb",
|
174
174
|
"test/new_relic/agent/transaction_sample_builder_test.rb",
|
175
175
|
"test/new_relic/agent/transaction_sampler_test.rb",
|
176
176
|
"test/new_relic/agent/worker_loop_test.rb",
|
@@ -185,6 +185,7 @@ Gem::Specification.new do |s|
|
|
185
185
|
"test/new_relic/delayed_job_injection_test.rb",
|
186
186
|
"test/new_relic/local_environment_test.rb",
|
187
187
|
"test/new_relic/metric_data_test.rb",
|
188
|
+
"test/new_relic/metric_parser/metric_parser_test.rb",
|
188
189
|
"test/new_relic/metric_spec_test.rb",
|
189
190
|
"test/new_relic/rack/all_test.rb",
|
190
191
|
"test/new_relic/rack/browser_monitoring_test.rb",
|
@@ -200,6 +201,9 @@ Gem::Specification.new do |s|
|
|
200
201
|
"test/new_relic/transaction_sample_subtest_test.rb",
|
201
202
|
"test/new_relic/transaction_sample_test.rb",
|
202
203
|
"test/new_relic/version_number_test.rb",
|
204
|
+
"test/script/build_test_gem.sh",
|
205
|
+
"test/script/ci.sh",
|
206
|
+
"test/script/ci_bench.sh",
|
203
207
|
"test/test_contexts.rb",
|
204
208
|
"test/test_helper.rb",
|
205
209
|
"ui/helpers/developer_mode_helper.rb",
|
@@ -281,7 +285,7 @@ Gem::Specification.new do |s|
|
|
281
285
|
"vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/web_transaction.rb"
|
282
286
|
]
|
283
287
|
s.homepage = "http://www.github.com/newrelic/rpm"
|
284
|
-
s.post_install_message = "\nPLEASE NOTE:\n\nDeveloper Mode is now a Rack middleware.\n\nDeveloper Mode is no longer available in Rails 2.1 and earlier.\nHowever, starting in version 2.12 you can use Developer Mode in any\nRack based framework, in addition to Rails. To install developer mode\nin a non-Rails application, just add NewRelic::Rack::DeveloperMode to\nyour middleware stack.\n\nIf you are using JRuby, we recommend using at least version 1.4 or \nlater because of issues with the implementation of the timeout library.\n\nRefer to the README.md file for more information.\n\nPlease see http://github.com/newrelic/rpm/blob/master/CHANGELOG\nfor a complete description of the features and enhancements available\nin version 3.
|
288
|
+
s.post_install_message = "\nPLEASE NOTE:\n\nDeveloper Mode is now a Rack middleware.\n\nDeveloper Mode is no longer available in Rails 2.1 and earlier.\nHowever, starting in version 2.12 you can use Developer Mode in any\nRack based framework, in addition to Rails. To install developer mode\nin a non-Rails application, just add NewRelic::Rack::DeveloperMode to\nyour middleware stack.\n\nIf you are using JRuby, we recommend using at least version 1.4 or \nlater because of issues with the implementation of the timeout library.\n\nRefer to the README.md file for more information.\n\nPlease see http://github.com/newrelic/rpm/blob/master/CHANGELOG\nfor a complete description of the features and enhancements available\nin version 3.3 of the Ruby Agent.\n \n"
|
285
289
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "New Relic Ruby Agent"]
|
286
290
|
s.require_paths = ["lib"]
|
287
291
|
s.rubygems_version = "1.8.23"
|
@@ -37,7 +37,6 @@ module NewRelic
|
|
37
37
|
@transaction_sampler = NewRelic::Agent::TransactionSampler.new
|
38
38
|
@sql_sampler = NewRelic::Agent::SqlSampler.new
|
39
39
|
@stats_engine.transaction_sampler = @transaction_sampler
|
40
|
-
@stats_engine.sql_sampler = @sql_sampler
|
41
40
|
@error_collector = NewRelic::Agent::ErrorCollector.new
|
42
41
|
@connect_attempts = 0
|
43
42
|
|
@@ -130,9 +129,9 @@ module NewRelic
|
|
130
129
|
if options['exception']
|
131
130
|
e = options['exception']
|
132
131
|
elsif options['error_message']
|
133
|
-
e =
|
132
|
+
e = StandardError.new options['error_message']
|
134
133
|
else
|
135
|
-
e =
|
134
|
+
e = StandardError.new 'Unknown Error'
|
136
135
|
end
|
137
136
|
error_collector.notice_error e, :uri => options['uri'], :metric => metric
|
138
137
|
end
|
@@ -539,7 +538,7 @@ module NewRelic
|
|
539
538
|
handle_force_disconnect(e)
|
540
539
|
rescue NewRelic::Agent::ServerConnectionException => e
|
541
540
|
handle_server_connection_problem(e)
|
542
|
-
rescue
|
541
|
+
rescue => e
|
543
542
|
handle_other_error(e)
|
544
543
|
end
|
545
544
|
|
@@ -775,13 +774,15 @@ module NewRelic
|
|
775
774
|
# Ask the server for permission to send transaction samples.
|
776
775
|
# determined by subscription license.
|
777
776
|
@transaction_sampler.config['enabled'] = server_enabled
|
778
|
-
@sql_sampler.
|
779
|
-
|
777
|
+
@sql_sampler.configure!
|
780
778
|
@should_send_samples = @config_should_send_samples && server_enabled
|
781
|
-
|
779
|
+
|
782
780
|
if @should_send_samples
|
783
781
|
# I don't think this is ever true, but...
|
784
782
|
enable_random_samples!(sample_rate) if @should_send_random_samples
|
783
|
+
|
784
|
+
@transaction_sampler.slow_capture_threshold = @slowest_transaction_threshold
|
785
|
+
|
785
786
|
log.debug "Transaction tracing threshold is #{@slowest_transaction_threshold} seconds."
|
786
787
|
else
|
787
788
|
log.debug "Transaction traces will not be sent to the New Relic service."
|
@@ -862,6 +863,11 @@ module NewRelic
|
|
862
863
|
@beacon_configuration = BeaconConfiguration.new(config_data)
|
863
864
|
@server_side_config_enabled = config_data['listen_to_server_config']
|
864
865
|
|
866
|
+
if @server_side_config_enabled
|
867
|
+
log.info "Using config from server"
|
868
|
+
log.debug "Server provided config: #{config_data.inspect}"
|
869
|
+
end
|
870
|
+
|
865
871
|
control.merge_server_side_config(config_data) if @server_side_config_enabled
|
866
872
|
config_transaction_tracer
|
867
873
|
log_connection!(config_data)
|
@@ -1042,7 +1048,7 @@ module NewRelic
|
|
1042
1048
|
# FIXME add the code to try to resend if our connection is down
|
1043
1049
|
sql_traces = @sql_sampler.harvest
|
1044
1050
|
unless sql_traces.empty?
|
1045
|
-
log.debug "Sending (#{sql_traces.
|
1051
|
+
log.debug "Sending (#{sql_traces.size}) sql traces"
|
1046
1052
|
begin
|
1047
1053
|
response = invoke_remote :sql_trace_data, sql_traces
|
1048
1054
|
# log.debug "Sql trace response: #{response}"
|
@@ -1063,6 +1069,7 @@ module NewRelic
|
|
1063
1069
|
unless @traces.empty?
|
1064
1070
|
now = Time.now
|
1065
1071
|
log.debug "Sending (#{@traces.length}) transaction traces"
|
1072
|
+
|
1066
1073
|
begin
|
1067
1074
|
options = { :keep_backtraces => true }
|
1068
1075
|
options[:record_sql] = @record_sql unless @record_sql == :off
|
@@ -1134,16 +1141,16 @@ module NewRelic
|
|
1134
1141
|
def compress_data(object)
|
1135
1142
|
dump = Marshal.dump(object)
|
1136
1143
|
|
1137
|
-
# this checks to make sure mongrel won't choke on big uploads
|
1138
|
-
check_post_size(dump)
|
1139
|
-
|
1140
1144
|
dump_size = dump.size
|
1141
1145
|
|
1142
1146
|
return [dump, 'identity'] if dump_size < (64*1024)
|
1143
1147
|
|
1144
|
-
|
1148
|
+
compressed_dump = Zlib::Deflate.deflate(dump, Zlib::DEFAULT_COMPRESSION)
|
1149
|
+
|
1150
|
+
# this checks to make sure mongrel won't choke on big uploads
|
1151
|
+
check_post_size(compressed_dump)
|
1145
1152
|
|
1146
|
-
[
|
1153
|
+
[compressed_dump, 'deflate']
|
1147
1154
|
end
|
1148
1155
|
|
1149
1156
|
# Raises a PostTooBigException if the post_string is longer
|
@@ -1265,7 +1272,7 @@ module NewRelic
|
|
1265
1272
|
def save_or_transmit_data
|
1266
1273
|
if NewRelic::DataSerialization.should_send_data?
|
1267
1274
|
log.debug "Sending data to New Relic Service"
|
1268
|
-
NewRelic::Agent.load_data
|
1275
|
+
NewRelic::Agent.load_data unless NewRelic::Control.instance.disable_serialization?
|
1269
1276
|
harvest_and_send_errors
|
1270
1277
|
harvest_and_send_slowest_sample
|
1271
1278
|
harvest_and_send_slowest_sql
|
@@ -1274,6 +1281,13 @@ module NewRelic
|
|
1274
1281
|
log.debug "Serializing agent data to disk"
|
1275
1282
|
NewRelic::Agent.save_data
|
1276
1283
|
end
|
1284
|
+
rescue => e
|
1285
|
+
NewRelic::Control.instance.disable_serialization = true
|
1286
|
+
NewRelic::Control.instance.log.warn("Disabling serialization: #{e.message}")
|
1287
|
+
retry_count ||= 0
|
1288
|
+
retry_count += 1
|
1289
|
+
retry unless retry_count > 1
|
1290
|
+
raise e
|
1277
1291
|
end
|
1278
1292
|
|
1279
1293
|
# This method contacts the server to send remaining data and
|
@@ -28,6 +28,13 @@ module NewRelic
|
|
28
28
|
# local config
|
29
29
|
attr_reader :rum_enabled
|
30
30
|
|
31
|
+
# whether JSONP is used to communicate with the Beacon or not
|
32
|
+
attr_reader :rum_jsonp
|
33
|
+
|
34
|
+
# RUM footer command used for 'finish' - based on whether JSONP is
|
35
|
+
# being used. 'nrfj' for JSONP, otherwise 'nrf2'
|
36
|
+
attr_reader :finish_command
|
37
|
+
|
31
38
|
# A static javascript header that is identical for every account
|
32
39
|
# and application
|
33
40
|
JS_HEADER = "<script type=\"text/javascript\">var NREUMQ=NREUMQ||[];NREUMQ.push([\"mark\",\"firstbyte\",new Date().getTime()]);</script>"
|
@@ -45,6 +52,10 @@ module NewRelic
|
|
45
52
|
NewRelic::Control.instance.log.debug("Browser timing header: #{@browser_timing_header.inspect}")
|
46
53
|
@browser_timing_static_footer = build_load_file_js(connect_data)
|
47
54
|
NewRelic::Control.instance.log.debug("Browser timing static footer: #{@browser_timing_static_footer.inspect}")
|
55
|
+
@rum_jsonp = connect_data['rum.jsonp']
|
56
|
+
@rum_jsonp = true if @rum_jsonp.nil?
|
57
|
+
NewRelic::Control.instance.log.debug("Real User Monitoring is using JSONP protocol") if @rum_jsonp
|
58
|
+
@finish_command = @rum_jsonp ? 'nrfj' : 'nrf2'
|
48
59
|
end
|
49
60
|
|
50
61
|
# returns a memoized version of the bytes in the license key for
|
@@ -6,6 +6,24 @@ module NewRelic
|
|
6
6
|
# javascript generation and configuration
|
7
7
|
module BrowserMonitoring
|
8
8
|
|
9
|
+
|
10
|
+
class DummyMetricFrame
|
11
|
+
def initialize
|
12
|
+
@attributes = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def user_attributes
|
16
|
+
@attributes
|
17
|
+
end
|
18
|
+
|
19
|
+
def queue_time
|
20
|
+
0.0
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
@@dummy_metric_frame = DummyMetricFrame.new
|
25
|
+
|
26
|
+
|
9
27
|
# This method returns a string suitable for inclusion in a page
|
10
28
|
# - known as 'manual instrumentation' for Real User
|
11
29
|
# Monitoring. Can return either a script tag with associated
|
@@ -34,32 +52,49 @@ module NewRelic
|
|
34
52
|
config = NewRelic::Agent.instance.beacon_configuration
|
35
53
|
return "" if config.nil? || !config.rum_enabled || config.browser_monitoring_key.nil?
|
36
54
|
return "" if !NewRelic::Agent.is_transaction_traced? || !NewRelic::Agent.is_execution_traced?
|
37
|
-
generate_footer_js
|
55
|
+
generate_footer_js(config)
|
38
56
|
end
|
39
57
|
|
40
58
|
private
|
41
59
|
|
42
|
-
def generate_footer_js
|
60
|
+
def generate_footer_js(config)
|
43
61
|
if browser_monitoring_start_time
|
44
|
-
config = NewRelic::Agent.instance.beacon_configuration
|
45
62
|
application_id = config.application_id
|
46
63
|
beacon = config.beacon
|
47
64
|
license_key = config.browser_monitoring_key
|
48
65
|
|
49
|
-
footer_js_string(beacon, license_key, application_id)
|
66
|
+
footer_js_string(config, beacon, license_key, application_id)
|
50
67
|
else
|
51
68
|
''
|
52
69
|
end
|
53
70
|
end
|
54
71
|
|
55
72
|
def browser_monitoring_transaction_name
|
56
|
-
|
73
|
+
NewRelic::Agent::TransactionInfo.get.transaction_name
|
57
74
|
end
|
58
75
|
|
59
76
|
def browser_monitoring_start_time
|
60
|
-
|
77
|
+
NewRelic::Agent::TransactionInfo.get.start_time
|
61
78
|
end
|
62
|
-
|
79
|
+
|
80
|
+
def metric_frame_attribute(key)
|
81
|
+
current_metric_frame.user_attributes[key] || ""
|
82
|
+
end
|
83
|
+
|
84
|
+
def current_metric_frame
|
85
|
+
Thread.current[:last_metric_frame] || @@dummy_metric_frame
|
86
|
+
end
|
87
|
+
|
88
|
+
def tt_guid
|
89
|
+
txn = NewRelic::Agent::TransactionInfo.get
|
90
|
+
return txn.guid if txn.include_guid?
|
91
|
+
""
|
92
|
+
end
|
93
|
+
|
94
|
+
def tt_token
|
95
|
+
return NewRelic::Agent::TransactionInfo.get.token
|
96
|
+
end
|
97
|
+
|
63
98
|
def clamp_to_positive(value)
|
64
99
|
return 0.0 if value < 0
|
65
100
|
value
|
@@ -70,12 +105,17 @@ module NewRelic
|
|
70
105
|
end
|
71
106
|
|
72
107
|
def browser_monitoring_queue_time
|
73
|
-
clamp_to_positive((
|
108
|
+
clamp_to_positive((current_metric_frame.queue_time.to_f * 1000.0).round)
|
74
109
|
end
|
75
110
|
|
76
|
-
def footer_js_string(beacon, license_key, application_id)
|
77
|
-
obfuscated_transaction_name = obfuscate(browser_monitoring_transaction_name)
|
78
|
-
|
111
|
+
def footer_js_string(config, beacon, license_key, application_id)
|
112
|
+
obfuscated_transaction_name = obfuscate(config, browser_monitoring_transaction_name)
|
113
|
+
|
114
|
+
user = obfuscate(config, metric_frame_attribute(:user))
|
115
|
+
account = obfuscate(config, metric_frame_attribute(:account))
|
116
|
+
product = obfuscate(config, metric_frame_attribute(:product))
|
117
|
+
|
118
|
+
html_safe_if_needed("<script type=\"text/javascript\">#{config.browser_timing_static_footer}NREUMQ.push([\"#{config.finish_command}\",\"#{beacon}\",\"#{license_key}\",#{application_id},\"#{obfuscated_transaction_name}\",#{browser_monitoring_queue_time},#{browser_monitoring_app_time},new Date().getTime(),\"#{tt_guid}\",\"#{tt_token}\",\"#{user}\",\"#{account}\",\"#{product}\"])</script>")
|
79
119
|
end
|
80
120
|
|
81
121
|
def html_safe_if_needed(string)
|
@@ -86,9 +126,9 @@ module NewRelic
|
|
86
126
|
end
|
87
127
|
end
|
88
128
|
|
89
|
-
def obfuscate(text)
|
129
|
+
def obfuscate(config, text)
|
90
130
|
obfuscated = ""
|
91
|
-
key_bytes =
|
131
|
+
key_bytes = config.license_bytes
|
92
132
|
index = 0
|
93
133
|
text.each_byte{|byte|
|
94
134
|
obfuscated.concat((byte ^ key_bytes[index % 13].to_i))
|
@@ -30,7 +30,7 @@ module NewRelic
|
|
30
30
|
def get_connection(config)
|
31
31
|
ConnectionManager.instance.get_connection(config)
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def close_connections
|
35
35
|
ConnectionManager.instance.close_connections
|
36
36
|
end
|
@@ -95,12 +95,12 @@ module NewRelic
|
|
95
95
|
|
96
96
|
def handle_exception_in_explain
|
97
97
|
yield
|
98
|
-
rescue
|
98
|
+
rescue => e
|
99
99
|
begin
|
100
100
|
# guarantees no throw from explain_sql
|
101
101
|
NewRelic::Control.instance.log.error("Error getting query plan: #{e.message}")
|
102
102
|
NewRelic::Control.instance.log.debug(e.backtrace.join("\n"))
|
103
|
-
rescue
|
103
|
+
rescue
|
104
104
|
# double exception. throw up your hands
|
105
105
|
end
|
106
106
|
end
|
@@ -111,10 +111,10 @@ module NewRelic
|
|
111
111
|
first_word, rest_of_statement = statement.split($;, 2)
|
112
112
|
(first_word.upcase == 'SELECT')
|
113
113
|
end
|
114
|
-
|
114
|
+
|
115
115
|
class ConnectionManager
|
116
116
|
include Singleton
|
117
|
-
|
117
|
+
|
118
118
|
# Returns a cached connection for a given ActiveRecord
|
119
119
|
# configuration - these are stored or reopened as needed, and if
|
120
120
|
# we cannot get one, we ignore it and move on without explaining
|
@@ -187,16 +187,36 @@ module NewRelic
|
|
187
187
|
end
|
188
188
|
|
189
189
|
def default_sql_obfuscator(sql)
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
190
|
+
stmt = sql.kind_of?(Statement) ? sql : Statement.new(sql)
|
191
|
+
adapter = stmt.adapter
|
192
|
+
obfuscated = remove_escaped_quotes(stmt)
|
193
|
+
obfuscated = obfuscate_single_quote_literals(obfuscated)
|
194
|
+
if !(adapter.to_s =~ /postgres/ || adapter.to_s =~ /sqlite/)
|
195
|
+
obfuscated = obfuscate_double_quote_literals(obfuscated)
|
196
|
+
end
|
197
|
+
obfuscated = obfuscate_numeric_literals(obfuscated)
|
198
|
+
obfuscated.to_s # return back to a regular String
|
199
|
+
end
|
200
|
+
|
201
|
+
def remove_escaped_quotes(sql)
|
202
|
+
sql.gsub(/\\"/, '').gsub(/\\'/, '')
|
199
203
|
end
|
204
|
+
|
205
|
+
def obfuscate_single_quote_literals(sql)
|
206
|
+
sql.gsub(/'(?:[^']|'')*'/, '?')
|
207
|
+
end
|
208
|
+
|
209
|
+
def obfuscate_double_quote_literals(sql)
|
210
|
+
sql.gsub(/"(?:[^"]|"")*"/, '?')
|
211
|
+
end
|
212
|
+
|
213
|
+
def obfuscate_numeric_literals(sql)
|
214
|
+
sql.gsub(/\b\d+\b/, "?")
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
class Statement < String
|
219
|
+
attr_accessor :adapter
|
200
220
|
end
|
201
221
|
end
|
202
222
|
end
|
@@ -223,7 +223,7 @@ module NewRelic
|
|
223
223
|
exception_options = error_params_from_options(options).merge(exception_info(exception))
|
224
224
|
add_to_error_queue(NewRelic::NoticedError.new(action_path, exception_options, exception))
|
225
225
|
exception
|
226
|
-
rescue
|
226
|
+
rescue => e
|
227
227
|
log.error("Error capturing an error, yodawg. #{e}")
|
228
228
|
end
|
229
229
|
|
@@ -2,7 +2,9 @@ DependencyDetection.defer do
|
|
2
2
|
@name = :active_merchant
|
3
3
|
|
4
4
|
depends_on do
|
5
|
-
defined?(ActiveMerchant) && defined?(ActiveMerchant::Billing)
|
5
|
+
defined?(ActiveMerchant) && defined?(ActiveMerchant::Billing) &&
|
6
|
+
defined?(ActiveMerchant::Billing::Gateway) &&
|
7
|
+
ActiveMerchant::Billing::Gateway.respond_to?(:implementations)
|
6
8
|
end
|
7
9
|
|
8
10
|
executes do
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module NewRelic
|
2
|
+
module Agent
|
3
|
+
module Instrumentation
|
4
|
+
module ActiveRecord
|
5
|
+
def self.included(instrumented_class)
|
6
|
+
instrumented_class.class_eval do
|
7
|
+
unless instrumented_class.method_defined?(:log_without_newrelic_instrumentation)
|
8
|
+
alias_method :log_without_newrelic_instrumentation, :log
|
9
|
+
alias_method :log, :log_with_newrelic_instrumentation
|
10
|
+
protected :log
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def log_with_newrelic_instrumentation(*args, &block)
|
16
|
+
if !NewRelic::Agent.is_execution_traced?
|
17
|
+
return log_without_newrelic_instrumentation(*args, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
sql, name, binds = args
|
21
|
+
metric = metric_for_name(name) || metric_for_sql(sql)
|
22
|
+
|
23
|
+
if !metric
|
24
|
+
log_without_newrelic_instrumentation(*args, &block)
|
25
|
+
else
|
26
|
+
metrics = [metric, remote_service_metric].compact
|
27
|
+
metrics += rollup_metrics_for(metric)
|
28
|
+
self.class.trace_execution_scoped(metrics) do
|
29
|
+
t0 = Time.now
|
30
|
+
begin
|
31
|
+
log_without_newrelic_instrumentation(*args, &block)
|
32
|
+
ensure
|
33
|
+
elapsed_time = (Time.now - t0).to_f
|
34
|
+
NewRelic::Agent.instance.transaction_sampler.notice_sql(sql,
|
35
|
+
@config, elapsed_time)
|
36
|
+
NewRelic::Agent.instance.sql_sampler.notice_sql(sql, metric,
|
37
|
+
@config, elapsed_time)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def remote_service_metric
|
44
|
+
if @config && @config[:adapter]
|
45
|
+
type = @config[:adapter].sub(/\d*/, '')
|
46
|
+
host = @config[:host] || 'localhost'
|
47
|
+
"RemoteService/sql/#{type}/#{host}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def metric_for_name(name)
|
52
|
+
if name && (parts = name.split " ") && parts.size == 2
|
53
|
+
model = parts.first
|
54
|
+
operation = parts.last.downcase
|
55
|
+
op_name = case operation
|
56
|
+
when 'load', 'count', 'exists' then 'find'
|
57
|
+
when 'indexes', 'columns' then nil # fall back to DirectSQL
|
58
|
+
when 'destroy', 'find', 'save', 'create' then operation
|
59
|
+
when 'update' then 'save'
|
60
|
+
else
|
61
|
+
if model == 'Join'
|
62
|
+
operation
|
63
|
+
end
|
64
|
+
end
|
65
|
+
"ActiveRecord/#{model}/#{op_name}" if op_name
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def metric_for_sql(sql)
|
70
|
+
metric = NewRelic::Agent::Instrumentation::MetricFrame.database_metric_name
|
71
|
+
if metric.nil?
|
72
|
+
if sql =~ /^(select|update|insert|delete|show)/i
|
73
|
+
# Could not determine the model/operation so let's find a better
|
74
|
+
# metric. If it doesn't match the regex, it's probably a show
|
75
|
+
# command or some DDL which we'll ignore.
|
76
|
+
metric = "Database/SQL/#{$1.downcase}"
|
77
|
+
else
|
78
|
+
metric = "Database/SQL/other"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
metric
|
82
|
+
end
|
83
|
+
|
84
|
+
def rollup_metrics_for(metric)
|
85
|
+
metrics = ["ActiveRecord/all"]
|
86
|
+
metrics << "ActiveRecord/#{$1}" if metric =~ /ActiveRecord\/\w+\/(\w+)/
|
87
|
+
metrics
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
DependencyDetection.defer do
|
95
|
+
@name = :active_record
|
96
|
+
|
97
|
+
depends_on do
|
98
|
+
defined?(ActiveRecord) && defined?(ActiveRecord::Base)
|
99
|
+
end
|
100
|
+
|
101
|
+
depends_on do
|
102
|
+
!NewRelic::Control.instance['skip_ar_instrumentation']
|
103
|
+
end
|
104
|
+
|
105
|
+
depends_on do
|
106
|
+
!NewRelic::Control.instance['disable_activerecord_instrumentation']
|
107
|
+
end
|
108
|
+
|
109
|
+
executes do
|
110
|
+
NewRelic::Agent.logger.debug 'Installing ActiveRecord instrumentation'
|
111
|
+
end
|
112
|
+
|
113
|
+
executes do
|
114
|
+
if defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 3
|
115
|
+
Rails.configuration.after_initialize do
|
116
|
+
insert_instrumentation
|
117
|
+
end
|
118
|
+
else
|
119
|
+
insert_instrumentation
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def insert_instrumentation
|
124
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.module_eval do
|
125
|
+
include ::NewRelic::Agent::Instrumentation::ActiveRecord
|
126
|
+
end
|
127
|
+
|
128
|
+
ActiveRecord::Base.class_eval do
|
129
|
+
class << self
|
130
|
+
add_method_tracer(:find_by_sql, 'ActiveRecord/#{self.name}/find_by_sql',
|
131
|
+
:metric => false)
|
132
|
+
add_method_tracer(:transaction, 'ActiveRecord/#{self.name}/transaction',
|
133
|
+
:metric => false)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|