datadog-notifications 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fadcae3b1ef25818ba7aa40d9da48019e1ce3f40
4
+ data.tar.gz: b64e1b4672ed2cfaea03590f1ba4fd7e1e6e2d1e
5
+ SHA512:
6
+ metadata.gz: b4fb5671f2f94651db09531be28a407eddb4ab75cbcc8ccf36639fd01d40acd4eec2c335d4cd365c5611531c688b742b34871b73014440272c759ce894e4e505
7
+ data.tar.gz: a7ae41851bfbbb16463b6f73d92f3e548147d22691819e6afd7416edb33a7669f501dba35ef268c3f7797f199ac41fdcb70fe4faaabbd8487653ab166d7be98d
@@ -0,0 +1,9 @@
1
+ root = true
2
+
3
+ [*]
4
+ indent_style = space
5
+ indent_size = 2
6
+ end_of_line = lf
7
+ charset = utf-8
8
+ trim_trailing_whitespace = true
9
+ insert_final_newline = true
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
4
+ - 2.1.1
5
+ - 2.0.0
6
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Black Square Media
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,34 @@
1
+ datadog-notifications
2
+ =====================
3
+
4
+ Datadog intrumentation for [ActiveSupport::Notifications](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html).
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'datadog-notifications'
11
+
12
+ Or install:
13
+
14
+ $ gem install datadog-notifications
15
+
16
+ Configure it in an initializer:
17
+
18
+ Datadog::Notifications.configure do |c|
19
+ c.hostname = "my-host"
20
+ c.tags = ["my:tag"]
21
+
22
+ c.use Datadog::Notifications::Plugins::ActionController
23
+ c.use Datadog::Notifications::Plugins::ActiveRecord, tags: ["more:tags"]
24
+ end
25
+
26
+ For full configuration options, please see the [Documentation](http://www.rubydoc.info/gems/datadog-notifications).
27
+
28
+ ## Contributing
29
+
30
+ 1. Fork it
31
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
32
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
33
+ 4. Push to the branch (`git push origin my-new-feature`)
34
+ 5. Make a pull request
@@ -0,0 +1,20 @@
1
+ require "bundler/gem_tasks"
2
+
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
+
11
+ require 'rake'
12
+
13
+ require 'rspec/core'
14
+ require 'rspec/core/rake_task'
15
+
16
+ RSpec::Core::RakeTask.new(:spec) do |spec|
17
+ spec.pattern = FileList['spec/**/*_spec.rb']
18
+ end
19
+
20
+ task :default => :spec
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'datadog/notifications/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "datadog-notifications"
8
+ s.version = Datadog::Notifications::VERSION.dup
9
+ s.authors = ["Dimitrij Denissenko"]
10
+ s.email = ["dimitrij@blacksquaremedia.com"]
11
+ s.description = %q{Datadog instrumnetation for ActiveSupport::Notifications}
12
+ s.summary = %q{Generic ActiveSupport::Notifications Datadog handler}
13
+ s.homepage = "https://github.com/bsm/datadog-notifications"
14
+
15
+ s.files = `git ls-files`.split($/)
16
+ s.test_files = s.files.grep(%r{^(spec)/})
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_runtime_dependency(%q<activesupport>)
20
+ s.add_runtime_dependency(%q<dogstatsd-ruby>)
21
+
22
+ s.add_development_dependency(%q<rack-test>)
23
+ s.add_development_dependency(%q<grape>)
24
+ s.add_development_dependency(%q<sqlite3>)
25
+ s.add_development_dependency(%q<activerecord>)
26
+ s.add_development_dependency(%q<rake>)
27
+ s.add_development_dependency(%q<bundler>)
28
+ s.add_development_dependency(%q<rspec>)
29
+ end
@@ -0,0 +1 @@
1
+ require "datadog/notifications"
@@ -0,0 +1,77 @@
1
+ require 'statsd'
2
+ require 'socket'
3
+ require 'singleton'
4
+ require 'active_support/notifications'
5
+ require 'active_support/core_ext/string/inflections'
6
+
7
+ require 'datadog/notifications/version'
8
+ require 'datadog/notifications/reporter'
9
+ require 'datadog/notifications/config'
10
+ require 'datadog/notifications/plugins'
11
+
12
+ module Datadog
13
+ class Notifications
14
+ include Singleton
15
+
16
+ # Configure and install datadog instrumentation. Example:
17
+ #
18
+ # Datadog::Notifications.configure do |c|
19
+ # c.hostname = "my-host"
20
+ # c.tags = ["app:mine"]
21
+ #
22
+ # c.use Datadog::Notifications::Plugins::Grape, metric_name: "api.request", tags: ["grape:specific"]
23
+ # end
24
+ #
25
+ # Settings:
26
+ # * <tt>hostname</tt> - the hostname used for instrumentation, defaults to system hostname, respects +INSTRUMENTATION_HOSTNAME+ env variable
27
+ # * <tt>namespace</tt> - set a namespace to be prepended to every metric name
28
+ # * <tt>tags</tt> - set an array of tags to be added to every metric
29
+ # * <tt>statsd_host</tt> - the statsD host, defaults to "localhost", respects +STATSD_HOST+ env variable
30
+ # * <tt>statsd_port</tt> - the statsD port, defaults to 8125, respects +STATSD_PORT+ env variable
31
+ # * <tt>reporter</tt> - custom reporter class, defaults to `Datadog::Notifications::Reporter`
32
+ def self.configure(&block)
33
+ if instance.instance_variable_defined?(:@reporter)
34
+ warn "#{self.name} cannot be reconfigured once it has subscribed to notifications, called from: #{caller[1]}"
35
+ return
36
+ end
37
+ block.call instance.config if block
38
+ end
39
+
40
+ # You can subscribe to events exactly as with ActiveSupport::Notifications, but there will be an
41
+ # additional `statsd` block parameter available:
42
+ #
43
+ # Datadog::Notifications.subscribe('render') do |reporter, event|
44
+ # reporter # => Reporter instance
45
+ # event # => ActiveSupport::Notifications::Event object
46
+ # end
47
+ #
48
+ # Example:
49
+ #
50
+ # Datadog::Notifications.subscribe('render') do |reporter, _, start, finish, _, payload|
51
+ # status = payload[:status]
52
+ # reporter.seconds('myapp.render', finish-start, tags: ["status:#{status}"])
53
+ # end
54
+ #
55
+ def self.subscribe(pattern, &block)
56
+ instance.subscribe(pattern, &block)
57
+ end
58
+
59
+ attr_reader :config
60
+
61
+ def initialize
62
+ @config = Config.new
63
+ end
64
+
65
+ def subscribe(pattern, &block)
66
+ ActiveSupport::Notifications.subscribe(pattern) do |*args|
67
+ block.call reporter, ActiveSupport::Notifications::Event.new(*args)
68
+ end
69
+ end
70
+
71
+ def reporter
72
+ @reporter ||= config.send(:connect!)
73
+ end
74
+ private :reporter
75
+
76
+ end
77
+ end
@@ -0,0 +1,35 @@
1
+ module Datadog
2
+ class Notifications
3
+ class Config
4
+ attr_accessor :hostname, :namespace, :tags, :statsd_host, :statsd_port, :reporter
5
+
6
+ def initialize
7
+ @hostname = ENV['INSTRUMENTATION_HOSTNAME'] || Socket.gethostname
8
+ @statsd_host = ENV['STATSD_HOST'] || ::Statsd::DEFAULT_HOST
9
+ @statsd_port = (ENV['STATSD_PORT'] || ::Statsd::DEFAULT_PORT).to_i
10
+ @reporter = Datadog::Notifications::Reporter
11
+ @tags = []
12
+ @plugins = []
13
+ end
14
+
15
+ # Use a plugin
16
+ def use(klass, opts = {})
17
+ @plugins.push [klass, opts]
18
+ end
19
+
20
+ def connect!
21
+ @plugins.each do |klass, opts|
22
+ klass.new(opts)
23
+ end
24
+
25
+ env = ENV['RACK_ENV'] || ENV['RAILS_ENV']
26
+ tags.push("env:#{env}") if env && tags.none? {|t| t =~ /^env\:/ }
27
+ tags.push("host:#{hostname}") if tags.none? {|t| t =~ /^host\:/ }
28
+
29
+ reporter.new statsd_host, statsd_port, namespace: namespace, tags: tags
30
+ end
31
+ protected :connect!
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,10 @@
1
+ module Datadog
2
+ class Notifications
3
+ module Plugins
4
+ end
5
+ end
6
+ end
7
+
8
+ %w|base grape active_record active_job action_controller|.each do |name|
9
+ require "datadog/notifications/plugins/#{name}"
10
+ end
@@ -0,0 +1,39 @@
1
+ module Datadog::Notifications::Plugins
2
+ class ActionController < Base
3
+
4
+ attr_reader :metric_name
5
+
6
+ # Options:
7
+ #
8
+ # *<tt>:metric_name</tt> - the metric name, defaults to "rails.request"
9
+ # *<tt>:tags</tt> - additional tags
10
+ def initialize(opts = {})
11
+ super
12
+ @metric_name = opts[:metric_name] || "rails.request"
13
+
14
+ Datadog::Notifications.subscribe 'process_action.action_controller' do |reporter, event|
15
+ record reporter, event
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def record(reporter, event)
22
+ payload = event.payload
23
+ method = payload[:method].downcase
24
+ status = payload[:status]
25
+ action = payload[:action]
26
+ ctrl = payload[:controller].sub(/Controller$/, '').underscore
27
+ format = payload[:format]
28
+ tags = self.tags + %W|method:#{method} status:#{status} action:#{action} controller:#{ctrl} format:#{format}|
29
+
30
+ reporter.batch do
31
+ reporter.increment metric_name, tags: tags
32
+ reporter.timing "#{metric_name}.time", event.duration, tags: tags
33
+ reporter.timing "#{metric_name}.time.db", to_millis(payload[:db_runtime]), tags: tags
34
+ reporter.timing "#{metric_name}.time.view", to_millis(payload[:view_runtime]), tags: tags
35
+ end
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,33 @@
1
+ module Datadog::Notifications::Plugins
2
+ class ActiveJob < Base
3
+
4
+ attr_reader :metric_name
5
+
6
+ # Options:
7
+ #
8
+ # *<tt>:metric_name</tt> - the metric name, defaults to "activejob.perform"
9
+ # *<tt>:tags</tt> - additional tags
10
+ def initialize(opts = {})
11
+ super
12
+ @metric_name = opts[:metric_name] || "activejob.perform"
13
+
14
+ Datadog::Notifications.subscribe 'perform.active_job' do |reporter, event|
15
+ record reporter, event
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def record(reporter, event)
22
+ job = event.payload[:job]
23
+ name = job.class.name.sub(/Job$/, '').underscore
24
+ tags = self.tags + %W|name:#{name} queue:#{job.queue_name}|
25
+
26
+ reporter.batch do
27
+ reporter.increment metric_name, tags: tags
28
+ reporter.timing "#{metric_name}.time", event.duration, tags: tags
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,43 @@
1
+ module Datadog::Notifications::Plugins
2
+ class ActiveRecord < Base
3
+
4
+ attr_reader :metric_name
5
+
6
+ # Options:
7
+ #
8
+ # *<tt>:metric_name</tt> - the metric name, defaults to "activerecord.query"
9
+ # *<tt>:include_schema</tt> - record schema queries, off by default
10
+ # *<tt>:include_generic</tt> - record general (nameless) queries, off by default
11
+ # *<tt>:tags</tt> - additional tags
12
+ def initialize(opts = {})
13
+ super
14
+ @metric_name = opts[:metric_name] || "activerecord.sql"
15
+ @include_schema = opts[:include_schema] == true
16
+ @include_generic = opts[:include_generic] == true
17
+ @include_raw = opts[:include_raw] == true
18
+
19
+ Datadog::Notifications.subscribe 'sql.active_record' do |reporter, event|
20
+ record reporter, event
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def record(reporter, event)
27
+ payload = event.payload
28
+ name = payload[:name]
29
+ return if (name.nil? || name == "SQL") && !@include_generic
30
+ return if name == "SCHEMA" && !@include_schema
31
+
32
+ name = name.downcase.split(/\W/).join(".") if name
33
+ tags = self.tags.dup
34
+ tags.push "query:#{name}" if name
35
+
36
+ reporter.batch do
37
+ reporter.increment metric_name, tags: tags
38
+ reporter.timing "#{metric_name}.time", event.duration, tags: tags
39
+ end
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,13 @@
1
+ module Datadog::Notifications::Plugins
2
+ class Base
3
+ attr_reader :tags
4
+
5
+ # Options:
6
+ #
7
+ # *<tt>:tags</tt> - additional tags
8
+ def initialize(opts = {})
9
+ @tags = opts[:tags] || []
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,43 @@
1
+ module Datadog::Notifications::Plugins
2
+ class Grape < Base
3
+
4
+ attr_reader :metric_name
5
+
6
+ # Options:
7
+ #
8
+ # *<tt>:metric_name</tt> - the metric name, defaults to "grape.request"
9
+ # *<tt>:tags</tt> - additional tags
10
+ def initialize(opts = {})
11
+ super
12
+ @metric_name = opts[:metric_name] || "grape.request"
13
+
14
+ Datadog::Notifications.subscribe 'endpoint_run.grape' do |reporter, event|
15
+ record reporter, event
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def record(reporter, event)
22
+ payload = event.payload
23
+ endpoint = payload[:endpoint]
24
+ route = endpoint.route
25
+ version = route.route_version
26
+ method = route.route_method
27
+
28
+ path = route.route_path
29
+ path.sub!("(.:format)", "")
30
+ path.sub!(":version/", "") if version
31
+ path.gsub!(/\(?:(\w+)\)?/) {|m| "_#{m[1..-1]}_" }
32
+
33
+ tags = self.tags + %W|method:#{method} path:#{path} status:#{endpoint.status}|
34
+ tags.push "version:#{version}" if version
35
+
36
+ reporter.batch do
37
+ reporter.increment metric_name, tags: tags
38
+ reporter.timing "#{metric_name}.time", event.duration, tags: tags
39
+ end
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,6 @@
1
+ module Datadog
2
+ class Notifications
3
+ class Reporter < ::Statsd
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Datadog
2
+ class Notifications
3
+ VERSION = "0.3.0"
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Datadog::Notifications::Config do
4
+
5
+ it 'should be connect!' do
6
+ subject.reporter = Mock::Reporter
7
+ subject.hostname = "test.host"
8
+ subject.tags = ["custom:tag"]
9
+
10
+ client = subject.send(:connect!)
11
+ expect(client).to be_instance_of(Mock::Reporter)
12
+ expect(subject.tags).to eq(["custom:tag", "env:test", "host:test.host"])
13
+ end
14
+
15
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Datadog::Notifications::Plugins::ActiveRecord do
4
+
5
+ it 'should send an increment and timing event for each query' do
6
+ Post.all.to_a
7
+ expect(buffered).to eq([
8
+ "activerecord.sql:1|c|#custom:tag,env:test,host:test.host,query:post.load",
9
+ "activerecord.sql.time:333|ms|#custom:tag,env:test,host:test.host,query:post.load",
10
+ ])
11
+ end
12
+
13
+ it 'should skip unnamed by default' do
14
+ Post.create!(title: "Hello!")
15
+ expect(buffered).to eq([])
16
+ end
17
+
18
+ it 'should support custom queries' do
19
+ Post.find_by_sql("SELECT * FROM posts LIMIT 1").to_a
20
+ expect(buffered).to eq([
21
+ "activerecord.sql:1|c|#custom:tag,env:test,host:test.host,query:post.load",
22
+ "activerecord.sql.time:333|ms|#custom:tag,env:test,host:test.host,query:post.load",
23
+ ])
24
+ end
25
+
26
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ describe Datadog::Notifications::Plugins::Grape do
4
+ include Rack::Test::Methods
5
+
6
+ let(:app) do
7
+ sub_api = Class.new(Grape::API) do
8
+ version 'v1'
9
+ prefix 'api'
10
+
11
+ get('versioned') { "OK" }
12
+ end
13
+
14
+ Class.new(Grape::API) do
15
+ get 'echo/:key1/:key2' do
16
+ "#{params['key1']} #{params['key2']}"
17
+ end
18
+
19
+ namespace :sub do
20
+ mount sub_api
21
+
22
+ namespace :secure do
23
+ get("/resource") { error!("forbidden", 403) }
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ it 'should send an increment and timing event for each request' do
30
+ get '/echo/1/1234'
31
+ expect(last_response.status).to eq(200)
32
+ expect(last_response.body).to eq('1 1234')
33
+
34
+ expect(buffered).to eq([
35
+ "api.request:1|c|#custom:tag,env:test,host:test.host,more:tags,method:GET,path:/echo/_key1_/_key2_,status:200",
36
+ "api.request.time:333|ms|#custom:tag,env:test,host:test.host,more:tags,method:GET,path:/echo/_key1_/_key2_,status:200",
37
+ ])
38
+ end
39
+
40
+ it 'should support namespaces and versioning' do
41
+ get '/api/v1/sub/versioned'
42
+ expect(last_response.status).to eq(200)
43
+ expect(last_response.body).to eq('OK')
44
+
45
+ expect(buffered).to eq([
46
+ "api.request:1|c|#custom:tag,env:test,host:test.host,more:tags,method:GET,path:/api/sub/versioned,status:200,version:v1",
47
+ "api.request.time:333|ms|#custom:tag,env:test,host:test.host,more:tags,method:GET,path:/api/sub/versioned,status:200,version:v1",
48
+ ])
49
+ end
50
+
51
+ it 'should support deep nesting' do
52
+ get '/sub/secure/resource'
53
+ expect(last_response.status).to eq(403)
54
+ expect(last_response.body).to eq('forbidden')
55
+
56
+ expect(buffered).to eq([
57
+ "api.request:1|c|#custom:tag,env:test,host:test.host,more:tags,method:GET,path:/sub/secure/resource,status:403",
58
+ "api.request.time:333|ms|#custom:tag,env:test,host:test.host,more:tags,method:GET,path:/sub/secure/resource,status:403",
59
+ ])
60
+ end
61
+
62
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe Datadog::Notifications do
4
+
5
+ subject { described_class.instance }
6
+ after { ActiveSupport::Notifications.unsubscribe(subscription) }
7
+
8
+ let!(:subscription) do
9
+ subject.subscribe("mock.perform") do |reporter, event|
10
+ status = event.payload[:status]
11
+ method = event.payload[:method]
12
+ tags = ["status:#{status}", "method:#{method}"]
13
+
14
+ reporter.batch do
15
+ reporter.increment "web.render", tags: tags
16
+ reporter.timing "web.render.time", event.duration, tags: tags
17
+ end
18
+ end
19
+ end
20
+
21
+ it 'should have a reporter' do
22
+ expect(subject.send(:reporter)).to be_instance_of(Mock::Reporter)
23
+ end
24
+
25
+ it 'should subscribe and report' do
26
+ Mock::Instrumentable.new(method: 'GET').perform
27
+ expect(buffered).to eq([
28
+ "web.render:1|c|#custom:tag,env:test,host:test.host,status:200,method:GET",
29
+ "web.render.time:333|ms|#custom:tag,env:test,host:test.host,status:200,method:GET",
30
+ ])
31
+ end
32
+
33
+ end
@@ -0,0 +1,66 @@
1
+ ENV['RACK_ENV'] ||= 'test'
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+
4
+ require 'datadog-notifications'
5
+ require 'rspec'
6
+ require 'rack/test'
7
+ require 'grape'
8
+ require 'active_record'
9
+ require 'sqlite3'
10
+
11
+ ### Active-record test preparation
12
+
13
+ ActiveRecord::Base.configurations["test"] = { 'adapter' => 'sqlite3', 'database' => ':memory:' }
14
+ ActiveRecord::Base.establish_connection(:test)
15
+ ActiveRecord::Base.connection.create_table :posts do |t|
16
+ t.string :title
17
+ end
18
+ class Post < ActiveRecord::Base
19
+ end
20
+
21
+ ### Mocks
22
+
23
+ module Mock
24
+ class Reporter < Datadog::Notifications::Reporter
25
+ def timing(stat, ms, opts={}); super(stat, 333, opts); end
26
+ def flush_buffer; end
27
+ alias :send_stat :send_to_buffer
28
+ end
29
+
30
+ class Instrumentable
31
+ def initialize(opts = {})
32
+ @opts = opts
33
+ end
34
+
35
+ def perform
36
+ ActiveSupport::Notifications.instrument("mock.start", @opts)
37
+ ActiveSupport::Notifications.instrument("mock.perform", @opts) do |payload|
38
+ payload[:status] = 200
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ ### Configuration
45
+
46
+ RSpec.configure do |c|
47
+ helpers = Module.new do
48
+ def buffered
49
+ Datadog::Notifications.instance.send(:reporter).buffer
50
+ end
51
+ end
52
+
53
+ c.include helpers
54
+ c.before do
55
+ buffered.clear
56
+ end
57
+ end
58
+
59
+ Datadog::Notifications.configure do |c|
60
+ c.hostname = "test.host"
61
+ c.reporter = Mock::Reporter
62
+ c.tags = ["custom:tag"]
63
+
64
+ c.use Datadog::Notifications::Plugins::ActiveRecord
65
+ c.use Datadog::Notifications::Plugins::Grape, tags: ["more:tags"], metric_name: "api.request"
66
+ end
metadata ADDED
@@ -0,0 +1,198 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: datadog-notifications
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Dimitrij Denissenko
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: dogstatsd-ruby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rack-test
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: grape
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: activerecord
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: bundler
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: Datadog instrumnetation for ActiveSupport::Notifications
140
+ email:
141
+ - dimitrij@blacksquaremedia.com
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - ".editorconfig"
147
+ - ".gitignore"
148
+ - ".travis.yml"
149
+ - Gemfile
150
+ - MIT-LICENCE
151
+ - README.md
152
+ - Rakefile
153
+ - datadog-notifications.gemspec
154
+ - lib/datadog-notifications.rb
155
+ - lib/datadog/notifications.rb
156
+ - lib/datadog/notifications/config.rb
157
+ - lib/datadog/notifications/plugins.rb
158
+ - lib/datadog/notifications/plugins/action_controller.rb
159
+ - lib/datadog/notifications/plugins/active_job.rb
160
+ - lib/datadog/notifications/plugins/active_record.rb
161
+ - lib/datadog/notifications/plugins/base.rb
162
+ - lib/datadog/notifications/plugins/grape.rb
163
+ - lib/datadog/notifications/reporter.rb
164
+ - lib/datadog/notifications/version.rb
165
+ - spec/datadog/notifications/config_spec.rb
166
+ - spec/datadog/notifications/plugins/active_record_spec.rb
167
+ - spec/datadog/notifications/plugins/grape_spec.rb
168
+ - spec/datadog/notifications_spec.rb
169
+ - spec/spec_helper.rb
170
+ homepage: https://github.com/bsm/datadog-notifications
171
+ licenses: []
172
+ metadata: {}
173
+ post_install_message:
174
+ rdoc_options: []
175
+ require_paths:
176
+ - lib
177
+ required_ruby_version: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ required_rubygems_version: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ requirements: []
188
+ rubyforge_project:
189
+ rubygems_version: 2.4.7
190
+ signing_key:
191
+ specification_version: 4
192
+ summary: Generic ActiveSupport::Notifications Datadog handler
193
+ test_files:
194
+ - spec/datadog/notifications/config_spec.rb
195
+ - spec/datadog/notifications/plugins/active_record_spec.rb
196
+ - spec/datadog/notifications/plugins/grape_spec.rb
197
+ - spec/datadog/notifications_spec.rb
198
+ - spec/spec_helper.rb