Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sidekiq support #344

Merged
merged 9 commits into from
Dec 7, 2023
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ library_gemfile: &library_gemfile
- "./gemfiles/sidekiq_42.gemfile"
- "./gemfiles/sidekiq_50.gemfile"
- "./gemfiles/sidekiq_60.gemfile"
- "./gemfiles/sidekiq_65.gemfile"
- "./gemfiles/sidekiq_70.gemfile"
- "./gemfiles/sinatra_14.gemfile"
- "./gemfiles/sinatra_22.gemfile"
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/sidekiq_50.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ gem "puma"
gem "rubocop", "~> 1.9"
gem "rack-test"
gem "simplecov", "~> 0.21.2"
gem "sidekiq", ">= 5.0", "< 6.0"
gem "sidekiq", "< 6.0"

gemspec path: "../"
2 changes: 1 addition & 1 deletion gemfiles/sidekiq_60.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ gem "puma"
gem "rubocop", "~> 1.9"
gem "rack-test"
gem "simplecov", "~> 0.21.2"
gem "sidekiq", ">= 6.0", "< 7.0"
gem "sidekiq", ">= 6.0.0", "< 6.5.0"

gemspec path: "../"
15 changes: 15 additions & 0 deletions gemfiles/sidekiq_65.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# (c) Copyright IBM Corp. 2023

source "https://rubygems.org"

gem "rake"
gem "minitest", "5.20.0"
gem "minitest-reporters"
gem "webmock"
gem "puma"
gem "rubocop", "~> 1.9"
gem "rack-test"
gem "simplecov", "~> 0.21.2"
gem "sidekiq", ">= 6.5.12", "< 7.0.0"

gemspec path: "../"
2 changes: 1 addition & 1 deletion gemfiles/sidekiq_70.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ gem "puma"
gem "rubocop", "~> 1.9"
gem "rack-test"
gem "simplecov", "~> 0.21.2"
gem "sidekiq", ">= 7.0"
gem "sidekiq", ">= 7.2.0"

gemspec path: "../"
3 changes: 1 addition & 2 deletions lib/instana/activators/sidekiq_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ module Instana
module Activators
class SidekiqClient < Activator
def can_instrument?
defined?(::Sidekiq) && ::Sidekiq.respond_to?(:configure_client) && ::Instana.config[:'sidekiq-client'][:enabled] &&
Gem::Specification.find_by_name('sidekiq').version < Gem::Version.new('5.3')
defined?(::Sidekiq) && ::Sidekiq.respond_to?(:configure_client) && ::Instana.config[:'sidekiq-client'][:enabled]
end

def instrument
Expand Down
3 changes: 1 addition & 2 deletions lib/instana/activators/sidekiq_worker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ module Instana
module Activators
class SidekiqWorker < Activator
def can_instrument?
defined?(::Sidekiq) && ::Sidekiq.respond_to?(:configure_server) && ::Instana.config[:'sidekiq-worker'][:enabled] &&
Gem::Specification.find_by_name('sidekiq').version < Gem::Version.new('5.3')
defined?(::Sidekiq) && ::Sidekiq.respond_to?(:configure_server) && ::Instana.config[:'sidekiq-worker'][:enabled]
end

def instrument
Expand Down
13 changes: 11 additions & 2 deletions lib/instana/instrumentation/sidekiq-client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,17 @@ def call(worker_class, msg, queue, _redis_pool)
# Temporary until we move connection collection to redis
# instrumentation
Sidekiq.redis_pool.with do |client|
opts = client.respond_to?(:connection) ? client.connection : client.client.options
kv_payload[:'sidekiq-client'][:'redis-url'] = "#{opts[:host]}:#{opts[:port]}"
sidekiq_version = Gem::Specification.find_by_name('sidekiq').version
host, port = if sidekiq_version >= Gem::Version.new('7.0') && client.respond_to?(:config) && client.config.respond_to?(:host) && client.config.respond_to?(:port)
[client.config.host, client.config.port]
elsif client.respond_to?(:connection)
[client.connection[:host], client.connection[:port]]
elsif client.respond_to?(:client) && client.client.respond_to?(:options)
[client.client.options[:host], client.client.options[:port]]
else # Unexpected version, continue without recording any redis-url
break
end
kv_payload[:'sidekiq-client'][:'redis-url'] = "#{host}:#{port}"
end

