From bf98e2ce2dc9af5a838ae57250fd0b81f88c7fda Mon Sep 17 00:00:00 2001 From: Peter Solnica Date: Wed, 4 Nov 2026 12:41:50 +0000 Subject: [PATCH] feat(queues): improve core queue conformance Closes #3121 --- sentry-ruby/lib/sentry-ruby.rb | 1 + .../lib/sentry/job_extensions/extension.rb | 5 +++-- sentry-ruby/lib/sentry/span.rb | 1 + sentry-ruby/lib/sentry/utils/latency.rb | 18 ++++++++++++++++ .../sentry/job_extensions/extension_spec.rb | 3 ++- sentry-ruby/spec/sentry/utils/latency_spec.rb | 21 +++++++++++++++++++ 6 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 sentry-ruby/lib/sentry/utils/latency.rb create mode 100644 sentry-ruby/spec/sentry/utils/latency_spec.rb diff --git a/sentry-ruby/lib/sentry-ruby.rb b/sentry-ruby/lib/sentry-ruby.rb index 288a8c6c1..0532e622d 100644 --- a/sentry-ruby/lib/sentry-ruby.rb +++ b/sentry-ruby/lib/sentry-ruby.rb @@ -12,6 +12,7 @@ require "sentry/utils/logging_helper" require "sentry/utils/callback_helper" require "sentry/utils/sample_rand" +require "sentry/utils/latency" require "sentry/configuration" require "sentry/structured_logger" require "sentry/debug_structured_logger" diff --git a/sentry-ruby/lib/sentry/job_extensions/extension.rb b/sentry-ruby/lib/sentry/job_extensions/extension.rb index 1e62eb50f..de56ac08c 100644 --- a/sentry-ruby/lib/sentry/job_extensions/extension.rb +++ b/sentry-ruby/lib/sentry/job_extensions/extension.rb @@ -16,7 +16,8 @@ class Extension message_id: Span::DataConventions::MESSAGING_MESSAGE_ID, destination: Span::DataConventions::MESSAGING_DESTINATION_NAME, receive_latency: Span::DataConventions::MESSAGING_MESSAGE_RECEIVE_LATENCY, - retry_count: Span::DataConventions::MESSAGING_MESSAGE_RETRY_COUNT + retry_count: Span::DataConventions::MESSAGING_MESSAGE_RETRY_COUNT, + body_size: Span::DataConventions::MESSAGING_MESSAGE_BODY_SIZE }.freeze # The extension's name, used in SDK log messages. @@ -194,7 +195,7 @@ def extract_trace_headers(job:, **) # # @param job [Object] # @return [Hash] with optional `:system`, `:message_id`, `:destination`, - # `:receive_latency` and `:retry_count` + # `:receive_latency`, `:retry_count` and `:body_size` def messaging_data(job:, **) {} end diff --git a/sentry-ruby/lib/sentry/span.rb b/sentry-ruby/lib/sentry/span.rb index 4942de161..9b0c418d6 100644 --- a/sentry-ruby/lib/sentry/span.rb +++ b/sentry-ruby/lib/sentry/span.rb @@ -50,6 +50,7 @@ module DataConventions MESSAGING_DESTINATION_NAME = "messaging.destination.name" MESSAGING_MESSAGE_RECEIVE_LATENCY = "messaging.message.receive.latency" MESSAGING_MESSAGE_RETRY_COUNT = "messaging.message.retry.count" + MESSAGING_MESSAGE_BODY_SIZE = "messaging.message.body.size" # Time in ms the request spent in the server queue before processing began. HTTP_QUEUE_TIME_MS = "http.server.request.time_in_queue" diff --git a/sentry-ruby/lib/sentry/utils/latency.rb b/sentry-ruby/lib/sentry/utils/latency.rb new file mode 100644 index 000000000..702735a2f --- /dev/null +++ b/sentry-ruby/lib/sentry/utils/latency.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require "time" + +module Sentry + module Utils + module Latency + module_function + + def milliseconds_since(time) + return unless time + + time = Time.parse(time) if time.is_a?(String) + (Time.now.to_f - time.to_f) * 1000.0 + end + end + end +end diff --git a/sentry-ruby/spec/sentry/job_extensions/extension_spec.rb b/sentry-ruby/spec/sentry/job_extensions/extension_spec.rb index dbce9d9f4..cc6598c99 100644 --- a/sentry-ruby/spec/sentry/job_extensions/extension_spec.rb +++ b/sentry-ruby/spec/sentry/job_extensions/extension_spec.rb @@ -25,7 +25,7 @@ def build_extension(**hooks) def enriching_extension build_extension( - messaging_data: ->(job:, **) { { system: "backend", message_id: job.id, destination: job.queue, receive_latency: 42.5, retry_count: 3 } }, + messaging_data: ->(job:, **) { { system: "backend", message_id: job.id, destination: job.queue, receive_latency: 42.5, retry_count: 3, body_size: 128 } }, scope_data: ->(job:, **) { { contexts: { backend: { "jid" => "backend-jid" } }, tags: { "backend.queue" => "low" }, extra: { size: 12 } } } ) end @@ -235,6 +235,7 @@ def capture(extension, **options) "messaging.message.id" => "job-1", "messaging.destination.name" => "critical", "messaging.message.receive.latency" => 42.5, + "messaging.message.body.size" => 128, "messaging.message.retry.count" => 3 ) end diff --git a/sentry-ruby/spec/sentry/utils/latency_spec.rb b/sentry-ruby/spec/sentry/utils/latency_spec.rb new file mode 100644 index 000000000..9cd24aad8 --- /dev/null +++ b/sentry-ruby/spec/sentry/utils/latency_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +RSpec.describe Sentry::Utils::Latency do + let(:started_at) { Time.utc(2026, 1, 1, 12, 0, 0) } + + around do |example| + Timecop.freeze(started_at + 2.5) { example.run } + end + + it "measures the milliseconds since a Time" do + expect(described_class.milliseconds_since(started_at)).to eq(2_500.0) + end + + it "measures the milliseconds since an ISO 8601 String" do + expect(described_class.milliseconds_since(started_at.iso8601(3))).to eq(2_500.0) + end + + it "measures nothing without a time" do + expect(described_class.milliseconds_since(nil)).to be_nil + end +end