Skip to content

Commit

Permalink
rebased with svn repo
Browse files Browse the repository at this point in the history
  • Loading branch information
Bill Kayser committed Apr 30, 2009
1 parent a57be12 commit ddd292e
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 67 deletions.
98 changes: 52 additions & 46 deletions lib/new_relic/agent/agent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,19 @@ def manual_start(ignored=nil, also_ignored=nil)
# for passenger where processes are forked and the agent is dormant
#
def ensure_worker_thread_started
return unless config.agent_enabled? && config.monitor_mode? && !@invalid_license
if @worker_loop.nil? || @worker_loop.pid != $$
return unless control.agent_enabled? && control.monitor_mode? && !@invalid_license
if !running?
launch_worker_thread
@stats_engine.spawn_sampler_thread
end
end

# True if the worker thread has been started. Doesn't necessarily
# mean we are connected
def running?
control.agent_enabled? && control.monitor_mode? && @worker_loop && @worker_loop.pid == $$
end

# True if we have initialized and completed 'start'
def started?
@started
Expand All @@ -57,7 +63,7 @@ def shutdown

# if litespeed, then ignore all future SIGUSR1 - it's litespeed trying to shut us down

if config.dispatcher == :litespeed
if control.dispatcher == :litespeed
Signal.trap("SIGUSR1", "IGNORE")
Signal.trap("SIGTERM", "IGNORE")
end
Expand Down Expand Up @@ -123,26 +129,26 @@ def log
end

# Start up the agent. This verifies that the agent_enabled? is true
# and initializes the sampler based on the current configuration settings.
# and initializes the sampler based on the current controluration settings.
# Then it will fire up the background thread for sending data to the server if applicable.
def start
if started?
config.log! "Agent Started Already!", :error
control.log! "Agent Started Already!", :error
return
end
return if !config.agent_enabled?
return if !control.agent_enabled?

@local_host = determine_host

log.info "Web container: #{config.dispatcher.to_s}"
log.info "Web container: #{control.dispatcher.to_s}"

if config.dispatcher == :passenger
if control.dispatcher == :passenger
log.warn "Phusion Passenger has been detected. Some RPM memory statistics may have inaccuracies due to short process lifespans."
end

@started = true

sampler_config = config.fetch('transaction_tracer', {})
sampler_config = control.fetch('transaction_tracer', {})
@use_transaction_sampler = sampler_config.fetch('enabled', false)

@record_sql = sampler_config.fetch('record_sql', :obfuscated).to_sym
Expand All @@ -164,30 +170,34 @@ def start
@explain_threshold = sampler_config.fetch('explain_threshold', 0.5).to_f
@explain_enabled = sampler_config.fetch('explain_enabled', true)
@random_sample = sampler_config.fetch('random_sample', false)
log.info "Transaction tracing is enabled in agent config" if @use_transaction_sampler
log.info "Transaction tracing is enabled in agent control" if @use_transaction_sampler
log.warn "Agent is configured to send raw SQL to RPM service" if @record_sql == :raw
# Initialize transaction sampler
@transaction_sampler.random_sampling = @random_sample

if config.monitor_mode?
if control.monitor_mode?
# make sure the license key exists and is likely to be really a license key
# by checking it's string length (license keys are 40 character strings.)
if !config.license_key || config.license_key.length != 40
config.log! "No license key found. Please edit your newrelic.yml file and insert your license key.", :error
if !control.license_key
@invalid_license = true
control.log! "No license key found. Please edit your newrelic.yml file and insert your license key.", :error
elsif control.license_key.length != 40
@invalid_license = true
control.log! "Invalid license key: #{control.license_key}", :error
else
launch_worker_thread
# When the VM shuts down, attempt to send a message to the server that
# this agent run is stopping, assuming it has successfully connected
at_exit { shutdown }
end
end
config.log! "New Relic RPM Agent #{NewRelic::VERSION::STRING} Initialized: pid = #{$$}"
config.log! "Agent Log found in #{NewRelic::Control.instance.log_file}"
control.log! "New Relic RPM Agent #{NewRelic::VERSION::STRING} Initialized: pid = #{$$}"
control.log! "Agent Log found in #{NewRelic::Control.instance.log_file}"
end

private
def collector
@collector ||= config.server
@collector ||= control.server
end

# Connect to the server, and run the worker loop forever. Will not return.
Expand All @@ -204,7 +214,7 @@ def run_worker_loop
# note if the agent attempts to report more frequently than the specified
# report data, then it will be ignored.

