newrelic_rpm 2.12.3 → 2.13.0.beta3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of newrelic_rpm might be problematic. Click here for more details.
- data/CHANGELOG +24 -2
- data/README.rdoc +172 -0
- data/bin/newrelic +13 -0
- data/bin/newrelic_cmd +2 -1
- data/install.rb +8 -45
- data/lib/new_relic/agent.rb +43 -30
- data/lib/new_relic/agent/agent.rb +699 -631
- data/lib/new_relic/agent/busy_calculator.rb +81 -81
- data/lib/new_relic/agent/error_collector.rb +9 -6
- data/lib/new_relic/agent/instrumentation/active_record_instrumentation.rb +2 -2
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +10 -5
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +13 -45
- data/lib/new_relic/agent/instrumentation/memcache.rb +15 -4
- data/lib/new_relic/agent/instrumentation/metric_frame.rb +37 -29
- data/lib/new_relic/agent/instrumentation/rack.rb +20 -34
- data/lib/new_relic/agent/method_tracer.rb +9 -9
- data/lib/new_relic/agent/samplers/delayed_job_lock_sampler.rb +31 -31
- data/lib/new_relic/agent/stats_engine/metric_stats.rb +5 -5
- data/lib/new_relic/agent/stats_engine/samplers.rb +3 -0
- data/lib/new_relic/agent/transaction_sampler.rb +31 -15
- data/lib/new_relic/agent/worker_loop.rb +29 -28
- data/lib/new_relic/collection_helper.rb +4 -2
- data/lib/new_relic/command.rb +85 -0
- data/lib/new_relic/commands/deployments.rb +74 -114
- data/lib/new_relic/commands/install.rb +81 -0
- data/lib/new_relic/control.rb +54 -379
- data/lib/new_relic/control/configuration.rb +149 -0
- data/lib/new_relic/control/{external.rb → frameworks/external.rb} +2 -2
- data/lib/new_relic/control/{merb.rb → frameworks/merb.rb} +1 -1
- data/lib/new_relic/control/frameworks/rails.rb +126 -0
- data/lib/new_relic/control/{rails3.rb → frameworks/rails3.rb} +11 -10
- data/lib/new_relic/control/{ruby.rb → frameworks/ruby.rb} +1 -1
- data/lib/new_relic/control/{sinatra.rb → frameworks/sinatra.rb} +2 -2
- data/lib/new_relic/control/instrumentation.rb +84 -0
- data/lib/new_relic/control/logging_methods.rb +74 -0
- data/lib/new_relic/control/profiling.rb +24 -0
- data/lib/new_relic/control/server_methods.rb +88 -0
- data/lib/new_relic/local_environment.rb +3 -3
- data/lib/new_relic/metric_parser.rb +13 -2
- data/lib/new_relic/metric_parser/active_record.rb +4 -1
- data/lib/new_relic/metric_parser/apdex.rb +53 -0
- data/lib/new_relic/metric_parser/controller.rb +13 -5
- data/lib/new_relic/metric_parser/mem_cache.rb +1 -1
- data/lib/new_relic/metric_parser/other_transaction.rb +21 -0
- data/lib/new_relic/metric_spec.rb +3 -3
- data/lib/new_relic/noticed_error.rb +1 -1
- data/lib/new_relic/rack/developer_mode.rb +257 -0
- data/lib/new_relic/rack/metric_app.rb +56 -50
- data/lib/new_relic/rack/mongrel_rpm.ru +7 -6
- data/lib/new_relic/rack/newrelic.yml +4 -3
- data/lib/new_relic/rack_app.rb +2 -1
- data/lib/new_relic/recipes.rb +7 -7
- data/lib/new_relic/stats.rb +6 -14
- data/lib/new_relic/timer_lib.rb +27 -0
- data/lib/new_relic/transaction_analysis.rb +2 -7
- data/lib/new_relic/transaction_sample.rb +17 -85
- data/lib/new_relic/url_rule.rb +14 -0
- data/lib/new_relic/version.rb +3 -3
- data/lib/newrelic_rpm.rb +5 -9
- data/newrelic.yml +26 -9
- data/newrelic_rpm.gemspec +67 -32
- data/test/config/newrelic.yml +5 -0
- data/test/config/test_control.rb +6 -8
- data/test/new_relic/agent/active_record_instrumentation_test.rb +5 -6
- data/test/new_relic/agent/agent_controller_test.rb +18 -4
- data/test/new_relic/agent/agent_test_controller.rb +1 -6
- data/test/new_relic/agent/busy_calculator_test.rb +2 -0
- data/test/new_relic/agent/collection_helper_test.rb +6 -6
- data/test/new_relic/agent/error_collector_test.rb +13 -21
- data/test/new_relic/agent/metric_data_test.rb +3 -6
- data/test/new_relic/agent/rpm_agent_test.rb +121 -117
- data/test/new_relic/agent/task_instrumentation_test.rb +128 -133
- data/test/new_relic/agent/transaction_sample_test.rb +176 -170
- data/test/new_relic/agent/worker_loop_test.rb +24 -18
- data/test/new_relic/control_test.rb +13 -3
- data/test/new_relic/deployments_api_test.rb +7 -7
- data/test/new_relic/environment_test.rb +1 -1
- data/test/new_relic/metric_parser_test.rb +58 -4
- data/test/new_relic/rack/episodes_test.rb +317 -0
- data/test/new_relic/stats_test.rb +3 -2
- data/test/test_contexts.rb +28 -0
- data/test/test_helper.rb +24 -5
- data/ui/helpers/{newrelic_helper.rb → developer_mode_helper.rb} +63 -23
- data/ui/views/layouts/newrelic_default.rhtml +6 -6
- data/ui/views/newrelic/_explain_plans.rhtml +4 -4
- data/ui/views/newrelic/_sample.rhtml +18 -17
- data/ui/views/newrelic/_segment.rhtml +1 -0
- data/ui/views/newrelic/_segment_row.rhtml +8 -8
- data/ui/views/newrelic/_show_sample_detail.rhtml +1 -1
- data/ui/views/newrelic/_show_sample_sql.rhtml +2 -2
- data/ui/views/newrelic/_sql_row.rhtml +8 -3
- data/ui/views/newrelic/_stack_trace.rhtml +9 -24
- data/ui/views/newrelic/_table.rhtml +1 -1
- data/ui/views/newrelic/explain_sql.rhtml +3 -2
- data/ui/views/newrelic/{images → file/images}/arrow-close.png +0 -0
- data/ui/views/newrelic/{images → file/images}/arrow-open.png +0 -0
- data/ui/views/newrelic/{images → file/images}/blue_bar.gif +0 -0
- data/ui/views/newrelic/{images → file/images}/file_icon.png +0 -0
- data/ui/views/newrelic/{images → file/images}/gray_bar.gif +0 -0
- data/ui/views/newrelic/{images → file/images}/new-relic-rpm-desktop.gif +0 -0
- data/ui/views/newrelic/{images → file/images}/new_relic_rpm_desktop.gif +0 -0
- data/ui/views/newrelic/{images → file/images}/textmate.png +0 -0
- data/ui/views/newrelic/file/javascript/jquery-1.4.2.js +6240 -0
- data/ui/views/newrelic/file/javascript/transaction_sample.js +120 -0
- data/ui/views/newrelic/{stylesheets → file/stylesheets}/style.css +0 -0
- data/ui/views/newrelic/index.rhtml +7 -5
- data/ui/views/newrelic/sample_not_found.rhtml +1 -1
- data/ui/views/newrelic/show_sample.rhtml +5 -6
- metadata +92 -34
- data/README.md +0 -138
- data/lib/new_relic/commands/new_relic_commands.rb +0 -30
- data/lib/new_relic/control/rails.rb +0 -151
- data/test/new_relic/agent/mock_ar_connection.rb +0 -40
- data/test/ui/newrelic_controller_test.rb +0 -14
- data/test/ui/newrelic_helper_test.rb +0 -53
- data/ui/controllers/newrelic_controller.rb +0 -220
- data/ui/views/newrelic/javascript/prototype-scriptaculous.js +0 -7288
- data/ui/views/newrelic/javascript/transaction_sample.js +0 -107
@@ -1,58 +1,64 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
module NewRelic
|
3
|
-
module Rack
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
3
|
+
module Rack
|
4
|
+
class MetricApp
|
5
|
+
def initialize(options)
|
6
|
+
if options[:install]
|
7
|
+
src = File.join(File.dirname(__FILE__), "newrelic.yml")
|
8
|
+
require 'new_relic/command'
|
9
|
+
begin
|
10
|
+
NewRelic::Command::Install.new(:quiet => true, :src_file => src).run
|
11
|
+
NewRelic::Agent.logger.info "A newrelic.yml template was copied to #{File.expand_path('.')}."
|
12
|
+
NewRelic::Agent.logger.info "Please add a license key to the file and restart #{$0}"
|
13
|
+
exit 0
|
14
|
+
rescue NewRelic::Command::CommandFailure => e
|
15
|
+
NewRelic::Agent.logger.error e.message
|
16
|
+
exit 1
|
17
|
+
end
|
18
|
+
end
|
19
|
+
options[:app_name] ||= 'EPM Monitor'
|
20
|
+
options[:disable_samplers] = true
|
21
|
+
NewRelic::Agent.manual_start options
|
22
|
+
unless NewRelic::Control.instance.license_key
|
23
|
+
raise "Please add a valid license key to newrelic.yml."
|
24
|
+
end
|
12
25
|
end
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
26
|
+
def call(env)
|
27
|
+
request = ::Rack::Request.new env
|
28
|
+
params = request.params
|
29
|
+
if !(params['uri'] || params['metric'])
|
30
|
+
[400, { 'Content-Type' => 'text/plain' }, "Missing 'uri' or 'metric' parameter: #{params.inspect}" ]
|
31
|
+
elsif !params['value']
|
32
|
+
[400, { 'Content-Type' => 'text/plain' }, "Missing 'value' parameter: #{params.inspect}" ]
|
33
|
+
else
|
34
|
+
NewRelic::Agent.record_transaction( params['value'].to_f, params )
|
35
|
+
::Rack::Response.new(params.collect { |k, v| "#{k}=#{v} " }.join).finish
|
36
|
+
end
|
19
37
|
end
|
20
38
|
end
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
body.puts "<dt>host<dd>#{request.host}"
|
45
|
-
body.puts "<dt>path<dd>#{request.url}"
|
46
|
-
body.puts "<dt>query<dd>#{request.query_string}"
|
47
|
-
body.puts "<dt>params<dd>#{request.params.inspect}"
|
48
|
-
body.puts "</dl>"
|
49
|
-
body.puts "<h2>Complete ENV</h2>"
|
50
|
-
body.puts "<ul>"
|
51
|
-
body.puts env.to_a.map{|k,v| "<li>#{k} = #{v}</li>" }.join("\n")
|
52
|
-
body.puts "</ul></body></html>"
|
53
|
-
response = ::Rack::Response.new body.string
|
54
|
-
response.finish
|
39
|
+
class Status
|
40
|
+
def call(env)
|
41
|
+
request = ::Rack::Request.new env
|
42
|
+
data_url = "http://#{env['HTTP_HOST']}/metrics/path?value=nnn"
|
43
|
+
body = StringIO.new
|
44
|
+
body.puts "<html><body>"
|
45
|
+
body.puts "<h1>New Relic Actively Monitoring #{NewRelic::Control.instance.app_names.join(' and ')}</h1>"
|
46
|
+
body.puts "<p>To submit a metric value, use <a href='#{data_url}'>#{data_url}</a></p>"
|
47
|
+
body.puts "<h2>Request Details</h2>"
|
48
|
+
body.puts "<dl>"
|
49
|
+
body.puts "<dt>ip<dd>#{request.ip}"
|
50
|
+
body.puts "<dt>host<dd>#{request.host}"
|
51
|
+
body.puts "<dt>path<dd>#{request.url}"
|
52
|
+
body.puts "<dt>query<dd>#{request.query_string}"
|
53
|
+
body.puts "<dt>params<dd>#{request.params.inspect}"
|
54
|
+
body.puts "</dl>"
|
55
|
+
body.puts "<h2>Complete ENV</h2>"
|
56
|
+
body.puts "<ul>"
|
57
|
+
body.puts env.to_a.map{|k,v| "<li>#{k} = #{v}</li>" }.join("\n")
|
58
|
+
body.puts "</ul></body></html>"
|
59
|
+
response = ::Rack::Response.new body.string
|
60
|
+
response.finish
|
61
|
+
end
|
55
62
|
end
|
56
63
|
end
|
57
64
|
end
|
58
|
-
end
|
@@ -11,15 +11,16 @@ require 'new_relic/rack_app'
|
|
11
11
|
# :app_name optional name of app
|
12
12
|
# :logging optional, false to omit request logging to stdout
|
13
13
|
|
14
|
-
options
|
14
|
+
# use Rack::CommonLogger unless options[:logging] == false
|
15
|
+
# use Rack::ShowExceptions
|
16
|
+
# use Rack::Reloader if ENV['RACK_ENV'] == 'development'
|
17
|
+
|
18
|
+
map "/newrelic/record_value" do
|
19
|
+
run NewRelic::Rack::MetricApp.new(options)
|
20
|
+
end
|
15
21
|
|
16
|
-
use Rack::CommonLogger unless options[:logging] == false
|
17
|
-
use Rack::ShowExceptions
|
18
22
|
map "/" do
|
19
23
|
run NewRelic::Rack::Status.new
|
20
24
|
end
|
21
|
-
map "/metrics" do
|
22
|
-
run NewRelic::Rack::MetricApp.new(options)
|
23
|
-
end
|
24
25
|
|
25
26
|
|
@@ -2,19 +2,20 @@
|
|
2
2
|
# This file configures the Rack NewRelic Metric Application. Place a copy of this file
|
3
3
|
# in the directory where you start the mongrel_rpm process.
|
4
4
|
#
|
5
|
+
# <%= generated_for_user %>
|
6
|
+
#
|
5
7
|
common: &default_settings
|
6
8
|
log_level: info
|
7
9
|
enabled: true
|
8
10
|
|
9
11
|
# This is the key generated by script/create_admin
|
10
|
-
license_key: '
|
12
|
+
license_key: '<%= license_key %>'
|
11
13
|
|
12
14
|
# Replace this with the name of the application feeding
|
13
15
|
# metrics into the Metric application;
|
14
16
|
app_name: Application Monitor
|
15
17
|
|
16
|
-
#
|
17
|
-
# these values will be overrides
|
18
|
+
# Set RACK_ENV to one of the following:
|
18
19
|
|
19
20
|
production:
|
20
21
|
<<: *default_settings
|
data/lib/new_relic/rack_app.rb
CHANGED
data/lib/new_relic/recipes.rb
CHANGED
@@ -16,7 +16,7 @@ make_notify_task = lambda do
|
|
16
16
|
desc "Record a deployment in New Relic RPM (rpm.newrelic.com)"
|
17
17
|
task :notice_deployment, :roles => :app, :except => {:no_release => true } do
|
18
18
|
rails_env = fetch(:newrelic_rails_env, fetch(:rails_env, "production"))
|
19
|
-
require File.join(File.dirname(__FILE__), '
|
19
|
+
require File.join(File.dirname(__FILE__), 'command.rb')
|
20
20
|
begin
|
21
21
|
# Try getting the changelog from the server. Then fall back to local changelog
|
22
22
|
# if it doesn't work. Problem is that I don't know what directory the .git is
|
@@ -52,15 +52,15 @@ make_notify_task = lambda do
|
|
52
52
|
:description => description,
|
53
53
|
:appname => appname }
|
54
54
|
logger.debug "Uploading deployment to New Relic"
|
55
|
-
deployment = NewRelic::
|
55
|
+
deployment = NewRelic::Command::Deployments.new deploy_options
|
56
56
|
deployment.run
|
57
57
|
logger.info "Uploaded deployment information to New Relic"
|
58
|
-
rescue
|
59
|
-
logger.info
|
60
|
-
rescue NewRelic::Commands::CommandFailure => e
|
61
|
-
logger.info "unable to notify New Relic of the deployment (#{e})... skipping"
|
58
|
+
rescue NewRelic::Command::CommandFailure => e
|
59
|
+
logger.info e.message
|
62
60
|
rescue Capistrano::CommandError
|
63
|
-
logger.info "
|
61
|
+
logger.info "Unable to notify New Relic of the deployment... skipping"
|
62
|
+
rescue Exception => e
|
63
|
+
logger.info "Error creating New Relic deployment (#{e})\n#{e.backtrace.join("\n")}"
|
64
64
|
end
|
65
65
|
# WIP: For rollbacks, let's update the deployment we created with an indication of the failure:
|
66
66
|
# on_rollback do
|
data/lib/new_relic/stats.rb
CHANGED
@@ -44,7 +44,7 @@ module NewRelic
|
|
44
44
|
self
|
45
45
|
end
|
46
46
|
|
47
|
-
def merge!
|
47
|
+
def merge!(other_stats)
|
48
48
|
Array(other_stats).each do |s|
|
49
49
|
self.total_call_time += s.total_call_time
|
50
50
|
self.total_exclusive_time += s.total_exclusive_time
|
@@ -59,7 +59,7 @@ module NewRelic
|
|
59
59
|
self
|
60
60
|
end
|
61
61
|
|
62
|
-
def merge
|
62
|
+
def merge(other_stats)
|
63
63
|
stats = self.clone
|
64
64
|
stats.merge! other_stats
|
65
65
|
end
|
@@ -175,21 +175,13 @@ module NewRelic
|
|
175
175
|
alias requests_per_minute calls_per_minute
|
176
176
|
|
177
177
|
def to_s
|
178
|
-
|
179
|
-
s << "Duration=#{duration} s, "
|
180
|
-
s << "Count=#{call_count}, "
|
181
|
-
s << "Total=#{to_ms(total_call_time)}, "
|
182
|
-
s << "Total Exclusive=#{to_ms(total_exclusive_time)}, "
|
183
|
-
s << "Avg=#{to_ms(average_call_time)}, "
|
184
|
-
s << "Min=#{to_ms(min_call_time)}, "
|
185
|
-
s << "Max=#{to_ms(max_call_time)}, "
|
186
|
-
s << "StdDev=#{to_ms(standard_deviation)}"
|
178
|
+
summary
|
187
179
|
end
|
188
|
-
|
180
|
+
|
189
181
|
# Summary string to facilitate testing
|
190
182
|
def summary
|
191
|
-
format = "%m/%d %I:%M%p"
|
192
|
-
"[#{Time.at(begin_time).strftime(format)}, #{'%2.3fs' % duration}; #{'%
|
183
|
+
format = "%m/%d/%y %I:%M%p"
|
184
|
+
"[#{Time.at(begin_time).utc.strftime(format)} UTC, #{'%2.3fs' % duration}; #{'%2i' % call_count} calls #{'%4i' % to_ms(average_call_time)} ms]"
|
193
185
|
end
|
194
186
|
|
195
187
|
# round all of the values to n decimal points
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Copyright: (C) 2008 David Vollbracht & Philippe Hanrigou
|
2
|
+
|
3
|
+
# This code was borrowed from the system_timer gem under the terms
|
4
|
+
# of the Ruby license. It has been slightly modified.
|
5
|
+
|
6
|
+
# Defines the constant TimerLib to the appropriate timeout library
|
7
|
+
module NewRelic #:nodoc:
|
8
|
+
|
9
|
+
begin
|
10
|
+
# Try to use the SystemTimer gem instead of Ruby's timeout library
|
11
|
+
# when running on Ruby 1.8.x. See:
|
12
|
+
# http://ph7spot.com/articles/system_timer
|
13
|
+
# We don't want to bother trying to load SystemTimer on jruby,
|
14
|
+
# ruby 1.9+ and rbx.
|
15
|
+
if !defined?(RUBY_ENGINE) || (RUBY_ENGINE == 'ruby' && RUBY_VERSION < '1.9.0')
|
16
|
+
require 'system_timer'
|
17
|
+
TimerLib = SystemTimer
|
18
|
+
else
|
19
|
+
require 'timeout'
|
20
|
+
TimerLib = Timeout
|
21
|
+
end
|
22
|
+
rescue LoadError => e
|
23
|
+
require 'timeout'
|
24
|
+
TimerLib = Timeout
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -94,15 +94,10 @@ module TransactionAnalysis
|
|
94
94
|
|
95
95
|
# return an array of sql statements executed by this transaction
|
96
96
|
# each element in the array contains [sql, parent_segment_metric_name, duration]
|
97
|
-
def sql_segments
|
97
|
+
def sql_segments(show_non_sql_segments = true)
|
98
98
|
segments = []
|
99
99
|
each_segment do |segment|
|
100
|
-
if segment[:sql]
|
101
|
-
segments << segment
|
102
|
-
end
|
103
|
-
if segment[:sql_obfuscated]
|
104
|
-
segments << segment
|
105
|
-
end
|
100
|
+
segments << segment if segment[:sql] || segment[:sql_obfuscated] || (show_non_sql_segments && segment[:key])
|
106
101
|
end
|
107
102
|
segments
|
108
103
|
end
|
@@ -16,14 +16,14 @@ module NewRelic
|
|
16
16
|
].freeze
|
17
17
|
|
18
18
|
class TransactionSample
|
19
|
+
|
20
|
+
attr_accessor :params, :root_segment
|
19
21
|
EMPTY_ARRAY = [].freeze
|
20
22
|
|
21
23
|
@@start_time = Time.now
|
22
24
|
|
23
25
|
include TransactionAnalysis
|
24
26
|
class Segment
|
25
|
-
|
26
|
-
|
27
27
|
attr_reader :entry_timestamp
|
28
28
|
# The exit timestamp will be relative except for the outermost sample which will
|
29
29
|
# have a timestamp.
|
@@ -66,35 +66,6 @@ module NewRelic
|
|
66
66
|
map.to_json
|
67
67
|
end
|
68
68
|
|
69
|
-
def self.from_json(json, id_generator)
|
70
|
-
json = ActiveSupport::JSON.decode(json) if json.is_a?(String)
|
71
|
-
if json.is_a?(Array)
|
72
|
-
entry_timestamp = json[0].to_f / 1000
|
73
|
-
exit_timestamp = json[1].to_f / 1000
|
74
|
-
metric_name = json[2]
|
75
|
-
params = json[3]
|
76
|
-
called_segments = json[4]
|
77
|
-
else
|
78
|
-
entry_timestamp = json["entry_timestamp"].to_f
|
79
|
-
exit_timestamp = json["exit_timestamp"].to_f
|
80
|
-
metric_name = json["metric_name"]
|
81
|
-
params = json["params"]
|
82
|
-
|
83
|
-
called_segments = json["called_segments"]
|
84
|
-
end
|
85
|
-
segment = Segment.new(entry_timestamp, metric_name, id_generator.next_id)
|
86
|
-
segment.end_trace exit_timestamp
|
87
|
-
if params
|
88
|
-
segment.send :params=, HashWithIndifferentAccess.new(params)
|
89
|
-
end
|
90
|
-
if called_segments
|
91
|
-
called_segments.each do |child|
|
92
|
-
segment.add_called_segment(self.from_json(child, id_generator))
|
93
|
-
end
|
94
|
-
end
|
95
|
-
segment
|
96
|
-
end
|
97
|
-
|
98
69
|
def path_string
|
99
70
|
"#{metric_name}[#{called_segments.collect {|segment| segment.path_string }.join('')}]"
|
100
71
|
end
|
@@ -250,6 +221,11 @@ module NewRelic
|
|
250
221
|
explanations
|
251
222
|
end
|
252
223
|
|
224
|
+
def params=(p)
|
225
|
+
@params = p
|
226
|
+
end
|
227
|
+
|
228
|
+
|
253
229
|
def handle_exception_in_explain(e)
|
254
230
|
x = 1 # this is here so that code coverage knows we've entered this block
|
255
231
|
# swallow failed attempts to run an explain. One example of a failure is the
|
@@ -268,9 +244,6 @@ module NewRelic
|
|
268
244
|
def parent_segment=(s)
|
269
245
|
@parent_segment = s
|
270
246
|
end
|
271
|
-
def params=(p)
|
272
|
-
@params = p
|
273
|
-
end
|
274
247
|
end
|
275
248
|
|
276
249
|
class FakeSegment < Segment
|
@@ -322,7 +295,6 @@ module NewRelic
|
|
322
295
|
NewRelic::Agent.instance.obfuscator.call(sql)
|
323
296
|
end
|
324
297
|
|
325
|
-
|
326
298
|
def get_connection(config)
|
327
299
|
@@connections ||= {}
|
328
300
|
|
@@ -399,36 +371,7 @@ module NewRelic
|
|
399
371
|
map.to_json
|
400
372
|
end
|
401
373
|
|
402
|
-
|
403
|
-
def self.from_json(json) #:nodoc:
|
404
|
-
json = ActiveSupport::JSON.decode(json) if json.is_a?(String)
|
405
|
-
|
406
|
-
if json.is_a?(Array)
|
407
|
-
start_time = json[0].to_f / 1000
|
408
|
-
custom_params = HashWithIndifferentAccess.new(json[2])
|
409
|
-
params = {:request_params => HashWithIndifferentAccess.new(json[1]),
|
410
|
-
:custom_params => custom_params}
|
411
|
-
cpu_time = custom_params.delete(:cpu_time)
|
412
|
-
sample_id = nil
|
413
|
-
params[:cpu_time] = cpu_time.to_f / 1000 if cpu_time
|
414
|
-
root = json[3]
|
415
|
-
else
|
416
|
-
start_time = json["start_time"].to_f
|
417
|
-
sample_id = json["sample_id"].to_i
|
418
|
-
params = json["params"]
|
419
|
-
root = json["root_segment"]
|
420
|
-
end
|
421
|
-
|
422
|
-
sample = TransactionSample.new(start_time, sample_id)
|
423
|
-
|
424
|
-
if params
|
425
|
-
sample.send :params=, HashWithIndifferentAccess.new(params)
|
426
|
-
end
|
427
|
-
if root
|
428
|
-
sample.send :root_segment=, Segment.from_json(root, IDGenerator.new)
|
429
|
-
end
|
430
|
-
sample
|
431
|
-
end
|
374
|
+
|
432
375
|
|
433
376
|
def start_time
|
434
377
|
Time.at(@start_time)
|
@@ -499,11 +442,12 @@ module NewRelic
|
|
499
442
|
end
|
500
443
|
|
501
444
|
# return a new transaction sample that can be sent to the RPM service.
|
502
|
-
# this involves potentially one or more of the following options
|
445
|
+
# this involves potentially one or more of the following options
|
446
|
+
#
|
503
447
|
# :explain_sql : run EXPLAIN on all queries whose response times equal the value for this key
|
504
448
|
# (for example :explain_sql => 2.0 would explain everything over 2 seconds. 0.0 would explain everything.)
|
505
449
|
# :keep_backtraces : keep backtraces, significantly increasing size of trace (off by default)
|
506
|
-
# :
|
450
|
+
# :record_sql => [ :raw | :obfuscated] : copy over the sql, obfuscating if necessary
|
507
451
|
def prepare_to_send(options={})
|
508
452
|
sample = TransactionSample.new(@start_time, sample_id)
|
509
453
|
|
@@ -533,10 +477,6 @@ module NewRelic
|
|
533
477
|
|
534
478
|
end
|
535
479
|
|
536
|
-
protected
|
537
|
-
def root_segment=(segment)
|
538
|
-
@root_segment = segment
|
539
|
-
end
|
540
480
|
def params=(params)
|
541
481
|
@params = params
|
542
482
|
end
|
@@ -620,15 +560,16 @@ module NewRelic
|
|
620
560
|
when :backtrace
|
621
561
|
target_called_segment[k]=v if options[:keep_backtraces]
|
622
562
|
when :sql
|
623
|
-
sql = v
|
624
|
-
|
625
563
|
# run an EXPLAIN on this sql if specified.
|
626
|
-
if options[:
|
564
|
+
if options[:record_sql] && options[:record_sql] && options[:explain_sql] && source_called_segment.duration > options[:explain_sql].to_f
|
627
565
|
target_called_segment[:explanation] = source_called_segment.explain_sql
|
628
566
|
end
|
629
567
|
|
630
|
-
target_called_segment[:sql]=
|
631
|
-
|
568
|
+
target_called_segment[:sql] = case options[:record_sql]
|
569
|
+
when :raw then v
|
570
|
+
when :obfuscated then TransactionSample.obfuscate_sql(v)
|
571
|
+
else raise "Invalid value for record_sql: #{options[:record_sql]}"
|
572
|
+
end if options[:record_sql]
|
632
573
|
when :connection_config
|
633
574
|
# don't copy it
|
634
575
|
else
|
@@ -641,14 +582,5 @@ module NewRelic
|
|
641
582
|
end
|
642
583
|
end
|
643
584
|
|
644
|
-
# Generates segment ids for json transaction segments
|
645
|
-
class IDGenerator
|
646
|
-
def initialize
|
647
|
-
@next_id = 0
|
648
|
-
end
|
649
|
-
def next_id
|
650
|
-
@next_id += 1
|
651
|
-
end
|
652
|
-
end
|
653
585
|
end
|
654
586
|
end
|