README.md in yodeler-0.0.10 vs README.md in yodeler-0.1.1

- old
+ new

@@ -1,106 +1,197 @@ -Yodeler -======= +# Yodeler -Spouting noise to whoever is listening. +A generic instrumentation library thats supports reporting to multiple endpoints via pluggable backend adapters. -Yodeler is an easy way to notify users of different events that occur in your app. +Spoutin' off noise to whoever is listening. - * Notify your marketing team on the 10,000 sign-up. - * Notify user's when their profile has been viewed - * Notify your dev team about events that are not quite exception worthy, but you don't want to dig through a bunch of logs to find. +![Build Status](https://travis-ci.org/coryodaniel/yodeler.svg "Build Status") +[![Test Coverage](https://codeclimate.com/github/coryodaniel/yodeler/badges/coverage.svg)](https://codeclimate.com/github/coryodaniel/yodeler/coverage) +[![Code Climate](https://codeclimate.com/github/coryodaniel/yodeler/badges/gpa.svg)](https://codeclimate.com/github/coryodaniel/yodeler) +## Installation -Features -======== +Add this line to your application's Gemfile: - * store notifications via ActiveRecord - * benchmark event duration - * i18n support - * flexible payloads +```ruby +gem 'yodeler', '~>0.1.1' +``` +And then execute: -What's wrong with XMPP? -======================= + $ bundle - Why don't you fly to Walmart on a rocket? +Or install it yourself as: - Don't even say it's because you don't have a rocket. + $ gem install yodeler - Why don't you kill ants with a bazooka? +## Usage - Nevermind, you get it. +### Configuration +#### Single endpoint +In ```config/initializers/yodeler.rb``` +```ruby +Yodeler.configure do |client| + # if no endpoint name is given, it defaults to :default + client.adapter(:http) do |http| + http.path = '/events' + http.host = 'example.com' + # http.port = 80 + # http.use_ssl = false + # http.default_params = {} + end +end +``` -Usage -===== - +#### Multiple Endpoints +In ```config/initializers/yodeler.rb``` ```ruby -# in config/initializers/yodeler.rb -Yodeler.register :another_thousand_users -Yodeler.register :view_user do - # Default states are unread: 0, read: 1 - config.states = { - unread: 0, - read: 1, - ignored: 2 - } +Yodeler.configure do |client| + client.endpoint(:sales_reporting).adapter(:http) do |http| + http.path = '/events' + http.host = 'sales.example.com' + end + + client.endpoint(:devops_reporting).adapter(:http) do |http| + http.path = '/events' + http.host = 'devops.example.com' + end + + # by default, the client dispatches to the first registered endpoint + # you can change it to a different one + # Alternatively you can dispatch to a set of endpoints when dispatching a metric + # Yodeler.gauge('users.count', 35, to: [:sales_reporting, :devops_reporting]) + client.default_endpoint_name = :devops_reporting end ``` +#### Full Configuration Example +In ```config/yodeler.yml``` +```yaml +development: + auth_token: SOSECUREZ + sales_reporting: + host: localhost + port: 3030 + devops_reporting: + host: localhost + port: 3031 +``` + +In ```config/initializers/yodeler.rb``` ```ruby -# in a controller or Anywhere you want to hear some noise -class UserController < ApplicationController - around_action :track_user_view, only: :show - - def show - # do your User#show as normal +config = YAML.load(File.read("./config/yodeler.yml"))[Rails.env] + +Yodeler.configure do |client| + client.endpoint(:sales_reporting).adapter(:http) do |http| + http.path = '/events' + http.host = config[:sales_reporting][:host] + http.port = config[:sales_reporting][:port] + http.default_params = { + auth_token: config[:auth_token] + } end - private + client.endpoint(:devops_reporting).adapter(:http) do |http| + http.path = '/events' + http.host = config[:devops_reporting][:host] + http.port = config[:devops_reporting][:port] + http.default_params = { + auth_token: config[:auth_token] + } - def track_user_view - # This will also benchmark the action since it is in a block - Yodeler.dispatch :view_user, {viewer_id: 3, viewee_id: 23} do |payload| - yield #yield the action dispatch, the payload is available + # Overwrite the default http dispatcher or overwrite an individual metric dispatcher + # http.handle(:gauge){|url, metric, default_params| ... something cool ... } + http.handle(:default) do |url, metric, default_params| + # This is the default handler definition, but you could change it + HTTP.post(url, json: default_params.merge(metric.to_hash)) end end + + client.default_endpoint_name = :devops_reporting end + ``` +#### [Dashing Example](https://github.com/shopify/dashing) ```ruby -# off in some scorned rails-observer -class UserObserver - observers :user +Yodeler.configure do |client| + client.endpoint(:karma_widget).adapter(:http) do |http| + http.path = '/widgets/karma' + http.host = 'localhost' + http.default_params = { + auth_token: config[:auth_token] + } + end - def after_create - # let the marketing know another thousandth user has registered! - if (User.count % 1000).zero? - Yodeler.dispatch :another_thousand_users, {give_him_a_prize: @user.id} - end + client.endpoint(:user_count_widget).adapter(:http) do |http| + http.path = '/widgets/user_count' + http.host = 'localhost' + http.default_params = { + auth_token: config[:auth_token] + } end end ``` +### Publishing Metrics and Events -Getting around the objects -========================== +#### All instrumentation methods support an options hash +* :prefix - [~String] :prefix your metric/event names +* :tags - [Array<String,Symbol>, String, Symbol] :tags ([]) array of tags to apply to metric/event +* :sample_rate - [Float] :sample_rate (1.0) The sample rate to use +* :to - [Array<Symbol>, Symbol] :to array of endpoint names to send the metric/event to. If not set will send to Yodeler::Client#default_endpoint_name + +#### Gauge ```ruby -@event.subscriptions #=> Array<Yodeler::Subscription> all subscriber subscriptions -@event.notifications #=> Array<Yodeler::Notifications> +Yodeler.gauge 'user.count', 35 +Yodeler.gauge 'user.count', 35, prefix: 'test' +Yodeler.gauge 'user.count', 35, sample_rate: 0.5 +Yodeler.gauge 'user.count', 35, prefix: 'test', tags: ['cool'] +Yodeler.gauge 'user.count', 35, to: [:devops_reporting, :sales_reporting] +``` -@notification.subscriber #=> Your 'subscriber' class, delegated to #subscription -@notification.subscription.subscriber -@notification.event #=> The subscriber to event, delegated to #subscription -@notification.message #=> i18n message interpolated w/ the payload +#### Increment +```ruby +Yodeler.increment 'users.count' +Yodeler.increment 'users.count', to: [:devops_reporting, :sales_reporting] +Yodeler.increment 'revenue', 10_000 +Yodeler.increment 'revenue', 10_000, to: [:devops_reporting, :sales_reporting] -@subscription.subscriber #=> the 'subscriber' subscribed to this event -@subscription.notifications #=> all notifications of this event type for this subscriber -@subscription.event +``` +#### Timing +```ruby +Yodeler.timing('eat.sandwich', {prefix: :test}) do + user.eat(sandwich) +end #=> returns result of block + +Yodeler.timing 'eat.sandwich', 250 #in ms +Yodeler.timing 'eat.sandwich', 250, to: [:devops_reporting, :sales_reporting] ``` -TODO -======= -* Pluggable back-end, redis, obvi \ No newline at end of file +#### Event +```ruby +wizz_bang = {name: 'Wizz Bang 3000', image_url: 'http://example.com/wizzbang.jpg'} +Yodeler.publish 'product.sold', wizz_bang +Yodeler.publish 'product.sold', wizz_bang, prefix: 'ecommerce' +Yodeler.publish 'product.sold', wizz_bang, sample_rate: 0.25 +Yodeler.publish 'product.sold', wizz_bang, to: [:devops_reporting, :sales_reporting] +``` + +## Development + +After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. + +To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). + +## Contributing + +Bug reports and pull requests are welcome on GitHub at https://github.com/coryodaniel/yodeler. + +## TODOs + * [ ] Custom adapter documentation + * [ ] Client#format_options -> Metric.format_options + * [ ] Client#default_endpoint_name accept array of names