README.md in harness-0.3.0 vs README.md in harness-0.4.0
- old
+ new
@@ -5,10 +5,12 @@
redis before being sent to the service.
Currently Supported Services:
* Librato
+* Statsd (thanks to fluxlux)
+* Stathat
Current Features:
* Track counters over time (# of registered users)
* Read time specific values (# time to cache something)
@@ -43,24 +45,30 @@
## Installation
Add this line to your application's Gemfile:
- gem 'harness'
+```
+gem 'harness'
+```
And then execute:
- $ bundle
+```
+$ bundle
+```
Or install it yourself as:
- $ gem install harness
+```
+$ gem install harness
+```
## Usage
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
+Gauges are time sensitive 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. Meters monitor counters. They
allow you look at rates of counters (read: counters per second).
@@ -92,30 +100,48 @@
stored in redis and incremented. This means you can simply pass
`:counter => true` in instrumentations if you'd like to count it. You
may also pass `:counter => 5` if you'd like to provide your own value.
This value is stored in redis so the next time `:counter => true` will
work correctly. You can reset all the counters back to zero by calling:
-`Harness.reset_counters!`.
+`Harness.reset_counters!`.
+**NOTE**: You should use the bundled rake task to reset counters with
+a cron job. This will prevent unbounded growth of this metadata. You
+can call `rake harness:reset_counters` to do this. You should call
+this rake task at whatever your longest measurable interval is. Here's
+an example: You log gauges every 12 hours. You should reset the
+counters every 12 hours. This issue is discussed [here](https://github.com/twinturbo/harness/issues/15).
+
```ruby
class MyClass
def important_method(stuff)
ActiveSupport::Notifications.instrument "important_method.my_class", :counter => true do
do_important_stuff
end
end
end
```
-The instuments name will be sent as the name (`important_method.my_class`)
+The instruments name will be sent as the name (`important_method.my_class`)
for that gauge or counter.
+Note that `ActiveSupport::Notifications.instrument` doesn't require
+a block. This can be useful when you are taking an instant measurement.
+
+```ruby
+class MyClass
+ def important_method(stuff)
+ ActiveSupport::Notifications.instrument "important_method.my_class", :counter => true
+ end
+end
+```
+
Harness will do all the extra work in sending these metrics to whatever
service you're using.
Once you the counters are you are instrumented, then you can meter them.
-Meters allow you take arbitary readings of counter rates. The results
+Meters allow you take arbitrary readings of counter rates. The results
return a gauge so they can be logged as well.
```ruby
# Define a counter
class MyClass
@@ -135,29 +161,34 @@
meter.per_hour
```
## Customizing
-You can pash a hash to `:counter` or `:gauge` to initialize the
+You can pass a hash to `:counter` or `:gauge` to initialize the
measurement your own way.
+If you pass a value attribute to a gauge, it will be the value
+sent instead of the duration of the block.
+
```ruby
class MyClass
def important_method(stuff)
- ActiveSupport::Notifications.instrument "important_method.my_class", :gauge => { :id => 'custom-id', :name => "My Measurement" } do
+ ActiveSupport::Notifications.instrument "important_method.my_class",
+ :gauge => { :id => 'custom-id', :name => "My Measurement",
+ :value => my_current_val, :units => 'cogs' } do
do_important_stuff
end
end
end
```
## One Off Gauges and Counters
-You can instantiate `Harness::Counter` and `Harness::Guage` wherever you
+You can instantiate `Harness::Counter` and `Harness::Gauge` wherever you
want. Events from `ActiveSupport` are just converted to these classes
under the covers anyways. You can use these class if you want to take
-peridocial measurements or tracking something that happens outside the
+periodic measurements or tracking something that happens outside the
application.
```ruby
gauge = Harness::Gauge.new
gauge.id = "foo.bar"
@@ -172,27 +203,57 @@
counter.name = "# of Foo bars"
counter.time # defaults to Time.now
counter.value = read_total_users_in_database
counter.log
-# Both class take an option hash
+### Both classes take an option hash
-gauge = Harness::Guage.new :time => Time.now, :id => 'foo.bar'
+gauge = Harness::Gauge.new :time => Time.now, :id => 'foo.bar'
counter = Harness::Counter.new :time => Time.now, :id => 'foo.bar'
```
## Configuration
+### Librato
```ruby
Harness.config.adapter = :librato
Harness.config.librato.email = 'example@example.com'
Harness.config.librato.token = 'your-api-key'
-Harness.redis = Redis.new
```
+### StatsD
+
+Harness does **not** configure StatsD for you. It uses the StatsD class
+under the covers. If you've already configured that in your own way, great.
+If not, you can use the configuration proxy as described below. You
+must also add `statsd-instrument` to your `Gemfile`. This is a soft
+dependency that is not installed for you.
+
+```ruby
+Harness.config.adapter = :statsd
+
+# Harness.config.statsd is a proxy for the StatsD class
+Harness.config.statsd.host = 'localhost'
+Harness.config.statsd.port = '8080'
+Harness.config.statsd.default_sample_rate = 0.1
+Harness.config.statsd.logger = Rails.logger
+
+# You can assign your own StatsD implementation
+# by setting the "backend" attribute
+Harness.config.statsd.backend = CustomStatsD
+```
+
+### Stathat
+
+```ruby
+Harness.config.adapter = :stathat
+
+Harness.config.stathat.ezkey = 'example@example.com'
+```
+
## Rails Integration
Harness will automatically log metrics coming from `ActionPack`,
`ActiveRecord`, and `ActionMailer`. `ActiveSupport` instrumentation is
disabled by default. Also, custom integrations are disabled by default.
@@ -207,12 +268,12 @@
You can configure Harness from `application.rb`
```ruby
config.harness.adapter = :librato
-config.librato.email = 'example@example.com'
-config.librato.token = 'your-api-key'
+config.harness.librato.email = 'example@example.com'
+config.harness.librato.token = 'your-api-key'
```
Redis will be automatically configured if you `REDISTOGO_URL` or
`REDIS_URL` environment variables at set. They are wrapped in a
namespace so there will be no conflicts. If they are not present, the
@@ -223,11 +284,11 @@
require 'erb'
file = Rails.root.join 'config', 'resque.yml'
config = YAML.load(ERB.new(File.read(Rails.root.join('config', 'redis.yml'))).result)
-Harness.redis = Redis.new(:url => config[Rails.env])
+Harness.redis = Redis::Namespace.new('harness', :redis => Redis.connect(:url => config[Rails.env]))
```
`rake harness:reset_counters` is also added.
### Rails Environments
@@ -237,13 +298,13 @@
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
+reporting measurements can take time and add unnecessary 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:
+specifying a class like so:
```ruby
Harness.config.queue = MyCustomQueue
```