Skip to content

Commit

Permalink
Change memcache metrics, introduce allWeb and allOther
Browse files Browse the repository at this point in the history
  • Loading branch information
Bill Kayser committed Feb 26, 2010
1 parent 7ad0e42 commit f3e24ae
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 160 deletions.
155 changes: 18 additions & 137 deletions lib/new_relic/agent/instrumentation/memcache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,146 +4,27 @@
# http://www.deveiate.org/code/Ruby-MemCache/ (Gem: Ruby-MemCache)
# http://seattlerb.rubyforge.org/memcache-client/ (Gem: memcache-client)
unless NewRelic::Control.instance['disable_memcache_instrumentation']
MemCache.class_eval do

# This is in the memcache-client implementation and has never existed in Ruby-MemCache
if self.method_defined? :cache_get

if self.method_defined? :get
def get_with_newrelic_trace(key, raw=false)
if NewRelic::Agent::Instrumentation::MetricFrame.recording_web_transaction?
self.class.trace_execution_scoped(['MemCache/read', 'MemCache/allWeb']) do
get_without_newrelic_trace(key, raw)
end
else
self.class.trace_execution_scoped(['MemCache/read', 'MemCache/allOther']) do
get_without_newrelic_trace(key, raw)
end
end
end

alias get_without_newrelic_trace get
alias get get_with_newrelic_trace
end

if self.method_defined? :get_multi
def get_multi_with_newrelic_trace(*keys)
if NewRelic::Agent::Instrumentation::MetricFrame.recording_web_transaction?
self.class.trace_execution_scoped(['MemCache/read', 'MemCache/allWeb']) do
get_without_newrelic_trace(keys)
end
else
self.class.trace_execution_scoped(['MemCache/read', 'MemCache/allOther']) do
get_without_newrelic_trace(keys)
end
end
end

alias get_multi_without_newrelic_trace get_multi
alias get_multi get_multi_with_newrelic_trace
end

if self.method_defined? :add
def add_with_newrelic_trace(key, value, expiry=0, raw=false)
if NewRelic::Agent::Instrumentation::MetricFrame.recording_web_transaction?
self.class.trace_execution_scoped(['MemCache/write', 'MemCache/allWeb']) do
add_without_newrelic_trace(key, value, expiry, raw)
end
else
self.class.trace_execution_scoped(['MemCache/write', 'MemCache/allOther']) do
add_without_newrelic_trace(key, value, expiry, raw)
end
end
end

alias add_without_newrelic_trace add
alias add add_with_newrelic_trace
end

if self.method_defined? :decr
def decr_with_newrelic_trace(key, amount=1)
if NewRelic::Agent::Instrumentation::MetricFrame.recording_web_transaction?
self.class.trace_execution_scoped(['MemCache/write', 'MemCache/allWeb']) do
decr_without_newrelic_trace(key, amount)
end
else
self.class.trace_execution_scoped(['MemCache/write', 'MemCache/allOther']) do
decr_without_newrelic_trace(key, amount)
end
end
end

alias decr_without_newrelic_trace decr
alias decr decr_with_newrelic_trace
end

if self.method_defined? :delete
def delete_with_newrelic_trace(key, expiry=0)
if NewRelic::Agent::Instrumentation::MetricFrame.recording_web_transaction?
self.class.trace_execution_scoped(['MemCache/write', 'MemCache/allWeb']) do
delete_without_newrelic_trace(key, expiry)
end
else
self.class.trace_execution_scoped(['MemCache/write', 'MemCache/allOther']) do
delete_without_newrelic_trace(key, expiry)
end
end
end

alias delete_without_newrelic_trace delete
alias delete delete_with_newrelic_trace
end

if self.method_defined? :incr
def incr_with_newrelic_trace(key, amount=1)
if NewRelic::Agent::Instrumentation::MetricFrame.recording_web_transaction?
self.class.trace_execution_scoped(['MemCache/write', 'MemCache/allWeb']) do
incr_without_newrelic_trace(key, amount)
end
else
self.class.trace_execution_scoped(['MemCache/write', 'MemCache/allOther']) do
incr_without_newrelic_trace(key, amount)
end
end
end

alias incr_without_newrelic_trace incr
alias incr incr_with_newrelic_trace
end

