Skip to content

Commit

Permalink
Refactored: Rake to use Datadog::Contrib::Integration. (#554)
Browse files Browse the repository at this point in the history
  • Loading branch information
delner authored Sep 26, 2018
1 parent 16d9782 commit 611bcdd
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 67 deletions.
2 changes: 1 addition & 1 deletion lib/ddtrace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def configure(target = configuration, opts = {})
require 'ddtrace/contrib/racecar/integration'
require 'ddtrace/contrib/rack/integration'
require 'ddtrace/contrib/rails/integration'
require 'ddtrace/contrib/rake/patcher'
require 'ddtrace/contrib/rake/integration'
require 'ddtrace/contrib/redis/patcher'
require 'ddtrace/contrib/resque/integration'
require 'ddtrace/contrib/rest_client/integration'
Expand Down
18 changes: 18 additions & 0 deletions lib/ddtrace/contrib/rake/configuration/settings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
require 'ddtrace/contrib/configuration/settings'
require 'ddtrace/contrib/rake/ext'

module Datadog
module Contrib
module Rake
module Configuration
# Custom settings for the Rake integration
class Settings < Contrib::Configuration::Settings
option :service_name, default: Ext::SERVICE_NAME
option :tracer, default: Datadog.tracer
option :enabled, default: true
option :quantize, default: {}
end
end
end
end
end
18 changes: 18 additions & 0 deletions lib/ddtrace/contrib/rake/ext.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module Datadog
module Contrib
module Rake
# Rake integration constants
module Ext
APP = 'rake'.freeze
SERVICE_NAME = 'rake'.freeze

SPAN_INVOKE = 'rake.invoke'.freeze
SPAN_EXECUTE = 'rake.execute'.freeze

TAG_EXECUTE_ARGS = 'rake.execute.args'.freeze
TAG_INVOKE_ARGS = 'rake.invoke.args'.freeze
TAG_TASK_ARG_NAMES = 'rake.task.arg_names'.freeze
end
end
end
end
15 changes: 7 additions & 8 deletions lib/ddtrace/contrib/rake/instrumentation.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
require 'ddtrace/contrib/rake/ext'

module Datadog
module Contrib
module Rake
# Instrumentation for Rake tasks
module Instrumentation
SPAN_NAME_INVOKE = 'rake.invoke'.freeze
SPAN_NAME_EXECUTE = 'rake.execute'.freeze

def self.included(base)
base.send(:prepend, InstanceMethods)
end
Expand All @@ -15,7 +14,7 @@ module InstanceMethods
def invoke(*args)
return super unless enabled?

tracer.trace(SPAN_NAME_INVOKE, span_options) do |span|
tracer.trace(Ext::SPAN_INVOKE, span_options) do |span|
super
annotate_invoke!(span, args)
end
Expand All @@ -26,7 +25,7 @@ def invoke(*args)
def execute(args = nil)
return super unless enabled?

tracer.trace(SPAN_NAME_EXECUTE, span_options) do |span|
tracer.trace(Ext::SPAN_EXECUTE, span_options) do |span|
super
annotate_execute!(span, args)
end
Expand All @@ -42,15 +41,15 @@ def shutdown_tracer!

def annotate_invoke!(span, args)
span.resource = name
span.set_tag('rake.task.arg_names', arg_names)
span.set_tag('rake.invoke.args', quantize_args(args)) unless args.nil?
span.set_tag(Ext::TAG_TASK_ARG_NAMES, arg_names)
span.set_tag(Ext::TAG_INVOKE_ARGS, quantize_args(args)) unless args.nil?
rescue StandardError => e
Datadog::Tracer.log.debug("Error while tracing Rake invoke: #{e.message}")
end

def annotate_execute!(span, args)
span.resource = name
span.set_tag('rake.execute.args', quantize_args(args.to_hash)) unless args.nil?
span.set_tag(Ext::TAG_EXECUTE_ARGS, quantize_args(args.to_hash)) unless args.nil?
rescue StandardError => e
Datadog::Tracer.log.debug("Error while tracing Rake execute: #{e.message}")
end
Expand Down
36 changes: 36 additions & 0 deletions lib/ddtrace/contrib/rake/integration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require 'ddtrace/contrib/integration'
require 'ddtrace/contrib/rake/configuration/settings'
require 'ddtrace/contrib/rake/patcher'

module Datadog
module Contrib
module Rake
# Description of Rake integration
class Integration
include Contrib::Integration

register_as :rake

def self.version
Gem.loaded_specs['rake'] && Gem.loaded_specs['rake'].version
end

def self.present?
super && defined?(::Rake)
end

def self.compatible?
super && RUBY_VERSION >= '2.0.0'
end

def default_configuration
Configuration::Settings.new
end

def patcher
Patcher
end
end
end
end
end
56 changes: 23 additions & 33 deletions lib/ddtrace/contrib/rake/patcher.rb
Original file line number Diff line number Diff line change
@@ -1,51 +1,41 @@
require 'ddtrace/contrib/patcher'
require 'ddtrace/ext/app_types'
require 'ddtrace/contrib/rake/ext'
require 'ddtrace/contrib/rake/instrumentation'

module Datadog
module Contrib
module Rake
# Patcher for Rake instrumentation
# Patcher enables patching of 'rake' module.
module Patcher
include Base

register_as :rake
option :service_name, default: 'rake'
option :tracer, default: Datadog.tracer
option :enabled, default: true
option :quantize, default: {}
include Contrib::Patcher

module_function

def patch
return patched? if patched? || !compatible?

patch_rake

# Set service info
configuration[:tracer].set_service_info(
configuration[:service_name],
'rake',
Ext::AppTypes::WORKER
)

@patched = true
end

def patched?
return @patched if defined?(@patched)
@patched = false
done?(:rake)
end

def patch_rake
::Rake::Task.send(:include, Instrumentation)
end

def compatible?
RUBY_VERSION >= '2.0.0' && defined?(::Rake)
def patch
do_once(:rake) do
begin
# Add instrumentation patch to Rake task
::Rake::Task.send(:include, Instrumentation)

# Set service info
get_option(:tracer).set_service_info(
get_option(:service_name),
Ext::APP,
Datadog::Ext::AppTypes::WORKER
)
rescue StandardError => e
Datadog::Tracer.log.error("Unable to apply Rake integration: #{e}")
end
end
end

def configuration
Datadog.configuration[:rake]
def get_option(option)
Datadog.configuration[:rake].get_option(option)
end
end
end
Expand Down
52 changes: 27 additions & 25 deletions spec/ddtrace/contrib/rake/instrumentation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
let(:span) { spans.first }

before(:each) do
skip('Rake integration incompatible.') unless Datadog::Contrib::Rake::Patcher.compatible?
skip('Rake integration incompatible.') unless Datadog::Contrib::Rake::Integration.compatible?

# Reset options (that might linger from other tests)
Datadog.configuration[:rake].reset_options!
Expand Down Expand Up @@ -74,24 +74,24 @@ def reset_task!(task_name)
task.invoke(*args)
end

let(:invoke_span) { spans.find { |s| s.name == described_class::SPAN_NAME_INVOKE } }
let(:execute_span) { spans.find { |s| s.name == described_class::SPAN_NAME_EXECUTE } }
let(:invoke_span) { spans.find { |s| s.name == Datadog::Contrib::Rake::Ext::SPAN_INVOKE } }
let(:execute_span) { spans.find { |s| s.name == Datadog::Contrib::Rake::Ext::SPAN_EXECUTE } }

it do
expect(spans).to have(2).items
end

describe '\'rake.invoke\' span' do
it do
expect(invoke_span.name).to eq(described_class::SPAN_NAME_INVOKE)
expect(invoke_span.name).to eq(Datadog::Contrib::Rake::Ext::SPAN_INVOKE)
expect(invoke_span.resource).to eq(task_name.to_s)
expect(invoke_span.parent_id).to eq(0)
end
end

describe '\'rake.execute\' span' do
it do
expect(execute_span.name).to eq(described_class::SPAN_NAME_EXECUTE)
expect(execute_span.name).to eq(Datadog::Contrib::Rake::Ext::SPAN_EXECUTE)
expect(execute_span.resource).to eq(task_name.to_s)
expect(execute_span.parent_id).to eq(invoke_span.span_id)
end
Expand Down Expand Up @@ -124,15 +124,15 @@ def reset_task!(task_name)
it_behaves_like 'a single task execution' do
describe '\'rake.invoke\' span tags' do
it do
expect(invoke_span.get_tag('rake.task.arg_names')).to eq([].to_s)
expect(invoke_span.get_tag('rake.invoke.args')).to eq(['?'].to_s)
expect(invoke_span.get_tag(Datadog::Contrib::Rake::Ext::TAG_TASK_ARG_NAMES)).to eq([].to_s)
expect(invoke_span.get_tag(Datadog::Contrib::Rake::Ext::TAG_INVOKE_ARGS)).to eq(['?'].to_s)
end
end

describe '\'rake.execute\' span tags' do
it do
expect(execute_span.get_tag('rake.task.arg_names')).to be nil
expect(execute_span.get_tag('rake.execute.args')).to eq({}.to_s)
expect(execute_span.get_tag(Datadog::Contrib::Rake::Ext::TAG_TASK_ARG_NAMES)).to be nil
expect(execute_span.get_tag(Datadog::Contrib::Rake::Ext::TAG_EXECUTE_ARGS)).to eq({}.to_s)
end
end
end
Expand All @@ -144,15 +144,17 @@ def reset_task!(task_name)
it_behaves_like 'a single task execution' do
describe '\'rake.invoke\' span tags' do
it do
expect(invoke_span.get_tag('rake.task.arg_names')).to eq([:one, :two, :three].to_s)
expect(invoke_span.get_tag('rake.invoke.args')).to eq(['?'].to_s)
expect(invoke_span.get_tag(Datadog::Contrib::Rake::Ext::TAG_TASK_ARG_NAMES)).to eq([:one, :two, :three].to_s)
expect(invoke_span.get_tag(Datadog::Contrib::Rake::Ext::TAG_INVOKE_ARGS)).to eq(['?'].to_s)
end
end

describe '\'rake.execute\' span tags' do
it do
expect(execute_span.get_tag('rake.arg_names')).to be nil
expect(execute_span.get_tag('rake.execute.args')).to eq({ one: '?', two: '?', three: '?' }.to_s)
expect(execute_span.get_tag(Datadog::Contrib::Rake::Ext::TAG_TASK_ARG_NAMES)).to be nil
expect(execute_span.get_tag(Datadog::Contrib::Rake::Ext::TAG_EXECUTE_ARGS)).to eq(
{ one: '?', two: '?', three: '?' }.to_s
)
end
end
end
Expand Down Expand Up @@ -189,16 +191,16 @@ def reset_task!(task_name)
task.invoke(*args)
end

let(:invoke_span) { spans.find { |s| s.name == described_class::SPAN_NAME_INVOKE } }
let(:invoke_span) { spans.find { |s| s.name == Datadog::Contrib::Rake::Ext::SPAN_INVOKE } }
let(:prerequisite_task_execute_span) do
spans.find do |s|
s.name == described_class::SPAN_NAME_EXECUTE \
s.name == Datadog::Contrib::Rake::Ext::SPAN_EXECUTE \
&& s.resource == prerequisite_task_name.to_s
end
end
let(:task_execute_span) do
spans.find do |s|
s.name == described_class::SPAN_NAME_EXECUTE \
s.name == Datadog::Contrib::Rake::Ext::SPAN_EXECUTE \
&& s.resource == task_name.to_s
end
end
Expand All @@ -209,31 +211,31 @@ def reset_task!(task_name)

describe '\'rake.invoke\' span' do
it do
expect(invoke_span.name).to eq(described_class::SPAN_NAME_INVOKE)
expect(invoke_span.name).to eq(Datadog::Contrib::Rake::Ext::SPAN_INVOKE)
expect(invoke_span.resource).to eq(task_name.to_s)
expect(invoke_span.parent_id).to eq(0)
expect(invoke_span.get_tag('rake.task.arg_names')).to eq([].to_s)
expect(invoke_span.get_tag('rake.invoke.args')).to eq(['?'].to_s)
expect(invoke_span.get_tag(Datadog::Contrib::Rake::Ext::TAG_TASK_ARG_NAMES)).to eq([].to_s)
expect(invoke_span.get_tag(Datadog::Contrib::Rake::Ext::TAG_INVOKE_ARGS)).to eq(['?'].to_s)
end
end

describe 'prerequisite \'rake.execute\' span' do
it do
expect(prerequisite_task_execute_span.name).to eq(described_class::SPAN_NAME_EXECUTE)
expect(prerequisite_task_execute_span.name).to eq(Datadog::Contrib::Rake::Ext::SPAN_EXECUTE)
expect(prerequisite_task_execute_span.resource).to eq(prerequisite_task_name.to_s)
expect(prerequisite_task_execute_span.parent_id).to eq(invoke_span.span_id)
expect(prerequisite_task_execute_span.get_tag('rake.task.arg_names')).to be nil
expect(prerequisite_task_execute_span.get_tag('rake.execute.args')).to eq({}.to_s)
expect(prerequisite_task_execute_span.get_tag(Datadog::Contrib::Rake::Ext::TAG_TASK_ARG_NAMES)).to be nil
expect(prerequisite_task_execute_span.get_tag(Datadog::Contrib::Rake::Ext::TAG_EXECUTE_ARGS)).to eq({}.to_s)
end
end

describe 'task \'rake.execute\' span' do
it do
expect(task_execute_span.name).to eq(described_class::SPAN_NAME_EXECUTE)
expect(task_execute_span.name).to eq(Datadog::Contrib::Rake::Ext::SPAN_EXECUTE)
expect(task_execute_span.resource).to eq(task_name.to_s)
expect(task_execute_span.parent_id).to eq(invoke_span.span_id)
expect(task_execute_span.get_tag('rake.task.arg_names')).to be nil
expect(task_execute_span.get_tag('rake.execute.args')).to eq({}.to_s)
expect(task_execute_span.get_tag(Datadog::Contrib::Rake::Ext::TAG_TASK_ARG_NAMES)).to be nil
expect(task_execute_span.get_tag(Datadog::Contrib::Rake::Ext::TAG_EXECUTE_ARGS)).to eq({}.to_s)
end
end
end
Expand Down

0 comments on commit 611bcdd

Please sign in to comment.