context = ::Instana.tracer.context
Expand Down
13 changes: 11 additions & 2 deletions lib/instana/instrumentation/sidekiq-worker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,17 @@ def call(_worker, msg, _queue)
# Temporary until we move connection collection to redis
# instrumentation
Sidekiq.redis_pool.with do |client|
opts = client.respond_to?(:connection) ? client.connection : client.client.options
kv_payload[:'sidekiq-worker'][:'redis-url'] = "#{opts[:host]}:#{opts[:port]}"
sidekiq_version = Gem::Specification.find_by_name('sidekiq').version
host, port = if sidekiq_version >= Gem::Version.new('7.0') && client.respond_to?(:config) && client.config.respond_to?(:host) && client.config.respond_to?(:port)
[client.config.host, client.config.port]
elsif client.respond_to?(:connection)
[client.connection[:host], client.connection[:port]]
elsif client.respond_to?(:client) && client.client.respond_to?(:options)
[client.client.options[:host], client.client.options[:port]]
else # Unexpected version, continue without recording any redis-url
break
end
kv_payload[:'sidekiq-worker'][:'redis-url'] = "#{host}:#{port}"
end

context = {}
Expand Down
20 changes: 2 additions & 18 deletions test/instrumentation/sidekiq-client_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,6 @@

class SidekiqClientTest < Minitest::Test
def setup
@framework_version = Gem::Specification.find_by_name('sidekiq').version
@supported_framework_version = @framework_version < Gem::Version.new('5.3')
@execute_test_if_framework_version_is_supported = lambda {
unless @supported_framework_version
skip "Skipping this test because sidekiq version #{@framework_version} is not yet supported!"
end
}
@execute_test_only_if_framework_version_is_not_supported = lambda {
if @supported_framework_version
skip "Skipping this test because sidekiq version #{@framework_version} is already supported!"
end
}

Sidekiq.configure_client do |config|
config.redis = { url: ENV["REDIS_URL"] }
end
::Sidekiq::Queue.new('some_random_queue').clear
end

Expand All @@ -32,7 +16,6 @@ def test_config_defaults
end

def test_enqueue
@execute_test_if_framework_version_is_supported.call
clear_all!
Instana.tracer.start_or_continue_trace(:sidekiqtests) do
disable_redis_instrumentation
Expand All @@ -53,7 +36,6 @@ def test_enqueue
end

def test_enqueue_failure
@execute_test_if_framework_version_is_supported.call
clear_all!

Instana.tracer.start_or_continue_trace(:sidekiqtests) do
Expand Down Expand Up @@ -104,6 +86,7 @@ def assert_normal_trace_recorded(job)
assert_equal 'some_random_queue', second_span[:data][:'sidekiq-client'][:queue]
assert_equal 'SidekiqJobOne', second_span[:data][:'sidekiq-client'][:job]
assert_equal "false", second_span[:data][:'sidekiq-client'][:retry]
assert second_span[:data][:'sidekiq-client'][:'redis-url']
assert_equal job['jid'], second_span[:data][:'sidekiq-client'][:job_id]
end

Expand All @@ -124,6 +107,7 @@ def assert_failure_trace_recorded
assert_equal 'some_random_queue', second_span[:data][:'sidekiq-client'][:queue]
assert_equal 'SidekiqJobTwo', second_span[:data][:'sidekiq-client'][:job]
assert_equal "false", second_span[:data][:'sidekiq-client'][:retry]
assert second_span[:data][:'sidekiq-client'][:'redis-url']
assert_equal 'Fail to enqueue job', second_span[:data][:log][:message]
end

Expand Down
48 changes: 3 additions & 45 deletions test/instrumentation/sidekiq-worker_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,55 +5,13 @@
require 'support/apps/sidekiq/boot'

class SidekiqServerTest < Minitest::Test
def setup
@framework_version = Gem::Specification.find_by_name('sidekiq').version
@supported_framework_version = @framework_version < Gem::Version.new('5.3')
@execute_test_if_framework_version_is_supported = lambda {
unless @supported_framework_version
skip "Skipping this test because sidekiq version #{@framework_version} is not yet supported!"
end
}
@execute_test_only_if_framework_version_is_not_supported = lambda {
if @supported_framework_version
skip "Skipping this test because sidekiq version #{@framework_version} is already supported!"
end
}

Sidekiq.configure_client do |config|
config.redis = { url: ENV["REDIS_URL"] }
end
end

