Skip to content

Commit

Permalink
add sidekiq integration
Browse files Browse the repository at this point in the history
  • Loading branch information
galdor committed Feb 24, 2017
1 parent c3a689c commit fd6d2c0
Show file tree
Hide file tree
Showing 9 changed files with 222 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,6 @@ Metrics/CyclomaticComplexity:

Metrics/PerceivedComplexity:
Max: 15

Lint/UnusedMethodArgument:
Enabled: false
1 change: 1 addition & 0 deletions Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,5 @@ appraise "contrib" do
gem "hiredis"
gem "rack-test"
gem "sinatra"
gem "sidekiq"
end
6 changes: 4 additions & 2 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require 'appraisal'
require 'yard'

namespace :test do
task all: [:main, :rails, :railsredis, :elasticsearch, :http, :redis, :sinatra, :monkey]
task all: [:main, :rails, :railsredis, :elasticsearch, :http, :redis, :sidekiq, :sinatra, :monkey]

Rake::TestTask.new(:main) do |t|
t.libs << %w(test lib)
Expand All @@ -30,7 +30,7 @@ namespace :test do
t.test_files = FileList['test/contrib/rails/**/*redis*_test.rb']
end

[:elasticsearch, :http, :redis, :sinatra].each do |contrib|
[:elasticsearch, :http, :redis, :sinatra, :sidekiq].each do |contrib|
Rake::TestTask.new(contrib) do |t|
t.libs << %w(test lib)
t.test_files = FileList["test/contrib/#{contrib}/*_test.rb"]
Expand All @@ -49,6 +49,7 @@ Rake::TestTask.new(:benchmark) do |t|
end

RuboCop::RakeTask.new(:rubocop) do |t|
t.options << ['-D']
t.patterns = ['lib/**/*.rb', 'test/**/*.rb', 'Gemfile', 'Rakefile']
end

Expand Down Expand Up @@ -114,6 +115,7 @@ task :ci do
sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:http'
sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:redis'
sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:sinatra'
sh 'rvm $MRI_VERSIONS --verbose do appraisal contrib rake test:sidekiq'
when 2
sh 'rvm $RAILS_VERSIONS --verbose do appraisal rails3-postgres rake test:rails'
sh 'rvm $RAILS_VERSIONS --verbose do appraisal rails3-mysql2 rake test:rails'
Expand Down
45 changes: 45 additions & 0 deletions docs/GettingStarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,47 @@ Net::HTTP module.

content = Net::HTTP.get(URI('http://127.0.0.1/index.html'))

### Sidekiq

The Sidekiq integration is a server-side middleware which will trace job
executions. It can be added as any other Sidekiq middleware:

require 'sidekiq'
require 'ddtrace'
require 'ddtrace/contrib/sidekiq/tracer'

Sidekiq.configure_server do |config|
config.server_middleware do |chain|
chain.add(Datadog::Contrib::Sidekiq::Tracer, debug: true)
end
end

#### Configure the tracer

To modify the default configuration, simply pass arguments to the middleware.
For example, to change the default service name and activate the debug mode:

Sidekiq.configure_server do |config|
config.server_middleware do |chain|
chain.add(Datadog::Contrib::Sidekiq::Tracer,
default_service: 'my_app', debug: true)
end
end

Available settings are:

* ``enabled``: define if the ``tracer`` is enabled or not. If set to
``false``, the code is still instrumented but no spans are sent to the local
trace agent.
* ``default_service``: set the service name used when tracing application
requests. Defaults to ``sidekiq``.
* ``tracer``: set the tracer to use. Usually you don't need to change that
value unless you're already using a different initialized tracer somewhere
else.
* ``debug``: set to ``true`` to enable debug logging.
* ``trace_agent_hostname``: set the hostname of the trace agent.
* ``trace_agent_port``: set the port the trace agent is listening on.

## Advanced usage

### Manual Instrumentation
Expand Down Expand Up @@ -360,6 +401,10 @@ The currently supported web server are:

Currently we are supporting Sinatra >= 1.4.0.

#### Sidekiq versions

Currently we are supporting Sidekiq >= 4.0.0.

### Glossary

* ``Service``: The name of a set of processes that do the same job. Some examples are ``datadog-web-app`` or ``datadog-metrics-db``.
Expand Down
52 changes: 52 additions & 0 deletions lib/ddtrace/contrib/sidekiq/tracer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

require 'sidekiq/api'

require 'ddtrace/ext/app_types'

sidekiq_vs = Gem::Version.new(Sidekiq::VERSION)
sidekiq_min_vs = Gem::Version.new('4.0.0')
if sidekiq_vs < sidekiq_min_vs
raise "sidekiq version #{sidekiq_vs} is not supported yet " \
+ "(supporting versions >=#{sidekiq_min_vs})"
end

