Permalink
Browse files

Reorganize and repackage from the rpm_contrib gem

  • Loading branch information...
0 parents commit 19dc5806ef8b1508ed3572a8d993fbc4ad45983e @evanphx committed Mar 9, 2012
Showing with 242 additions and 0 deletions.
  1. +23 −0 .autotest
  2. +6 −0 History.txt
  3. +8 −0 Manifest.txt
  4. +58 −0 README.txt
  5. +10 −0 Rakefile
  6. +3 −0 bin/newrelic_redis
  7. +1 −0 lib/newrelic_redis.rb
  8. +72 −0 lib/newrelic_redis/instrumentation.rb
  9. +3 −0 lib/newrelic_redis/version.rb
  10. +58 −0 test/test_newrelic_redis.rb
@@ -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
@@ -0,0 +1,6 @@
+=== 1.0.0 / 2012-03-09
+
+* 1 major enhancement
+
+ * Birthday!
+
@@ -0,0 +1,8 @@
+.autotest
+History.txt
+Manifest.txt
+README.txt
+Rakefile
+bin/newrelic-redis
+lib/newrelic-redis.rb
+test/test_newrelic-redis.rb
@@ -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.
@@ -0,0 +1,10 @@
+# -*- ruby -*-
+
+require 'rubygems'
+require 'hoe'
+
+Hoe.spec 'newrelic-redis' do
+ developer 'Evan Phoenix', 'evan@phx.io'
+end
+
+# vim: syntax=ruby
@@ -0,0 +1,3 @@
+#!/usr/bin/env ruby
+
+abort "you need to write me"
@@ -0,0 +1 @@
+require 'newrelic_redis/instrumentation'
@@ -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
+
@@ -0,0 +1,3 @@
+class NewRelicRedis
+ VERSION = '1.0.0'
+end
@@ -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.