newrelic_rpm 3.6.0.74.beta → 3.6.0.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data.tar.gz.sig +1 -2
- data/CHANGELOG +18 -0
- data/Gemfile +3 -3
- data/Rakefile +8 -0
- data/lib/new_relic/agent/agent.rb +4 -9
- data/lib/new_relic/agent/agent_logger.rb +1 -2
- data/lib/new_relic/agent/audit_logger.rb +7 -3
- data/lib/new_relic/agent/busy_calculator.rb +3 -3
- data/lib/new_relic/agent/configuration/server_source.rb +23 -10
- data/lib/new_relic/agent/cross_app_monitor.rb +1 -0
- data/lib/new_relic/agent/database.rb +2 -0
- data/lib/new_relic/agent/error_collector.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_record.rb +14 -13
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +72 -0
- data/lib/new_relic/agent/instrumentation/rails4/action_controller.rb +0 -76
- data/lib/new_relic/agent/instrumentation/rails4/action_view.rb +138 -0
- data/lib/new_relic/agent/instrumentation/rails4/active_record.rb +108 -0
- data/lib/new_relic/agent/null_logger.rb +15 -0
- data/lib/new_relic/agent/stats.rb +1 -0
- data/lib/new_relic/agent/stats_engine/transactions.rb +4 -4
- data/lib/new_relic/control/frameworks/rails.rb +0 -37
- data/lib/new_relic/control/frameworks/rails3.rb +0 -17
- data/lib/new_relic/control/instance_methods.rb +1 -2
- data/lib/new_relic/environment_report.rb +159 -0
- data/lib/new_relic/helper.rb +4 -0
- data/lib/new_relic/local_environment.rb +0 -161
- data/lib/newrelic_rpm.rb +1 -1
- data/test/multiverse/lib/multiverse/suite.rb +7 -0
- data/test/multiverse/suites/active_record/Envfile +0 -1
- data/test/multiverse/suites/agent_only/key_transactions_test.rb +22 -12
- data/test/multiverse/suites/rails/Envfile +8 -1
- data/test/multiverse/suites/rails/app.rb +7 -2
- data/test/multiverse/suites/rails/error_tracing_test.rb +28 -16
- data/test/multiverse/suites/rails/view_instrumentation_test.rb +8 -2
- data/test/new_relic/agent/agent/connect_test.rb +5 -8
- data/test/new_relic/agent/agent/start_test.rb +3 -1
- data/test/new_relic/agent/agent_logger_test.rb +8 -8
- data/test/new_relic/agent/agent_test.rb +0 -6
- data/test/new_relic/agent/agent_test_controller_test.rb +18 -14
- data/test/new_relic/agent/audit_logger_test.rb +12 -0
- data/test/new_relic/agent/configuration/server_source_test.rb +48 -0
- data/test/new_relic/agent/cross_app_monitor_test.rb +8 -0
- data/test/new_relic/agent/instrumentation/action_view_subscriber_test.rb +254 -0
- data/test/new_relic/agent/instrumentation/active_record_helper_test.rb +52 -0
- data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +32 -51
- data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +132 -0
- data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +20 -0
- data/test/new_relic/agent_test.rb +0 -8
- data/test/new_relic/control_test.rb +1 -2
- data/test/new_relic/dispatcher_test.rb +1 -5
- data/test/new_relic/environment_report_test.rb +89 -0
- data/test/new_relic/license_test.rb +1 -3
- data/test/new_relic/load_test.rb +5 -1
- data/test/new_relic/local_environment_test.rb +0 -27
- data/test/new_relic/rack/browser_monitoring_test.rb +1 -0
- data/test/script/ci.sh +19 -18
- data/test/test_helper.rb +15 -3
- metadata +42 -3
- metadata.gz.sig +0 -0
@@ -0,0 +1,138 @@
|
|
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
|
+
# Listen for ActiveSupport::Notifications events for ActionView render
|
6
|
+
# events. Write metric data and transaction trace segments for each event.
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
module Instrumentation
|
10
|
+
class ActionViewSubscriber
|
11
|
+
def initialize
|
12
|
+
@queue_key = ['NewRelic', self.class.name, object_id].join('-')
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.subscribe
|
16
|
+
if !subscribed?
|
17
|
+
ActiveSupport::Notifications.subscribe(/render_.+\.action_view$/,
|
18
|
+
new)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.subscribed?
|
23
|
+
# TODO: need to talk to Rails core about an API for this,
|
24
|
+
# rather than digging through Listener ivars
|
25
|
+
ActiveSupport::Notifications.notifier.instance_variable_get(:@subscribers) \
|
26
|
+
.find{|s| s.instance_variable_get(:@delegate).class == self }
|
27
|
+
end
|
28
|
+
|
29
|
+
def start(name, id, payload)
|
30
|
+
event = RenderEvent.new(name, Time.now, nil, id, payload)
|
31
|
+
parent = event_stack[id].last
|
32
|
+
event.parent = parent
|
33
|
+
parent << event if parent
|
34
|
+
event_stack[id].push event
|
35
|
+
|
36
|
+
if NewRelic::Agent.is_execution_traced? && event.recordable?
|
37
|
+
event.scope = NewRelic::Agent.instance.stats_engine \
|
38
|
+
.push_scope(event.metric_name, event.time)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def finish(name, id, payload)
|
43
|
+
event = event_stack[id].pop
|
44
|
+
event.end = Time.now
|
45
|
+
|
46
|
+
if NewRelic::Agent.is_execution_traced? && event.recordable?
|
47
|
+
record_metrics(event)
|
48
|
+
NewRelic::Agent.instance.stats_engine \
|
49
|
+
.pop_scope(event.scope, event.duration, event.end)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def record_metrics(event)
|
54
|
+
NewRelic::Agent.instance.stats_engine \
|
55
|
+
.record_metrics(event.metric_name,
|
56
|
+
Helper.milliseconds_to_seconds(event.duration),
|
57
|
+
:scoped => true)
|
58
|
+
end
|
59
|
+
|
60
|
+
def event_stack
|
61
|
+
Thread.current[@queue_key] ||= Hash.new {|h,id| h[id] = [] }
|
62
|
+
end
|
63
|
+
|
64
|
+
if defined?(ActiveSupport::Notifications::Event)
|
65
|
+
class RenderEvent < ActiveSupport::Notifications::Event
|
66
|
+
attr_accessor :parent, :scope
|
67
|
+
|
68
|
+
# Nearly every "render_blah.action_view" event has a child
|
69
|
+
# in the form of "!render_blah.action_view". The children
|
70
|
+
# are the ones we want to record. There are a couple
|
71
|
+
# special cases of events without children.
|
72
|
+
def recordable?
|
73
|
+
name[0] == '!' ||
|
74
|
+
metric_name == 'View/text template/Rendering' ||
|
75
|
+
metric_name == 'View/(unknown)/Partial'
|
76
|
+
end
|
77
|
+
|
78
|
+
def metric_name
|
79
|
+
if parent && (payload[:virtual_path] ||
|
80
|
+
(parent.payload[:identifier] =~ /template$/))
|
81
|
+
return parent.metric_name
|
82
|
+
elsif payload[:virtual_path]
|
83
|
+
identifier = payload[:virtual_path]
|
84
|
+
else
|
85
|
+
identifier = payload[:identifier]
|
86
|
+
end
|
87
|
+
|
88
|
+
# memoize
|
89
|
+
@metric_name ||= "View/#{metric_path(identifier)}/#{metric_action(name)}"
|
90
|
+
@metric_name
|
91
|
+
end
|
92
|
+
|
93
|
+
def metric_path(identifier)
|
94
|
+
if identifier == nil
|
95
|
+
'file'
|
96
|
+
elsif identifier =~ /template$/
|
97
|
+
identifier
|
98
|
+
elsif (parts = identifier.split('/')).size > 1
|
99
|
+
parts[-2..-1].join('/')
|
100
|
+
else
|
101
|
+
'(unknown)'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def metric_action(name)
|
106
|
+
case name
|
107
|
+
when /render_template.action_view$/ then 'Rendering'
|
108
|
+
when 'render_partial.action_view' then 'Partial'
|
109
|
+
when 'render_collection.action_view' then 'Partial'
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
DependencyDetection.defer do
|
120
|
+
@name = :rails4_view
|
121
|
+
|
122
|
+
depends_on do
|
123
|
+
defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 4
|
124
|
+
end
|
125
|
+
|
126
|
+
depends_on do
|
127
|
+
!NewRelic::Agent.config[:disable_view_instrumentation] &&
|
128
|
+
!NewRelic::Agent::Instrumentation::ActionViewSubscriber.subscribed?
|
129
|
+
end
|
130
|
+
|
131
|
+
executes do
|
132
|
+
::NewRelic::Agent.logger.info 'Installing Rails 4 view instrumentation'
|
133
|
+
end
|
134
|
+
|
135
|
+
executes do
|
136
|
+
NewRelic::Agent::Instrumentation::ActionViewSubscriber.subscribe
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,108 @@
|
|
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
|
+
require 'new_relic/agent/instrumentation/active_record_helper'
|
5
|
+
|
6
|
+
# Listen for ActiveSupport::Notifications events for ActiveRecord query
|
7
|
+
# events. Write metric data, transaction trace segments and slow sql
|
8
|
+
# nodes for each event.
|
9
|
+
module NewRelic
|
10
|
+
module Agent
|
11
|
+
module Instrumentation
|
12
|
+
class ActiveRecordSubscriber
|
13
|
+
include NewRelic::Agent::Instrumentation
|
14
|
+
|
15
|
+
def self.subscribed?
|
16
|
+
# TODO: need to talk to Rails core about an API for this,
|
17
|
+
# rather than digging through Listener ivars
|
18
|
+
ActiveSupport::Notifications.notifier.listeners_for('sql.active_record') \
|
19
|
+
.find{|l| l.instance_variable_get(:@delegate).class == self }
|
20
|
+
end
|
21
|
+
|
22
|
+
def call(*args)
|
23
|
+
return unless NewRelic::Agent.is_execution_traced?
|
24
|
+
|
25
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
26
|
+
record_metrics(event)
|
27
|
+
notice_sql(event)
|
28
|
+
end
|
29
|
+
|
30
|
+
def notice_sql(event)
|
31
|
+
config = active_record_config_for_event(event)
|
32
|
+
metric = base_metric(event)
|
33
|
+
|
34
|
+
# enter transaction trace segment
|
35
|
+
scope = NewRelic::Agent.instance.stats_engine.push_scope(metric, event.time)
|
36
|
+
|
37
|
+
NewRelic::Agent.instance.transaction_sampler \
|
38
|
+
.notice_sql(event.payload[:sql], config,
|
39
|
+
Helper.milliseconds_to_seconds(event.duration))
|
40
|
+
|
41
|
+
NewRelic::Agent.instance.sql_sampler \
|
42
|
+
.notice_sql(event.payload[:sql], metric, config,
|
43
|
+
Helper.milliseconds_to_seconds(event.duration))
|
44
|
+
|
45
|
+
# exit transaction trace segment
|
46
|
+
NewRelic::Agent.instance.stats_engine.pop_scope(scope, event.duration, event.end)
|
47
|
+
end
|
48
|
+
|
49
|
+
def record_metrics(event)
|
50
|
+
base = base_metric(event)
|
51
|
+
NewRelic::Agent.instance.stats_engine.record_metrics(base,
|
52
|
+
Helper.milliseconds_to_seconds(event.duration),
|
53
|
+
:scoped => true)
|
54
|
+
|
55
|
+
other_metrics = ActiveRecordHelper.rollup_metrics_for(base)
|
56
|
+
if config = active_record_config_for_event(event)
|
57
|
+
other_metrics << ActiveRecordHelper.remote_service_metric(config[:adapter], config[:host])
|
58
|
+
end
|
59
|
+
|
60
|
+
other_metrics.compact.each do |metric_name|
|
61
|
+
NewRelic::Agent.instance.stats_engine.record_metrics(metric_name,
|
62
|
+
Helper.milliseconds_to_seconds(event.duration),
|
63
|
+
:scoped => false)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def base_metric(event)
|
68
|
+
ActiveRecordHelper.metric_for_name(event.payload[:name]) ||
|
69
|
+
ActiveRecordHelper.metric_for_sql(NewRelic::Helper.correctly_encoded(event.payload[:sql]))
|
70
|
+
end
|
71
|
+
|
72
|
+
def active_record_config_for_event(event)
|
73
|
+
return unless event.payload[:connection_id]
|
74
|
+
|
75
|
+
# TODO: This will not work for JRuby and in any case we want
|
76
|
+
# this to be part of the event meta data so it doesn't have
|
77
|
+
# to be dug out of an ivar.
|
78
|
+
connection = ObjectSpace._id2ref(event.payload[:connection_id])
|
79
|
+
connection.instance_variable_get(:@config) if connection
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
DependencyDetection.defer do
|
87
|
+
@name = :active_record
|
88
|
+
|
89
|
+
depends_on do
|
90
|
+
defined?(::ActiveRecord) && defined?(::ActiveRecord::Base) &&
|
91
|
+
defined?(::ActiveRecord::VERSION) &&
|
92
|
+
::ActiveRecord::VERSION::MAJOR.to_i >= 4
|
93
|
+
end
|
94
|
+
|
95
|
+
depends_on do
|
96
|
+
!NewRelic::Agent.config[:disable_activerecord_instrumentation] &&
|
97
|
+
!NewRelic::Agent::Instrumentation::ActiveRecordSubscriber.subscribed?
|
98
|
+
end
|
99
|
+
|
100
|
+
executes do
|
101
|
+
::NewRelic::Agent.logger.info 'Installing ActiveRecord instrumentation'
|
102
|
+
end
|
103
|
+
|
104
|
+
executes do
|
105
|
+
ActiveSupport::Notifications.subscribe('sql.active_record',
|
106
|
+
NewRelic::Agent::Instrumentation::ActiveRecordSubscriber.new)
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,15 @@
|
|
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
|
+
# A stub object that we can use in place of a real Logger instance when
|
6
|
+
# the agent is disabled.
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
class NullLogger
|
10
|
+
def method_missing(method, *args, &blk)
|
11
|
+
nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -75,17 +75,17 @@ module Agent
|
|
75
75
|
@transaction_sampler.notice_pop_scope(scope.name, time) if sampler_enabled?
|
76
76
|
scope
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
def sampler_enabled?
|
80
80
|
@transaction_sampler && Agent.config[:'transaction_tracer.enabled']
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
# Rename the segment associated with the last pushed scope to +new_name+.
|
84
84
|
def rename_scope_segment( new_name )
|
85
85
|
self.peek_scope.name = new_name
|
86
|
-
@transaction_sampler.rename_scope_segment( new_name )
|
86
|
+
@transaction_sampler.rename_scope_segment( new_name ) if sampler_enabled?
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
89
|
# Returns the latest ScopeStackElement
|
90
90
|
def peek_scope
|
91
91
|
scope_stack.last
|
@@ -125,43 +125,6 @@ module NewRelic
|
|
125
125
|
File.join(root,'vendor','rails')
|
126
126
|
end
|
127
127
|
|
128
|
-
def rails_gem_list
|
129
|
-
::Rails.configuration.gems.map do |gem|
|
130
|
-
version = (gem.respond_to?(:version) && gem.version) ||
|
131
|
-
(gem.specification.respond_to?(:version) && gem.specification.version)
|
132
|
-
gem.name + (version ? "(#{version})" : "")
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
# Collect the Rails::Info into an associative array as well as the list of plugins
|
137
|
-
def append_environment_info
|
138
|
-
local_env.append_environment_value('Rails version'){ ::Rails::VERSION::STRING }
|
139
|
-
if rails_version >= NewRelic::VersionNumber.new('2.2.0')
|
140
|
-
local_env.append_environment_value('Rails threadsafe') do
|
141
|
-
::Rails.configuration.action_controller.allow_concurrency == true
|
142
|
-
end
|
143
|
-
end
|
144
|
-
local_env.append_environment_value('Rails Env') { ENV['RAILS_ENV'] }
|
145
|
-
if rails_version >= NewRelic::VersionNumber.new('2.1.0')
|
146
|
-
local_env.append_gem_list do
|
147
|
-
(bundler_gem_list + rails_gem_list).uniq
|
148
|
-
end
|
149
|
-
# The plugins is configured manually. If it's nil, it loads everything non-deterministically
|
150
|
-
if ::Rails.configuration.plugins
|
151
|
-
local_env.append_plugin_list { ::Rails.configuration.plugins }
|
152
|
-
else
|
153
|
-
::Rails.configuration.plugin_paths.each do |path|
|
154
|
-
local_env.append_plugin_list { Dir[File.join(path, '*')].collect{ |p| File.basename p if File.directory? p }.compact }
|
155
|
-
end
|
156
|
-
end
|
157
|
-
else
|
158
|
-
# Rails prior to 2.1, can't get the gems. Find plugins in the default location
|
159
|
-
local_env.append_plugin_list do
|
160
|
-
Dir[File.join(root, 'vendor', 'plugins', '*')].collect{ |p| File.basename p if File.directory? p }.compact
|
161
|
-
end
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
128
|
def install_shim
|
166
129
|
super
|
167
130
|
require 'new_relic/agent/instrumentation/controller_instrumentation'
|
@@ -46,23 +46,6 @@ module NewRelic
|
|
46
46
|
|
47
47
|
protected
|
48
48
|
|
49
|
-
# Collect the Rails::Info into an associative array as well as the list of plugins
|
50
|
-
def append_environment_info
|
51
|
-
local_env.append_environment_value('Rails version'){ ::Rails::VERSION::STRING }
|
52
|
-
local_env.append_environment_value('Rails threadsafe') do
|
53
|
-
true == ::Rails.configuration.action_controller.allow_concurrency
|
54
|
-
end
|
55
|
-
local_env.append_environment_value('Rails Env') { env }
|
56
|
-
local_env.append_gem_list do
|
57
|
-
bundler_gem_list
|
58
|
-
end
|
59
|
-
append_plugin_list
|
60
|
-
end
|
61
|
-
|
62
|
-
def append_plugin_list
|
63
|
-
local_env.append_plugin_list { ::Rails.configuration.plugins.to_a }
|
64
|
-
end
|
65
|
-
|
66
49
|
def install_shim
|
67
50
|
super
|
68
51
|
ActiveSupport.on_load(:action_controller) do
|
@@ -3,6 +3,7 @@
|
|
3
3
|
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
4
|
|
5
5
|
require 'new_relic/language_support'
|
6
|
+
require 'new_relic/agent/null_logger'
|
6
7
|
require 'new_relic/agent/agent_logger'
|
7
8
|
|
8
9
|
module NewRelic
|
@@ -74,8 +75,6 @@ module NewRelic
|
|
74
75
|
start_agent
|
75
76
|
install_instrumentation
|
76
77
|
load_samplers unless Agent.config[:disable_samplers]
|
77
|
-
local_env.gather_environment_info
|
78
|
-
append_environment_info
|
79
78
|
elsif !Agent.config[:agent_enabled]
|
80
79
|
install_shim
|
81
80
|
end
|
@@ -0,0 +1,159 @@
|
|
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
|
+
# The EnvironmentReport is responsible for analyzing the application's
|
7
|
+
# environment and generating the data for the Environment Report in New
|
8
|
+
# Relic's interface.
|
9
|
+
#
|
10
|
+
# It contains useful system information like Ruby version, OS, loaded gems,
|
11
|
+
# etc.
|
12
|
+
#
|
13
|
+
# Additional logic can be registered by using the EnvironmentReport.report_on
|
14
|
+
# hook.
|
15
|
+
class EnvironmentReport
|
16
|
+
|
17
|
+
# This is the main interface for registering logic that should be included
|
18
|
+
# in the Environment Report. For example:
|
19
|
+
#
|
20
|
+
# EnvironmentReport.report_on "Day of week" do
|
21
|
+
# Time.now.strftime("%A")
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# The passed blocks will be run in EnvironmentReport instances on #initialize.
|
25
|
+
#
|
26
|
+
# Errors raised in passed blocks will be handled and logged at debug, so it
|
27
|
+
# is safe to report on things that may not work in certain environments.
|
28
|
+
#
|
29
|
+
# The blocks should only return strings or arrays full of strings. Falsey
|
30
|
+
# values will be ignored.
|
31
|
+
def self.report_on(key, &block)
|
32
|
+
registered_reporters[key] = block
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.registered_reporters
|
36
|
+
@registered_reporters ||= Hash.new
|
37
|
+
end
|
38
|
+
|
39
|
+
# allow the logic to be swapped out in tests
|
40
|
+
def self.registered_reporters=(logic)
|
41
|
+
@registered_reporters = logic
|
42
|
+
end
|
43
|
+
|
44
|
+
# register reporting logic
|
45
|
+
####################################
|
46
|
+
report_on 'Gems' do
|
47
|
+
begin
|
48
|
+
Bundler.rubygems.all_specs.map { |gem| "#{gem.name}(#{gem.version})" }
|
49
|
+
rescue
|
50
|
+
# There are certain rubygem, bundler, rails combinations (e.g. gem
|
51
|
+
# 1.6.2, rails 2.3, bundler 1.2.3) where the code above throws an error
|
52
|
+
# in bundler because of rails monkey patching gem. The below does work
|
53
|
+
# though so try it if the above fails.
|
54
|
+
Bundler.load.specs.map do | spec |
|
55
|
+
version = (spec.respond_to?(:version) && spec.version)
|
56
|
+
spec.name + (version ? "(#{version})" : "")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
report_on('Plugin List'){ ::Rails.configuration.plugins.to_a }
|
61
|
+
report_on('Ruby version'){ RUBY_VERSION }
|
62
|
+
report_on('Ruby description'){ RUBY_DESCRIPTION }
|
63
|
+
report_on('Ruby platform'){ RUBY_PLATFORM }
|
64
|
+
report_on('Ruby patchlevel'){ RUBY_PATCHLEVEL.to_s }
|
65
|
+
report_on('JRuby version') { JRUBY_VERSION }
|
66
|
+
report_on('Java VM version') { ENV_JAVA['java.vm.version']}
|
67
|
+
report_on 'Processors' do
|
68
|
+
cpuinfo = ''
|
69
|
+
proc_file = '/proc/cpuinfo'
|
70
|
+
File.open(proc_file) do |f|
|
71
|
+
loop do
|
72
|
+
begin
|
73
|
+
cpuinfo << f.read_nonblock(4096).strip
|
74
|
+
rescue EOFError
|
75
|
+
break
|
76
|
+
rescue Errno::EWOULDBLOCK, Errno::EAGAIN
|
77
|
+
cpuinfo = ''
|
78
|
+
break # don't select file handle, just give up
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
processors = cpuinfo.split("\n").select {|line| line =~ /^processor\s*:/ }.size
|
83
|
+
|
84
|
+
if processors == 0
|
85
|
+
processors = nil # assume there is at least one processor
|
86
|
+
::NewRelic::Agent.logger.warn("Cannot determine the number of processors in #{proc_file}")
|
87
|
+
end
|
88
|
+
processors
|
89
|
+
end
|
90
|
+
report_on 'Arch' do
|
91
|
+
arch = `uname -p`
|
92
|
+
arch = ENV['PROCESSOR_ARCHITECTURE'] if arch == ''
|
93
|
+
arch
|
94
|
+
end
|
95
|
+
report_on('OS version'){ `uname -v` }
|
96
|
+
report_on('OS') do
|
97
|
+
os = `uname -s`
|
98
|
+
os = ENV['OS'] if os == ''
|
99
|
+
os
|
100
|
+
end
|
101
|
+
report_on 'Database adapter' do
|
102
|
+
ActiveRecord::Base.configurations[NewRelic::Control.instance.env]['adapter']
|
103
|
+
end
|
104
|
+
report_on('Framework') { Agent.config[:framework].to_s }
|
105
|
+
report_on('Dispatcher') { Agent.config[:dispatcher].to_s }
|
106
|
+
report_on('Environment') { NewRelic::Control.instance.env }
|
107
|
+
report_on('Rails version') { ::Rails::VERSION::STRING }
|
108
|
+
report_on 'Rails threadsafe' do
|
109
|
+
::Rails.configuration.action_controller.allow_concurrency
|
110
|
+
end
|
111
|
+
report_on 'Rails Env' do
|
112
|
+
if defined? ::Rails and ::Rails.respond_to?(:env)
|
113
|
+
::Rails.env
|
114
|
+
else
|
115
|
+
ENV['RAILS_ENV']
|
116
|
+
end
|
117
|
+
end
|
118
|
+
# end reporting logic
|
119
|
+
####################################
|
120
|
+
|
121
|
+
|
122
|
+
attr_reader :data
|
123
|
+
# Generate the report based on the class level logic.
|
124
|
+
def initialize
|
125
|
+
@data = self.class.registered_reporters.inject(Hash.new) do |data, (key, logic)|
|
126
|
+
begin
|
127
|
+
value = logic.call
|
128
|
+
if value
|
129
|
+
data[key] = value
|
130
|
+
|
131
|
+
Agent.record_metric("Supportability/EnvironmentReport/success", 0.0)
|
132
|
+
Agent.record_metric("Supportability/EnvironmentReport/success/#{key}", 0.0)
|
133
|
+
else
|
134
|
+
Agent.logger.debug("EnvironmentReport ignoring value for #{key.inspect} which came back falsey: #{value.inspect}")
|
135
|
+
Agent.record_metric("Supportability/EnvironmentReport/empty", 0.0)
|
136
|
+
Agent.record_metric("Supportability/EnvironmentReport/empty/#{key}", 0.0)
|
137
|
+
end
|
138
|
+
rescue => e
|
139
|
+
Agent.logger.debug("EnvironmentReport failed to retrieve value for #{key.inspect}: #{e}")
|
140
|
+
Agent.record_metric("Supportability/EnvironmentReport/error", 0.0)
|
141
|
+
Agent.record_metric("Supportability/EnvironmentReport/error/#{key}", 0.0)
|
142
|
+
end
|
143
|
+
data
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def [](key)
|
148
|
+
@data[key]
|
149
|
+
end
|
150
|
+
|
151
|
+
def []=(key, value)
|
152
|
+
@data[key] = value
|
153
|
+
end
|
154
|
+
|
155
|
+
def to_a
|
156
|
+
@data.to_a
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|