config.log! "Reporting performance data every #{@report_period} seconds."
control.log! "Reporting performance data every #{@report_period} seconds."
@worker_loop.add_task(@report_period) do
harvest_and_send_timeslice_data
end
Expand All @@ -213,7 +223,7 @@ def run_worker_loop
@worker_loop.add_task(@report_period) do
harvest_and_send_slowest_sample
end
elsif !config.developer_mode?
elsif !control.developer_mode?
# We still need the sampler for dev mode.
@transaction_sampler.disable
end
Expand All @@ -232,43 +242,43 @@ def run_worker_loop
end

def launch_worker_thread
if (config.dispatcher == :passenger && $0 =~ /ApplicationSpawner/)
if (control.dispatcher == :passenger && $0 =~ /ApplicationSpawner/)
log.debug "Process is passenger spawner - don't connect to RPM service"
return
end

@worker_loop = WorkerLoop.new(log)

if config['check_bg_loading']
if control['check_bg_loading']
log.warn "Agent background loading checking turned on"
require 'new_relic/agent/patch_const_missing'
ClassLoadingWatcher.enable_warning
end

@worker_thread = Thread.new do
begin
ClassLoadingWatcher.background_thread=Thread.current if config['check_bg_loading']
ClassLoadingWatcher.background_thread=Thread.current if control['check_bg_loading']

run_worker_loop
rescue IgnoreSilentlyException
config.log! "Unable to establish connection with the server. Run with log level set to debug for more information."
control.log! "Unable to establish connection with the server. Run with log level set to debug for more information."
rescue StandardError => e
config.log! e, :error
config.log! e.backtrace.join("\n "), :error
control.log! e, :error
control.log! e.backtrace.join("\n "), :error
end
end

# This code should be activated to check that no dependency loading is occuring in the background thread
# by stopping the foreground thread after the background thread is created. Turn on dependency loading logging
# and make sure that no loading occurs.
#
# config.log! "FINISHED AGENT INIT"
# control.log! "FINISHED AGENT INIT"
# while true
# sleep 1
# end
end

def config
def control
NewRelic::Control.instance
end

Expand Down Expand Up @@ -302,24 +312,20 @@ def connect

begin
sleep connect_retry_period.to_i
@agent_id = invoke_remote :launch,
@local_host,
config.dispatcher_instance_id,
determine_home_directory,
$$,
@launch_time.to_f,
NewRelic::VERSION::STRING,
config.local_env.snapshot,
config['app_name'],
config.settings
@agent_id = invoke_remote :start, @local_host,
{ :pid => $$,
:launch_time => @launch_time.to_f,
:agent_version => NewRelic::VERSION::STRING,
:environment => control.local_env.snapshot,
:settings => control.settings }

host = invoke_remote(:get_redirect_host) rescue nil

@collector = config.server_from_host(host) if host
@collector = control.server_from_host(host) if host

@report_period = invoke_remote :get_data_report_period, @agent_id

config.log! "Connected to NewRelic Service at #{@collector}"
control.log! "Connected to NewRelic Service at #{@collector}"
log.debug "Agent ID = #{@agent_id}."

# Ask the server for permission to send transaction samples. determined by subscription license.
Expand All @@ -341,13 +347,13 @@ def connect
@connected = true

rescue LicenseException => e
config.log! e.message, :error
config.log! "Visit NewRelic.com to obtain a valid license key, or to upgrade your account."
control.log! e.message, :error
control.log! "Visit NewRelic.com to obtain a valid license key, or to upgrade your account."
@invalid_license = true
return false

rescue Timeout::Error, StandardError => e
log.info "Unable to establish connection with New Relic RPM Service at #{config.server}"
log.info "Unable to establish connection with New Relic RPM Service at #{control.server}"
unless e.instance_of? IgnoreSilentlyException
log.error e.message
log.debug e.backtrace.join("\n")
Expand All @@ -374,7 +380,7 @@ def determine_host
end

def determine_home_directory
config.root
control.root
end

def harvest_and_send_timeslice_data
Expand Down Expand Up @@ -469,9 +475,9 @@ def invoke_remote(method, *args)
data = Marshal.dump(args)
encoding = data.size > 2000 ? 'deflate' : 'identity' # don't compress small payloads
post_data = encoding == 'deflate' ? Zlib::Deflate.deflate(data, Zlib::BEST_SPEED) : data
http = config.http_connection(collector)
http = control.http_connection(collector)

uri = "/agent_listener/#{PROTOCOL_VERSION}/#{config.license_key}/#{method}"
uri = "/agent_listener/#{PROTOCOL_VERSION}/#{control.license_key}/#{method}"
uri += "?run_id=#{@agent_id}" if @agent_id

request = Net::HTTP::Post.new(uri, 'CONTENT-ENCODING' => encoding, 'ACCEPT-ENCODING' => 'gzip', 'HOST' => collector.name)
Expand Down Expand Up @@ -525,9 +531,9 @@ def invoke_remote(method, *args)
end

