From 17d2c1c73746eda7405456535fa8e8c1c085b99a Mon Sep 17 00:00:00 2001 From: Andrei Makarov Date: Thu, 16 Oct 2025 12:32:28 +0300 Subject: [PATCH 1/3] feat(monitor_check_ins): enhance slug generation with hash truncation Added a new SLUG_HASH_LENGTH constant and updated the slug generation logic to truncate long slugs from the beginning and append a hash for uniqueness. Updated tests to reflect the new slug format. --- sentry-ruby/lib/sentry/cron/monitor_check_ins.rb | 16 ++++++++++++++-- .../spec/sentry/cron/monitor_check_ins_spec.rb | 2 +- .../sentry/sidekiq-scheduler/scheduler_spec.rb | 3 ++- sentry-sidekiq/spec/sentry/sidekiq_spec.rb | 4 ++-- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/sentry-ruby/lib/sentry/cron/monitor_check_ins.rb b/sentry-ruby/lib/sentry/cron/monitor_check_ins.rb index df7445286..8f5158b81 100644 --- a/sentry-ruby/lib/sentry/cron/monitor_check_ins.rb +++ b/sentry-ruby/lib/sentry/cron/monitor_check_ins.rb @@ -4,6 +4,7 @@ module Sentry module Cron module MonitorCheckIns MAX_SLUG_LENGTH = 50 + SLUG_HASH_LENGTH = 10 module Patch def perform(*args, **opts) @@ -59,8 +60,19 @@ def sentry_monitor_check_ins(slug: nil, monitor_config: nil) def sentry_monitor_slug(name: self.name) @sentry_monitor_slug ||= begin - slug = name.gsub("::", "-").downcase - slug[-MAX_SLUG_LENGTH..-1] || slug + slug = name.gsub("::", "-").gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase + if slug.length > MAX_SLUG_LENGTH + diff_length = slug.length + SLUG_HASH_LENGTH - MAX_SLUG_LENGTH + trim_part = "" + slug.scan(/([^_-]+)([_-])/) do |match, separator| + trim_part = "#{trim_part}#{match}#{separator}" + break if trim_part.length >= diff_length + end + trim_part = slug[0...diff_length] if trim_part.empty? + hash = OpenSSL::Digest::SHA256.hexdigest(trim_part)[0..SLUG_HASH_LENGTH-1] + slug = "#{hash}_#{slug.sub(trim_part, '')}" + end + slug end end diff --git a/sentry-ruby/spec/sentry/cron/monitor_check_ins_spec.rb b/sentry-ruby/spec/sentry/cron/monitor_check_ins_spec.rb index b1aafc4b2..e305a5693 100644 --- a/sentry-ruby/spec/sentry/cron/monitor_check_ins_spec.rb +++ b/sentry-ruby/spec/sentry/cron/monitor_check_ins_spec.rb @@ -183,7 +183,7 @@ def perform it 'truncates from the beginning and parameterizes slug' do slug = VeryLongOuterModule::VeryVeryVeryVeryLongInnerModule::Job.sentry_monitor_slug - expect(slug).to eq('ongoutermodule-veryveryveryverylonginnermodule-job') + expect(slug).to eq('675905e0c9_very_very_very_long_inner_module-job') end end diff --git a/sentry-sidekiq/spec/sentry/sidekiq-scheduler/scheduler_spec.rb b/sentry-sidekiq/spec/sentry/sidekiq-scheduler/scheduler_spec.rb index 02efd1ccc..252a3dc12 100644 --- a/sentry-sidekiq/spec/sentry/sidekiq-scheduler/scheduler_spec.rb +++ b/sentry-sidekiq/spec/sentry/sidekiq-scheduler/scheduler_spec.rb @@ -66,7 +66,8 @@ it 'truncates from the beginning and parameterizes slug' do expect(VeryLongOuterModule::VeryVeryVeryVeryLongInnerModule::Job.ancestors).to include(Sentry::Cron::MonitorCheckIns) - expect(VeryLongOuterModule::VeryVeryVeryVeryLongInnerModule::Job.sentry_monitor_slug).to eq('ongoutermodule-veryveryveryverylonginnermodule-job') + expect(VeryLongOuterModule::VeryVeryVeryVeryLongInnerModule::Job.sentry_monitor_slug.length).to be <= 50 + expect(VeryLongOuterModule::VeryVeryVeryVeryLongInnerModule::Job.sentry_monitor_slug).to eq('675905e0c9_very_very_very_long_inner_module-job') expect(VeryLongOuterModule::VeryVeryVeryVeryLongInnerModule::Job.sentry_monitor_config).to be_a(Sentry::Cron::MonitorConfig) expect(VeryLongOuterModule::VeryVeryVeryVeryLongInnerModule::Job.sentry_monitor_config.schedule).to be_a(Sentry::Cron::MonitorSchedule::Crontab) expect(VeryLongOuterModule::VeryVeryVeryVeryLongInnerModule::Job.sentry_monitor_config.schedule.value).to eq('* * * * *') diff --git a/sentry-sidekiq/spec/sentry/sidekiq_spec.rb b/sentry-sidekiq/spec/sentry/sidekiq_spec.rb index de65bb074..c9c3d9d86 100644 --- a/sentry-sidekiq/spec/sentry/sidekiq_spec.rb +++ b/sentry-sidekiq/spec/sentry/sidekiq_spec.rb @@ -320,7 +320,7 @@ def retry_last_failed_job expect(first.to_hash).to include( type: 'check_in', check_in_id: check_in_id, - monitor_slug: "happyworkerwithcron", + monitor_slug: "happy_worker_with_cron", status: :in_progress ) @@ -330,7 +330,7 @@ def retry_last_failed_job :duration, type: 'check_in', check_in_id: check_in_id, - monitor_slug: "happyworkerwithcron", + monitor_slug: "happy_worker_with_cron", status: :ok ) end From f350aece8f8463e7788796f2e8cd0252bdec21f7 Mon Sep 17 00:00:00 2001 From: Andrei Makarov Date: Thu, 16 Oct 2025 12:37:23 +0300 Subject: [PATCH 2/3] feat(monitor_check_ins): add MAX_NAME_LENGTH constant for name validation Introduced a new MAX_NAME_LENGTH constant set to 128 to enforce length validation for names in the MonitorCheckIns module. --- sentry-ruby/lib/sentry/cron/monitor_check_ins.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/sentry-ruby/lib/sentry/cron/monitor_check_ins.rb b/sentry-ruby/lib/sentry/cron/monitor_check_ins.rb index 8f5158b81..afbdcb557 100644 --- a/sentry-ruby/lib/sentry/cron/monitor_check_ins.rb +++ b/sentry-ruby/lib/sentry/cron/monitor_check_ins.rb @@ -4,6 +4,7 @@ module Sentry module Cron module MonitorCheckIns MAX_SLUG_LENGTH = 50 + MAX_NAME_LENGTH = 128 SLUG_HASH_LENGTH = 10 module Patch From 53e99ed0a4f414121525922af3b9a481c2b3c0cf Mon Sep 17 00:00:00 2001 From: Andrei Makarov Date: Thu, 16 Oct 2025 13:01:42 +0300 Subject: [PATCH 3/3] fix(monitor_check_ins): adjust slug length calculation for accuracy Updated the slug length calculation to correctly account for the additional character when generating slugs, ensuring proper truncation and uniqueness in the MonitorCheckIns module. --- sentry-ruby/lib/sentry/cron/monitor_check_ins.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry-ruby/lib/sentry/cron/monitor_check_ins.rb b/sentry-ruby/lib/sentry/cron/monitor_check_ins.rb index afbdcb557..10ad28d00 100644 --- a/sentry-ruby/lib/sentry/cron/monitor_check_ins.rb +++ b/sentry-ruby/lib/sentry/cron/monitor_check_ins.rb @@ -63,7 +63,7 @@ def sentry_monitor_slug(name: self.name) @sentry_monitor_slug ||= begin slug = name.gsub("::", "-").gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase if slug.length > MAX_SLUG_LENGTH - diff_length = slug.length + SLUG_HASH_LENGTH - MAX_SLUG_LENGTH + diff_length = slug.length + 1 + SLUG_HASH_LENGTH - MAX_SLUG_LENGTH trim_part = "" slug.scan(/([^_-]+)([_-])/) do |match, separator| trim_part = "#{trim_part}#{match}#{separator}"