def test_config_defaults
assert ::Instana.config[:'sidekiq-worker'].is_a?(Hash)
assert ::Instana.config[:'sidekiq-worker'].key?(:enabled)
assert_equal true, ::Instana.config[:'sidekiq-worker'][:enabled]
end

def test_no_sidekiq_tracing_if_unsupported_version_only_redis
@execute_test_only_if_framework_version_is_not_supported.call
clear_all!
::Sidekiq.redis_pool.with do |redis|
redis.sadd('queues'.freeze, 'important')
redis.lpush(
'queue:important',
<<-JSON
{
"class":"SidekiqJobOne",
"args":[1,2,3],
"queue":"important",
"jid":"123456789"
}
JSON
)
end

spans = Instana.processor.queued_spans
assert spans
end

def test_successful_worker_starts_new_trace
@execute_test_if_framework_version_is_supported.call
clear_all!
$sidekiq_mode = :server
inject_instrumentation
Expand Down Expand Up @@ -84,7 +42,6 @@ def test_successful_worker_starts_new_trace
end

def test_failed_worker_starts_new_trace
@execute_test_if_framework_version_is_supported.call
clear_all!
$sidekiq_mode = :server
inject_instrumentation
Expand Down Expand Up @@ -116,7 +73,6 @@ def test_failed_worker_starts_new_trace
end

def test_successful_worker_continues_previous_trace
@execute_test_if_framework_version_is_supported.call
clear_all!
$sidekiq_mode = :server
inject_instrumentation
Expand Down Expand Up @@ -150,7 +106,6 @@ def test_successful_worker_continues_previous_trace
end

def test_failed_worker_continues_previous_trace
@execute_test_if_framework_version_is_supported.call
clear_all!
$sidekiq_mode = :server
inject_instrumentation
Expand Down Expand Up @@ -200,6 +155,7 @@ def assert_successful_worker_span(worker_span)

assert_equal 'important', worker_span[:data][:'sidekiq-worker'][:queue]
assert_equal 'SidekiqJobOne', worker_span[:data][:'sidekiq-worker'][:job]
assert worker_span[:data][:'sidekiq-worker'][:'redis-url']
assert_equal false, worker_span[:data][:'sidekiq-worker'][:job_id].nil?
end

Expand All @@ -208,6 +164,7 @@ def assert_failed_worker_span(worker_span)

assert_equal 'important', worker_span[:data][:'sidekiq-worker'][:queue]
assert_equal 'SidekiqJobTwo', worker_span[:data][:'sidekiq-worker'][:job]
assert worker_span[:data][:'sidekiq-worker'][:'redis-url']
assert_equal false, worker_span[:data][:'sidekiq-worker'][:job_id].nil?

assert_equal true, worker_span[:data][:'sidekiq-worker'][:error]
Expand All @@ -217,6 +174,7 @@ def assert_failed_worker_span(worker_span)
def assert_client_span(client_span, job)
assert_equal :'sidekiq-client', client_span[:n]
assert_equal 'important', client_span[:data][:'sidekiq-client'][:queue]
assert client_span[:data][:'sidekiq-client'][:'redis-url']
assert_equal job.name, client_span[:data][:'sidekiq-client'][:job]
end
end
5 changes: 5 additions & 0 deletions test/support/apps/sidekiq/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
:concurrency: 2
:timeout: 25
:queues:
- [important]
16 changes: 8 additions & 8 deletions test/support/apps/sidekiq/worker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@
::Instana.logger.info "Booting instrumented sidekiq worker for tests."
::Sidekiq.logger.level = ::Logger::FATAL

properties = {queues: ['important'], concurrency: 2}

sidekiq_version = Gem::Specification.find_by_name('sidekiq').version
config_or_options =
if sidekiq_version >= Gem::Version.new('7.0.0')
::Sidekiq::Config.new(Sidekiq.default_configuration.merge!(properties))
else
::Sidekiq.options.merge(properties)
end
cli = ::Sidekiq::CLI.instance
cli.parse(['sidekiq', '-r', __FILE__, '-C', "#{File.dirname(__FILE__)}/config.yaml"])

config_or_options = if sidekiq_version >= Gem::Version.new('6.5.0')
cli.config
else
cli.send :options
end

sidekiq_thread = Thread.new do
launcher = ::Sidekiq::Launcher.new(
Expand Down
Loading