Class: NewRelic::Control
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, 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.
- #to_s ⇒ Object
- #use_ssl? ⇒ Boolean
-
#use_textmate? ⇒ Boolean
True if we should view files in textmate.
- #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
399 400 401 |
# File 'lib/new_relic/control.rb', line 399 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
117 118 119 |
# File 'lib/new_relic/control.rb', line 117 def [](key) fetch(key) end |
#[]=(key, value) ⇒ Object
138 139 140 |
# File 'lib/new_relic/control.rb', line 138 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.
308 309 310 311 312 313 314 |
# File 'lib/new_relic/control.rb', line 308 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.
188 189 190 191 192 193 194 195 196 197 |
# File 'lib/new_relic/control.rb', line 188 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
155 156 157 158 |
# File 'lib/new_relic/control.rb', line 155 def apdex_t # Always initialized with a default fetch('apdex_t').to_f end |
#api_server ⇒ Object
227 228 229 230 231 232 233 234 |
# File 'lib/new_relic/control.rb', line 227 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
199 200 201 |
# File 'lib/new_relic/control.rb', line 199 def app @local_env.framework end |
#app_names ⇒ Object
210 211 212 |
# File 'lib/new_relic/control.rb', line 210 def app_names self['app_name'] ? self['app_name'].split(';') : [] end |
#capture_params ⇒ Object
162 163 164 |
# File 'lib/new_relic/control.rb', line 162 def capture_params fetch('capture_params') end |
#developer_mode? ⇒ Boolean
True if we are capturing data and displaying in /newrelic
170 171 172 |
# File 'lib/new_relic/control.rb', line 170 def developer_mode? fetch('developer_mode', fetch('developer')) end |
#dispatcher ⇒ Object
207 208 209 |
# File 'lib/new_relic/control.rb', line 207 def dispatcher (self['dispatcher'] && self['dispatcher'].to_sym) || @local_env.dispatcher end |
#dispatcher_instance_id ⇒ Object
204 205 206 |
# File 'lib/new_relic/control.rb', line 204 def dispatcher_instance_id self['dispatcher_instance_id'] || @local_env.dispatcher_instance_id end |
#fetch(key, default = nil) ⇒ Object
142 143 144 |
# File 'lib/new_relic/control.rb', line 142 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.
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
# File 'lib/new_relic/control.rb', line 255 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) 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 at most once.
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 |
# File 'lib/new_relic/control.rb', line 76 def init_plugin(={}) require 'new_relic/agent' # Merge the stringified options into the config as overrides: logger_override = .delete(:log) environment_name = .delete(:env) self.env = environment_name if environment_name # 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 .each { |sym, val | self[sym.to_s] = val unless sym == :config } 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() if agent_enabled? && !@started setup_log unless logger_override start_agent install_instrumentation load_samplers unless self['disable_samplers'] local_env.gather_environment_info append_environment_info @started = true elsif !agent_enabled? install_shim end end |
#install_instrumentation ⇒ Object
315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
# File 'lib/new_relic/control.rb', line 315 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.
298 299 300 301 302 |
# File 'lib/new_relic/control.rb', line 298 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
159 160 161 |
# File 'lib/new_relic/control.rb', line 159 def license_key fetch('license_key') end |
#load_samplers ⇒ Object
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
# File 'lib/new_relic/control.rb', line 330 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.info "Registered #{subclass.name} for harvest time sampling" else agent.stats_engine.add_sampler sampler log.info "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
276 277 278 279 280 281 282 283 284 |
# File 'lib/new_relic/control.rb', line 276 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
290 291 292 293 294 |
# File 'lib/new_relic/control.rb', line 290 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
166 167 168 |
# File 'lib/new_relic/control.rb', line 166 def monitor_mode? fetch('monitor_mode', fetch('enabled')) end |
#multi_threaded? ⇒ Boolean
True if the app runs in multi-threaded mode
174 175 176 |
# File 'lib/new_relic/control.rb', line 174 def multi_threaded? fetch('multi_threaded') end |
#post_size_limit ⇒ Object
181 182 183 |
# File 'lib/new_relic/control.rb', line 181 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
236 237 238 239 |
# File 'lib/new_relic/control.rb', line 236 def proxy_server @proxy_server ||= NewRelic::Control::ProxyServer.new self['proxy_host'], self['proxy_port'], self['proxy_user'], self['proxy_pass'] end |
#server ⇒ Object
223 224 225 |
# File 'lib/new_relic/control.rb', line 223 def server @remote_server ||= server_from_host(nil) end |
#server_from_host(hostname = nil) ⇒ Object
241 242 243 244 245 246 |
# File 'lib/new_relic/control.rb', line 241 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
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/new_relic/control.rb', line 121 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.
112 113 114 115 |
# File 'lib/new_relic/control.rb', line 112 def start_agent NewRelic::Agent.agent = NewRelic::Agent::Agent.instance NewRelic::Agent.agent.start end |
#to_s ⇒ Object
272 273 274 |
# File 'lib/new_relic/control.rb', line 272 def to_s "Control[#{self.app}]" end |
#use_ssl? ⇒ Boolean
214 215 216 |
# File 'lib/new_relic/control.rb', line 214 def use_ssl? @use_ssl ||= fetch('ssl', false) end |
#use_textmate? ⇒ Boolean
True if we should view files in textmate
178 179 180 |
# File 'lib/new_relic/control.rb', line 178 def use_textmate? fetch('textmate') end |
#verify_certificate? ⇒ Boolean
218 219 220 221 |
# File 'lib/new_relic/control.rb', line 218 def verify_certificate? #this can only be on when SSL is enabled @verify_certificate ||= ( use_ssl? ? fetch('verify_certificate', false) : false) end |