Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 3 commits
  • 5 files changed
  • 0 commit comments
  • 1 contributor
View
75 README.md
@@ -8,6 +8,39 @@ Currently Supported Services:
* Librato
+Current Features:
+
+* Track counters over time (# of registered users)
+* Read time specific values (# time to cache something)
+* Build meters on top of counters (# requests per second)
+* Sidekiq integration
+* Resque integration
+* Rails integration
+* Capture and log all measurements coming out of Rails
+
+**Crash Course**
+
+```ruby
+class ComplicatedClass
+ def hard_work
+ # Automatically track how long each of these calls takes so they can
+ # tracked and compared over time.
+ ActiveSupport::Notifications.instrument "hard_work", :gauge => true do
+ # do hard_work
+ end
+ end
+
+ def register_user
+ # Automatically track the total # of registered users you have.
+ # As well, as be able to take measurements of users created in a
+ # specific interval
+ ActiveSupport::Notifications.instrument "register_user", :counter => true do
+ # register_user
+ end
+ end
+end
+```
+
## Installation
Add this line to your application's Gemfile:
@@ -28,7 +61,8 @@ In the metrics world there are two types of things: Gauges and Counters.
Gauges are time senstive and represent something at a specific point in
time. Counters keep track of things and should be increasing. Counters
can be reset back to zero. You can combine counters and/or gauges to
-correlate data about your application.
+correlate data about your application. Meters monitor counters. They
+allow you look at rates of counters (read: counters per second).
Harness makes this process easily. Harness' primary goal it make it dead
simple to start measuring different parts of your application.
@@ -78,7 +112,30 @@ for that gauge or counter.
Harness will do all the extra work in sending these metrics to whatever
service you're using.
-## Customzing
+Once you the counters are you are instrumented, then you can meter them.
+Meters allow you take arbitary readings of counter rates. The results
+return a gauge so they can be logged as well.
+
+```ruby
+# Define a counter
+class MyClass
+ def important_method(stuff)
+ ActiveSupport::Notifications.instrument "important_method.my_class", :counter => true do
+ do_important_stuff
+ end
+ end
+end
+
+# Now you can meter it
+meter = Harnes::Meter.new('important_method.my_class')
+meter.per_second # returns a gauge
+meter.per_second.value # if you just want the number
+meter.per(1.hour).value # You can use your own interval
+meter.per_minute
+meter.per_hour
+```
+
+## Customizing
You can pash a hash to `:counter` or `:gauge` to initialize the
measurement your own way.
@@ -157,7 +214,7 @@ default values are used. You can customize this in an initializer:
require 'erb'
file = Rails.root.join 'config', 'resque.yml'
-config = YAML.load(ERB.new(File.read(Rails.root.join('config', 'resque.yml'))).result)
+config = YAML.load(ERB.new(File.read(Rails.root.join('config', 'redis.yml'))).result)
Harness.redis = Redis.new(:url => config[Rails.env])
```
@@ -170,6 +227,18 @@ Measurements are completely ignored in the test env. They are processed
in development mode, but not sent to the external service. Everything is
logged in production.
+### Background Processing
+
+Harness integrates automatically with Resque or Sidekiq. This is because
+reporting measurements can take time and add unncessary overhead to the
+response time. If neither of these libraries are present, measurements
+**will be posted in realtime.** You can set your own queue by
+specifiying a class like so:
+
+```ruby
+Harness.config.queue = MyCustomQueue
+```
+
## Contributing
1. Fork it
View
2  lib/harness/counter.rb
@@ -25,7 +25,7 @@ def self.from_event(event)
counter.value = Harness.redis.incr(counter.id).to_i
end
- Harness.redis.zadd "meters/#{counter.id}", counter.time.to_i, counter.value
+ Harness.redis.zadd "meters/#{counter.id}", counter.time.to_f, counter.value
counter
end
View
23 lib/harness/meter.rb
@@ -19,7 +19,18 @@ def per_hour
end
def per(rate, base = Time.now)
- redis.zcount(key, base.to_i - rate, base.to_i)
+ gauge = Gauge.new :value => redis.zcount(key, base.to_f - rate, base.to_f)
+
+ if words = rate_in_words(rate)
+ gauge.name = "#{@name} per #{words}"
+ gauge.id = "#{@name}-per-#{words}"
+ else
+ gauge.id = "#{@name} gauge"
+ end
+
+ gauge.time = Time.now
+
+ gauge
end
private
@@ -30,5 +41,15 @@ def key
def redis
Harness.redis
end
+
+ def rate_in_words(rate)
+ if rate < 1.minute
+ "second"
+ elsif rate >= 1.minute && rate < 1.hour
+ "minute"
+ elsif rate >= 1.hour && rate < 1.day
+ "hour"
+ end
+ end
end
end
View
20 test/integration/meter_test.rb
@@ -5,9 +5,9 @@ def test_counters_can_act_like_gauges
50.times { instrument "event-counter", :counter => true }
meter = Harness::Meter.new 'event-counter'
- assert_equal 50, meter.per_second
- assert_equal 50, meter.per_minute
- assert_equal 50, meter.per_hour
+ assert_equal 50, meter.per_second.value
+ assert_equal 50, meter.per_minute.value
+ assert_equal 50, meter.per_hour.value
end
def tests_raises_an_error_when_no_such_counter
@@ -15,4 +15,18 @@ def tests_raises_an_error_when_no_such_counter
Harness::Meter.new 'unknown-counter'
end
end
+
+ def test_rates_return_gauges
+ 50.times { instrument "event-counter", :counter => true }
+
+ meter = Harness::Meter.new 'event-counter'
+
+ gauge = meter.per_second
+
+ assert_kind_of Harness::Gauge, gauge
+
+ assert_equal "event-counter-per-second", gauge.id
+ assert_equal "event-counter per second", gauge.name
+ assert_kind_of Time, gauge.time
+ end
end
View
0  test/unit/meter_test.rb
No changes.

No commit comments for this range

Something went wrong with that request. Please try again.