def graceful_disconnect
if @connected && !(config.server.name == "localhost" && config.dispatcher_instance_id == '3000')
if @connected && !(control.server.name == "localhost" && control.dispatcher_instance_id == '3000')
begin
log.debug "Sending graceful shutdown message to #{config.server}"
log.debug "Sending graceful shutdown message to #{control.server}"

@request_timeout = 5

Expand Down
2 changes: 1 addition & 1 deletion lib/new_relic/commands/deployments.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def initialize command_line_args
@description = options.parse(command_line_args).join " "
end
config.env = @environment if @environment
@appname ||= config.app_name || config.env || 'development'
@appname ||= config.app_names[0] || config.env || 'development'
end

# Run the Deployment upload in RPM via Active Resource.
Expand Down
4 changes: 2 additions & 2 deletions lib/new_relic/control.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ def dispatcher_instance_id
def dispatcher
self['dispatcher'] || @local_env.dispatcher
end
def app_name
self['app_name']
def app_names
self['app_name'] ? self['app_name'].split(';') : []
end

def use_ssl?
Expand Down
12 changes: 2 additions & 10 deletions lib/new_relic/local_environment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,9 @@ def append_plugin_list

def dispatcher_instance_id
if @dispatcher_instance_id.nil?
if @dispatcher
@dispatcher_instance_id = @dispatcher.to_s
else
if @dispatcher.nil?
@dispatcher_instance_id = File.basename($0).split(".").first
end
app_name = NewRelic::Control.instance['app_name']
@dispatcher_instance_id += ":#{app_name}" if app_name
end
@dispatcher_instance_id
end
Expand All @@ -68,10 +64,6 @@ def gather_environment_info
append_environment_value 'Framework', @framework.to_s
append_environment_value 'Dispatcher', @dispatcher.to_s if @dispatcher
append_environment_value 'Dispatcher instance id', @dispatcher_instance_id if @dispatcher_instance_id
append_environment_value('RPM agent version') do
require 'new_relic/version'
NewRelic::VERSION::STRING
end
append_environment_value('Application root') { File.expand_path(NewRelic::Control.instance.root) }
append_environment_value('Ruby version'){ RUBY_VERSION }
append_environment_value('Ruby platform') { RUBY_PLATFORM }
Expand Down Expand Up @@ -233,7 +225,7 @@ def default_port
default_port = 3000
OptionParser.new do |opts|
opts.on("-p", "--port=port", String) { | default_port | }
opts.parse!(ARGV.clone)
opts.parse(ARGV.clone) rescue nil
end
default_port
end
Expand Down
6 changes: 5 additions & 1 deletion lib/new_relic/metric_parser/controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ def controller_name
end

def action_name
segments[-1]
if segments[-1] =~ /^\(other\)$/
'(template only)'
else
segments[-1]
end
end

def developer_name
Expand Down
12 changes: 12 additions & 0 deletions lib/new_relic/metric_parser/mem_cache.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module NewRelic::MetricParser::MemCache
def is_memcache?; true; end

# for MemCache metrics, the short name is actually
# the full name
def short_name
name
end
def developer_name
"MemCache #{segments[1..-1].join '/'}"
end
end
6 changes: 4 additions & 2 deletions lib/new_relic/rack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
module NewRelic
module Rack
class MetricApp
def initialize(appname)
NewRelic::Agent.manual_start :app_name => appname, :disable_samplers => true
def initialize(options)
options[:app_name] ||= 'EPM Monitor'
options[:disable_samplers] = true
NewRelic::Agent.manual_start options
@stats_engine = NewRelic::Agent.instance.stats_engine
end
def call(env)
Expand Down
15 changes: 10 additions & 5 deletions lib/new_relic/rack/newrelic.ru
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ ENV['NEWRELIC_DISPATCHER'] = 'none'
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..','..'))

require 'new_relic/rack'
puts ENV.inspect
appname ||= 'EPM Agent'
license_key ||= nil
use Rack::CommonLogger if defined?(logging) && logging

# Valid options which may be present in this binding:
# :license_key optional license key override
# :app_name optional name of app
# :logging optional, false to omit request logging to stdout

options ||= {}

use Rack::CommonLogger unless options[:logging] == false
use Rack::ShowExceptions
map "http://localhost/metrics" do
run NewRelic::Rack::MetricApp.new(appname, license_key)
run NewRelic::Rack::MetricApp.new(options)
end
map "/" do
run NewRelic::Rack::Status.new
Expand Down

0 comments on commit ddd292e

Please sign in to comment.