Skip to content

Commit

Permalink
HACK: support custom error handlers for grape instrumentation (ruby-g…
Browse files Browse the repository at this point in the history
  • Loading branch information
dim committed Mar 16, 2017
1 parent e618e4c commit 138cd29
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 19 deletions.
30 changes: 15 additions & 15 deletions Gemfile.lock
Expand Up @@ -8,13 +8,13 @@ PATH
GEM
remote: https://rubygems.org/
specs:
activemodel (5.0.1)
activesupport (= 5.0.1)
activerecord (5.0.1)
activemodel (= 5.0.1)
activesupport (= 5.0.1)
activemodel (5.0.2)
activesupport (= 5.0.2)
activerecord (5.0.2)
activemodel (= 5.0.2)
activesupport (= 5.0.2)
arel (~> 7.0)
activesupport (5.0.1)
activesupport (5.0.2)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (~> 0.7)
minitest (~> 5.1)
Expand All @@ -24,16 +24,16 @@ GEM
descendants_tracker (~> 0.0.4)
ice_nine (~> 0.11.0)
thread_safe (~> 0.3, >= 0.3.1)
builder (3.2.2)
builder (3.2.3)
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
concurrent-ruby (1.0.4)
concurrent-ruby (1.0.5)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
diff-lcs (1.2.5)
diff-lcs (1.3)
dogstatsd-ruby (2.0.0)
equalizer (0.0.11)
grape (0.19.0)
grape (0.19.1)
activesupport
builder
hashie (>= 2.1.0)
Expand All @@ -43,8 +43,8 @@ GEM
rack (>= 1.3.0)
rack-accept
virtus (>= 1.0.0)
hashie (3.4.6)
i18n (0.7.0)
hashie (3.5.5)
i18n (0.8.1)
ice_nine (0.11.2)
minitest (5.10.1)
multi_json (1.12.1)
Expand Down Expand Up @@ -72,8 +72,8 @@ GEM
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.5.0)
rspec-support (3.5.0)
sqlite3 (1.3.12)
thread_safe (0.3.5)
sqlite3 (1.3.13)
thread_safe (0.3.6)
tool (0.2.3)
tzinfo (1.2.2)
thread_safe (~> 0.1)
Expand All @@ -97,4 +97,4 @@ DEPENDENCIES
sqlite3

BUNDLED WITH
1.11.2
1.14.5
11 changes: 9 additions & 2 deletions lib/datadog/notifications/plugins/grape.rb
@@ -1,15 +1,17 @@
module Datadog::Notifications::Plugins
class Grape < Base

attr_reader :metric_name
attr_reader :metric_name, :exception_handler

# Options:
#
# *<tt>:metric_name</tt> - the metric name, defaults to "grape.request"
# *<tt>:exception_handler</tt> - a custom exception handler proc which accepts an exception object and returns a status
# *<tt>:tags</tt> - additional tags
def initialize(opts = {})
super
@metric_name = opts[:metric_name] || "grape.request"
@exception_handler = opts[:exception_handler] || ->_ { 500 }

Datadog::Notifications.subscribe 'endpoint_run.grape' do |reporter, event|
record reporter, event
Expand All @@ -24,14 +26,19 @@ def record(reporter, event)
route = endpoint.route
version = route.version
method = route.request_method
status = endpoint.status

if payload[:exception_object]
status = exception_handler.call(payload[:exception_object])
end

path = route.pattern.path.dup
path.sub!(/\(\.\:format\)$/, '')
path.sub!(":version/", "") if version
path.gsub!(/:(\w+)/) {|m| m[1..-1].upcase }
path.gsub!(/[^\w\/\-]+/, '_')

tags = self.tags + %W|method:#{method} path:#{path} status:#{endpoint.status}|
tags = self.tags + %W|method:#{method} path:#{path} status:#{status}|
tags.push "version:#{version}" if version

reporter.batch do
Expand Down
2 changes: 1 addition & 1 deletion lib/datadog/notifications/version.rb
@@ -1,5 +1,5 @@
module Datadog
class Notifications
VERSION = "0.4.4"
VERSION = "0.4.5"
end
end
28 changes: 28 additions & 0 deletions spec/datadog/notifications/plugins/grape_spec.rb
Expand Up @@ -4,6 +4,8 @@
include Rack::Test::Methods

let(:app) do
unauthorized = Class.new(RuntimeError)

sub_api = Class.new(Grape::API) do
version 'v1'
prefix 'api'
Expand All @@ -12,10 +14,19 @@
end

Class.new(Grape::API) do

rescue_from unauthorized do |e|
error!({ message: "unauthorized", error: '401 Unauthorized' }, 401)
end

get 'echo/:key1/:key2' do
"#{params['key1']} #{params['key2']}"
end

get '/rescued' do
raise unauthorized.new("unauthorized")
end

namespace :sub do
mount sub_api

Expand Down Expand Up @@ -59,4 +70,21 @@
])
end

it 'should handle rescued errors' do
get '/rescued'
expect(last_response.status).to eq(401)

expect(buffered).to eq([
"api.request:1|c|#custom:tag,env:test,host:test.host,more:tags,method:GET,path:/rescued,status:401",
"api.request.time:333|ms|#custom:tag,env:test,host:test.host,more:tags,method:GET,path:/rescued,status:401",
])
end

it 'should not report paths on 404s' do
get '/sub/missing'
expect(last_response.status).to eq(404)

expect(buffered).to eq([])
end

end
5 changes: 4 additions & 1 deletion spec/spec_helper.rb
Expand Up @@ -62,5 +62,8 @@ def buffered
c.tags = ["custom:tag"]

c.use Datadog::Notifications::Plugins::ActiveRecord
c.use Datadog::Notifications::Plugins::Grape, tags: ["more:tags"], metric_name: "api.request"
c.use Datadog::Notifications::Plugins::Grape,
tags: ["more:tags"],
metric_name: "api.request",
exception_handler: ->e { e.message.include?("unauthorized") ? 401 : 500 }
end

0 comments on commit 138cd29

Please sign in to comment.