From c26e057fd1d4c421161f59e1d48c62b144f269e5 Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Fri, 3 Feb 2012 12:26:19 +0000 Subject: [PATCH] initial import of airbrake-statsd gem --- .gitignore | 17 +++++ Gemfile | 4 ++ Rakefile | 20 ++++++ airbrake-statsd.gemspec | 26 +++++++ lib/airbrake-statsd.rb | 40 +++++++++++ lib/airbrake-statsd/airbrake_ext.rb | 13 ++++ lib/airbrake-statsd/configuration.rb | 19 +++++ lib/airbrake-statsd/version.rb | 5 ++ spec/spec_helper.rb | 10 +++ .../unit/airbrake-statsd/airbrake_ext_spec.rb | 34 +++++++++ .../airbrake-statsd/configuration_spec.rb | 42 +++++++++++ spec/unit/airbrake-statsd_spec.rb | 72 +++++++++++++++++++ 12 files changed, 302 insertions(+) create mode 100644 .gitignore create mode 100644 Gemfile create mode 100644 Rakefile create mode 100644 airbrake-statsd.gemspec create mode 100644 lib/airbrake-statsd.rb create mode 100644 lib/airbrake-statsd/airbrake_ext.rb create mode 100644 lib/airbrake-statsd/configuration.rb create mode 100644 lib/airbrake-statsd/version.rb create mode 100644 spec/spec_helper.rb create mode 100644 spec/unit/airbrake-statsd/airbrake_ext_spec.rb create mode 100644 spec/unit/airbrake-statsd/configuration_spec.rb create mode 100644 spec/unit/airbrake-statsd_spec.rb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d87d4be --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +*.gem +*.rbc +.bundle +.config +.yardoc +Gemfile.lock +InstalledFiles +_yardoc +coverage +doc/ +lib/bundler/man +pkg +rdoc +spec/reports +test/tmp +test/version_tmp +tmp diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..4e877cc --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source 'http://rubygems.org' + +# Specify your gem's dependencies in airbrake-statsd.gemspec +gemspec diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..b9592c9 --- /dev/null +++ b/Rakefile @@ -0,0 +1,20 @@ +#!/usr/bin/env rake +require "bundler/gem_tasks" + +# Default task +task :default => 'spec' + +# Rspec +require "rspec/core/rake_task" + +RSpec::Core::RakeTask.new(:spec) + +namespace :spec do + RSpec::Core::RakeTask.new(:integration) do |spec| + spec.pattern = 'spec/integration/**/*_spec.rb' + end + + RSpec::Core::RakeTask.new(:unit) do |spec| + spec.pattern = 'spec/unit/**/*_spec.rb' + end +end diff --git a/airbrake-statsd.gemspec b/airbrake-statsd.gemspec new file mode 100644 index 0000000..4dfe42d --- /dev/null +++ b/airbrake-statsd.gemspec @@ -0,0 +1,26 @@ +# -*- encoding: utf-8 -*- +require File.expand_path('../lib/airbrake-statsd/version', __FILE__) + +Gem::Specification.new do |gem| + gem.authors = ['Jim Myhrberg'] + gem.email = ['contact@jimeh.me'] + gem.description = 'Increment an exception counter in StatsD whenever ' + + 'the Airbrake gem reports and exception.' + gem.summary = 'Increment an exception counter in StatsD whenever ' + + 'the Airbrake gem reports and exception.' + gem.homepage = 'http://github.com/jimeh/airbrake-statsd' + + gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } + gem.files = `git ls-files`.split("\n") + gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + gem.name = 'airbrake-statsd' + gem.require_paths = ['lib'] + gem.version = Airbrake::Statsd::VERSION + + gem.add_development_dependency 'rake' + gem.add_development_dependency 'rspec' + gem.add_development_dependency 'simplecov' + + gem.add_runtime_dependency 'airbrake' + gem.add_runtime_dependency 'statsd-ruby' +end diff --git a/lib/airbrake-statsd.rb b/lib/airbrake-statsd.rb new file mode 100644 index 0000000..3ca9a0e --- /dev/null +++ b/lib/airbrake-statsd.rb @@ -0,0 +1,40 @@ +require 'airbrake' +require 'statsd' + +require 'airbrake-statsd/version' +require 'airbrake-statsd/configuration' +require 'airbrake-statsd/airbrake_ext' + +module Airbrake + module Statsd + class << self + + def configure(&block) + @configured = true + block.call(config) if block_given? + end + + def configured? + !!@configured + end + + def config + @config ||= Configuration.new + end + + def client + @client ||= begin + client = ::Statsd.new(config.host, config.port) + client.namespace = config.namespace if config.namespace + client + end + end + + def increment + return unless configured? + client.increment('exceptions') + end + + end # << self + end # Statsd +end # Airbrake diff --git a/lib/airbrake-statsd/airbrake_ext.rb b/lib/airbrake-statsd/airbrake_ext.rb new file mode 100644 index 0000000..c5f2e53 --- /dev/null +++ b/lib/airbrake-statsd/airbrake_ext.rb @@ -0,0 +1,13 @@ +module Airbrake + class << self + + def notify_with_statds(*args) + Airbrake::Statsd.increment + notify_without_statsd(*args) + end + + alias :notify_without_statsd :notify + alias :notify :notify_with_statds + + end +end diff --git a/lib/airbrake-statsd/configuration.rb b/lib/airbrake-statsd/configuration.rb new file mode 100644 index 0000000..6c17b1b --- /dev/null +++ b/lib/airbrake-statsd/configuration.rb @@ -0,0 +1,19 @@ +module Airbrake + module Statsd + class Configuration + + attr_accessor :namespace + + def host + @host ||= 'localhost' + end + attr_writer :host + + def port + @port ||= 8125 + end + attr_writer :port + + end # Configuration + end # Statsd +end # Airbrake diff --git a/lib/airbrake-statsd/version.rb b/lib/airbrake-statsd/version.rb new file mode 100644 index 0000000..dc63997 --- /dev/null +++ b/lib/airbrake-statsd/version.rb @@ -0,0 +1,5 @@ +module Airbrake + module Statsd + VERSION = "0.0.1" + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..d34b5fe --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,10 @@ +require 'rspec' +require 'rspec/autorun' + +require 'simplecov' +SimpleCov.start do + add_filter 'spec' + add_filter 'vendor' +end + +require 'airbrake-statsd' diff --git a/spec/unit/airbrake-statsd/airbrake_ext_spec.rb b/spec/unit/airbrake-statsd/airbrake_ext_spec.rb new file mode 100644 index 0000000..d8179ac --- /dev/null +++ b/spec/unit/airbrake-statsd/airbrake_ext_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +describe Airbrake do + + subject { Airbrake } + + it '#notify is an alias to #notify_with_statsd' do + subject.method(:notify).should == subject.method(:notify_with_statds) + end + + describe '#notify_without_statsd' do + + it 'does not call Airbrake::Statsd.increment' do + Airbrake.stub(:send_notice).and_return(nil) + + Airbrake.should_receive(:build_notice_for).with('oops', {}) + Airbrake::Statsd.should_not_receive(:increment) + + Airbrake.notify_without_statsd('oops', {}) + end + end + + describe '#notify' do + it 'calls Airbrake::Statsd.increment' do + Airbrake.stub(:send_notice).and_return(nil) + + Airbrake.should_receive(:build_notice_for).with('oops', {}) + Airbrake::Statsd.should_receive(:increment) + + Airbrake.notify('oops', {}) + end + end + +end diff --git a/spec/unit/airbrake-statsd/configuration_spec.rb b/spec/unit/airbrake-statsd/configuration_spec.rb new file mode 100644 index 0000000..b9cdd3b --- /dev/null +++ b/spec/unit/airbrake-statsd/configuration_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +module Airbrake + module Statsd + describe Configuration do + + describe '`host` option' do + it 'defaults to "localhost"' do + subject.host.should == 'localhost' + end + + it 'can be set' do + subject.host = 'not-default.com' + subject.host.should == 'not-default.com' + end + end + + describe '`port` option' do + it 'defaults to 8125' do + subject.port.should == 8125 + end + + it 'can be set' do + subject.port = 88125 + subject.port.should == 88125 + end + end + + describe '`namespace` option' do + it 'defaults to "nil"' do + subject.namespace.should be_nil + end + + it 'can be set' do + subject.namespace = 'my_awesome_app' + subject.namespace.should == 'my_awesome_app' + end + end + + end + end +end diff --git a/spec/unit/airbrake-statsd_spec.rb b/spec/unit/airbrake-statsd_spec.rb new file mode 100644 index 0000000..450fcb1 --- /dev/null +++ b/spec/unit/airbrake-statsd_spec.rb @@ -0,0 +1,72 @@ +require 'spec_helper' + +module Airbrake + describe Statsd do + + subject { Statsd } + + before do + subject.instance_variable_set('@configured', nil) + subject.instance_variable_set('@config', nil) + subject.instance_variable_set('@client', nil) + end + + describe '#configured?' do + context 'when #configure has been called' do + it 'returns true' do + subject.configure + subject.configured?.should be_true + end + end # configure called + + context 'when #configure has not been called' do + it 'returns false' do + subject.configured?.should be_false + end + end # configure not called + end # configured? + + describe '#config' do + it 'creates new Configuration instance if not set' do + subject.config.should be_a(Statsd::Configuration) + end + end + + describe '#client' do + it 'creates a new ::Statsd client instance if not set' do + subject.config.should_receive(:host).once.and_return('testhost') + subject.config.should_receive(:port).once.and_return(1234) + ::Statsd.should_receive(:new).with('testhost', 1234) + subject.client + end + + context 'when a namespace is set in #config instance' do + before do + subject.configure { |config| config.namespace = 'test' } + end + + it 'sets namespace on client' do + ::Statsd.any_instance.should_receive(:namespace=).with('test').once + subject.client + end + end + end + + describe '#increment' do + context 'when #configure has been called' do + before { subject.configure } + + it 'calls #increment on #client instance' do + subject.client.should_receive(:increment).once + subject.increment + end + + it 'default bucket name used is "exceptions"' do + subject.client.should_receive(:increment).with('exceptions').once + subject.increment + end + end # configure called + end # increment + + end +end