Datadog::Tracer.log.info("activating instrumentation for sidekiq #{sidekiq_vs}")

module Datadog
module Contrib
module Sidekiq
# Middleware is a Sidekiq server-side middleware which traces executed
# jobs.
class Tracer
def initialize(options)
@enabled = options.fetch(:enabled, true)
@default_service = options.fetch(:default_service, 'sidekiq')
@tracer = options.fetch(:tracer, Datadog.tracer)
@debug = options.fetch(:debug, false)
@trace_agent_hostname = options.fetch(:trace_agent_hostname,
Datadog::Writer::HOSTNAME)
@trace_agent_port = options.fetch(:trace_agent_port,
Datadog::Writer::PORT)

Datadog::Tracer.debug_logging = @debug

@tracer.enabled = @enabled
@tracer.set_service_info(@default_service, 'sidekiq',
Datadog::Ext::AppTypes::JOB_PROCESSOR)
end

def call(worker, job, queue)
return yield unless @enabled

@tracer.trace('sidekiq.job',
service: @default_service, span_type: 'job') do |span|
span.resource = job['class']
span.set_tag('sidekiq.job.queue', job['queue'])

yield
end
end
end
end
end
end
1 change: 1 addition & 0 deletions lib/ddtrace/ext/app_types.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module AppTypes
WEB = 'web'.freeze
DB = 'db'.freeze
CACHE = 'cache'.freeze
JOB_PROCESSOR = 'job_processor'.freeze
end
end
end
26 changes: 26 additions & 0 deletions test/contrib/sidekiq/disabled_tracer_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

require 'contrib/sidekiq/tracer_test_base'

class DisabledTracerTest < TracerTestBase
class EmptyWorker
include Sidekiq::Worker

def perform; end
end

def setup
super

Sidekiq::Testing.server_middleware do |chain|
chain.add(Datadog::Contrib::Sidekiq::Tracer,
tracer: @tracer, enabled: false)
end
end

def test_empty
EmptyWorker.perform_async()

spans = @writer.spans()
assert_equal(0, spans.length)
end
end
63 changes: 63 additions & 0 deletions test/contrib/sidekiq/tracer_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

require 'contrib/sidekiq/tracer_test_base'

class TracerTest < TracerTestBase
class TestError < StandardError; end

class EmptyWorker
include Sidekiq::Worker

def perform(); end
end

class ErrorWorker
include Sidekiq::Worker

def perform
raise TestError, 'job error'
end
end

def setup
super

Sidekiq::Testing.server_middleware do |chain|
chain.add(Datadog::Contrib::Sidekiq::Tracer,
tracer: @tracer, enabled: true)
end
end

def test_empty
EmptyWorker.perform_async()

spans = @writer.spans()
assert_equal(1, spans.length)

span = spans[0]
assert_equal('sidekiq', span.service)
assert_equal('TracerTest::EmptyWorker', span.resource)
assert_equal('default', span.get_tag('sidekiq.job.queue'))
assert_equal(0, span.status)
assert_nil(span.parent)
end

# rubocop:disable Lint/HandleExceptions
def test_error
begin
ErrorWorker.perform_async()
rescue TestError
end

spans = @writer.spans()
assert_equal(1, spans.length)

span = spans[0]
assert_equal('sidekiq', span.service)
assert_equal('TracerTest::ErrorWorker', span.resource)
assert_equal('default', span.get_tag('sidekiq.job.queue'))
assert_equal(1, span.status)
assert_equal('job error', span.get_tag(Datadog::Ext::Errors::MSG))
assert_equal('TracerTest::TestError', span.get_tag(Datadog::Ext::Errors::TYPE))
assert_nil(span.parent)
end
end
27 changes: 27 additions & 0 deletions test/contrib/sidekiq/tracer_test_base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

require 'sidekiq/testing'
require 'ddtrace'
require 'ddtrace/contrib/sidekiq/tracer'
require 'helper'

class TracerTestBase < Minitest::Test
REDIS_HOST = '127.0.0.1'.freeze()
REDIS_PORT = 46379

def setup
@writer = FauxWriter.new()
@tracer = Datadog::Tracer.new(writer: @writer)

redis_url = "redis://#{REDIS_HOST}:#{REDIS_PORT}"

Sidekiq.configure_client do |config|
config.redis = { url: redis_url }
end

Sidekiq.configure_server do |config|
config.redis = { url: redis_url }
end

Sidekiq::Testing.inline!
end
end

0 comments on commit fd6d2c0

Please sign in to comment.