Skip to content
This repository has been archived by the owner on Nov 21, 2017. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
Reorganize and repackage from the rpm_contrib gem
  • Loading branch information
evanphx committed Mar 9, 2012
0 parents commit 19dc580
Show file tree
Hide file tree
Showing 10 changed files with 242 additions and 0 deletions.
23 changes: 23 additions & 0 deletions .autotest
@@ -0,0 +1,23 @@
# -*- ruby -*-

require 'autotest/restart'

# Autotest.add_hook :initialize do |at|
# at.extra_files << "../some/external/dependency.rb"
#
# at.libs << ":../some/external"
#
# at.add_exception 'vendor'
#
# at.add_mapping(/dependency.rb/) do |f, _|
# at.files_matching(/test_.*rb$/)
# end
#
# %w(TestA TestB).each do |klass|
# at.extra_class_map[klass] = "test/test_misc.rb"
# end
# end

# Autotest.add_hook :run_command do |at|
# system "rake build"
# end
6 changes: 6 additions & 0 deletions History.txt
@@ -0,0 +1,6 @@
=== 1.0.0 / 2012-03-09

* 1 major enhancement

* Birthday!

8 changes: 8 additions & 0 deletions Manifest.txt
@@ -0,0 +1,8 @@
.autotest
History.txt
Manifest.txt
README.txt
Rakefile
bin/newrelic-redis
lib/newrelic-redis.rb
test/test_newrelic-redis.rb
58 changes: 58 additions & 0 deletions README.txt
@@ -0,0 +1,58 @@
= newrelic-redis

* http://github.com/evanphx/newrelic-redis

== DESCRIPTION:

Redis instrumentation for Newrelic.

== FEATURES/PROBLEMS:

* Allows transactions to show time spent inside redis requests
* Supports normal and pipelined commands

== SYNOPSIS:

Just add the gem to your project!

== REQUIREMENTS:

* redis-rb

== INSTALL:

* gem install newrelic-redis

== DEVELOPERS:

After checking out the source, run:

$ rake newb

This task will install any missing dependencies, run the tests/specs,
and generate the RDoc.

== LICENSE:

(The MIT License)

Copyright (c) 2012 FIX

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 changes: 10 additions & 0 deletions Rakefile
@@ -0,0 +1,10 @@
# -*- ruby -*-

require 'rubygems'
require 'hoe'

Hoe.spec 'newrelic-redis' do
developer 'Evan Phoenix', 'evan@phx.io'
end

# vim: syntax=ruby
3 changes: 3 additions & 0 deletions bin/newrelic_redis
@@ -0,0 +1,3 @@
#!/usr/bin/env ruby

abort "you need to write me"
1 change: 1 addition & 0 deletions lib/newrelic_redis.rb
@@ -0,0 +1 @@
require 'newrelic_redis/instrumentation'
72 changes: 72 additions & 0 deletions lib/newrelic_redis/instrumentation.rb
@@ -0,0 +1,72 @@
require 'new_relic/agent/method_tracer'
require 'redis'

# Redis instrumentation.
# Originally contributed by Ashley Martens of ngmoco
# Rewritten, reorganized, and repackaged by Evan Phoenix

# defined?(::Redis) && !NewRelic::Control.instance['disable_redis']

NewRelic::Agent.logger.debug 'Installing Redis instrumentation'

::Redis::Client.class_eval do

include NewRelic::Agent::MethodTracer

# Support older versions of Redis::Client that used the method
# +raw_call_command+.

call_method =
::Redis::Client.new.respond_to?(:call) ? :call : :raw_call_command

def call_with_newrelic_trace(*args)
if NewRelic::Agent::Instrumentation::MetricFrame.recording_web_transaction?
total_metric = 'Database/Redis/allWeb'
else
total_metric = 'Database/Redis/allOther'
end

method_name = args[0].is_a?(Array) ? args[0][0] : args[0]
metrics = ["Database/Redis/#{method_name.to_s.upcase}", total_metric]

self.class.trace_execution_scoped(metrics) do
call_without_newrelic_trace(*args)
end
end

alias_method :call_without_newrelic_trace, call_method
alias_method call_method, :call_with_newrelic_trace

# Older versions of Redis handle pipelining completely differently.
# Don't bother supporting them for now.
#
if public_method_defined? :call_pipelined
def call_pipelined_with_newrelic_trace(commands, options={})
if NewRelic::Agent::Instrumentation::MetricFrame.recording_web_transaction?
total_metric = 'Database/Redis/allWeb'
else
total_metric = 'Database/Redis/allOther'
end

# Report each command as a metric under pipelined, so the user
# can at least see what all the commands were. This prevents
# metric namespace explosion.

metrics = [total_metric, "Database/Redis/Pipelined"]

commands.each do |c|
name = c.kind_of?(Array) ? c[0] : c
metrics << "Database/Redis/Pipelined/#{name.to_s.upcase}"
end

self.class.trace_execution_scoped(metrics) do
call_pipelined_without_newrelic_trace commands, options
end
end


alias_method :call_pipelined_without_newrelic_trace, :call_pipelined
alias_method :call_pipelined, :call_pipelined_with_newrelic_trace
end
end

3 changes: 3 additions & 0 deletions lib/newrelic_redis/version.rb
@@ -0,0 +1,3 @@
class NewRelicRedis
VERSION = '1.0.0'
end
58 changes: 58 additions & 0 deletions test/test_newrelic_redis.rb
@@ -0,0 +1,58 @@
require 'test/unit'
require 'redis'

require 'newrelic_redis/instrumentation'

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

module StubProcess
def establish_connection
end

def read(*args)
end

def process(*args)
@process_args = args
end

attr_reader :process_args

end

def setup
NewRelic::Agent.manual_start
@engine = NewRelic::Agent.instance.stats_engine
@engine.clear_stats

@redis = Redis.new :path => "/tmp/redis"
@client = @redis.client
class << @client
include StubProcess
end
end

def assert_metrics(*m)
assert_equal m.sort, @engine.metrics.sort
end

def test_call
@redis.hgetall "foo"
assert_equal [[[:hgetall, "foo"]]], @client.process_args
assert_metrics "Database/Redis/HGETALL", "Database/Redis/allOther"
end

def test_call_pipelined
@redis.pipelined do
@redis.hgetall "foo"
@redis.inc "bar"
end

assert_equal [[[:hgetall, "foo"], [:inc, "bar"]]], @client.process_args
assert_metrics "Database/Redis/Pipelined/HGETALL",
"Database/Redis/Pipelined/INC",
"Database/Redis/Pipelined",
"Database/Redis/allOther"
end
end

0 comments on commit 19dc580

Please sign in to comment.