if self.method_defined? :set
def set_with_newrelic_trace(key, value, expiry=0, raw=false)
if NewRelic::Agent::Instrumentation::MetricFrame.recording_web_transaction?
self.class.trace_execution_scoped(['MemCache/write', 'MemCache/allWeb']) do
set_without_newrelic_trace(key, value, expiry, raw)
end
else
self.class.trace_execution_scoped(['MemCache/write', 'MemCache/allOther']) do
set_without_newrelic_trace(key, value, expiry, raw)
end

# This is in the memcache-client implementation and has never existed in Ruby-MemCache
def self.instrument_method(the_class, method_name)
return unless the_class.method_defined? method_name.to_sym
the_class.class_eval <<-EOD
def #{method_name}_with_newrelic_trace(*args)
metrics = ["MemCache/#{method_name}",
(NewRelic::Agent::Instrumentation::MetricFrame.recording_web_transaction? ? 'MemCache/allWeb' : 'MemCache/allOther')]
self.class.trace_execution_scoped(metrics) do
#{method_name}_without_newrelic_trace(*args)
end
end

alias set_without_newrelic_trace set
alias set set_with_newrelic_trace
end

else # Ruby-MemCache
add_method_tracer :get, 'MemCache/read' if self.method_defined? :get
add_method_tracer :get_multi, 'MemCache/read' if self.method_defined? :get_multi
%w[set add incr decr delete].each do | method |
add_method_tracer method, 'MemCache/write' if self.method_defined? method
end
end
end if defined? MemCache

alias #{method_name}_without_newrelic_trace #{method_name}
alias #{method_name} #{method_name}_with_newrelic_trace
EOD
end
# Support for libmemcached through Evan Weaver's memcached wrapper
# http://blog.evanweaver.com/files/doc/fauna/memcached/classes/Memcached.html
Memcached.class_eval do
add_method_tracer :get, 'MemCache/read' if self.method_defined? :get
%w[set add increment decrement delete replace append prepend cas].each do | method |
add_method_tracer method, "MemCache/write" if self.method_defined? method
end
end if defined? Memcached
%w[get get_multi set add incr decr delete replace append prepand cas].each do | method_name |
instrument_method(::MemCache, method_name) if defined? ::MemCache
instrument_method(::Memcached, method_name) if defined? ::Memcached
end

end
38 changes: 38 additions & 0 deletions lib/new_relic/metric_parser/mem_cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,42 @@ def short_name
def developer_name
"MemCache #{segments[1..-1].join '/'}"
end

def all?
segments[1]['all'] == 0
end
def operation
all? ? 'All Operations' : segments[1]
end
def legend_name
case segments[1]
when 'allWeb'
"MemCache"
when 'allOther'
"Non-web MemCache"
else
"MemCache #{operation} operations"
end
end
def tooltip_name
case segments[1]
when 'allWeb'
"MemCache calls from web transactions"
when 'allOther'
"MemCache calls from non-web transactions"
else
"MemCache #{operation} operations"
end

end
def developer_name
case segments[1]
when 'allWeb'
"Web MemCache"
when 'allOther'
"Non-web MemCache"
else
"MemCache #{operation}"
end
end
end
48 changes: 25 additions & 23 deletions test/new_relic/agent/memcache_instrumentation_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

class NewRelic::Agent::MemcacheInstrumentationTest < Test::Unit::TestCase
include NewRelic::Agent::Instrumentation::ControllerInstrumentation

# This implementation: http://seattlerb.rubyforge.org/memcache-client/
def using_memcache_client?
::MemCache.method_defined? :cache_get
end

def setup
NewRelic::Agent.manual_start
@engine = NewRelic::Agent.instance.stats_engine
Expand All @@ -19,83 +19,85 @@ def setup
@cache = ::MemCache.new(server)
end
@key = 'schluessel'
@task = 'task'
end

def _call_test_method_in_web_transaction(method, *args)
@engine.clear_stats
begin
perform_action_with_newrelic_trace(@task) do
perform_action_with_newrelic_trace(:name=>'action', :category => :controller) do
@cache.send(method.to_sym, *[@key, *args])
end
rescue ::MemCache::MemCacheError
# There's probably no memcached around
end
end

def _call_test_method_in_background_task(method, *args)
@engine.clear_stats
begin
perform_action_with_newrelic_trace(@task, :category => :task) do
perform_action_with_newrelic_trace(:name => 'bg_task', :category => :task) do
@cache.send(method.to_sym, *[@key, *args])
end
rescue ::MemCache::MemCacheError
# There's probably no memcached around
end
end

