nogara-resque-statsd 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ # gem "rspec"
10
+ gem "yard"
11
+ gem "jeweler"
12
+ # gem "rcov", ">= 0"
13
+ end
14
+
15
+ gem 'jamster-statsd'
data/Gemfile.lock ADDED
@@ -0,0 +1,23 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ jamster-statsd (0.1.0)
6
+ jeweler (1.8.3)
7
+ bundler (~> 1.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ rdoc
11
+ json (1.6.5)
12
+ rake (0.9.2.2)
13
+ rdoc (3.12)
14
+ json (~> 1.4)
15
+ yard (0.7.5)
16
+
17
+ PLATFORMS
18
+ ruby
19
+
20
+ DEPENDENCIES
21
+ jamster-statsd
22
+ jeweler
23
+ yard
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Jason Amster
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.mdown ADDED
@@ -0,0 +1,89 @@
1
+ # resque-statsd
2
+
3
+ Resque Statsd is a Resque plugin that will collect and send data samples from your Resque Jobs. It samples 4 statistics for any Job for which the plugin extends, enqueue count, completion count, failure count, and the time to process. It will monitor for each specific job, in addition to the totals for all jobs (not including timing stats)
4
+
5
+ ## CURRENT STATUS
6
+
7
+ This is a fork of jamster's original gem designed to make it easier to run with Bundler and Rails 3.0.
8
+
9
+ ## Final Outcome
10
+
11
+ ![Graph of a Job](https://img.skitch.com/20110323-ghsnyg8nhs6hta8etea63q6965.jpg "Report Running Job Stats")
12
+
13
+
14
+
15
+ ## Usage
16
+
17
+ ### Install
18
+
19
+ Add this to your Gemfile:
20
+
21
+ gem "resque-statsd", :git => "git://github.com/cloudability/resque-statsd.git"
22
+
23
+ ### Rails Setup
24
+
25
+ in an initializer, set up the Statsd
26
+
27
+ touch config/initializers/resque-statsd.rb
28
+
29
+ in file add code
30
+
31
+ require 'enqueue_time'
32
+
33
+ module Resque
34
+ include Resque::EnqueueTime
35
+ end
36
+
37
+ StatsdHelper.graphite_host = 'graphite.YOUR_HOST.com'
38
+ StatsdHelper.namespace = "YOUR_APP.#{Rails.env.development? ? ENV['USER'] : Rails.env}.resque"
39
+
40
+ Change `YOUR_HOST` and `YOUR_APP` accordingly.
41
+
42
+ ### In Your Code
43
+
44
+ Extend your class like this:
45
+
46
+ class MyJob
47
+ extend Resque::Plugins::Statsd
48
+ def self.perform(*payload)
49
+ # ..
50
+ end
51
+ end
52
+
53
+ ## Background Reading
54
+
55
+ ### Graphite
56
+
57
+ http://graphite.wikidot.com/
58
+
59
+ ### StatsD Comes From Etsy
60
+
61
+ The folks at Etsy (kastner) have come up with a neat node.js app to listen for Graphite stats.
62
+
63
+ * http://codeascraft.etsy.com/2010/12/08/track-every-release/
64
+ * http://codeascraft.etsy.com/2011/02/15/measure-anything-measure-everything/
65
+ * https://github.com/etsy/statsd
66
+
67
+ ### Ruby StatsD Client
68
+
69
+ I've required a particular version (jnunemaker's) of the ruby StatsD client
70
+ Read the post here
71
+
72
+ * http://railstips.org/blog/archives/2011/03/21/hi-my-name-is-john/
73
+ * A Ruby statsd client (https://github.com/etsy/statsd)
74
+
75
+ ## Contributing to resque-statsd
76
+
77
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
78
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
79
+ * Fork the project
80
+ * Start a feature/bugfix branch
81
+ * Commit and push until you are happy with your contribution
82
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
83
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
84
+
85
+ ## Copyright
86
+
87
+ Copyright (c) 2011 Jason Amster. See LICENSE.txt for
88
+ further details.
89
+
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ gem.name = "resque-statsd"
15
+ gem.homepage = "http://github.com/cloudability/resque-statsd"
16
+ gem.license = "MIT"
17
+ gem.summary = %Q{Adds simple counters and timers for statsd into your Resque jobs}
18
+ gem.description = %Q{Will add a counter for enqueuing, performing, failing and timing Jobs}
19
+ gem.email = "engineering@cloudability.com"
20
+ gem.authors = ["Jon Frisby", "Jason Amster"]
21
+ gem.require_path = 'lib'
22
+
23
+ gem.files.reject! do |fn|
24
+ fn =~ /^\.(rvmrc|rspec|document|gitignore)$/ ||
25
+ fn =~ /^VERSION$/ ||
26
+ fn =~ /^(spec|features)\//
27
+ end
28
+ end
29
+ Jeweler::RubygemsDotOrgTasks.new
30
+
31
+ # require 'rspec/core'
32
+ # require 'rspec/core/rake_task'
33
+ # RSpec::Core::RakeTask.new(:spec) do |spec|
34
+ # spec.pattern = FileList['spec/**/*_spec.rb']
35
+ # end
36
+ #
37
+ # RSpec::Core::RakeTask.new(:rcov) do |spec|
38
+ # spec.pattern = 'spec/**/*_spec.rb'
39
+ # spec.rcov = true
40
+ # end
41
+ #
42
+ # task :default => :spec
43
+
44
+ # require 'yard'
45
+ # YARD::Rake::YardocTask.new
@@ -0,0 +1,49 @@
1
+ # Monkey-patch to record queue length since resque doesn't have hooks that give access to the
2
+ # redis stored object, so we can add metadata
3
+ # Ideal solution: contribute to the resque project to add hooks for the push and perform action:
4
+ # https://github.com/defunkt/resque/issues/464
5
+
6
+ module Resque
7
+ module EnqueueTime
8
+
9
+ def self.included(base)
10
+ base.class_eval do
11
+ alias_method :push_without_enqueued_at, :push
12
+ # Wrapper for the original Resque push method, which adds
13
+ # enqueued_at time
14
+ def push(queue, item)
15
+ begin
16
+ if item.respond_to?(:[]=)
17
+ item[:enqueued_at] = Time.now
18
+ end
19
+ rescue Exception => e
20
+ Rails.logger.error "Error in Resque::EnqueueTime: #{e.message}"
21
+ end
22
+ push_without_enqueued_at queue, item
23
+ end
24
+ end
25
+ end
26
+
27
+ end
28
+ end
29
+
30
+
31
+ module Resque
32
+ class Job
33
+ alias_method :perform_without_enqueue_time, :perform
34
+
35
+ def perform
36
+ begin
37
+ if payload['enqueued_at']
38
+ queue_time = (Time.now - DateTime.parse(payload['enqueued_at'])) * 1000.0
39
+ StatsdHelper.statsd.timing("queues.#{queue}.queue_time", queue_time)
40
+ StatsdHelper.statsd.timing("total.queue_time", queue_time)
41
+ end
42
+ rescue Exception => e
43
+ Rails.logger.error "Error in Resque::EnqueueTime in recording queue_time in statsd: #{e.message}"
44
+ end
45
+ perform_without_enqueue_time
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ require 'statsd' # Really Jnunemakers's mine branch of statsd
3
+ require 'resque/plugins/statsd'
4
+
5
+ class StatsdHelper
6
+ def self.graphite_host
7
+ return @graphite_host || ENV['GRAPHITE_HOST'] || 'localhost'
8
+ end
9
+ def self.graphite_host=(val)
10
+ @graphite_host = val
11
+ end
12
+
13
+ def self.graphite_port
14
+ return @graphite_port || ENV['GRAPHITE_PORT'] || 8125
15
+ end
16
+ def self.graphite_port=(val)
17
+ @graphite_port = val
18
+ end
19
+
20
+ def self.namespace
21
+ return @namespace || ENV['GRAPHITE_NAMESPACE'] || 'resque'
22
+ end
23
+ def self.namespace=(val)
24
+ @namespace = val
25
+ end
26
+
27
+ # Set up the client lazily, to minimize order-of-operations headaches.
28
+ def self.statsd
29
+ if(@stats.nil?)
30
+ @statsd = Statsd.new(graphite_host, graphite_port)
31
+ @statsd.namespace = namespace
32
+ end
33
+ return @statsd
34
+ end
35
+ end
36
+
37
+ module Resque
38
+ module Plugins
39
+ module Statsd
40
+ VERSION = "0.0.4"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,80 @@
1
+ module Resque
2
+ module Plugins
3
+ module Statsd
4
+ def after_enqueue_statsd(*args)
5
+ StatsdHelper.statsd.increment("queues.#{@queue}.enqueued")
6
+ StatsdHelper.statsd.increment("jobs.#{self.name}.enqueued")
7
+ StatsdHelper.statsd.increment("total.enqueued")
8
+ rescue SocketError => se
9
+ # Common cause of this is failure of getaddrinfo (I.E. can't route to
10
+ # statsd server or some such). This may happen in development, when
11
+ # your net connection isn't in a good way, for example.
12
+ #
13
+ # Ignoring this because we don't want unreachability of statsd to
14
+ # impair the ability of an app to actually operate.
15
+ end
16
+
17
+ def before_perform_statsd(*args)
18
+ StatsdHelper.statsd.increment("queues.#{@queue}.started")
19
+ StatsdHelper.statsd.increment("jobs.#{self.name}.started")
20
+ StatsdHelper.statsd.increment("total.started")
21
+ rescue SocketError => se
22
+ # Common cause of this is failure of getaddrinfo (I.E. can't route to
23
+ # statsd server or some such). This may happen in development, when
24
+ # your net connection isn't in a good way, for example.
25
+ #
26
+ # Ignoring this because we don't want unreachability of statsd to
27
+ # impair the ability of an app to actually operate.
28
+ end
29
+
30
+ def after_perform_statsd(*args)
31
+ StatsdHelper.statsd.increment("queues.#{@queue}.finished")
32
+ StatsdHelper.statsd.increment("jobs.#{self.name}.finished")
33
+ StatsdHelper.statsd.increment("total.finished")
34
+ rescue SocketError => se
35
+ # Common cause of this is failure of getaddrinfo (I.E. can't route to
36
+ # statsd server or some such). This may happen in development, when
37
+ # your net connection isn't in a good way, for example.
38
+ #
39
+ # Ignoring this because we don't want unreachability of statsd to
40
+ # impair the ability of an app to actually operate.
41
+ end
42
+
43
+ def on_failure_statsd(*args)
44
+ StatsdHelper.statsd.increment("queues.#{@queue}.failed")
45
+ StatsdHelper.statsd.increment("jobs.#{self.name}.failed")
46
+ StatsdHelper.statsd.increment("total.failed")
47
+ rescue SocketError => se
48
+ # Common cause of this is failure of getaddrinfo (I.E. can't route to
49
+ # statsd server or some such). This may happen in development, when
50
+ # your net connection isn't in a good way, for example.
51
+ #
52
+ # Ignoring this because we don't want unreachability of statsd to
53
+ # impair the ability of an app to actually operate.
54
+ end
55
+
56
+ def around_perform_statsd(*args)
57
+ # We don't want to swallow a SocketError if it didn't actually come
58
+ # from our attempts to talk to statsd.
59
+ failure_is_in_app = true
60
+ StatsdHelper.statsd.time("queues.#{@queue}.processed") do
61
+ StatsdHelper.statsd.time("jobs.#{self.name}.processed") do
62
+ yield
63
+ failure_is_in_app = false
64
+ end
65
+ end
66
+ rescue SocketError => se
67
+ # Common cause of this is failure of getaddrinfo (I.E. can't route to
68
+ # statsd server or some such). This may happen in development, when
69
+ # your net connection isn't in a good way, for example.
70
+ #
71
+ # Ignoring this iff it's statsd-related because we don't want
72
+ # unreachability of statsd to impair the ability of an app to actually
73
+ # operate.
74
+ raise se if(failure_is_in_app)
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+
@@ -0,0 +1,54 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "nogara-resque-statsd"
8
+ s.version = "0.0.4"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jon Frisby", "Jason Amster"]
12
+ s.date = "2012-03-23"
13
+ s.description = "Will add a counter for enqueuing, performing, failing and timing Jobs"
14
+ s.email = "engineering@cloudability.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.mdown"
18
+ ]
19
+ s.files = [
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "LICENSE.txt",
23
+ "README.mdown",
24
+ "Rakefile",
25
+ "lib/enqueue_time.rb",
26
+ "lib/resque-statsd.rb",
27
+ "lib/resque/plugins/statsd.rb",
28
+ "resque-statsd.gemspec"
29
+ ]
30
+ s.homepage = "http://github.com/cloudability/resque-statsd"
31
+ s.licenses = ["MIT"]
32
+ s.require_paths = ["lib"]
33
+ s.rubygems_version = "1.8.13"
34
+ s.summary = "Adds simple counters and timers for statsd into your Resque jobs"
35
+
36
+ if s.respond_to? :specification_version then
37
+ s.specification_version = 3
38
+
39
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
40
+ s.add_runtime_dependency(%q<statsd-ruby>, [">= 0"])
41
+ s.add_development_dependency(%q<yard>, [">= 0"])
42
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
43
+ else
44
+ s.add_dependency(%q<statsd-ruby>, [">= 0"])
45
+ s.add_dependency(%q<yard>, [">= 0"])
46
+ s.add_dependency(%q<jeweler>, [">= 0"])
47
+ end
48
+ else
49
+ s.add_dependency(%q<statsd-ruby>, [">= 0"])
50
+ s.add_dependency(%q<yard>, [">= 0"])
51
+ s.add_dependency(%q<jeweler>, [">= 0"])
52
+ end
53
+ end
54
+
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nogara-resque-statsd
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jon Frisby
9
+ - Jason Amster
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-03-23 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: statsd-ruby
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: yard
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :development
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: jeweler
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ description: Will add a counter for enqueuing, performing, failing and timing Jobs
64
+ email: engineering@cloudability.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files:
68
+ - LICENSE.txt
69
+ - README.mdown
70
+ files:
71
+ - Gemfile
72
+ - Gemfile.lock
73
+ - LICENSE.txt
74
+ - README.mdown
75
+ - Rakefile
76
+ - lib/enqueue_time.rb
77
+ - lib/resque-statsd.rb
78
+ - lib/resque/plugins/statsd.rb
79
+ - resque-statsd.gemspec
80
+ homepage: http://github.com/cloudability/resque-statsd
81
+ licenses:
82
+ - MIT
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 1.8.24
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Adds simple counters and timers for statsd into your Resque jobs
105
+ test_files: []