rpm_contrib 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG ADDED
@@ -0,0 +1,7 @@
1
+ * Version 1.0.0
2
+
3
+ Initial Release:
4
+ - Camping
5
+ - Authlogic
6
+ - DelayedJob
7
+ - Paperclip
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 New Relic, Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # The RPM Contrib Gem
2
+
3
+ The `rpm_contrib` gem contains instrumentation for the New Relic RPM agent
4
+ contributed by the community of RPM users. It requires the RPM Agent
5
+ to run.
6
+
7
+ We encourage contributions to this project and will provide whatever
8
+ assistance we can to those wishing to develop instrumentation for
9
+ other open source Ruby libraries.
10
+
11
+ ## Note on Patches/Pull Requests
12
+
13
+ * Fork the http://www.github.com/newrelic/rpm_contrib project.
14
+ * Add instrumentation files to `lib/rpm_contrib/instrumentation`. These
15
+ files will be loaded when the RPM agent is initialized.
16
+ * Add samplers to `lib/rpm_contrib/samplers`. These classes are
17
+ installed automatically when the RPM agent is initialized.
18
+ * Add tests.
19
+ * Commit, do not mess with the Rakefile, version, or history. (if you
20
+ want to have your own version, that is fine but bump version in a
21
+ commit by itself I can ignore when I pull)
22
+ * Send me a pull request. Bonus points for topic branches.
23
+
24
+ ## Further Information
25
+
26
+ Refer to the [Agent API Documentation](http://newrelic.github.com/rpm).
27
+
28
+ See [the support site](http://support.newrelic.com/faqs) for additional tips and documentation.
29
+
30
+ Contact support@newrelic.com for help.
31
+
32
+ ## Copyright
33
+
34
+ Copyright (c) 2010 New Relic. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,60 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ # See http://www.rubygems.org/read/chapter/20
4
+
5
+ def version
6
+ @rpm_contrib_version ||= File.read("CHANGELOG")[/Version ([\d\.]+)$/, 1]
7
+ end
8
+
9
+ begin
10
+ require 'jeweler'
11
+ Jeweler::Tasks.new do |gem|
12
+ gem.name = "rpm_contrib"
13
+ gem.summary = %Q{Contributed Instrumentation for New Relic RPM}
14
+ gem.description = <<-EOF
15
+ Community contributed instrumentation for various frameworks based on
16
+ the New Relic Ruby monitoring gem newrelic_rpm.
17
+ EOF
18
+ gem.email = "support@newrelic.com"
19
+ gem.homepage = "http://github.com/newrelic/rpm_contrib"
20
+ gem.author = "Bill Kayser"
21
+ gem.add_dependency 'newrelic_rpm', '>= 2.10.2.2'
22
+ gem.version = version
23
+ gem.files = FileList['LICENSE', 'README*', 'lib/**/*.rb', 'bin/*', '[A-Z]*', 'test/**/*'].to_a
24
+ end
25
+ Jeweler::GemcutterTasks.new
26
+ rescue LoadError
27
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
28
+ end
29
+
30
+ require 'rake/testtask'
31
+ Rake::TestTask.new(:test) do |test|
32
+ test.libs << 'lib' << 'test'
33
+ test.pattern = 'test/**/test_*.rb'
34
+ test.verbose = true
35
+ end
36
+
37
+ begin
38
+ require 'rcov/rcovtask'
39
+ Rcov::RcovTask.new do |test|
40
+ test.libs << 'test'
41
+ test.pattern = 'test/**/test_*.rb'
42
+ test.verbose = true
43
+ end
44
+ rescue LoadError
45
+ task :rcov do
46
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
47
+ end
48
+ end
49
+
50
+ task :test => :check_dependencies
51
+
52
+ task :default => :test
53
+
54
+ require 'rake/rdoctask'
55
+ Rake::RDocTask.new do |rdoc|
56
+ rdoc.rdoc_dir = 'rdoc'
57
+ rdoc.title = "rpm_contrib #{version}"
58
+ rdoc.rdoc_files.include('README*')
59
+ rdoc.rdoc_files.include('lib/**/*.rb')
60
+ end
@@ -0,0 +1,8 @@
1
+ if defined? Authlogic::Session::Base
2
+ Authlogic::Session::Base.class_eval do
3
+ # add_method_tracer :record, 'Authlogic/record'
4
+ class << self
5
+ add_method_tracer :find, 'Authlogic/find'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,74 @@
1
+ require 'new_relic/agent/instrumentation/controller_instrumentation'
2
+
3
+ module RPMContrib
4
+ module Instrumentation
5
+ # == Instrumentation for Camping
6
+ # To instrument all controllers do the following:
7
+ # 1. Add the necessary NewRelic-specific requires in your require section
8
+ # 2. Add an include at the end of your main Camping app module
9
+ # 3. Add a call to NewRelic::Agent.manual_start at the end of the file to start the agent
10
+ # 4. Run the following command to get the NewRelic license key to use: heroku config -all
11
+ # 5. Create a newrelic.yml under the /config folder with the following content:
12
+ #
13
+ # common: &default_settings
14
+ # license_key: 'PASTE THE VALUE OF NEW_RELIC_LICENSE_KEY HERE'
15
+ # agent_enabled: true
16
+ # app_name: PASTE THE NAME OF YOUR CAMPING APP HERE
17
+ # enabled: true
18
+ #
19
+ # production:
20
+ # <<: *default_settings
21
+ # enabled: true
22
+ #
23
+ # Camping code example:
24
+ # --------------------------------------------------------------------------------------
25
+ # require "newrelic_rpm"
26
+ # require 'new_relic/agent/agent'
27
+ # require 'new_relic/agent/instrumentation/controller_instrumentation'
28
+ # require 'new_relic/agent/instrumentation/camping'
29
+ #
30
+ # Camping.goes :NewRelicCampingTest
31
+ #
32
+ # module NewRelicCampingTest
33
+ # # your code
34
+ #
35
+ # include NewRelic::Agent::Instrumentation::ControllerInstrumentation
36
+ # include NewRelic::Agent::Instrumentation::Camping
37
+ # end
38
+ #
39
+ # NewRelic::Agent.manual_start
40
+ #
41
+
42
+ module Camping
43
+
44
+ def self.included(mod)
45
+
46
+ # Since the Camping::Base module is essentially copied
47
+ # into the main module (the mod passed in) of a Camping app
48
+ # using the Camping.goes :NewRelicCampingTest syntax
49
+ # we need to evaluate "weld" the NewRelic plugin in the context of the new Base
50
+
51
+ (Kernel.const_get(mod.name)::Base).module_eval do
52
+
53
+ # Add the new method to the Camping app's Base module
54
+ # since the Camping::Base module is being included
55
+ # in every Camping controller
56
+
57
+ def service_with_newrelic(*args)
58
+ perform_action_with_newrelic_trace(:category => :rack) do
59
+ service_without_newrelic(*args)
60
+ end
61
+ end
62
+
63
+ # Alias the "standard" service method
64
+ # so we can provide a level of indirection
65
+ # to perform the tracing for NewRelic
66
+
67
+ alias service_without_newrelic service
68
+ alias service service_with_newrelic
69
+ end
70
+ end
71
+
72
+ end #RPMContrib::Instrumentation::Camping
73
+ end
74
+ end
@@ -0,0 +1,45 @@
1
+ module RPMContrib::Instrumentation::DelayedJobInstrumentation
2
+ extend self
3
+ Delayed::Job.class_eval do
4
+ include NewRelic::Agent::Instrumentation::ControllerInstrumentation
5
+ if self.instance_methods.include?('name')
6
+ add_transaction_tracer "invoke_job", :category => :task, :name => '#{self.name}'
7
+ else
8
+ add_transaction_tracer "invoke_job", :category => :task
9
+ end
10
+ end
11
+
12
+ Delayed::Worker.class_eval do
13
+ def initialize_with_new_relic(*args)
14
+ initialize_without_new_relic(*args)
15
+ NewRelic::.delayed_worker = self
16
+ end
17
+
18
+ alias initialize_without_new_relic initialize
19
+ alias initialize initialize_with_new_relic
20
+ end
21
+
22
+ def delayed_worker=(w)
23
+ @delayed_worker = w
24
+ env = NewRelic::Control.instance.local_env
25
+ env.dispatcher = :delayed_job
26
+ env.dispatcher_instance_id = case
27
+ when @delayed_worker.respond_to?(:name)
28
+ @delayed_worker.name
29
+ when @delayed_worker.class.respond_to?(:default_name)
30
+ @delayed_worker.class.default_name
31
+ else
32
+ "host:#{Socket.gethostname} pid:#{Process.pid}" rescue "pid:#{Process.pid}"
33
+ end
34
+
35
+ env.append_environment_value 'Dispatcher', @dispatcher.to_s
36
+ env.append_environment_value 'Dispatcher instance id', @dispatcher_instance_id
37
+
38
+ @delayed_worker
39
+ end
40
+
41
+ def delayed_worker
42
+ @delayed_worker
43
+ end
44
+
45
+ end if defined?(Delayed::Job)
@@ -0,0 +1,22 @@
1
+ # Paperclip Instrumentation.
2
+
3
+ if defined? ::Paperclip
4
+
5
+ ::Paperclip::Attachment.class_eval do
6
+ add_method_tracer :save, 'Paperclip/#{name}/save'
7
+ add_method_tracer :assign, 'Paperclip/#{name}/assign'
8
+ add_method_tracer :post_process, 'Paperclip/#{name}/post_process'
9
+ end
10
+
11
+ ::Paperclip::Storage::Filesystem.class_eval do
12
+ add_method_tracer :flush_deletes, 'Paperclip/Storage/flush_deletes'
13
+ add_method_tracer :flush_writes, 'Paperclip/Storage/flush_writes'
14
+ end
15
+
16
+ ::Paperclip::Storage::S3.class_eval do
17
+ add_method_tracer :flush_deletes, 'Paperclip/Storage/flush_deletes'
18
+ add_method_tracer :flush_writes, 'Paperclip/Storage/flush_writes'
19
+ end
20
+
21
+ end
22
+
@@ -0,0 +1,28 @@
1
+ module NewRelic::Agent::Samplers
2
+ class DelayedJobLockSampler < NewRelic::Agent::Sampler
3
+ def initialize
4
+ super :delayed_job_lock
5
+ raise Unsupported, "No delayed job workers running" unless Instrumentation::DelayedJobInstrumentation.delayed_worker
6
+ end
7
+
8
+ def stats
9
+ stats_engine.get_stats("DJ/Locked Jobs", false)
10
+ end
11
+
12
+ def local_env
13
+ NewRelic::Control.instance.local_env
14
+ end
15
+
16
+ def worker_name
17
+ local_env.dispatcher_instance_id
18
+ end
19
+
20
+ def locked_jobs
21
+ Delayed::Job.count(:conditions => {:locked_by => worker_name})
22
+ end
23
+
24
+ def poll
25
+ stats.record_data_point locked_jobs
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ # Hook instrumentation and samplers in this gem into the normal RPM
2
+ # start up sequence.
3
+ require 'newrelic_rpm'
4
+ module RPMContrib
5
+
6
+ lib_root = File.dirname(__FILE__)
7
+
8
+ # Tell the agent to load all the files in the rpm_contrib/instrumentation directory.
9
+
10
+ NewRelic::Agent.add_instrumentation(lib_root+"/rpm_contrib/instrumentation/**/*.rb")
11
+
12
+ # Load all the Sampler class definitions. These will register
13
+ # automatically with the agent.
14
+ Dir.glob(lib_root + "/rpm_contrib/samplers/**/*.rb") { |file| require file }
15
+
16
+ VERSION = File.read(lib_root+"/../CHANGELOG")[/Version ([\d\.]+)$/, 1]
17
+ end
@@ -0,0 +1,108 @@
1
+ module DelayedJobInstrumentation
2
+ require File.expand_path(File.join(File.dirname(__FILE__),'/../test_helper'))
3
+
4
+ class LongRunningJob
5
+ def perform
6
+ sleep 5
7
+ end
8
+ end
9
+
10
+ class NamedJob
11
+ def display_name
12
+ 'some custom name'
13
+ end
14
+ def perform
15
+ true
16
+ end
17
+ end
18
+
19
+ class DelayedJobTest < Test::Unit::TestCase
20
+ def local_env
21
+ NewRelic::Control.instance.local_env
22
+ end
23
+
24
+ def worker_name
25
+ local_env.dispatcher_instance_id
26
+ end
27
+
28
+ def lock_n_jobs(n=1)
29
+ n.times do
30
+ job = Delayed::Job.create
31
+ job.update_attributes({
32
+ :locked_at => Time.now,
33
+ :locked_by => worker_name
34
+ })
35
+ end
36
+ end
37
+
38
+ def setup
39
+ NewRelic::Agent.manual_start
40
+ @agent = NewRelic::Agent.instance
41
+
42
+ @agent.transaction_sampler.harvest
43
+ @agent.stats_engine.clear_stats
44
+ end
45
+
46
+ def teardown
47
+ @agent.instance_variable_set("@histogram", NewRelic::Histogram.new)
48
+ end
49
+
50
+ def test_job_instrumentation
51
+ job = Delayed::Job.new(:payload_object => LongRunningJob.new)
52
+ job_name = "Controller/Task/Delayed::Job/LongRunningJob"
53
+
54
+ job.invoke_job
55
+ job_stats = @agent.stats_engine.get_stats(job_name)
56
+
57
+ assert @agent.stats_engine.metrics.include?(job_name)
58
+ assert_equal 1, job_stats.call_count
59
+ end
60
+
61
+ def test_custom_name
62
+ job = Delayed::Job.new(:payload_object => NamedJob.new)
63
+ job_name = "Controller/Task/Delayed::Job/some custom name"
64
+
65
+ job.invoke_job
66
+ job_stats = @agent.stats_engine.get_stats(job_name)
67
+
68
+ assert @agent.stats_engine.metrics.include?(job_name)
69
+ assert_equal 1, job_stats.call_count
70
+ end
71
+
72
+ def test_lock_sampler
73
+ stats_engine = NewRelic::Agent::StatsEngine.new
74
+ sampler = NewRelic::Agent::Samplers::DelayedJobLockSampler.new
75
+ sampler.stats_engine = stats_engine
76
+
77
+ lock_n_jobs(1)
78
+ sampler.poll
79
+
80
+ assert_equal 1, sampler.stats.data_point_count
81
+ assert_equal 1, sampler.stats.min_call_time
82
+ assert_equal 1, sampler.stats.max_call_time
83
+
84
+ lock_n_jobs(4)
85
+ sampler.poll
86
+
87
+ assert_equal 2, sampler.stats.data_point_count
88
+ assert_equal 1, sampler.stats.min_call_time
89
+ assert_equal 5, sampler.stats.max_call_time
90
+
91
+ lock_n_jobs(5)
92
+ sampler.poll
93
+ sampler.poll
94
+
95
+ assert_equal 4, sampler.stats.data_point_count
96
+ assert_equal 1, sampler.stats.min_call_time
97
+ assert_equal 10, sampler.stats.max_call_time
98
+
99
+ Delayed::Job.destroy_all
100
+ sampler.poll
101
+
102
+ assert_equal 5, sampler.stats.data_point_count
103
+ assert_equal 0, sampler.stats.min_call_time
104
+ assert_equal 10, sampler.stats.max_call_time
105
+ end
106
+
107
+ end
108
+ end if defined? Delayed::Job
data/test/helper.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ require 'rpm_contrib'
7
+
8
+ class Test::Unit::TestCase
9
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestRpmContrib < Test::Unit::TestCase
4
+ def test_something_for_real
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rpm_contrib
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Bill Kayser
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-28 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: newrelic_rpm
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.10.2.2
24
+ version:
25
+ description: " Community contributed instrumentation for various frameworks based on\n the New Relic Ruby monitoring gem newrelic_rpm.\n"
26
+ email: support@newrelic.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README.md
34
+ files:
35
+ - CHANGELOG
36
+ - LICENSE
37
+ - README.md
38
+ - Rakefile
39
+ - lib/rpm_contrib.rb
40
+ - lib/rpm_contrib/instrumentation/authlogic.rb
41
+ - lib/rpm_contrib/instrumentation/camping.rb
42
+ - lib/rpm_contrib/instrumentation/delayed_job_instrumentation.rb
43
+ - lib/rpm_contrib/instrumentation/paperclip.rb
44
+ - lib/rpm_contrib/samplers/delayed_job_lock_sampler.rb
45
+ - test/delayed_job_instrumentation/delayed_job_test.rb
46
+ - test/helper.rb
47
+ - test/test_rpm_contrib.rb
48
+ has_rdoc: true
49
+ homepage: http://github.com/newrelic/rpm_contrib
50
+ licenses: []
51
+
52
+ post_install_message:
53
+ rdoc_options:
54
+ - --charset=UTF-8
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.3.5
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: Contributed Instrumentation for New Relic RPM
76
+ test_files:
77
+ - test/delayed_job_instrumentation/delayed_job_test.rb
78
+ - test/helper.rb
79
+ - test/test_rpm_contrib.rb