From 59519554d576609d705d88ae6873763982c464fc Mon Sep 17 00:00:00 2001 From: Cody Sheffler Date: Fri, 10 May 2024 09:33:24 -0500 Subject: [PATCH] Add Datadog tracing to client, server, & worker --- .vscode/settings.json | 3 ++ lib/sidekiq/instrument/middleware/client.rb | 26 +++++++----- lib/sidekiq/instrument/middleware/server.rb | 36 ++++++++++------- lib/sidekiq/instrument/version.rb | 2 +- lib/sidekiq/instrument/worker.rb | 44 ++++++++++++--------- sidekiq-instrument.gemspec | 1 + 6 files changed, 69 insertions(+), 43 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..d0dca61 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "circleci.persistedProjectSelection": [] +} diff --git a/lib/sidekiq/instrument/middleware/client.rb b/lib/sidekiq/instrument/middleware/client.rb index 1e40816..9f38c3c 100644 --- a/lib/sidekiq/instrument/middleware/client.rb +++ b/lib/sidekiq/instrument/middleware/client.rb @@ -2,20 +2,28 @@ require 'sidekiq/instrument/mixin' require 'active_support/core_ext/string/inflections' +require 'ddtrace' module Sidekiq::Instrument class ClientMiddleware include Sidekiq::Instrument::MetricNames - def call(worker_class, job, queue, redis_pool) - # worker_class is a const in sidekiq >= 6.x - klass = Object.const_get(worker_class.to_s) - class_instance = klass.new - Statter.statsd.increment(metric_name(class_instance, 'enqueue')) - Statter.dogstatsd&.increment('sidekiq.enqueue', worker_dog_options(class_instance)) - WorkerMetrics.trace_workers_increment_counter(klass.name.underscore, redis_pool) - result = yield - Statter.dogstatsd&.flush(sync: true) + def call(worker_class, job, _queue, redis_pool) + span = Datadog::Tracing.trace('sidekiq.job.enqueue', service: 'sidekiq', resource: job['class']) + begin + # worker_class is a const in sidekiq >= 6.x + klass = Object.const_get(worker_class.to_s) + class_instance = klass.new + Statter.statsd.increment(metric_name(class_instance, 'enqueue')) + Statter.dogstatsd&.increment('sidekiq.enqueue', worker_dog_options(class_instance)) + WorkerMetrics.trace_workers_increment_counter(klass.name.underscore, redis_pool) + result = yield + rescue StandardError => e + span.set_error(e) + ensure + span.finish + Statter.dogstatsd&.flush(sync: true) + end result end end diff --git a/lib/sidekiq/instrument/middleware/server.rb b/lib/sidekiq/instrument/middleware/server.rb index 3cbb17b..1d43f15 100644 --- a/lib/sidekiq/instrument/middleware/server.rb +++ b/lib/sidekiq/instrument/middleware/server.rb @@ -2,27 +2,33 @@ require 'sidekiq/instrument/mixin' require 'active_support/core_ext/string/inflections' +require 'ddtrace' module Sidekiq::Instrument class ServerMiddleware include Sidekiq::Instrument::MetricNames - def call(worker, _job, _queue, &block) - Statter.statsd.increment(metric_name(worker, 'dequeue')) - Statter.dogstatsd&.increment('sidekiq.dequeue', worker_dog_options(worker)) + def call(worker, job, _queue, &block) + span = Datadog::Tracing.trace('sidekiq.job.dequeue', service: 'sidekiq', resource: job['class']) + begin + Statter.statsd.increment(metric_name(worker, 'dequeue')) + Statter.dogstatsd&.increment('sidekiq.dequeue', worker_dog_options(worker)) - start_time = Time.now - yield block - execution_time_ms = (Time.now - start_time) * 1000 - Statter.statsd.measure(metric_name(worker, 'runtime'), execution_time_ms) - Statter.dogstatsd&.timing('sidekiq.runtime', execution_time_ms, worker_dog_options(worker)) - rescue StandardError => e - Statter.statsd.increment(metric_name(worker, 'error')) - Statter.dogstatsd&.increment('sidekiq.error', worker_dog_options(worker)) - raise e - ensure - WorkerMetrics.trace_workers_decrement_counter(worker.class.to_s.underscore) - Statter.dogstatsd&.flush(sync: true) + start_time = Time.now + yield block + execution_time_ms = (Time.now - start_time) * 1000 + Statter.statsd.measure(metric_name(worker, 'runtime'), execution_time_ms) + Statter.dogstatsd&.timing('sidekiq.runtime', execution_time_ms, worker_dog_options(worker)) + rescue StandardError => e + span.set_error(e) + Statter.statsd.increment(metric_name(worker, 'error')) + Statter.dogstatsd&.increment('sidekiq.error', worker_dog_options(worker)) + raise e + ensure + span.finish + WorkerMetrics.trace_workers_decrement_counter(worker.class.to_s.underscore) + Statter.dogstatsd&.flush(sync: true) + end end end end diff --git a/lib/sidekiq/instrument/version.rb b/lib/sidekiq/instrument/version.rb index 5dac7ab..818a3ba 100644 --- a/lib/sidekiq/instrument/version.rb +++ b/lib/sidekiq/instrument/version.rb @@ -1,5 +1,5 @@ module Sidekiq module Instrument - VERSION = '0.6.2' + VERSION = '0.7.0' end end diff --git a/lib/sidekiq/instrument/worker.rb b/lib/sidekiq/instrument/worker.rb index b4c4476..ca3647a 100644 --- a/lib/sidekiq/instrument/worker.rb +++ b/lib/sidekiq/instrument/worker.rb @@ -2,6 +2,7 @@ require 'sidekiq' require 'sidekiq/api' +require 'ddtrace' module Sidekiq::Instrument class Worker @@ -18,35 +19,42 @@ class Worker }.freeze def perform - info = Sidekiq::Stats.new + span = Datadog::Tracing.trace('sidekiq.job.perform', service: 'sidekiq', resource: self.class.to_s) + begin + info = Sidekiq::Stats.new - self.class::METRIC_NAMES.each do |method, stat| - stat ||= method + self.class::METRIC_NAMES.each do |method, stat| + stat ||= method - Statter.statsd.gauge("shared.sidekiq.stats.#{stat}", info.send(method)) - Statter.dogstatsd&.gauge("sidekiq.#{stat}", info.send(method)) - end + Statter.statsd.gauge("shared.sidekiq.stats.#{stat}", info.send(method)) + Statter.dogstatsd&.gauge("sidekiq.#{stat}", info.send(method)) + end - working = Sidekiq::Workers.new.count - Statter.statsd.gauge('shared.sidekiq.stats.working', working) - Statter.dogstatsd&.gauge('sidekiq.working', working) - send_worker_metrics - Sidekiq::Queue.all.each do |queue| - Statter.statsd.gauge("shared.sidekiq.#{queue.name}.size", queue.size) - Statter.dogstatsd&.gauge('sidekiq.queue.size', queue.size, tags: dd_tags(queue)) + working = Sidekiq::Workers.new.count + Statter.statsd.gauge('shared.sidekiq.stats.working', working) + Statter.dogstatsd&.gauge('sidekiq.working', working) + send_worker_metrics + Sidekiq::Queue.all.each do |queue| + Statter.statsd.gauge("shared.sidekiq.#{queue.name}.size", queue.size) + Statter.dogstatsd&.gauge('sidekiq.queue.size', queue.size, tags: dd_tags(queue)) - Statter.statsd.gauge("shared.sidekiq.#{queue.name}.latency", queue.latency) - Statter.dogstatsd&.gauge('sidekiq.queue.latency', queue.latency, tags: dd_tags(queue)) + Statter.statsd.gauge("shared.sidekiq.#{queue.name}.latency", queue.latency) + Statter.dogstatsd&.gauge('sidekiq.queue.latency', queue.latency, tags: dd_tags(queue)) + end + rescue StandardError => e + span.set_error(e) + raise e + ensure + span.finish + Statter.dogstatsd&.flush(sync: true) end - - Statter.dogstatsd&.flush(sync: true) end private # @param [Sidekiq::Queue] queue used for stats emission # @return [Array] an array of tags - # @example this method can be override to add more tags + # @example this method can be overridden to add more tags # class MyStatsWorker < Sidekiq::Instrument::Worker # private # diff --git a/sidekiq-instrument.gemspec b/sidekiq-instrument.gemspec index e3a9cb0..6495d7c 100644 --- a/sidekiq-instrument.gemspec +++ b/sidekiq-instrument.gemspec @@ -18,6 +18,7 @@ Gem::Specification.new do |spec| spec.add_dependency 'sidekiq', '>= 4.2', '< 7' spec.add_dependency 'statsd-instrument', '>= 2.0.4' + spec.add_dependency 'ddtrace', '~> 1.0' spec.add_dependency 'dogstatsd-ruby', '~> 5.5' spec.add_dependency 'activesupport', '>= 5.1', '< 7' spec.add_dependency "redis-client", ">= 0.14.1"