Class: NewRelic::Control
- Inherits:
-
Object
- Object
- NewRelic::Control
- Defined in:
- lib/new_relic/control.rb
Overview
The Control is a singleton responsible for the startup and initialization sequence. The initializer uses a LocalEnvironment to detect the framework and instantiates the framework specific subclass.
The Control also implements some of the public API for the agent.
Defined Under Namespace
Classes: External, Merb, ProxyServer, Rails, Rails3, Ruby, Server, Sinatra
Instance Attribute Summary collapse
-
#env ⇒ Object
writeonly
The env is the setting used to identify which section of the newrelic.yml to load.
-
#local_env ⇒ Object
readonly
Returns the value of attribute local_env.
-
#log_file ⇒ Object
Returns the value of attribute log_file.
Class Method Summary collapse
-
.format_message(severity, timestamp, progname, msg) ⇒ Object
change the format just for our logger.
-
.instance ⇒ Object
Access the Control singleton, lazy initialized.
Instance Method Summary collapse
- #[](key) ⇒ Object
- #[]=(key, value) ⇒ Object
-
#add_instrumentation(pattern) ⇒ Object
Add instrumentation.
-
#agent_enabled? ⇒ Boolean
True if dev mode or monitor mode are enabled, and we are running inside a valid dispatcher like mongrel or passenger.
-
#apdex_t ⇒ Object
Agent config conveniences.
- #api_server ⇒ Object
- #app ⇒ Object (also: #framework)
- #app_names ⇒ Object
- #capture_params ⇒ Object
-
#developer_mode? ⇒ Boolean
True if we are capturing data and displaying in /newrelic.
- #dispatcher ⇒ Object
- #dispatcher_instance_id ⇒ Object
- #fetch(key, default = nil) ⇒ Object
-
#http_connection(host = nil) ⇒ Object
Return the Net::HTTP with proxy configuration given the NewRelic::Control::Server object.
-
#init_plugin(options = {}) ⇒ Object
Initialize the plugin/gem and start the agent.
- #install_instrumentation ⇒ Object
-
#install_shim ⇒ Object
Install stubs to the proper location so the app code will not fail if the agent is not running.
- #license_key ⇒ Object
- #load_samplers ⇒ Object
- #log ⇒ Object
-
#log!(msg, level = :info) ⇒ Object
send the given message to STDOUT so that it shows up in the console.
-
#monitor_mode? ⇒ Boolean
True if we are sending data to the server, monitoring production.
-
#multi_threaded? ⇒ Boolean
True if the app runs in multi-threaded mode.
- #post_size_limit ⇒ Object
-
#profiling=(val) ⇒ Object
Set the flag for capturing profiles in dev mode.
-
#profiling? ⇒ Boolean
A flag used in dev mode to indicate if profiling is available.
- #profiling_available? ⇒ Boolean
- #proxy_server ⇒ Object
- #server ⇒ Object
- #server_from_host(hostname = nil) ⇒ Object
- #settings ⇒ Object
-
#start_agent ⇒ Object
Install the real agent into the Agent module, and issue the start command.
- #sync_startup ⇒ Object
- #to_s ⇒ Object
- #use_ssl? ⇒ Boolean
-
#use_textmate? ⇒ Boolean
True if we should view files in textmate.
- #validate_seed ⇒ Object
- #validate_token ⇒ Object
- #verify_certificate? ⇒ Boolean
Instance Attribute Details
#env=(value) ⇒ Object (writeonly)
The env is the setting used to identify which section of the newrelic.yml to load. This defaults to a framework specific value, such as ENV but can be overridden as long as you set it before calling #init_plugin
42 43 44 |
# File 'lib/new_relic/control.rb', line 42 def env=(value) @env = value end |
#local_env ⇒ Object (readonly)
Returns the value of attribute local_env.
43 44 45 |
# File 'lib/new_relic/control.rb', line 43 def local_env @local_env end |
#log_file ⇒ Object
Returns the value of attribute log_file.
38 39 40 |
# File 'lib/new_relic/control.rb', line 38 def log_file @log_file end |
Class Method Details
.format_message(severity, timestamp, progname, msg) ⇒ Object
change the format just for our logger
418 419 420 |
# File 'lib/new_relic/control.rb', line 418 def @log.(severity, , progname, msg) "[#{.strftime("%m/%d/%y %H:%M:%S %z")} #{Socket.gethostname} (#{$$})] #{severity} : #{msg}\n" end |
.instance ⇒ Object
Access the Control singleton, lazy initialized
53 54 55 |
# File 'lib/new_relic/control.rb', line 53 def self.instance @instance ||= new_instance end |
Instance Method Details
#[](key) ⇒ Object
125 126 127 |
# File 'lib/new_relic/control.rb', line 125 def [](key) fetch(key) end |
#[]=(key, value) ⇒ Object
146 147 148 |
# File 'lib/new_relic/control.rb', line 146 def []=(key, value) settings[key] = value end |
#add_instrumentation(pattern) ⇒ Object
Add instrumentation. Don’t call this directly. Use NewRelic::Agent#add_instrumentation. This will load the file synchronously if we’ve already loaded the default instrumentation.
327 328 329 330 331 332 333 |
# File 'lib/new_relic/control.rb', line 327 def add_instrumentation pattern if @instrumented load_instrumentation_files pattern else @instrumentation_files << pattern end end |
#agent_enabled? ⇒ Boolean
True if dev mode or monitor mode are enabled, and we are running inside a valid dispatcher like mongrel or passenger. Can be overridden by NEWRELIC_ENABLE env variable, monitor_daemons config option when true, or agent_enabled config option when true or false.
200 201 202 203 204 205 206 207 208 209 |
# File 'lib/new_relic/control.rb', line 200 def agent_enabled? return false if !developer_mode? && !monitor_mode? return self['agent_enabled'].to_s =~ /true|on|yes/i if !self['agent_enabled'].nil? && self['agent_enabled'] != 'auto' return false if ENV['NEWRELIC_ENABLE'].to_s =~ /false|off|no/i return true if self['monitor_daemons'].to_s =~ /true|on|yes/i return true if ENV['NEWRELIC_ENABLE'].to_s =~ /true|on|yes/i # When in 'auto' mode the agent is enabled if there is a known # dispatcher running return true if @local_env.dispatcher != nil end |
#apdex_t ⇒ Object
Agent config conveniences
163 164 165 166 |
# File 'lib/new_relic/control.rb', line 163 def apdex_t # Always initialized with a default fetch('apdex_t').to_f end |
#api_server ⇒ Object
245 246 247 248 249 250 251 252 |
# File 'lib/new_relic/control.rb', line 245 def api_server api_host = self['api_host'] || 'rpm.newrelic.com' @api_server ||= NewRelic::Control::Server.new \ api_host, (self['api_port'] || self['port'] || (use_ssl? ? 443 : 80)).to_i, nil end |
#app ⇒ Object Also known as: framework
211 212 213 |
# File 'lib/new_relic/control.rb', line 211 def app @local_env.framework end |
#app_names ⇒ Object
222 223 224 |
# File 'lib/new_relic/control.rb', line 222 def app_names self['app_name'] ? self['app_name'].split(';') : [] end |
#capture_params ⇒ Object
170 171 172 |
# File 'lib/new_relic/control.rb', line 170 def capture_params fetch('capture_params') end |
#developer_mode? ⇒ Boolean
True if we are capturing data and displaying in /newrelic
178 179 180 |
# File 'lib/new_relic/control.rb', line 178 def developer_mode? fetch('developer_mode', fetch('developer')) end |
#dispatcher ⇒ Object
219 220 221 |
# File 'lib/new_relic/control.rb', line 219 def dispatcher (self['dispatcher'] && self['dispatcher'].to_sym) || @local_env.dispatcher end |
#dispatcher_instance_id ⇒ Object
216 217 218 |
# File 'lib/new_relic/control.rb', line 216 def dispatcher_instance_id self['dispatcher_instance_id'] || @local_env.dispatcher_instance_id end |
#fetch(key, default = nil) ⇒ Object
150 151 152 |
# File 'lib/new_relic/control.rb', line 150 def fetch(key, default=nil) settings.fetch(key, default) end |
#http_connection(host = nil) ⇒ Object
Return the Net::HTTP with proxy configuration given the NewRelic::Control::Server object. Default is the collector but for api calls you need to pass api_server
Experimental support for SSL verification: swap ‘VERIFY_NONE’ for ‘VERIFY_PEER’ line to try it out If verification fails, uncomment the ‘http.ca_file’ line and it will use the included certificate.
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
# File 'lib/new_relic/control.rb', line 273 def http_connection(host = nil) host ||= server # Proxy returns regular HTTP if @proxy_host is nil (the default) http_class = Net::HTTP::Proxy(proxy_server.name, proxy_server.port, proxy_server.user, proxy_server.password) http = http_class.new(host.ip || host.name, host.port) log.debug("Http Connection opened to #{host.ip||host.name}:#{host.port}") if use_ssl? http.use_ssl = true if verify_certificate? http.verify_mode = OpenSSL::SSL::VERIFY_PEER http.ca_file = File.join(File.dirname(__FILE__), '..', '..', 'cert', 'cacert.pem') else http.verify_mode = OpenSSL::SSL::VERIFY_NONE end end http end |
#init_plugin(options = {}) ⇒ Object
Initialize the plugin/gem and start the agent. This does the necessary configuration based on the framework environment and determines whether or not to start the agent. If the agent is not going to be started then it loads the agent shim which has stubs for all the external api.
This may be invoked multiple times, as long as you don’t attempt to uninstall the agent after it has been started.
If the plugin is initialized and it determines that the agent is not enabled, it will skip starting it and install the shim. But if you later call this with :agent_enabled => true
, then it will install the real agent and start it.
What determines whether the agent is launched is the result of calling agent_enabled? This will indicate whether the instrumentation should/will be installed. If we’re in a mode where tracers are not installed then we should not start the agent.
Subclasses are not allowed to override, but must implement init_config({}) which is called one or more times.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/new_relic/control.rb', line 76 def init_plugin(={}) ['app_name'] = ENV['NEWRELIC_APP_NAME'] if ENV['NEWRELIC_APP_NAME'] require 'new_relic/agent' # Load the DJ injection now. If you do it sooner, DJ might not be loaded and # you'll miss it. require 'new_relic/delayed_job_injection' # Merge the stringified options into the config as overrides: logger_override = .delete(:log) environment_name = .delete(:env) and self.env = environment_name dispatcher = .delete(:dispatcher) and @local_env.dispatcher = dispatcher dispatcher_instance_id = .delete(:dispatcher_instance_id) and @local_env.dispatcher_instance_id = dispatcher_instance_id # Clear out the settings, if they've already been loaded. It may be that # between calling init_plugin the first time and the second time, the env # has been overridden @settings = nil settings () if logger_override @log = logger_override # Try to grab the log filename @log_file = @log.instance_eval { @logdev.filename rescue nil } end # An artifact of earlier implementation, we put both #add_method_tracer and #trace_execution # methods in the module methods. Module.send :include, NewRelic::Agent::MethodTracer::ClassMethods Module.send :include, NewRelic::Agent::MethodTracer::InstanceMethods init_config() NewRelic::Agent.agent = NewRelic::Agent::Agent.instance if agent_enabled? && !NewRelic::Agent.instance.started? setup_log unless logger_override start_agent install_instrumentation load_samplers unless self['disable_samplers'] local_env.gather_environment_info append_environment_info elsif !agent_enabled? install_shim end end |
#install_instrumentation ⇒ Object
334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
# File 'lib/new_relic/control.rb', line 334 def install_instrumentation return if @instrumented @instrumented = true # Instrumentation for the key code points inside rails for monitoring by NewRelic. # note this file is loaded only if the newrelic agent is enabled (through config/newrelic.yml) instrumentation_path = File.join(File.dirname(__FILE__), 'agent','instrumentation') @instrumentation_files << File.join(instrumentation_path, '*.rb') << File.join(instrumentation_path, app.to_s, '*.rb') @instrumentation_files.each { | pattern | load_instrumentation_files pattern } log.debug "Finished instrumentation" end |
#install_shim ⇒ Object
Install stubs to the proper location so the app code will not fail if the agent is not running.
317 318 319 320 321 |
# File 'lib/new_relic/control.rb', line 317 def install_shim # Once we install instrumentation, you can't undo that by installing the shim. raise "Cannot install the Agent shim after instrumentation has already been installed!" if @instrumented NewRelic::Agent.agent = NewRelic::Agent::ShimAgent.instance end |
#license_key ⇒ Object
167 168 169 |
# File 'lib/new_relic/control.rb', line 167 def license_key fetch('license_key') end |
#load_samplers ⇒ Object
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
# File 'lib/new_relic/control.rb', line 349 def load_samplers agent = NewRelic::Agent.instance NewRelic::Agent::Sampler.sampler_classes.each do | subclass | begin log.debug "#{subclass.name} not supported on this platform." and next if not subclass.supported_on_this_platform? sampler = subclass.new if subclass.use_harvest_sampler? agent.stats_engine.add_harvest_sampler sampler log.debug "Registered #{subclass.name} for harvest time sampling" else agent.stats_engine.add_sampler sampler log.debug "Registered #{subclass.name} for periodic sampling" end rescue NewRelic::Agent::Sampler::Unsupported => e log.info "#{subclass} sampler not available: #{e}" rescue => e log.error "Error registering sampler: #{e}, #{e.backtrace.join("\n")}" end end end |
#log ⇒ Object
295 296 297 298 299 300 301 302 303 |
# File 'lib/new_relic/control.rb', line 295 def log # If we try to get a log before one has been set up, return a stdout log unless @log l = Logger.new(STDOUT) l.level = Logger::INFO return l end @log end |
#log!(msg, level = :info) ⇒ Object
send the given message to STDOUT so that it shows up in the console. This should be used for important informational messages at boot. The to_stdout may be implemented differently by different config subclasses. This will NOT print anything if tracers are not enabled
309 310 311 312 313 |
# File 'lib/new_relic/control.rb', line 309 def log!(msg, level=:info) return if @settings && !agent_enabled? to_stdout msg log.send level, msg if @log end |
#monitor_mode? ⇒ Boolean
True if we are sending data to the server, monitoring production
174 175 176 |
# File 'lib/new_relic/control.rb', line 174 def monitor_mode? fetch('monitor_mode', fetch('enabled')) end |
#multi_threaded? ⇒ Boolean
True if the app runs in multi-threaded mode
182 183 184 |
# File 'lib/new_relic/control.rb', line 182 def multi_threaded? fetch('multi_threaded') end |
#post_size_limit ⇒ Object
189 190 191 |
# File 'lib/new_relic/control.rb', line 189 def post_size_limit fetch('post_size_limit', 2 * 1024 * 1024) end |
#profiling=(val) ⇒ Object
Set the flag for capturing profiles in dev mode. If RubyProf is not loaded a true value is ignored.
34 35 36 |
# File 'lib/new_relic/control.rb', line 34 def profiling=(val) @profiling = profiling_available? && val && defined?(RubyProf) end |
#profiling? ⇒ Boolean
A flag used in dev mode to indicate if profiling is available
21 22 23 |
# File 'lib/new_relic/control.rb', line 21 def profiling? @profiling end |
#profiling_available? ⇒ Boolean
25 26 27 28 29 30 31 |
# File 'lib/new_relic/control.rb', line 25 def profiling_available? @profiling_available ||= begin require 'ruby-prof' true rescue LoadError; end end |
#proxy_server ⇒ Object
254 255 256 257 |
# File 'lib/new_relic/control.rb', line 254 def proxy_server @proxy_server ||= NewRelic::Control::ProxyServer.new self['proxy_host'], self['proxy_port'], self['proxy_user'], self['proxy_pass'] end |
#server ⇒ Object
241 242 243 |
# File 'lib/new_relic/control.rb', line 241 def server @remote_server ||= server_from_host(nil) end |
#server_from_host(hostname = nil) ⇒ Object
259 260 261 262 263 264 |
# File 'lib/new_relic/control.rb', line 259 def server_from_host(hostname=nil) host = hostname || self['host'] || 'collector.newrelic.com' # if the host is not an IP address, turn it into one NewRelic::Control::Server.new host, (self['port'] || (use_ssl? ? 443 : 80)).to_i, convert_to_ip_address(host) end |
#settings ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/new_relic/control.rb', line 129 def settings unless @settings @settings = (@yaml && merge_defaults(@yaml[env])) || {} # At the time we bind the settings, we also need to run this little piece # of magic which allows someone to augment the id with the app name, necessary if self['multi_homed'] && app_names.size > 0 if @local_env.dispatcher_instance_id @local_env.dispatcher_instance_id << ":#{app_names.first}" else @local_env.dispatcher_instance_id = app_names.first end end end @settings end |
#start_agent ⇒ Object
Install the real agent into the Agent module, and issue the start command.
121 122 123 |
# File 'lib/new_relic/control.rb', line 121 def start_agent NewRelic::Agent.agent.start end |
#sync_startup ⇒ Object
193 194 195 |
# File 'lib/new_relic/control.rb', line 193 def sync_startup fetch('sync_startup', false) end |
#to_s ⇒ Object
291 292 293 |
# File 'lib/new_relic/control.rb', line 291 def to_s "Control[#{self.app}]" end |
#use_ssl? ⇒ Boolean
232 233 234 |
# File 'lib/new_relic/control.rb', line 232 def use_ssl? @use_ssl ||= fetch('ssl', false) end |
#use_textmate? ⇒ Boolean
True if we should view files in textmate
186 187 188 |
# File 'lib/new_relic/control.rb', line 186 def use_textmate? fetch('textmate') end |
#validate_seed ⇒ Object
225 226 227 |
# File 'lib/new_relic/control.rb', line 225 def validate_seed self['validate_seed'] || ENV['NR_VALIDATE_SEED'] end |
#validate_token ⇒ Object
228 229 230 |
# File 'lib/new_relic/control.rb', line 228 def validate_token self['validate_token'] || ENV['NR_VALIDATE_TOKEN'] end |
#verify_certificate? ⇒ Boolean
236 237 238 239 |
# File 'lib/new_relic/control.rb', line 236 def verify_certificate? #this can only be on when SSL is enabled @verify_certificate ||= ( use_ssl? ? fetch('verify_certificate', false) : false) end |