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 8.0 beta updates #2570

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
ARG IMAGE="bitnami/ruby"
ARG TAG="latest"

FROM ${IMAGE}:${TAG}

USER root
RUN apt-get update && apt-get install -y \
gnupg \
git \
curl \
wget \
zsh \
vim \
build-essential \
sudo \
libssl-dev \
libreadline-dev \
zlib1g-dev \
autoconf \
bison \
libyaml-dev \
libncurses5-dev \
libffi-dev \
libgdbm-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

RUN groupadd --gid 1000 sentry \
&& useradd --uid 1000 --gid sentry --shell /bin/zsh --create-home sentry

# Add sentry to sudoers with NOPASSWD option
RUN echo "sentry ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/sentry \
&& chmod 0440 /etc/sudoers.d/sentry

WORKDIR /workspace/sentry

RUN chown -R sentry:sentry /workspace/sentry
RUN mkdir /workspace/gems && chown -R sentry:sentry /workspace/gems

ARG TAG=latest

ENV LANG=C.UTF-8 \
BUNDLE_JOBS=4 \
BUNDLE_RETRY=3 \
GEM_HOME=/workspace/gems/${TAG} \
REDIS_HOST=redis

USER sentry

CMD ["ruby", "--version"]
16 changes: 16 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "sentry-ruby",
"dockerComposeFile": "docker-compose.yml",
"service": "app",
"workspaceFolder": "/workspace/sentry",
"customizations": {
"vscode": {
"extensions": [
"sleistner.vscode-fileutils",
"Shopify.ruby-lsp"
]
}
},
"remoteUser": "sentry",
"postCreateCommand": "ruby --version"
}
22 changes: 22 additions & 0 deletions .devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
services:
app:
build:
context: .
dockerfile: Dockerfile
args:
IMAGE: ${IMAGE}
TAG: ${TAG}
volumes:
- ..:/workspace/sentry:cached
command: sleep infinity
environment:
- REDIS_URL=${REDIS_URL:-redis://redis:6379/0}
depends_on:
- redis

redis:
image: redis:latest
environment:
- ALLOW_EMPTY_PASSWORD=yes
ports:
- "6379:6379"
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
### Features

- Add correct breadcrumb levels for 4xx/5xx response codes ([#2549](https://github.com/getsentry/sentry-ruby/pull/2549))
- Update sentry-sidekiq to work correctly with Sidekiq 8.0 and its new timestamp format ([#2570](https://github.com/getsentry/sentry-ruby/pull/2570))

### Bug Fixes

Expand Down
64 changes: 37 additions & 27 deletions sentry-ruby.code-workspace
Original file line number Diff line number Diff line change
@@ -1,30 +1,40 @@
{
"folders": [
{
"path": "sentry-ruby"
},
{
"path": "sentry-rails"
},
{
"path": "sentry-sidekiq"
},
{
"path": "sentry-delayed_job"
},
{
"path": "sentry-resque"
},
{
"path": "sentry-opentelemetry"
},
{
"path": ".github"
}
],
"extensions": {
"recommendations": [
"Shopify.ruby-lsp"
]
"folders": [
{
"path": ".devcontainer"
},
{
"path": ".github",
},
{
"path": ".",
"name": "root"
},
{
"path": "sentry-ruby"
},
{
"path": "sentry-rails"
},
{
"path": "sentry-sidekiq"
},
{
"path": "sentry-delayed_job"
},
{
"path": "sentry-resque"
},
{
"path": "sentry-opentelemetry"
},
{
"path": "sentry-raven"
}
],
"extensions": {
"recommendations": [
"Shopify.ruby-lsp"
]
}
}
12 changes: 6 additions & 6 deletions sentry-ruby/spec/sentry/breadcrumb/redis_logger_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
require "spec_helper"

RSpec.describe :redis_logger do
let(:redis) { Redis.new(host: "127.0.0.1") }
let(:redis) { Redis.new(host: REDIS_HOST) }

before do
perform_basic_setup do |config|
Expand All @@ -20,7 +20,7 @@
expect(result).to eq("OK")
expect(Sentry.get_current_scope.breadcrumbs.peek).to have_attributes(
category: "db.redis",
data: { commands: [{ command: "SET", key: "key" }], server: "127.0.0.1:6379/0" }
data: { commands: [{ command: "SET", key: "key" }], server: "#{REDIS_HOST}:6379/0" }
)
end
end
Expand All @@ -34,7 +34,7 @@
expect(result).to eq("OK")
expect(Sentry.get_current_scope.breadcrumbs.peek).to have_attributes(
category: "db.redis",
data: { commands: [{ command: "SET", key: "key", arguments: "value" }], server: "127.0.0.1:6379/0" }
data: { commands: [{ command: "SET", key: "key", arguments: "value" }], server: "#{REDIS_HOST}:6379/0" }
)
end

Expand Down Expand Up @@ -62,7 +62,7 @@
expect(result.key?("uptime_in_days")).to eq(true)
expect(Sentry.get_current_scope.breadcrumbs.peek).to have_attributes(
category: "db.redis",
data: { commands: [{ command: "INFO", key: nil }], server: "127.0.0.1:6379/0" }
data: { commands: [{ command: "INFO", key: nil }], server: "#{REDIS_HOST}:6379/0" }
)
end
end
Expand All @@ -88,7 +88,7 @@
{ command: "INCR", key: "counter" },
{ command: "EXEC", key: nil }
],
server: "127.0.0.1:6379/0"
server: "#{REDIS_HOST}:6379/0"
}
)
end
Expand All @@ -105,7 +105,7 @@
expect(result).to eq("OK")
expect(Sentry.get_current_scope.breadcrumbs.peek).to have_attributes(
category: "db.redis",
data: { commands: [{ command: "SET", key: "key" }], server: "127.0.0.1:6379/0" }
data: { commands: [{ command: "SET", key: "key" }], server: "#{REDIS_HOST}:6379/0" }
)
end
end
Expand Down
4 changes: 2 additions & 2 deletions sentry-ruby/spec/sentry/redis_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
require "spec_helper"

RSpec.describe Sentry::Redis do
let(:redis) { Redis.new(host: "127.0.0.1") }
let(:redis) { Redis.new(host: REDIS_HOST) }

context "with tracing enabled" do
before do
Expand Down Expand Up @@ -33,7 +33,7 @@
expect(request_span.data).to eq({
"db.name" => 0,
"db.system" => "redis",
"server.address" => "127.0.0.1",
"server.address" => REDIS_HOST,
"server.port" => 6379
})
end
Expand Down
2 changes: 2 additions & 0 deletions sentry-ruby/spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
coverage_dir File.join(__FILE__, "../../coverage")
end

REDIS_HOST = ENV.fetch("REDIS_HOST", "127.0.0.1")

if ENV["CI"]
require 'simplecov-cobertura'
SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
Expand Down
17 changes: 16 additions & 1 deletion sentry-sidekiq/lib/sentry/sidekiq/sentry_context_middleware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@ def set_span_data(span, id:, queue:, latency: nil, retry_count: nil)
span.set_data(Span::DataConventions::MESSAGING_MESSAGE_RECEIVE_LATENCY, latency) if latency
span.set_data(Span::DataConventions::MESSAGING_MESSAGE_RETRY_COUNT, retry_count) if retry_count
end

if ::Gem::Version.new(::Sidekiq::VERSION) >= ::Gem::Version.new("8.0.0.beta")
def calculate_latency(job)
now_in_ms - job["enqueued_at"] if job["enqueued_at"]
end
else
def calculate_latency(job)
((Time.now.to_f - job["enqueued_at"]) * 1000).to_i if job["enqueued_at"]
end
end

def now_in_ms
::Process.clock_gettime(::Process::CLOCK_REALTIME, :millisecond)
end
end

class SentryContextServerMiddleware
Expand Down Expand Up @@ -40,7 +54,8 @@ def call(worker, job, queue)
if transaction
scope.set_span(transaction)

latency = ((Time.now.to_f - job["enqueued_at"]) * 1000).to_i if job["enqueued_at"]
latency = calculate_latency(job)

set_span_data(
transaction,
id: job["jid"],
Expand Down
46 changes: 32 additions & 14 deletions sentry-sidekiq/spec/sentry/sidekiq/error_handler_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,38 @@
Sentry.get_current_client.transport
end

let(:context) do
{
"args" => [true, true],
"class" => "HardWorker",
"created_at" => 1_474_922_824.910579,
"enqueued_at" => 1_474_922_824.910665,
"error_class" => "RuntimeError",
"error_message" => "a wild exception appeared",
"failed_at" => 1_474_922_825.158953,
"jid" => "701ed9cfa51c84a763d56bc4",
"queue" => "default",
"retry" => true,
"retry_count" => 0
}
if WITH_SIDEKIQ_8
let(:context) do
{
"args" => [true, true],
"class" => "HardWorker",
"created_at" => 1_474_922_824_910,
"enqueued_at" => 1_474_922_824_910,
"error_class" => "RuntimeError",
"error_message" => "a wild exception appeared",
"failed_at" => 1_474_922_825_158,
"jid" => "701ed9cfa51c84a763d56bc4",
"queue" => "default",
"retry" => true,
"retry_count" => 0
}
end
else
let(:context) do
{
"args" => [true, true],
"class" => "HardWorker",
"created_at" => 1_474_922_824.910579,
"enqueued_at" => 1_474_922_824.910665,
"error_class" => "RuntimeError",
"error_message" => "a wild exception appeared",
"failed_at" => 1_474_922_825.158953,
"jid" => "701ed9cfa51c84a763d56bc4",
"queue" => "default",
"retry" => true,
"retry_count" => 0
}
end
end

let(:processor) do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,13 @@
expect(transaction.spans.count).to eq(0)
expect(transaction.contexts[:trace][:data]['messaging.message.id']).to eq('123456') # Explicitly set above.
expect(transaction.contexts[:trace][:data]['messaging.destination.name']).to eq('default')
expect(transaction.contexts[:trace][:data]['messaging.message.receive.latency']).to eq(86400000)
expect(transaction.contexts[:trace][:data]['messaging.message.retry.count']).to eq(0)

if WITH_SIDEKIQ_8
expect(transaction.contexts[:trace][:data]['messaging.message.receive.latency']).to eq(0)
else
expect(transaction.contexts[:trace][:data]['messaging.message.receive.latency']).to eq(86400000)
end
end

if MIN_SIDEKIQ_6
Expand Down
21 changes: 20 additions & 1 deletion sentry-sidekiq/spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

MIN_SIDEKIQ_6 = Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new("6.0")
WITH_SIDEKIQ_7 = Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new("7.0")
WITH_SIDEKIQ_8 = Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new("8.0.0.beta")
WITH_SIDEKIQ_6 = MIN_SIDEKIQ_6 && !WITH_SIDEKIQ_7

require "sidekiq/embedded" if WITH_SIDEKIQ_7
Expand Down Expand Up @@ -56,6 +57,14 @@
c.syntax = :expect
end

config.before :suite do
if WITH_SIDEKIQ_8
puts "*" * 100
puts "Running with Sidekiq 8.0.0.beta"
puts "*" * 100
end
end

config.before :each do
# Make sure we reset the env in case something leaks in
ENV.delete('SENTRY_DSN')
Expand Down Expand Up @@ -240,6 +249,10 @@ def sidekiq_config(opts)
WITH_SIDEKIQ_7 ? ::Sidekiq::Config.new(opts) : SidekiqConfigMock.new(opts)
end

def now_in_ms
::Process.clock_gettime(::Process::CLOCK_REALTIME, :millisecond)
end

def execute_worker(processor, klass, **options)
klass_options = klass.sidekiq_options_hash || {}
# for Ruby < 2.6
Expand All @@ -250,7 +263,13 @@ def execute_worker(processor, klass, **options)
jid = options.delete(:jid) || "123123"
timecop_delay = options.delete(:timecop_delay)

msg = Sidekiq.dump_json(created_at: Time.now.to_f, enqueued_at: Time.now.to_f, jid: jid, class: klass, args: [], **options)
if WITH_SIDEKIQ_8
current_time_ms = now_in_ms
msg = Sidekiq.dump_json(created_at: current_time_ms, enqueued_at: current_time_ms, jid: jid, class: klass, args: [], **options)
else
msg = Sidekiq.dump_json(created_at: Time.now.to_f, enqueued_at: Time.now.to_f, jid: jid, class: klass, args: [], **options)
end

Timecop.freeze(timecop_delay) if timecop_delay
work = Sidekiq::BasicFetch::UnitOfWork.new('queue:default', msg)
process_work(processor, work)
Expand Down
Loading