def test_reads__web
%w[get get_multi].each do |method|
if @cache.class.method_defined?(method)
_call_test_method_in_web_transaction(method)
assert_equal ["MemCache/read", "MemCache/allWeb", "MemCache/read:Controller/NewRelic::Agent::MemcacheInstrumentationTest/#{@task}"].sort, @engine.metrics.select{|m| m =~ /^memcache.*/i}.sort, "Failed on method #{method}"
compare_metrics ["MemCache/#{method}", "MemCache/allWeb", "MemCache/#{method}:Controller/NewRelic::Agent::MemcacheInstrumentationTest/action"],
@engine.metrics.select{|m| m =~ /^memcache.*/i}
end
end
end

def test_writes__web
expected_metrics = ["MemCache/write", "MemCache/allWeb", "MemCache/write:Controller/NewRelic::Agent::MemcacheInstrumentationTest/#{@task}"]

%w[incr decr delete].each do |method|
if @cache.class.method_defined?(method)
_call_test_method_in_web_transaction(method)
assert_equal expected_metrics.sort, @engine.metrics.select{|m| m =~ /^memcache.*/i}.sort, "Failed on method #{method}"
expected_metrics = ["MemCache/#{method}", "MemCache/allWeb", "MemCache/#{method}:Controller/NewRelic::Agent::MemcacheInstrumentationTest/action"]
compare_metrics expected_metrics, @engine.metrics.select{|m| m =~ /^memcache.*/i}
end
end

%w[set add].each do |method|
if @cache.class.method_defined?(method)
expected_metrics = ["MemCache/#{method}", "MemCache/allWeb", "MemCache/#{method}:Controller/NewRelic::Agent::MemcacheInstrumentationTest/action"]
_call_test_method_in_web_transaction(method, 'value')
assert_equal expected_metrics.sort, @engine.metrics.select{|m| m =~ /^memcache.*/i}.sort, "Failed on method #{method}"
compare_metrics expected_metrics, @engine.metrics.select{|m| m =~ /^memcache.*/i}
end
end
end

def test_reads__background
%w[get get_multi].each do |method|
if @cache.class.method_defined?(method)
_call_test_method_in_background_task(method)
assert_equal ["MemCache/read", "MemCache/allOther", "MemCache/read:OtherTransaction/Background/NewRelic::Agent::MemcacheInstrumentationTest/#{@task}"].sort, @engine.metrics.select{|m| m =~ /^memcache.*/i}.sort, "Failed on method #{method}"
compare_metrics ["MemCache/#{method}", "MemCache/allOther", "MemCache/#{method}:OtherTransaction/Background/NewRelic::Agent::MemcacheInstrumentationTest/bg_task"],
@engine.metrics.select{|m| m =~ /^memcache.*/i}
end
end
end

def test_writes__background
expected_metrics = ["MemCache/write", "MemCache/allOther", "MemCache/write:OtherTransaction/Background/NewRelic::Agent::MemcacheInstrumentationTest/#{@task}"]


%w[incr decr delete].each do |method|
expected_metrics = ["MemCache/#{method}", "MemCache/allOther", "MemCache/#{method}:OtherTransaction/Background/NewRelic::Agent::MemcacheInstrumentationTest/bg_task"]
if @cache.class.method_defined?(method)
_call_test_method_in_background_task(method)
assert_equal expected_metrics.sort, @engine.metrics.select{|m| m =~ /^memcache.*/i}.sort, "Failed on method #{method}"
compare_metrics expected_metrics, @engine.metrics.select{|m| m =~ /^memcache.*/i}
end
end

%w[set add].each do |method|
expected_metrics = ["MemCache/#{method}", "MemCache/allOther", "MemCache/#{method}:OtherTransaction/Background/NewRelic::Agent::MemcacheInstrumentationTest/bg_task"]
if @cache.class.method_defined?(method)
_call_test_method_in_background_task(method, 'value')
assert_equal expected_metrics.sort, @engine.metrics.select{|m| m =~ /^memcache.*/i}.sort, "Failed on method #{method}"
compare_metrics expected_metrics, @engine.metrics.select{|m| m =~ /^memcache.*/i}
end
end
end

end if defined? MemCache

0 comments on commit f3e24ae

Please sign in to comment.