newrelic_rpm 3.1.2 → 3.2.0.beta1
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 +9 -0
- data/lib/new_relic/agent.rb +12 -3
- data/lib/new_relic/agent/agent.rb +99 -97
- data/lib/new_relic/agent/database.rb +203 -0
- data/lib/new_relic/agent/instrumentation/active_merchant.rb +2 -0
- data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +2 -0
- data/lib/new_relic/agent/instrumentation/authlogic.rb +2 -0
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +2 -0
- data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +2 -0
- data/lib/new_relic/agent/instrumentation/memcache.rb +23 -13
- data/lib/new_relic/agent/instrumentation/merb/controller.rb +2 -1
- data/lib/new_relic/agent/instrumentation/merb/errors.rb +2 -0
- data/lib/new_relic/agent/instrumentation/metric_frame.rb +7 -1
- data/lib/new_relic/agent/instrumentation/metric_frame/pop.rb +1 -0
- data/lib/new_relic/agent/instrumentation/net.rb +2 -0
- data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +2 -0
- data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +63 -36
- data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +2 -0
- data/lib/new_relic/agent/instrumentation/rails/active_record_instrumentation.rb +5 -2
- data/lib/new_relic/agent/instrumentation/rails/errors.rb +4 -2
- data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +56 -2
- data/lib/new_relic/agent/instrumentation/rails3/active_record_instrumentation.rb +5 -2
- data/lib/new_relic/agent/instrumentation/rails3/errors.rb +3 -1
- data/lib/new_relic/agent/instrumentation/sunspot.rb +2 -0
- data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +2 -1
- data/lib/new_relic/agent/shim_agent.rb +1 -0
- data/lib/new_relic/agent/sql_sampler.rb +230 -0
- data/lib/new_relic/agent/stats_engine/transactions.rb +10 -0
- data/lib/new_relic/agent/transaction_sampler.rb +11 -6
- data/lib/new_relic/collection_helper.rb +7 -4
- data/lib/new_relic/commands/deployments.rb +1 -1
- data/lib/new_relic/commands/install.rb +2 -13
- data/lib/new_relic/control/class_methods.rb +4 -3
- data/lib/new_relic/control/configuration.rb +21 -0
- data/lib/new_relic/control/frameworks/rails.rb +1 -1
- data/lib/new_relic/control/logging_methods.rb +17 -6
- data/lib/new_relic/delayed_job_injection.rb +1 -1
- data/lib/new_relic/local_environment.rb +8 -14
- data/lib/new_relic/rack/developer_mode.rb +1 -0
- data/lib/new_relic/stats.rb +1 -0
- data/lib/new_relic/transaction_sample.rb +5 -60
- data/lib/new_relic/transaction_sample/segment.rb +7 -82
- data/lib/new_relic/version.rb +3 -3
- data/newrelic_rpm.gemspec +8 -3
- data/test/new_relic/agent/agent/connect_test.rb +95 -0
- data/test/new_relic/agent/agent/start_test.rb +0 -85
- data/test/new_relic/agent/agent/start_worker_thread_test.rb +1 -0
- data/test/new_relic/agent/agent_test.rb +0 -73
- data/test/new_relic/agent/browser_monitoring_test.rb +1 -1
- data/test/new_relic/agent/database_test.rb +160 -0
- data/test/new_relic/agent/instrumentation/metric_frame/pop_test.rb +3 -0
- data/test/new_relic/agent/memcache_instrumentation_test.rb +14 -15
- data/test/new_relic/agent/sql_sampler_test.rb +135 -0
- data/test/new_relic/agent/transaction_sampler_test.rb +12 -3
- data/test/new_relic/collection_helper_test.rb +4 -4
- data/test/new_relic/control/configuration_test.rb +31 -0
- data/test/new_relic/control/logging_methods_test.rb +20 -4
- data/test/new_relic/delayed_job_injection_test.rb +1 -1
- data/test/new_relic/rack/developer_mode_helper_test.rb +141 -0
- data/test/new_relic/stats_test.rb +3 -3
- data/test/new_relic/transaction_sample/segment_test.rb +4 -92
- data/test/new_relic/transaction_sample_test.rb +1 -1
- data/test/test_helper.rb +1 -1
- data/ui/helpers/developer_mode_helper.rb +14 -8
- data/ui/helpers/google_pie_chart.rb +0 -1
- 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/mem_cache.rb +11 -11
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/view.rb +4 -0
- metadata +15 -10
@@ -67,6 +67,7 @@ module NewRelic
|
|
67
67
|
log_without_newrelic_instrumentation(*args, &block)
|
68
68
|
ensure
|
69
69
|
NewRelic::Agent.instance.transaction_sampler.notice_sql(sql, supported_config, (Time.now - t0).to_f)
|
70
|
+
NewRelic::Agent.instance.sql_sampler.notice_sql(sql, metric, supported_config, (Time.now - t0).to_f)
|
70
71
|
end
|
71
72
|
end
|
72
73
|
end
|
@@ -78,12 +79,14 @@ module NewRelic
|
|
78
79
|
end
|
79
80
|
|
80
81
|
DependencyDetection.defer do
|
82
|
+
@name = :rails3_active_record
|
83
|
+
|
81
84
|
depends_on do
|
82
85
|
defined?(ActiveRecord) && defined?(ActiveRecord::Base)
|
83
86
|
end
|
84
87
|
|
85
88
|
depends_on do
|
86
|
-
defined?(Rails) && Rails::VERSION::MAJOR.to_i == 3
|
89
|
+
defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 3
|
87
90
|
end
|
88
91
|
|
89
92
|
depends_on do
|
@@ -95,7 +98,7 @@ DependencyDetection.defer do
|
|
95
98
|
end
|
96
99
|
|
97
100
|
executes do
|
98
|
-
NewRelic::Agent.logger.debug 'Installing
|
101
|
+
NewRelic::Agent.logger.debug 'Installing Rails 3 ActiveRecord instrumentation'
|
99
102
|
end
|
100
103
|
|
101
104
|
executes do
|
@@ -15,8 +15,10 @@ module NewRelic
|
|
15
15
|
end
|
16
16
|
|
17
17
|
DependencyDetection.defer do
|
18
|
+
@name = :rails3_error
|
19
|
+
|
18
20
|
depends_on do
|
19
|
-
defined?(Rails) && Rails.respond_to?(:version) && Rails.version.to_i == 3
|
21
|
+
defined?(::Rails) && ::Rails.respond_to?(:version) && ::Rails.version.to_i == 3
|
20
22
|
end
|
21
23
|
|
22
24
|
depends_on do
|
@@ -1,4 +1,6 @@
|
|
1
1
|
DependencyDetection.defer do
|
2
|
+
@name = :unicorn
|
3
|
+
|
2
4
|
depends_on do
|
3
5
|
defined?(::Unicorn) && defined?(::Unicorn::HttpServer)
|
4
6
|
end
|
@@ -9,7 +11,6 @@ DependencyDetection.defer do
|
|
9
11
|
|
10
12
|
executes do
|
11
13
|
Unicorn::HttpServer.class_eval do
|
12
|
-
NewRelic::Agent.logger.debug "Installing Unicorn worker hook."
|
13
14
|
old_worker_loop = instance_method(:worker_loop)
|
14
15
|
define_method(:worker_loop) do | worker |
|
15
16
|
NewRelic::Agent.after_fork(:force_reconnect => true)
|
@@ -12,6 +12,7 @@ module NewRelic
|
|
12
12
|
@stats_engine.extend NewRelic::Agent::StatsEngine::Shim
|
13
13
|
@stats_engine.extend NewRelic::Agent::StatsEngine::Transactions::Shim
|
14
14
|
@transaction_sampler.extend NewRelic::Agent::TransactionSampler::Shim
|
15
|
+
@sql_sampler.extend NewRelic::Agent::SqlSampler::Shim
|
15
16
|
@error_collector.extend NewRelic::Agent::ErrorCollector::Shim
|
16
17
|
end
|
17
18
|
def after_fork *args; end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'new_relic/agent'
|
2
|
+
require 'new_relic/control'
|
3
|
+
module NewRelic
|
4
|
+
module Agent
|
5
|
+
|
6
|
+
class SqlSampler
|
7
|
+
|
8
|
+
# Module defining methods stubbed out when the agent is disabled
|
9
|
+
module Shim #:nodoc:
|
10
|
+
def notice_scope_empty(*args); end
|
11
|
+
def notice_first_scope_push(*args); end
|
12
|
+
def notice_transaction(*args); end
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :disabled
|
16
|
+
|
17
|
+
# this is for unit tests only
|
18
|
+
attr_reader :sql_traces
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
config = NewRelic::Control.instance
|
22
|
+
sampler_config = config.fetch('transaction_tracer', {})
|
23
|
+
@explain_threshold = sampler_config.fetch('explain_threshold', 0.5).to_f
|
24
|
+
# @stack_trace_threshold = sampler_config.fetch('stack_trace_threshold', 0.500).to_f
|
25
|
+
@sql_traces = {}
|
26
|
+
clear_transaction_data
|
27
|
+
|
28
|
+
# This lock is used to synchronize access to the @last_sample
|
29
|
+
# and related variables. It can become necessary on JRuby or
|
30
|
+
# any 'honest-to-god'-multithreaded system
|
31
|
+
@samples_lock = Mutex.new
|
32
|
+
end
|
33
|
+
|
34
|
+
# Enable the sql sampler - this also registers it with
|
35
|
+
# the statistics engine.
|
36
|
+
def enable
|
37
|
+
@disabled = false
|
38
|
+
NewRelic::Agent.instance.stats_engine.sql_sampler = self
|
39
|
+
end
|
40
|
+
|
41
|
+
# Disable the sql sampler - this also deregisters it
|
42
|
+
# with the statistics engine.
|
43
|
+
def disable
|
44
|
+
@disabled = true
|
45
|
+
NewRelic::Agent.instance.stats_engine.remove_sql_sampler(self)
|
46
|
+
end
|
47
|
+
|
48
|
+
def notice_transaction(path, uri=nil, params={})
|
49
|
+
transaction_data.set_transaction_info(path, uri, params) if !disabled && transaction_data
|
50
|
+
end
|
51
|
+
|
52
|
+
def notice_first_scope_push(time)
|
53
|
+
create_transaction_data
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_transaction_data
|
57
|
+
Thread.current[:new_relic_sql_data] = TransactionSqlData.new
|
58
|
+
end
|
59
|
+
|
60
|
+
def transaction_data
|
61
|
+
Thread.current[:new_relic_sql_data]
|
62
|
+
end
|
63
|
+
|
64
|
+
def clear_transaction_data
|
65
|
+
Thread.current[:new_relic_sql_data] = nil
|
66
|
+
end
|
67
|
+
|
68
|
+
# This is called when we are done with the transaction.
|
69
|
+
def notice_scope_empty(time=Time.now)
|
70
|
+
data = transaction_data
|
71
|
+
clear_transaction_data
|
72
|
+
|
73
|
+
if data.sql_data.count > 0
|
74
|
+
@samples_lock.synchronize do
|
75
|
+
NewRelic::Agent.instance.log.debug "Harvesting #{data.sql_data.count} slow transaction sql statement(s)"
|
76
|
+
#FIXME get tx name and uri
|
77
|
+
harvest_slow_sql data
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# this should always be called under the @samples_lock
|
83
|
+
def harvest_slow_sql(transaction_sql_data)
|
84
|
+
transaction_sql_data.sql_data.each do |sql_item|
|
85
|
+
obfuscated_sql = sql_item.normalize
|
86
|
+
sql_trace = @sql_traces[obfuscated_sql]
|
87
|
+
if sql_trace
|
88
|
+
sql_trace.aggregate(sql_item, transaction_sql_data.path,
|
89
|
+
transaction_sql_data.uri)
|
90
|
+
else
|
91
|
+
@sql_traces[obfuscated_sql] = SqlTrace.new(obfuscated_sql,
|
92
|
+
sql_item, transaction_sql_data.path, transaction_sql_data.uri)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
def notice_sql(sql, metric_name, config, duration)
|
99
|
+
return unless transaction_data
|
100
|
+
if NewRelic::Agent.is_sql_recorded?
|
101
|
+
if duration > @explain_threshold
|
102
|
+
backtrace = caller.join("\n")
|
103
|
+
transaction_data.sql_data << SlowSql.new(sql, metric_name, config,
|
104
|
+
duration, backtrace)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def merge(sql_traces)
|
110
|
+
@samples_lock.synchronize do
|
111
|
+
#FIXME we need to merge the sql_traces array back into the @sql_traces hash
|
112
|
+
# @sql_traces.merge! sql_traces
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def harvest
|
117
|
+
return [] if disabled
|
118
|
+
result = []
|
119
|
+
@samples_lock.synchronize do
|
120
|
+
result = @sql_traces.values
|
121
|
+
@sql_traces = {}
|
122
|
+
end
|
123
|
+
slowest = result.sort{|a,b| b.max_call_time <=> a.max_call_time}[0,10]
|
124
|
+
slowest.each {|trace| trace.prepare_to_send }
|
125
|
+
slowest
|
126
|
+
end
|
127
|
+
|
128
|
+
# reset samples without rebooting the web server
|
129
|
+
def reset!
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
class TransactionSqlData
|
134
|
+
attr_reader :path
|
135
|
+
attr_reader :uri
|
136
|
+
attr_reader :params
|
137
|
+
attr_reader :sql_data
|
138
|
+
|
139
|
+
def initialize
|
140
|
+
@sql_data = []
|
141
|
+
end
|
142
|
+
|
143
|
+
def set_transaction_info(path, uri, params)
|
144
|
+
@path = path
|
145
|
+
@uri = uri
|
146
|
+
@params = params
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
class SlowSql
|
151
|
+
attr_reader :sql
|
152
|
+
attr_reader :metric_name
|
153
|
+
attr_reader :duration
|
154
|
+
attr_reader :backtrace
|
155
|
+
|
156
|
+
def initialize(sql, metric_name, config, duration, backtrace = nil)
|
157
|
+
@sql = sql
|
158
|
+
@metric_name = metric_name
|
159
|
+
@config = config
|
160
|
+
@duration = duration
|
161
|
+
@backtrace = backtrace
|
162
|
+
end
|
163
|
+
|
164
|
+
def obfuscate
|
165
|
+
NewRelic::Agent::Database.obfuscate_sql(@sql)
|
166
|
+
end
|
167
|
+
|
168
|
+
def normalize
|
169
|
+
NewRelic::Agent::Database::Obfuscator.instance \
|
170
|
+
.default_sql_obfuscator(@sql).gsub(/\?\s*\,\s*/, '')
|
171
|
+
end
|
172
|
+
|
173
|
+
def explain
|
174
|
+
NewRelic::Agent::Database.explain_sql(@sql, @config)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
class SqlTrace < MethodTraceStats
|
179
|
+
attr_reader :path
|
180
|
+
attr_reader :url
|
181
|
+
attr_reader :sql_id
|
182
|
+
attr_reader :sql
|
183
|
+
attr_reader :database_metric_name
|
184
|
+
attr_reader :params
|
185
|
+
|
186
|
+
def initialize(obfuscated_sql, slow_sql, path, uri)
|
187
|
+
super()
|
188
|
+
@params = {} #FIXME
|
189
|
+
@sql_id = obfuscated_sql.hash
|
190
|
+
set_primary slow_sql, path, uri
|
191
|
+
record_data_point slow_sql.duration
|
192
|
+
end
|
193
|
+
|
194
|
+
def set_primary(slow_sql, path, uri)
|
195
|
+
@slow_sql = slow_sql
|
196
|
+
@sql = slow_sql.sql
|
197
|
+
@database_metric_name = slow_sql.metric_name
|
198
|
+
@path = path
|
199
|
+
@url = uri
|
200
|
+
# FIXME
|
201
|
+
@params[:backtrace] = slow_sql.backtrace if slow_sql.backtrace
|
202
|
+
end
|
203
|
+
|
204
|
+
def aggregate(slow_sql, path, uri)
|
205
|
+
if slow_sql.duration > max_call_time
|
206
|
+
set_primary slow_sql, path, uri
|
207
|
+
end
|
208
|
+
|
209
|
+
record_data_point slow_sql.duration
|
210
|
+
end
|
211
|
+
|
212
|
+
def prepare_to_send
|
213
|
+
begin
|
214
|
+
params[:explain_plan] = @slow_sql.explain
|
215
|
+
ensure
|
216
|
+
NewRelic::Agent::Database.close_connections
|
217
|
+
end
|
218
|
+
@sql = @slow_sql.obfuscate if need_to_obfuscate?
|
219
|
+
end
|
220
|
+
|
221
|
+
def need_to_obfuscate?
|
222
|
+
NewRelic::Control.instance['transaction_tracer']['record_sql'] == 'obfuscated'
|
223
|
+
end
|
224
|
+
|
225
|
+
def to_json(*a)
|
226
|
+
[@path, @url, @sql_id, @sql, @database_metric_name, @call_count, @total_call_time, @min_call_time, @max_call_time, @params].to_json(*a)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
@@ -25,6 +25,7 @@ module Agent
|
|
25
25
|
def end_transaction; end
|
26
26
|
def push_scope(*args); end
|
27
27
|
def transaction_sampler=(*args); end
|
28
|
+
def sql_sampler=(*args); end
|
28
29
|
def scope_name=(*args); end
|
29
30
|
def scope_name; end
|
30
31
|
def pop_scope(*args); end
|
@@ -42,6 +43,15 @@ module Agent
|
|
42
43
|
@transaction_sampler = nil
|
43
44
|
end
|
44
45
|
|
46
|
+
def sql_sampler= sampler
|
47
|
+
fail "Can't add a scope listener midflight in a transaction" if scope_stack.any?
|
48
|
+
@sql_sampler = sampler
|
49
|
+
end
|
50
|
+
|
51
|
+
def remove_sql_sampler(l)
|
52
|
+
@sql_sampler = nil
|
53
|
+
end
|
54
|
+
|
45
55
|
# Pushes a scope onto the transaction stack - this generates a
|
46
56
|
# TransactionSample::Segment at the end of transaction execution
|
47
57
|
def push_scope(metric, time = Time.now.to_f, deduct_call_time_from_parent = true)
|
@@ -32,7 +32,15 @@ module NewRelic
|
|
32
32
|
@harvest_count = 0
|
33
33
|
@random_sample = nil
|
34
34
|
@sampling_rate = 10
|
35
|
+
configure!
|
35
36
|
|
37
|
+
# This lock is used to synchronize access to the @last_sample
|
38
|
+
# and related variables. It can become necessary on JRuby or
|
39
|
+
# any 'honest-to-god'-multithreaded system
|
40
|
+
@samples_lock = Mutex.new
|
41
|
+
end
|
42
|
+
|
43
|
+
def configure!
|
36
44
|
# @segment_limit and @stack_trace_threshold come from the
|
37
45
|
# configuration file, with built-in defaults that should
|
38
46
|
# suffice for most customers
|
@@ -40,11 +48,7 @@ module NewRelic
|
|
40
48
|
sampler_config = config.fetch('transaction_tracer', {})
|
41
49
|
@segment_limit = sampler_config.fetch('limit_segments', 4000)
|
42
50
|
@stack_trace_threshold = sampler_config.fetch('stack_trace_threshold', 0.500).to_f
|
43
|
-
|
44
|
-
# This lock is used to synchronize access to the @last_sample
|
45
|
-
# and related variables. It can become necessary on JRuby or
|
46
|
-
# any 'honest-to-god'-multithreaded system
|
47
|
-
@samples_lock = Mutex.new
|
51
|
+
@explain_threshold = sampler_config.fetch('explain_threshold', 0.5).to_f
|
48
52
|
end
|
49
53
|
|
50
54
|
# Returns the current sample id, delegated from `builder`
|
@@ -236,7 +240,8 @@ module NewRelic
|
|
236
240
|
return unless builder
|
237
241
|
segment = builder.current_segment
|
238
242
|
if segment
|
239
|
-
segment[key] = truncate_message(append_new_message(segment[key],
|
243
|
+
segment[key] = truncate_message(append_new_message(segment[key],
|
244
|
+
message))
|
240
245
|
segment[config_key] = config if config_key
|
241
246
|
append_backtrace(segment, duration)
|
242
247
|
end
|
@@ -2,8 +2,8 @@ require 'new_relic/control'
|
|
2
2
|
|
3
3
|
module NewRelic
|
4
4
|
module CollectionHelper
|
5
|
-
DEFAULT_TRUNCATION_SIZE=
|
6
|
-
DEFAULT_ARRAY_TRUNCATION_SIZE=
|
5
|
+
DEFAULT_TRUNCATION_SIZE=16 * 1024
|
6
|
+
DEFAULT_ARRAY_TRUNCATION_SIZE=128
|
7
7
|
# Transform parameter hash into a hash whose values are strictly
|
8
8
|
# strings
|
9
9
|
def normalize_params(params)
|
@@ -17,7 +17,7 @@ module NewRelic
|
|
17
17
|
when Hash
|
18
18
|
new_params = {}
|
19
19
|
params.each do | key, value |
|
20
|
-
new_params[truncate(normalize_params(key),
|
20
|
+
new_params[truncate(normalize_params(key),64)] = normalize_params(value)
|
21
21
|
end
|
22
22
|
new_params
|
23
23
|
when Array
|
@@ -35,7 +35,10 @@ module NewRelic
|
|
35
35
|
# this is for 1.9.1, where strings no longer have Enumerable
|
36
36
|
backtrace = backtrace.split("\n") if String === backtrace
|
37
37
|
backtrace = backtrace.map &:to_s
|
38
|
-
backtrace = backtrace.reject
|
38
|
+
backtrace = backtrace.reject do |line|
|
39
|
+
line.include?(NewRelic::Control.newrelic_root) or
|
40
|
+
line =~ /^newrelic_rpm\s/
|
41
|
+
end
|
39
42
|
# rename methods back to their original state
|
40
43
|
backtrace = backtrace.collect {|line| line.gsub(/_without_(newrelic|trace)/, "")}
|
41
44
|
end
|
@@ -17,7 +17,7 @@ class NewRelic::Command::Deployments < NewRelic::Command
|
|
17
17
|
# Initialize the deployment uploader with command line args.
|
18
18
|
# Use -h to see options.
|
19
19
|
# When command_line_args is a hash, we are invoking directly and
|
20
|
-
# it's treated as an options with optional
|
20
|
+
# it's treated as an options with optional string values for
|
21
21
|
# :user, :description, :appname, :revision, :environment,
|
22
22
|
# and :changes.
|
23
23
|
#
|
@@ -52,21 +52,10 @@ at www.newrelic.com, and replace the newrelic.yml file with the one
|
|
52
52
|
you receive upon registration.
|
53
53
|
EOF
|
54
54
|
puts <<-EOF unless quiet
|
55
|
-
|
55
|
+
|
56
56
|
E-mail support@newrelic.com with any problems or questions.
|
57
|
-
|
58
|
-
EOF
|
59
|
-
puts <<-EOF
|
60
|
-
|
61
|
-
Installing the plugin from Rubyforge is deprecated. This repository will not be updated after January 2011
|
62
|
-
|
63
|
-
Please use one of the following options:
|
64
|
-
|
65
|
-
Gems: gem install newrelic_rpm
|
66
|
-
|
67
|
-
Github! git clone git://github.com/newrelic/rpm.git vendor/plugins/newrelic_rpm
|
68
|
-
|
69
57
|
EOF
|
58
|
+
|
70
59
|
end
|
71
60
|
|
72
61
|
def content
|
@@ -3,9 +3,10 @@ module NewRelic
|
|
3
3
|
# class-level methods for lazy creation of NewRelic::Control and
|
4
4
|
# NewRelic::LocalEnvironment instances.
|
5
5
|
module ClassMethods
|
6
|
-
# Access the Control singleton, lazy initialized
|
7
|
-
|
8
|
-
|
6
|
+
# Access the Control singleton, lazy initialized. Default will instantiate a new
|
7
|
+
# instance or pass false to defer
|
8
|
+
def instance(create=true)
|
9
|
+
@instance ||= create && new_instance
|
9
10
|
end
|
10
11
|
|
11
12
|
# Access the LocalEnvironment singleton, lazy initialized
|