diff --git a/.github/workflows/sentry_ruby_test.yml b/.github/workflows/sentry_ruby_test.yml index 688b54042..bc6a1ad64 100644 --- a/.github/workflows/sentry_ruby_test.yml +++ b/.github/workflows/sentry_ruby_test.yml @@ -25,6 +25,7 @@ jobs: working-directory: sentry-ruby name: Ruby ${{ matrix.ruby_version }} & Rack ${{ matrix.rack_version }}, options - ${{ toJson(matrix.options) }} runs-on: ubuntu-latest + timeout-minutes: 10 strategy: fail-fast: false matrix: diff --git a/.gitignore b/.gitignore index 0b513cc74..7e3c680b2 100644 --- a/.gitignore +++ b/.gitignore @@ -12,5 +12,6 @@ Gemfile.lock .ruby-gemset .idea *.rdb +.rgignore examples/**/node_modules diff --git a/.rubocop.yml b/.rubocop.yml index 451fd8589..9286a27d3 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -4,7 +4,17 @@ inherit_gem: Layout/SpaceInsideArrayLiteralBrackets: Enabled: false +Layout/EmptyLineAfterMagicComment: + Enabled: true + +Style/FrozenStringLiteralComment: + Enabled: true + +Style/RedundantFreeze: + Enabled: true + AllCops: Exclude: - "sentry-raven/**/*" - "sentry-*/tmp/**/*" + - "sentry-*/examples/**/*" diff --git a/CHANGELOG.md b/CHANGELOG.md index bac1d3102..b3dcdbf7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,61 @@ ## Unreleased +### Features + +- Add support for Sentry Cache instrumentation, when using Rails.cache ([#2380](https://github.com/getsentry/sentry-ruby/pull/2380)) + +## 5.21.0 + ### Features -- Add support for $SENTRY_DEBUG and $SENTRY_SPOTLIGHT ([#2374](https://github.com/getsentry/sentry-ruby/pull/2374)) +- Experimental support for multi-threaded profiling using [Vernier](https://github.com/jhawthorn/vernier) ([#2372](https://github.com/getsentry/sentry-ruby/pull/2372)) + + You can have much better profiles if you're using multi-threaded servers like Puma now by leveraging Vernier. + To use it, first add `vernier` to your `Gemfile` and make sure it is loaded before `sentry-ruby`. + + ```ruby + # Gemfile + + gem 'vernier' + gem 'sentry-ruby' + ``` + + Then, set a `profiles_sample_rate` and the new `profiler_class` configuration in your sentry initializer to use the new profiler. + + ```ruby + # config/initializers/sentry.rb + + Sentry.init do |config| + # ... + config.profiles_sample_rate = 1.0 + config.profiler_class = Sentry::Vernier::Profiler + end + ``` + +### Internal + +- Profile items have bigger size limit now ([#2421](https://github.com/getsentry/sentry-ruby/pull/2421)) +- Consistent string freezing ([#2422](https://github.com/getsentry/sentry-ruby/pull/2422)) + +## 5.20.1 + +### Bug Fixes + +- Skip `rubocop.yml` in `spec.files` ([#2420](https://github.com/getsentry/sentry-ruby/pull/2420)) + +## 5.20.0 + +- Add support for `$SENTRY_DEBUG` and `$SENTRY_SPOTLIGHT` ([#2374](https://github.com/getsentry/sentry-ruby/pull/2374)) - Support human readable intervals in `sidekiq-cron` ([#2387](https://github.com/getsentry/sentry-ruby/pull/2387)) -- Add support for Sentry Cache instrumentation, when using Rails.cache ([#2380](https://github.com/getsentry/sentry-ruby/pull/2380)) +- Set default app dirs pattern ([#2390](https://github.com/getsentry/sentry-ruby/pull/2390)) +- Add new `strip_backtrace_load_path` boolean config (default true) to enable disabling load path stripping ([#2409](https://github.com/getsentry/sentry-ruby/pull/2409)) + +### Bug Fixes + +- Fix error events missing a DSC when there's an active span ([#2408](https://github.com/getsentry/sentry-ruby/pull/2408)) +- Verifies presence of client before adding a breadcrumb ([#2394](https://github.com/getsentry/sentry-ruby/pull/2394)) +- Fix `Net:HTTP` integration for non-ASCII URI's ([#2417](https://github.com/getsentry/sentry-ruby/pull/2417)) +- Prevent Hub from having nil scope and client ([#2402](https://github.com/getsentry/sentry-ruby/pull/2402)) ## 5.19.0 diff --git a/Gemfile b/Gemfile index c897e543f..9847a55e8 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + source "https://rubygems.org" git_source(:github) { |name| "https://github.com/#{name}.git" } diff --git a/sentry-delayed_job/Gemfile b/sentry-delayed_job/Gemfile index 936bec48a..48e80fbdc 100644 --- a/sentry-delayed_job/Gemfile +++ b/sentry-delayed_job/Gemfile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + source "https://rubygems.org" git_source(:github) { |name| "https://github.com/#{name}.git" } diff --git a/sentry-delayed_job/Rakefile b/sentry-delayed_job/Rakefile index 7b2756854..13afab191 100644 --- a/sentry-delayed_job/Rakefile +++ b/sentry-delayed_job/Rakefile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "bundler/gem_tasks" require "rspec/core/rake_task" diff --git a/sentry-delayed_job/bin/console b/sentry-delayed_job/bin/console index 660c7a889..f0f5a7b6a 100755 --- a/sentry-delayed_job/bin/console +++ b/sentry-delayed_job/bin/console @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true require "bundler/setup" require "sentry/ruby" diff --git a/sentry-delayed_job/example/Gemfile b/sentry-delayed_job/example/Gemfile index 2ed843ab1..d138c16d5 100644 --- a/sentry-delayed_job/example/Gemfile +++ b/sentry-delayed_job/example/Gemfile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + source "https://rubygems.org" gem "rails" diff --git a/sentry-delayed_job/example/app.rb b/sentry-delayed_job/example/app.rb index bcec27c52..04f391468 100644 --- a/sentry-delayed_job/example/app.rb +++ b/sentry-delayed_job/example/app.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_job" require "active_record" require "delayed_job" diff --git a/sentry-delayed_job/lib/sentry-delayed_job.rb b/sentry-delayed_job/lib/sentry-delayed_job.rb index f96b03b6a..bc961259f 100644 --- a/sentry-delayed_job/lib/sentry-delayed_job.rb +++ b/sentry-delayed_job/lib/sentry-delayed_job.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "delayed_job" require "sentry-ruby" require "sentry/integrable" diff --git a/sentry-delayed_job/lib/sentry/delayed_job/configuration.rb b/sentry-delayed_job/lib/sentry/delayed_job/configuration.rb index 4408b37af..42ee8e63c 100644 --- a/sentry-delayed_job/lib/sentry/delayed_job/configuration.rb +++ b/sentry-delayed_job/lib/sentry/delayed_job/configuration.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sentry class Configuration attr_reader :delayed_job diff --git a/sentry-delayed_job/lib/sentry/delayed_job/version.rb b/sentry-delayed_job/lib/sentry/delayed_job/version.rb index 95d3630b0..e9d6999c6 100644 --- a/sentry-delayed_job/lib/sentry/delayed_job/version.rb +++ b/sentry-delayed_job/lib/sentry/delayed_job/version.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + module Sentry module DelayedJob - VERSION = "5.19.0" + VERSION = "5.21.0" end end diff --git a/sentry-delayed_job/sentry-delayed_job.gemspec b/sentry-delayed_job/sentry-delayed_job.gemspec index e97096bcb..fc6a50341 100644 --- a/sentry-delayed_job/sentry-delayed_job.gemspec +++ b/sentry-delayed_job/sentry-delayed_job.gemspec @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative "lib/sentry/delayed_job/version" Gem::Specification.new do |spec| @@ -11,7 +13,7 @@ Gem::Specification.new do |spec| spec.platform = Gem::Platform::RUBY spec.required_ruby_version = '>= 2.4' spec.extra_rdoc_files = ["README.md", "LICENSE.txt"] - spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples)'`.split("\n") + spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples|\.rubocop\.yml)'`.split("\n") github_root_uri = 'https://github.com/getsentry/sentry-ruby' spec.homepage = "#{github_root_uri}/tree/#{spec.version}/#{spec.name}" @@ -28,6 +30,6 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] - spec.add_dependency "sentry-ruby", "~> 5.19.0" + spec.add_dependency "sentry-ruby", "~> 5.21.0" spec.add_dependency "delayed_job", ">= 4.0" end diff --git a/sentry-delayed_job/spec/sentry/delayed_job/configuration_spec.rb b/sentry-delayed_job/spec/sentry/delayed_job/configuration_spec.rb index fdde5b4f5..a785f53c3 100644 --- a/sentry-delayed_job/spec/sentry/delayed_job/configuration_spec.rb +++ b/sentry-delayed_job/spec/sentry/delayed_job/configuration_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::DelayedJob::Configuration do diff --git a/sentry-delayed_job/spec/sentry/delayed_job_spec.rb b/sentry-delayed_job/spec/sentry/delayed_job_spec.rb index ac2d31fb1..24a1de77d 100644 --- a/sentry-delayed_job/spec/sentry/delayed_job_spec.rb +++ b/sentry-delayed_job/spec/sentry/delayed_job_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::DelayedJob do diff --git a/sentry-delayed_job/spec/spec_helper.rb b/sentry-delayed_job/spec/spec_helper.rb index 2d8bf6d10..3e07723bb 100644 --- a/sentry-delayed_job/spec/spec_helper.rb +++ b/sentry-delayed_job/spec/spec_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "bundler/setup" begin require "debug/prelude" diff --git a/sentry-opentelemetry/Gemfile b/sentry-opentelemetry/Gemfile index e084c17c6..b30d36d42 100644 --- a/sentry-opentelemetry/Gemfile +++ b/sentry-opentelemetry/Gemfile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + source "https://rubygems.org" git_source(:github) { |name| "https://github.com/#{name}.git" } diff --git a/sentry-opentelemetry/Rakefile b/sentry-opentelemetry/Rakefile index 7b2756854..13afab191 100644 --- a/sentry-opentelemetry/Rakefile +++ b/sentry-opentelemetry/Rakefile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "bundler/gem_tasks" require "rspec/core/rake_task" diff --git a/sentry-opentelemetry/lib/sentry/opentelemetry/version.rb b/sentry-opentelemetry/lib/sentry/opentelemetry/version.rb index ddc0cbe67..d9e8b1083 100644 --- a/sentry-opentelemetry/lib/sentry/opentelemetry/version.rb +++ b/sentry-opentelemetry/lib/sentry/opentelemetry/version.rb @@ -2,6 +2,6 @@ module Sentry module OpenTelemetry - VERSION = "5.19.0" + VERSION = "5.21.0" end end diff --git a/sentry-opentelemetry/sentry-opentelemetry.gemspec b/sentry-opentelemetry/sentry-opentelemetry.gemspec index aaee606be..516908891 100644 --- a/sentry-opentelemetry/sentry-opentelemetry.gemspec +++ b/sentry-opentelemetry/sentry-opentelemetry.gemspec @@ -13,7 +13,7 @@ Gem::Specification.new do |spec| spec.platform = Gem::Platform::RUBY spec.required_ruby_version = '>= 2.4' spec.extra_rdoc_files = ["README.md", "LICENSE.txt"] - spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples)'`.split("\n") + spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples|\.rubocop\.yml)'`.split("\n") github_root_uri = 'https://github.com/getsentry/sentry-ruby' spec.homepage = "#{github_root_uri}/tree/#{spec.version}/#{spec.name}" @@ -30,6 +30,6 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] - spec.add_dependency "sentry-ruby", "~> 5.19.0" + spec.add_dependency "sentry-ruby", "~> 5.21.0" spec.add_dependency "opentelemetry-sdk", "~> 1.0" end diff --git a/sentry-rails/Gemfile b/sentry-rails/Gemfile index e203e41a1..7695eff15 100644 --- a/sentry-rails/Gemfile +++ b/sentry-rails/Gemfile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + source "https://rubygems.org" git_source(:github) { |name| "https://github.com/#{name}.git" } diff --git a/sentry-rails/Rakefile b/sentry-rails/Rakefile index 2624fb72e..d58f59ad2 100644 --- a/sentry-rails/Rakefile +++ b/sentry-rails/Rakefile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "bundler/gem_tasks" require "rspec/core/rake_task" diff --git a/sentry-rails/app/jobs/sentry/send_event_job.rb b/sentry-rails/app/jobs/sentry/send_event_job.rb index 75ac80529..06ca59172 100644 --- a/sentry-rails/app/jobs/sentry/send_event_job.rb +++ b/sentry-rails/app/jobs/sentry/send_event_job.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + if defined?(ActiveJob) module Sentry parent_job = diff --git a/sentry-rails/benchmarks/allocation_comparison.rb b/sentry-rails/benchmarks/allocation_comparison.rb index f2499d937..15b1e3c4a 100644 --- a/sentry-rails/benchmarks/allocation_comparison.rb +++ b/sentry-rails/benchmarks/allocation_comparison.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'benchmark/memory' require "sentry-ruby" require "sentry/benchmarks/benchmark_transport" diff --git a/sentry-rails/benchmarks/allocation_report.rb b/sentry-rails/benchmarks/allocation_report.rb index 13fee1513..9bc691a26 100644 --- a/sentry-rails/benchmarks/allocation_report.rb +++ b/sentry-rails/benchmarks/allocation_report.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'benchmark/ipsa' require "sentry-ruby" require "sentry/benchmarks/benchmark_transport" diff --git a/sentry-rails/benchmarks/application.rb b/sentry-rails/benchmarks/application.rb index fa4d3f5e8..0ef435cee 100644 --- a/sentry-rails/benchmarks/application.rb +++ b/sentry-rails/benchmarks/application.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_support/all" require "action_controller" require_relative "../spec/support/test_rails_app/app" diff --git a/sentry-rails/bin/console b/sentry-rails/bin/console index 660c7a889..f0f5a7b6a 100755 --- a/sentry-rails/bin/console +++ b/sentry-rails/bin/console @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true require "bundler/setup" require "sentry/ruby" diff --git a/sentry-rails/lib/generators/sentry_generator.rb b/sentry-rails/lib/generators/sentry_generator.rb index de694e40d..e293dae95 100644 --- a/sentry-rails/lib/generators/sentry_generator.rb +++ b/sentry-rails/lib/generators/sentry_generator.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "rails/generators/base" class SentryGenerator < ::Rails::Generators::Base diff --git a/sentry-rails/lib/sentry-rails.rb b/sentry-rails/lib/sentry-rails.rb index c436e1dfa..a8d6499b1 100644 --- a/sentry-rails/lib/sentry-rails.rb +++ b/sentry-rails/lib/sentry-rails.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + require "sentry/rails/version" require "sentry/rails" diff --git a/sentry-rails/lib/sentry/rails.rb b/sentry-rails/lib/sentry/rails.rb index 14c8e1b80..b4b79dd85 100644 --- a/sentry-rails/lib/sentry/rails.rb +++ b/sentry-rails/lib/sentry/rails.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "rails" require "sentry-ruby" require "sentry/integrable" diff --git a/sentry-rails/lib/sentry/rails/action_cable.rb b/sentry-rails/lib/sentry/rails/action_cable.rb index 06833a68b..222aab1b8 100644 --- a/sentry-rails/lib/sentry/rails/action_cable.rb +++ b/sentry-rails/lib/sentry/rails/action_cable.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + module Sentry module Rails module ActionCableExtensions class ErrorHandler - OP_NAME = "websocket.server".freeze + OP_NAME = "websocket.server" SPAN_ORIGIN = "auto.http.rails.actioncable" class << self diff --git a/sentry-rails/lib/sentry/rails/active_job.rb b/sentry-rails/lib/sentry/rails/active_job.rb index afdf87cd7..953af632b 100644 --- a/sentry-rails/lib/sentry/rails/active_job.rb +++ b/sentry-rails/lib/sentry/rails/active_job.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sentry module Rails module ActiveJobExtensions @@ -16,8 +18,8 @@ def already_supported_by_sentry_integration? end class SentryReporter - OP_NAME = "queue.active_job".freeze - SPAN_ORIGIN = "auto.queue.active_job".freeze + OP_NAME = "queue.active_job" + SPAN_ORIGIN = "auto.queue.active_job" class << self def record(job, &block) diff --git a/sentry-rails/lib/sentry/rails/background_worker.rb b/sentry-rails/lib/sentry/rails/background_worker.rb index 56dcd6609..2c0cc7a71 100644 --- a/sentry-rails/lib/sentry/rails/background_worker.rb +++ b/sentry-rails/lib/sentry/rails/background_worker.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sentry class BackgroundWorker def _perform(&block) diff --git a/sentry-rails/lib/sentry/rails/backtrace_cleaner.rb b/sentry-rails/lib/sentry/rails/backtrace_cleaner.rb index 25812b97a..57030f733 100644 --- a/sentry-rails/lib/sentry/rails/backtrace_cleaner.rb +++ b/sentry-rails/lib/sentry/rails/backtrace_cleaner.rb @@ -1,11 +1,13 @@ +# frozen_string_literal: true + require "active_support/backtrace_cleaner" require "active_support/core_ext/string/access" module Sentry module Rails class BacktraceCleaner < ActiveSupport::BacktraceCleaner - APP_DIRS_PATTERN = /\A(?:\.\/)?(?:app|config|lib|test|\(\w*\))/.freeze - RENDER_TEMPLATE_PATTERN = /:in `.*_\w+_{2,3}\d+_\d+'/.freeze + APP_DIRS_PATTERN = /\A(?:\.\/)?(?:app|config|lib|test|\(\w*\))/ + RENDER_TEMPLATE_PATTERN = /:in `.*_\w+_{2,3}\d+_\d+'/ def initialize super diff --git a/sentry-rails/lib/sentry/rails/breadcrumb/active_support_logger.rb b/sentry-rails/lib/sentry/rails/breadcrumb/active_support_logger.rb index 9dfdd1d26..a301cb960 100644 --- a/sentry-rails/lib/sentry/rails/breadcrumb/active_support_logger.rb +++ b/sentry-rails/lib/sentry/rails/breadcrumb/active_support_logger.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sentry module Rails module Breadcrumb diff --git a/sentry-rails/lib/sentry/rails/breadcrumb/monotonic_active_support_logger.rb b/sentry-rails/lib/sentry/rails/breadcrumb/monotonic_active_support_logger.rb index 71785d256..541f9bea3 100644 --- a/sentry-rails/lib/sentry/rails/breadcrumb/monotonic_active_support_logger.rb +++ b/sentry-rails/lib/sentry/rails/breadcrumb/monotonic_active_support_logger.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "sentry/rails/instrument_payload_cleanup_helper" module Sentry diff --git a/sentry-rails/lib/sentry/rails/capture_exceptions.rb b/sentry-rails/lib/sentry/rails/capture_exceptions.rb index 3216d2a3a..f571bd689 100644 --- a/sentry-rails/lib/sentry/rails/capture_exceptions.rb +++ b/sentry-rails/lib/sentry/rails/capture_exceptions.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + module Sentry module Rails class CaptureExceptions < Sentry::Rack::CaptureExceptions RAILS_7_1 = Gem::Version.new(::Rails.version) >= Gem::Version.new("7.1.0.alpha") - SPAN_ORIGIN = "auto.http.rails".freeze + SPAN_ORIGIN = "auto.http.rails" def initialize(_) super @@ -20,7 +22,7 @@ def collect_exception(env) end def transaction_op - "http.server".freeze + "http.server" end def capture_exception(exception, env) diff --git a/sentry-rails/lib/sentry/rails/configuration.rb b/sentry-rails/lib/sentry/rails/configuration.rb index c88a2a7c7..a28a07f69 100644 --- a/sentry-rails/lib/sentry/rails/configuration.rb +++ b/sentry-rails/lib/sentry/rails/configuration.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "sentry/rails/tracing/action_controller_subscriber" require "sentry/rails/tracing/action_view_subscriber" require "sentry/rails/tracing/active_record_subscriber" diff --git a/sentry-rails/lib/sentry/rails/controller_methods.rb b/sentry-rails/lib/sentry/rails/controller_methods.rb index 90330e946..aa8b4f3e4 100644 --- a/sentry-rails/lib/sentry/rails/controller_methods.rb +++ b/sentry-rails/lib/sentry/rails/controller_methods.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sentry module Rails module ControllerMethods diff --git a/sentry-rails/lib/sentry/rails/controller_transaction.rb b/sentry-rails/lib/sentry/rails/controller_transaction.rb index cd3ffa38b..8f19bb63d 100644 --- a/sentry-rails/lib/sentry/rails/controller_transaction.rb +++ b/sentry-rails/lib/sentry/rails/controller_transaction.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + module Sentry module Rails module ControllerTransaction - SPAN_ORIGIN = "auto.view.rails".freeze + SPAN_ORIGIN = "auto.view.rails" def self.included(base) base.prepend_around_action(:sentry_around_action) diff --git a/sentry-rails/lib/sentry/rails/engine.rb b/sentry-rails/lib/sentry/rails/engine.rb index 12ac173a7..dc50819cd 100644 --- a/sentry-rails/lib/sentry/rails/engine.rb +++ b/sentry-rails/lib/sentry/rails/engine.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sentry class Engine < ::Rails::Engine isolate_namespace Sentry diff --git a/sentry-rails/lib/sentry/rails/error_subscriber.rb b/sentry-rails/lib/sentry/rails/error_subscriber.rb index fac675dbf..dad598c51 100644 --- a/sentry-rails/lib/sentry/rails/error_subscriber.rb +++ b/sentry-rails/lib/sentry/rails/error_subscriber.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sentry module Rails # This is not a user-facing class. You should use it with Rails 7.0's error reporter feature and its interfaces. diff --git a/sentry-rails/lib/sentry/rails/instrument_payload_cleanup_helper.rb b/sentry-rails/lib/sentry/rails/instrument_payload_cleanup_helper.rb index 343d2d41c..07422c5e8 100644 --- a/sentry-rails/lib/sentry/rails/instrument_payload_cleanup_helper.rb +++ b/sentry-rails/lib/sentry/rails/instrument_payload_cleanup_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sentry module Rails module InstrumentPayloadCleanupHelper diff --git a/sentry-rails/lib/sentry/rails/overrides/streaming_reporter.rb b/sentry-rails/lib/sentry/rails/overrides/streaming_reporter.rb index 5ce0c637b..1fdd4ad60 100644 --- a/sentry-rails/lib/sentry/rails/overrides/streaming_reporter.rb +++ b/sentry-rails/lib/sentry/rails/overrides/streaming_reporter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sentry module Rails module Overrides diff --git a/sentry-rails/lib/sentry/rails/railtie.rb b/sentry-rails/lib/sentry/rails/railtie.rb index e4926cc0f..0a0cdf213 100644 --- a/sentry-rails/lib/sentry/rails/railtie.rb +++ b/sentry-rails/lib/sentry/rails/railtie.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "sentry/rails/capture_exceptions" require "sentry/rails/rescued_exception_interceptor" require "sentry/rails/backtrace_cleaner" diff --git a/sentry-rails/lib/sentry/rails/rescued_exception_interceptor.rb b/sentry-rails/lib/sentry/rails/rescued_exception_interceptor.rb index 2c977dba4..43cb69db1 100644 --- a/sentry-rails/lib/sentry/rails/rescued_exception_interceptor.rb +++ b/sentry-rails/lib/sentry/rails/rescued_exception_interceptor.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sentry module Rails class RescuedExceptionInterceptor diff --git a/sentry-rails/lib/sentry/rails/tracing.rb b/sentry-rails/lib/sentry/rails/tracing.rb index 3c5ae2222..82509ab8b 100644 --- a/sentry-rails/lib/sentry/rails/tracing.rb +++ b/sentry-rails/lib/sentry/rails/tracing.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sentry module Rails module Tracing diff --git a/sentry-rails/lib/sentry/rails/tracing/abstract_subscriber.rb b/sentry-rails/lib/sentry/rails/tracing/abstract_subscriber.rb index fec3f7bde..7ba338c6b 100644 --- a/sentry-rails/lib/sentry/rails/tracing/abstract_subscriber.rb +++ b/sentry-rails/lib/sentry/rails/tracing/abstract_subscriber.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sentry module Rails module Tracing diff --git a/sentry-rails/lib/sentry/rails/tracing/action_controller_subscriber.rb b/sentry-rails/lib/sentry/rails/tracing/action_controller_subscriber.rb index 11e9eadf2..42b89ce32 100644 --- a/sentry-rails/lib/sentry/rails/tracing/action_controller_subscriber.rb +++ b/sentry-rails/lib/sentry/rails/tracing/action_controller_subscriber.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "sentry/rails/tracing/abstract_subscriber" require "sentry/rails/instrument_payload_cleanup_helper" @@ -8,8 +10,8 @@ class ActionControllerSubscriber < AbstractSubscriber extend InstrumentPayloadCleanupHelper EVENT_NAMES = ["process_action.action_controller"].freeze - OP_NAME = "view.process_action.action_controller".freeze - SPAN_ORIGIN = "auto.view.rails".freeze + OP_NAME = "view.process_action.action_controller" + SPAN_ORIGIN = "auto.view.rails" def self.subscribe! Sentry.logger.warn <<~MSG diff --git a/sentry-rails/lib/sentry/rails/tracing/action_view_subscriber.rb b/sentry-rails/lib/sentry/rails/tracing/action_view_subscriber.rb index baed2c7e5..3f56d72ac 100644 --- a/sentry-rails/lib/sentry/rails/tracing/action_view_subscriber.rb +++ b/sentry-rails/lib/sentry/rails/tracing/action_view_subscriber.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "sentry/rails/tracing/abstract_subscriber" module Sentry @@ -5,8 +7,8 @@ module Rails module Tracing class ActionViewSubscriber < AbstractSubscriber EVENT_NAMES = ["render_template.action_view"].freeze - SPAN_PREFIX = "template.".freeze - SPAN_ORIGIN = "auto.template.rails".freeze + SPAN_PREFIX = "template." + SPAN_ORIGIN = "auto.template.rails" def self.subscribe! subscribe_to_event(EVENT_NAMES) do |event_name, duration, payload| diff --git a/sentry-rails/lib/sentry/rails/tracing/active_storage_subscriber.rb b/sentry-rails/lib/sentry/rails/tracing/active_storage_subscriber.rb index 5d62bad22..50ee0d703 100644 --- a/sentry-rails/lib/sentry/rails/tracing/active_storage_subscriber.rb +++ b/sentry-rails/lib/sentry/rails/tracing/active_storage_subscriber.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "sentry/rails/tracing/abstract_subscriber" module Sentry @@ -19,12 +21,12 @@ class ActiveStorageSubscriber < AbstractSubscriber analyze.active_storage ].freeze - SPAN_ORIGIN = "auto.file.rails".freeze + SPAN_ORIGIN = "auto.file.rails" def self.subscribe! subscribe_to_event(EVENT_NAMES) do |event_name, duration, payload| record_on_current_span( - op: "file.#{event_name}".freeze, + op: "file.#{event_name}", origin: SPAN_ORIGIN, start_timestamp: payload[START_TIMESTAMP_NAME], description: payload[:service], diff --git a/sentry-rails/lib/sentry/rails/version.rb b/sentry-rails/lib/sentry/rails/version.rb index ac6bcb23b..f234ea7ea 100644 --- a/sentry-rails/lib/sentry/rails/version.rb +++ b/sentry-rails/lib/sentry/rails/version.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + module Sentry module Rails - VERSION = "5.19.0" + VERSION = "5.21.0" end end diff --git a/sentry-rails/sentry-rails.gemspec b/sentry-rails/sentry-rails.gemspec index 7cfdd0e70..ebb19c1b0 100644 --- a/sentry-rails/sentry-rails.gemspec +++ b/sentry-rails/sentry-rails.gemspec @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative "lib/sentry/rails/version" Gem::Specification.new do |spec| @@ -11,7 +13,7 @@ Gem::Specification.new do |spec| spec.platform = Gem::Platform::RUBY spec.required_ruby_version = '>= 2.4' spec.extra_rdoc_files = ["README.md", "LICENSE.txt"] - spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples)'`.split("\n") + spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples|\.rubocop\.yml)'`.split("\n") github_root_uri = 'https://github.com/getsentry/sentry-ruby' spec.homepage = "#{github_root_uri}/tree/#{spec.version}/#{spec.name}" @@ -29,5 +31,5 @@ Gem::Specification.new do |spec| spec.require_paths = ["lib"] spec.add_dependency "railties", ">= 5.0" - spec.add_dependency "sentry-ruby", "~> 5.19.0" + spec.add_dependency "sentry-ruby", "~> 5.21.0" end diff --git a/sentry-rails/spec/dummy/test_rails_app/app.rb b/sentry-rails/spec/dummy/test_rails_app/app.rb index c1181e5ff..9e9ccfd6d 100644 --- a/sentry-rails/spec/dummy/test_rails_app/app.rb +++ b/sentry-rails/spec/dummy/test_rails_app/app.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + ENV["RAILS_ENV"] = "test" require "rails" diff --git a/sentry-rails/spec/dummy/test_rails_app/apps/5-0.rb b/sentry-rails/spec/dummy/test_rails_app/apps/5-0.rb index f1b3a2758..a68a68358 100644 --- a/sentry-rails/spec/dummy/test_rails_app/apps/5-0.rb +++ b/sentry-rails/spec/dummy/test_rails_app/apps/5-0.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + ActiveRecord::Schema.define do create_table :posts, force: true do |t| end diff --git a/sentry-rails/spec/dummy/test_rails_app/apps/5-2.rb b/sentry-rails/spec/dummy/test_rails_app/apps/5-2.rb index e7b1f2180..9dfcf0d62 100644 --- a/sentry-rails/spec/dummy/test_rails_app/apps/5-2.rb +++ b/sentry-rails/spec/dummy/test_rails_app/apps/5-2.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + ActiveRecord::Schema.define do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false diff --git a/sentry-rails/spec/dummy/test_rails_app/apps/6-0.rb b/sentry-rails/spec/dummy/test_rails_app/apps/6-0.rb index e7b1f2180..9dfcf0d62 100644 --- a/sentry-rails/spec/dummy/test_rails_app/apps/6-0.rb +++ b/sentry-rails/spec/dummy/test_rails_app/apps/6-0.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + ActiveRecord::Schema.define do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false diff --git a/sentry-rails/spec/dummy/test_rails_app/apps/6-1.rb b/sentry-rails/spec/dummy/test_rails_app/apps/6-1.rb index ac504704e..a9148a3ee 100644 --- a/sentry-rails/spec/dummy/test_rails_app/apps/6-1.rb +++ b/sentry-rails/spec/dummy/test_rails_app/apps/6-1.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + ActiveRecord::Schema.define do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false diff --git a/sentry-rails/spec/dummy/test_rails_app/apps/7-0.rb b/sentry-rails/spec/dummy/test_rails_app/apps/7-0.rb index ac504704e..a9148a3ee 100644 --- a/sentry-rails/spec/dummy/test_rails_app/apps/7-0.rb +++ b/sentry-rails/spec/dummy/test_rails_app/apps/7-0.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + ActiveRecord::Schema.define do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false diff --git a/sentry-rails/spec/dummy/test_rails_app/apps/7-1.rb b/sentry-rails/spec/dummy/test_rails_app/apps/7-1.rb index ac504704e..a9148a3ee 100644 --- a/sentry-rails/spec/dummy/test_rails_app/apps/7-1.rb +++ b/sentry-rails/spec/dummy/test_rails_app/apps/7-1.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + ActiveRecord::Schema.define do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false diff --git a/sentry-rails/spec/dummy/test_rails_app/configs/5-0.rb b/sentry-rails/spec/dummy/test_rails_app/configs/5-0.rb index 70cb662b3..d291ac8f8 100644 --- a/sentry-rails/spec/dummy/test_rails_app/configs/5-0.rb +++ b/sentry-rails/spec/dummy/test_rails_app/configs/5-0.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + def run_pre_initialize_cleanup; end def configure_app(app); end diff --git a/sentry-rails/spec/dummy/test_rails_app/configs/5-2.rb b/sentry-rails/spec/dummy/test_rails_app/configs/5-2.rb index f6b4f39e5..d5d88d8b6 100644 --- a/sentry-rails/spec/dummy/test_rails_app/configs/5-2.rb +++ b/sentry-rails/spec/dummy/test_rails_app/configs/5-2.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_storage/engine" def run_pre_initialize_cleanup; end diff --git a/sentry-rails/spec/dummy/test_rails_app/configs/6-0.rb b/sentry-rails/spec/dummy/test_rails_app/configs/6-0.rb index 7b0673b3c..bab5746a8 100644 --- a/sentry-rails/spec/dummy/test_rails_app/configs/6-0.rb +++ b/sentry-rails/spec/dummy/test_rails_app/configs/6-0.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_storage/engine" require "action_cable/engine" diff --git a/sentry-rails/spec/dummy/test_rails_app/configs/6-1.rb b/sentry-rails/spec/dummy/test_rails_app/configs/6-1.rb index 4532be7ca..e36c83344 100644 --- a/sentry-rails/spec/dummy/test_rails_app/configs/6-1.rb +++ b/sentry-rails/spec/dummy/test_rails_app/configs/6-1.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_storage/engine" require "action_cable/engine" diff --git a/sentry-rails/spec/dummy/test_rails_app/configs/7-0.rb b/sentry-rails/spec/dummy/test_rails_app/configs/7-0.rb index dd5d0716c..84652ae04 100644 --- a/sentry-rails/spec/dummy/test_rails_app/configs/7-0.rb +++ b/sentry-rails/spec/dummy/test_rails_app/configs/7-0.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_storage/engine" require "action_cable/engine" diff --git a/sentry-rails/spec/dummy/test_rails_app/configs/7-1.rb b/sentry-rails/spec/dummy/test_rails_app/configs/7-1.rb index d17545fe0..d0126d985 100644 --- a/sentry-rails/spec/dummy/test_rails_app/configs/7-1.rb +++ b/sentry-rails/spec/dummy/test_rails_app/configs/7-1.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_storage/engine" require "action_cable/engine" require "sentry/rails/error_subscriber" diff --git a/sentry-rails/spec/dummy/test_rails_app/configs/7-2.rb b/sentry-rails/spec/dummy/test_rails_app/configs/7-2.rb index d17545fe0..d0126d985 100644 --- a/sentry-rails/spec/dummy/test_rails_app/configs/7-2.rb +++ b/sentry-rails/spec/dummy/test_rails_app/configs/7-2.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_storage/engine" require "action_cable/engine" require "sentry/rails/error_subscriber" diff --git a/sentry-rails/spec/sentry/rails/action_cable_spec.rb b/sentry-rails/spec/sentry/rails/action_cable_spec.rb index 4b353adff..e47ad2efa 100644 --- a/sentry-rails/spec/sentry/rails/action_cable_spec.rb +++ b/sentry-rails/spec/sentry/rails/action_cable_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + if defined?(ActionCable) && ActionCable.version >= Gem::Version.new('6.0.0') require "spec_helper" require "action_cable/engine" diff --git a/sentry-rails/spec/sentry/rails/activejob_spec.rb b/sentry-rails/spec/sentry/rails/activejob_spec.rb index f5892d944..9e9e0ce36 100644 --- a/sentry-rails/spec/sentry/rails/activejob_spec.rb +++ b/sentry-rails/spec/sentry/rails/activejob_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" require "active_job/railtie" diff --git a/sentry-rails/spec/sentry/rails/breadcrumbs/active_support_logger_spec.rb b/sentry-rails/spec/sentry/rails/breadcrumbs/active_support_logger_spec.rb index b156eaf59..e6a0ae6e3 100644 --- a/sentry-rails/spec/sentry/rails/breadcrumbs/active_support_logger_spec.rb +++ b/sentry-rails/spec/sentry/rails/breadcrumbs/active_support_logger_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe "Sentry::Breadcrumbs::ActiveSupportLogger", type: :request do diff --git a/sentry-rails/spec/sentry/rails/breadcrumbs/monotonic_active_support_logger_spec.rb b/sentry-rails/spec/sentry/rails/breadcrumbs/monotonic_active_support_logger_spec.rb index 0334531f6..031443c25 100644 --- a/sentry-rails/spec/sentry/rails/breadcrumbs/monotonic_active_support_logger_spec.rb +++ b/sentry-rails/spec/sentry/rails/breadcrumbs/monotonic_active_support_logger_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" diff --git a/sentry-rails/spec/sentry/rails/client_spec.rb b/sentry-rails/spec/sentry/rails/client_spec.rb index 81c847b9d..86ef1e110 100644 --- a/sentry-rails/spec/sentry/rails/client_spec.rb +++ b/sentry-rails/spec/sentry/rails/client_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Client, type: :request, retry: 3, skip: Gem::Version.new(Rails.version) < Gem::Version.new('5.1.0') do diff --git a/sentry-rails/spec/sentry/rails/configuration_spec.rb b/sentry-rails/spec/sentry/rails/configuration_spec.rb index 91cf21c4e..37c5a41d6 100644 --- a/sentry-rails/spec/sentry/rails/configuration_spec.rb +++ b/sentry-rails/spec/sentry/rails/configuration_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Rails::Configuration do diff --git a/sentry-rails/spec/sentry/rails/controller_methods_spec.rb b/sentry-rails/spec/sentry/rails/controller_methods_spec.rb index a751e1366..6254dc290 100644 --- a/sentry-rails/spec/sentry/rails/controller_methods_spec.rb +++ b/sentry-rails/spec/sentry/rails/controller_methods_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require "sentry/rails/controller_methods" diff --git a/sentry-rails/spec/sentry/rails/error_subscriber_spec.rb b/sentry-rails/spec/sentry/rails/error_subscriber_spec.rb index 1bce4baca..1dcc1a0f4 100644 --- a/sentry-rails/spec/sentry/rails/error_subscriber_spec.rb +++ b/sentry-rails/spec/sentry/rails/error_subscriber_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'sentry/rails/error_subscriber' diff --git a/sentry-rails/spec/sentry/rails/event_spec.rb b/sentry-rails/spec/sentry/rails/event_spec.rb index 674615f3a..6c3f7b661 100644 --- a/sentry-rails/spec/sentry/rails/event_spec.rb +++ b/sentry-rails/spec/sentry/rails/event_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Event do diff --git a/sentry-rails/spec/sentry/rails/tracing/action_controller_subscriber_spec.rb b/sentry-rails/spec/sentry/rails/tracing/action_controller_subscriber_spec.rb index f147e1b8e..9d0a4df4e 100644 --- a/sentry-rails/spec/sentry/rails/tracing/action_controller_subscriber_spec.rb +++ b/sentry-rails/spec/sentry/rails/tracing/action_controller_subscriber_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Rails::Tracing::ActionControllerSubscriber, :subscriber, type: :request do diff --git a/sentry-rails/spec/sentry/rails/tracing/action_view_subscriber_spec.rb b/sentry-rails/spec/sentry/rails/tracing/action_view_subscriber_spec.rb index aa2473312..555584024 100644 --- a/sentry-rails/spec/sentry/rails/tracing/action_view_subscriber_spec.rb +++ b/sentry-rails/spec/sentry/rails/tracing/action_view_subscriber_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Rails::Tracing::ActionViewSubscriber, :subscriber, type: :request do diff --git a/sentry-rails/spec/sentry/rails/tracing/active_record_subscriber_spec.rb b/sentry-rails/spec/sentry/rails/tracing/active_record_subscriber_spec.rb index aa29b82d2..2441a63d3 100644 --- a/sentry-rails/spec/sentry/rails/tracing/active_record_subscriber_spec.rb +++ b/sentry-rails/spec/sentry/rails/tracing/active_record_subscriber_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Rails::Tracing::ActiveRecordSubscriber, :subscriber do diff --git a/sentry-rails/spec/sentry/rails/tracing/active_storage_subscriber_spec.rb b/sentry-rails/spec/sentry/rails/tracing/active_storage_subscriber_spec.rb index 5d34db1e3..a5e186d7e 100644 --- a/sentry-rails/spec/sentry/rails/tracing/active_storage_subscriber_spec.rb +++ b/sentry-rails/spec/sentry/rails/tracing/active_storage_subscriber_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Rails::Tracing::ActiveStorageSubscriber, :subscriber, type: :request, skip: Rails.version.to_f <= 5.2 do diff --git a/sentry-rails/spec/sentry/rails/tracing_spec.rb b/sentry-rails/spec/sentry/rails/tracing_spec.rb index 287bd8acc..927e11c8e 100644 --- a/sentry-rails/spec/sentry/rails/tracing_spec.rb +++ b/sentry-rails/spec/sentry/rails/tracing_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Rails::Tracing, type: :request do diff --git a/sentry-rails/spec/sentry/rails_spec.rb b/sentry-rails/spec/sentry/rails_spec.rb index 88c1dae1f..dd069db81 100644 --- a/sentry-rails/spec/sentry/rails_spec.rb +++ b/sentry-rails/spec/sentry/rails_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Rails, type: :request do diff --git a/sentry-rails/spec/sentry/send_event_job_spec.rb b/sentry-rails/spec/sentry/send_event_job_spec.rb index c50130f65..00f89b2ed 100644 --- a/sentry-rails/spec/sentry/send_event_job_spec.rb +++ b/sentry-rails/spec/sentry/send_event_job_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_job" require "spec_helper" diff --git a/sentry-rails/spec/spec_helper.rb b/sentry-rails/spec/spec_helper.rb index 55d3334d3..68b7d5a04 100644 --- a/sentry-rails/spec/spec_helper.rb +++ b/sentry-rails/spec/spec_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "bundler/setup" begin require "debug/prelude" diff --git a/sentry-resque/Gemfile b/sentry-resque/Gemfile index 58c13cada..96f47a3a5 100644 --- a/sentry-resque/Gemfile +++ b/sentry-resque/Gemfile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + source "https://rubygems.org" git_source(:github) { |name| "https://github.com/#{name}.git" } diff --git a/sentry-resque/Gemfile_with_rails.rb b/sentry-resque/Gemfile_with_rails.rb index bceb75350..306b36624 100644 --- a/sentry-resque/Gemfile_with_rails.rb +++ b/sentry-resque/Gemfile_with_rails.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + eval_gemfile File.expand_path("Gemfile", __dir__) gem "sentry-rails", path: "../sentry-rails" diff --git a/sentry-resque/Rakefile b/sentry-resque/Rakefile index 7b2756854..13afab191 100644 --- a/sentry-resque/Rakefile +++ b/sentry-resque/Rakefile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "bundler/gem_tasks" require "rspec/core/rake_task" diff --git a/sentry-resque/bin/console b/sentry-resque/bin/console index 660c7a889..f0f5a7b6a 100755 --- a/sentry-resque/bin/console +++ b/sentry-resque/bin/console @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true require "bundler/setup" require "sentry/ruby" diff --git a/sentry-resque/example/Gemfile b/sentry-resque/example/Gemfile index b9432d218..20d98ac4a 100644 --- a/sentry-resque/example/Gemfile +++ b/sentry-resque/example/Gemfile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + source "https://rubygems.org" gem "rails" diff --git a/sentry-resque/example/app.rb b/sentry-resque/example/app.rb index 843e8c028..2e85eca19 100644 --- a/sentry-resque/example/app.rb +++ b/sentry-resque/example/app.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "active_job" require "resque" require "sentry-resque" diff --git a/sentry-resque/lib/sentry-resque.rb b/sentry-resque/lib/sentry-resque.rb index 10af757c0..1d499af8a 100644 --- a/sentry-resque/lib/sentry-resque.rb +++ b/sentry-resque/lib/sentry-resque.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "resque" require "sentry-ruby" require "sentry/integrable" diff --git a/sentry-resque/lib/sentry/resque/configuration.rb b/sentry-resque/lib/sentry/resque/configuration.rb index f0d7ffae8..126d6f7eb 100644 --- a/sentry-resque/lib/sentry/resque/configuration.rb +++ b/sentry-resque/lib/sentry/resque/configuration.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sentry class Configuration attr_reader :resque diff --git a/sentry-resque/lib/sentry/resque/version.rb b/sentry-resque/lib/sentry/resque/version.rb index 9e6a6ec4f..e8e9d7466 100644 --- a/sentry-resque/lib/sentry/resque/version.rb +++ b/sentry-resque/lib/sentry/resque/version.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + module Sentry module Resque - VERSION = "5.19.0" + VERSION = "5.21.0" end end diff --git a/sentry-resque/sentry-resque.gemspec b/sentry-resque/sentry-resque.gemspec index 36d777b00..1f5dd7085 100644 --- a/sentry-resque/sentry-resque.gemspec +++ b/sentry-resque/sentry-resque.gemspec @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative "lib/sentry/resque/version" Gem::Specification.new do |spec| @@ -11,7 +13,7 @@ Gem::Specification.new do |spec| spec.platform = Gem::Platform::RUBY spec.required_ruby_version = '>= 2.4' spec.extra_rdoc_files = ["README.md", "LICENSE.txt"] - spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples)'`.split("\n") + spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples|\.rubocop\.yml)'`.split("\n") github_root_uri = 'https://github.com/getsentry/sentry-ruby' spec.homepage = "#{github_root_uri}/tree/#{spec.version}/#{spec.name}" @@ -28,6 +30,6 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] - spec.add_dependency "sentry-ruby", "~> 5.19.0" + spec.add_dependency "sentry-ruby", "~> 5.21.0" spec.add_dependency "resque", ">= 1.24" end diff --git a/sentry-resque/spec/sentry/resque/configuration_spec.rb b/sentry-resque/spec/sentry/resque/configuration_spec.rb index abde7c4d4..af2f464d9 100644 --- a/sentry-resque/spec/sentry/resque/configuration_spec.rb +++ b/sentry-resque/spec/sentry/resque/configuration_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Resque::Configuration do diff --git a/sentry-resque/spec/sentry/resque_spec.rb b/sentry-resque/spec/sentry/resque_spec.rb index 2a4739b6f..7239284e3 100644 --- a/sentry-resque/spec/sentry/resque_spec.rb +++ b/sentry-resque/spec/sentry/resque_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" def process_job(worker) diff --git a/sentry-resque/spec/sentry/tracing_spec.rb b/sentry-resque/spec/sentry/tracing_spec.rb index e77b84f4e..bf81f9006 100644 --- a/sentry-resque/spec/sentry/tracing_spec.rb +++ b/sentry-resque/spec/sentry/tracing_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Resque do diff --git a/sentry-resque/spec/spec_helper.rb b/sentry-resque/spec/spec_helper.rb index dd212aab3..73b3baefe 100644 --- a/sentry-resque/spec/spec_helper.rb +++ b/sentry-resque/spec/spec_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "bundler/setup" begin require "debug/prelude" diff --git a/sentry-ruby/.rubocop.yml b/sentry-ruby/.rubocop.yml new file mode 120000 index 000000000..7cc18e076 --- /dev/null +++ b/sentry-ruby/.rubocop.yml @@ -0,0 +1 @@ +../.rubocop.yml \ No newline at end of file diff --git a/sentry-ruby/Gemfile b/sentry-ruby/Gemfile index c6e1db011..5ca0f99c2 100644 --- a/sentry-ruby/Gemfile +++ b/sentry-ruby/Gemfile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + source "https://rubygems.org" git_source(:github) { |name| "https://github.com/#{name}.git" } @@ -14,6 +16,7 @@ gem "puma" gem "timecop" gem "stackprof" unless RUBY_PLATFORM == "java" +gem "vernier", platforms: :ruby if RUBY_VERSION >= "3.2.1" gem "graphql", ">= 2.2.6" if RUBY_VERSION.to_f >= 2.7 diff --git a/sentry-ruby/Rakefile b/sentry-ruby/Rakefile index c199ef8f8..fb7a8c183 100644 --- a/sentry-ruby/Rakefile +++ b/sentry-ruby/Rakefile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "rake/clean" CLOBBER.include "pkg" diff --git a/sentry-ruby/benchmarks/allocation_comparison.rb b/sentry-ruby/benchmarks/allocation_comparison.rb index 90c7b2b19..c765b2ff6 100644 --- a/sentry-ruby/benchmarks/allocation_comparison.rb +++ b/sentry-ruby/benchmarks/allocation_comparison.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'benchmark/memory' require "sentry-ruby" require "sentry/benchmarks/benchmark_transport" diff --git a/sentry-ruby/benchmarks/allocation_report.rb b/sentry-ruby/benchmarks/allocation_report.rb index 3e0359d72..54fbd4139 100644 --- a/sentry-ruby/benchmarks/allocation_report.rb +++ b/sentry-ruby/benchmarks/allocation_report.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'benchmark/ipsa' require "sentry-ruby" require "sentry/benchmarks/benchmark_transport" diff --git a/sentry-ruby/benchmarks/exception_locals_capturing.rb b/sentry-ruby/benchmarks/exception_locals_capturing.rb index 00c05f9e9..6ebc46ee9 100644 --- a/sentry-ruby/benchmarks/exception_locals_capturing.rb +++ b/sentry-ruby/benchmarks/exception_locals_capturing.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'benchmark/ips' def raise_n_exceptions(n, with_sleep: false) diff --git a/sentry-ruby/bin/console b/sentry-ruby/bin/console index 57a532604..6ab9e0413 100755 --- a/sentry-ruby/bin/console +++ b/sentry-ruby/bin/console @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true require "bundler/setup" require "debug" diff --git a/sentry-ruby/lib/sentry-ruby.rb b/sentry-ruby/lib/sentry-ruby.rb index 734bc2cc9..6dcf99671 100644 --- a/sentry-ruby/lib/sentry-ruby.rb +++ b/sentry-ruby/lib/sentry-ruby.rb @@ -25,6 +25,7 @@ require "sentry/backpressure_monitor" require "sentry/cron/monitor_check_ins" require "sentry/metrics" +require "sentry/vernier/profiler" [ "sentry/rake", @@ -41,11 +42,11 @@ module Sentry CAPTURED_SIGNATURE = :@__sentry_captured - LOGGER_PROGNAME = "sentry".freeze + LOGGER_PROGNAME = "sentry" - SENTRY_TRACE_HEADER_NAME = "sentry-trace".freeze + SENTRY_TRACE_HEADER_NAME = "sentry-trace" - BAGGAGE_HEADER_NAME = "baggage".freeze + BAGGAGE_HEADER_NAME = "baggage" THREAD_LOCAL = :sentry_hub diff --git a/sentry-ruby/lib/sentry/attachment.rb b/sentry-ruby/lib/sentry/attachment.rb index 71a2b2b76..847d58c47 100644 --- a/sentry-ruby/lib/sentry/attachment.rb +++ b/sentry-ruby/lib/sentry/attachment.rb @@ -8,7 +8,7 @@ class Attachment def initialize(bytes: nil, filename: nil, content_type: nil, path: nil) @bytes = bytes - @filename = infer_filename(filename, path) + @filename = filename || infer_filename(path) @path = path @content_type = content_type end @@ -29,9 +29,7 @@ def payload private - def infer_filename(filename, path) - return filename if filename - + def infer_filename(path) if path File.basename(path) else diff --git a/sentry-ruby/lib/sentry/backtrace.rb b/sentry-ruby/lib/sentry/backtrace.rb index b7ebb2159..5fd2aadff 100644 --- a/sentry-ruby/lib/sentry/backtrace.rb +++ b/sentry-ruby/lib/sentry/backtrace.rb @@ -13,10 +13,10 @@ class Line ^ \s* (?: [a-zA-Z]: | uri:classloader: )? ([^:]+ | <.*>): (\d+) (?: :in\s('|`)([^']+)')?$ - /x.freeze + /x # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170) - JAVA_INPUT_FORMAT = /^(.+)\.([^\.]+)\(([^\:]+)\:(\d+)\)$/.freeze + JAVA_INPUT_FORMAT = /^(.+)\.([^\.]+)\(([^\:]+)\:(\d+)\)$/ # The file portion of the line (such as app/models/user.rb) attr_reader :file @@ -80,8 +80,6 @@ def inspect end end - APP_DIRS_PATTERN = /(bin|exe|app|config|lib|test|spec)/.freeze - # holder for an Array of Backtrace::Line instances attr_reader :lines @@ -91,7 +89,7 @@ def self.parse(backtrace, project_root, app_dirs_pattern, &backtrace_cleanup_cal ruby_lines = backtrace_cleanup_callback.call(ruby_lines) if backtrace_cleanup_callback in_app_pattern ||= begin - Regexp.new("^(#{project_root}/)?#{app_dirs_pattern || APP_DIRS_PATTERN}") + Regexp.new("^(#{project_root}/)?#{app_dirs_pattern}") end lines = ruby_lines.to_a.map do |unparsed_line| diff --git a/sentry-ruby/lib/sentry/baggage.rb b/sentry-ruby/lib/sentry/baggage.rb index 2b375a846..dc02dd8e6 100644 --- a/sentry-ruby/lib/sentry/baggage.rb +++ b/sentry-ruby/lib/sentry/baggage.rb @@ -6,7 +6,7 @@ module Sentry # A {https://www.w3.org/TR/baggage W3C Baggage Header} implementation. class Baggage SENTRY_PREFIX = "sentry-" - SENTRY_PREFIX_REGEX = /^sentry-/.freeze + SENTRY_PREFIX_REGEX = /^sentry-/ # @return [Hash] attr_reader :items diff --git a/sentry-ruby/lib/sentry/configuration.rb b/sentry-ruby/lib/sentry/configuration.rb index 4fb927cb4..b13c81c49 100644 --- a/sentry-ruby/lib/sentry/configuration.rb +++ b/sentry-ruby/lib/sentry/configuration.rb @@ -3,8 +3,8 @@ require "concurrent/utility/processor_counter" require "sentry/utils/exception_cause_chain" -require 'sentry/utils/custom_inspection' -require 'sentry/utils/env_helper' +require "sentry/utils/custom_inspection" +require "sentry/utils/env_helper" require "sentry/dsn" require "sentry/release_detector" require "sentry/transport/configuration" @@ -23,6 +23,8 @@ class Configuration # have an `engines` dir at the root of your project, you may want # to set this to something like /(app|config|engines|lib)/ # + # The default is value is /(bin|exe|app|config|lib|test|spec)/ + # # @return [Regexp, nil] attr_accessor :app_dirs_pattern @@ -188,6 +190,11 @@ def capture_exception_frame_locals=(value) # @return [String] attr_accessor :project_root + # Whether to strip the load path while constructing the backtrace frame filename. + # Defaults to true. + # @return [Boolean] + attr_accessor :strip_backtrace_load_path + # Insert sentry-trace to outgoing requests' headers # @return [Boolean] attr_accessor :propagate_traces @@ -284,6 +291,10 @@ def capture_exception_frame_locals=(value) # @return [Symbol] attr_reader :instrumenter + # The profiler class + # @return [Class] + attr_reader :profiler_class + # Take a float between 0.0 and 1.0 as the sample rate for capturing profiles. # Note that this rate is relative to traces_sample_rate / traces_sampler, # i.e. the profile is sampled by this rate after the transaction is sampled. @@ -324,18 +335,20 @@ def capture_exception_frame_locals=(value) ].freeze HEROKU_DYNO_METADATA_MESSAGE = "You are running on Heroku but haven't enabled Dyno Metadata. For Sentry's "\ - "release detection to work correctly, please run `heroku labs:enable runtime-dyno-metadata`".freeze + "release detection to work correctly, please run `heroku labs:enable runtime-dyno-metadata`" - LOG_PREFIX = "** [Sentry] ".freeze - MODULE_SEPARATOR = "::".freeze + LOG_PREFIX = "** [Sentry] " + MODULE_SEPARATOR = "::" SKIP_INSPECTION_ATTRIBUTES = [:@linecache, :@stacktrace_builder] INSTRUMENTERS = [:sentry, :otel] - PROPAGATION_TARGETS_MATCH_ALL = /.*/.freeze + PROPAGATION_TARGETS_MATCH_ALL = /.*/ DEFAULT_PATCHES = %i[redis puma http].freeze + APP_DIRS_PATTERN = /(bin|exe|app|config|lib|test|spec)/ + class << self # Post initialization callbacks are called at the end of initialization process # allowing extending the configuration of sentry-ruby by multiple extensions @@ -350,11 +363,12 @@ def add_post_initialization_callback(&block) end def initialize - self.app_dirs_pattern = nil + self.app_dirs_pattern = APP_DIRS_PATTERN self.debug = Sentry::Utils::EnvHelper.env_to_bool(ENV["SENTRY_DEBUG"]) self.background_worker_threads = (processor_count / 2.0).ceil self.background_worker_max_queue = BackgroundWorker::DEFAULT_MAX_QUEUE self.backtrace_cleanup_callback = nil + self.strip_backtrace_load_path = true self.max_breadcrumbs = BreadcrumbBuffer::DEFAULT_SIZE self.breadcrumbs_logger = [] self.context_lines = 3 @@ -377,9 +391,9 @@ def initialize self.auto_session_tracking = true self.enable_backpressure_handling = false self.trusted_proxies = [] - self.dsn = ENV['SENTRY_DSN'] + self.dsn = ENV["SENTRY_DSN"] - spotlight_env = ENV['SENTRY_SPOTLIGHT'] + spotlight_env = ENV["SENTRY_SPOTLIGHT"] spotlight_bool = Sentry::Utils::EnvHelper.env_to_bool(spotlight_env, strict: true) self.spotlight = spotlight_bool.nil? ? (spotlight_env || false) : spotlight_bool self.server_name = server_name_from_env @@ -393,6 +407,8 @@ def initialize self.traces_sampler = nil self.enable_tracing = nil + self.profiler_class = Sentry::Profiler + @transport = Transport::Configuration.new @cron = Cron::Configuration.new @metrics = Metrics::Configuration.new @@ -488,6 +504,18 @@ def profiles_sample_rate=(profiles_sample_rate) @profiles_sample_rate = profiles_sample_rate end + def profiler_class=(profiler_class) + if profiler_class == Sentry::Vernier::Profiler + begin + require "vernier" + rescue LoadError + raise ArgumentError, "Please add the 'vernier' gem to your Gemfile to use the Vernier profiler with Sentry." + end + end + + @profiler_class = profiler_class + end + def sending_allowed? spotlight || sending_to_dsn_allowed? end @@ -559,7 +587,8 @@ def stacktrace_builder app_dirs_pattern: @app_dirs_pattern, linecache: @linecache, context_lines: @context_lines, - backtrace_cleanup_callback: @backtrace_cleanup_callback + backtrace_cleanup_callback: @backtrace_cleanup_callback, + strip_backtrace_load_path: @strip_backtrace_load_path ) end diff --git a/sentry-ruby/lib/sentry/cron/monitor_check_ins.rb b/sentry-ruby/lib/sentry/cron/monitor_check_ins.rb index ac7e35d81..835ae84ad 100644 --- a/sentry-ruby/lib/sentry/cron/monitor_check_ins.rb +++ b/sentry-ruby/lib/sentry/cron/monitor_check_ins.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sentry module Cron module MonitorCheckIns diff --git a/sentry-ruby/lib/sentry/envelope.rb b/sentry-ruby/lib/sentry/envelope.rb index 4e1d8acb2..d60e79ba7 100644 --- a/sentry-ruby/lib/sentry/envelope.rb +++ b/sentry-ruby/lib/sentry/envelope.rb @@ -3,91 +3,6 @@ module Sentry # @api private class Envelope - class Item - STACKTRACE_FRAME_LIMIT_ON_OVERSIZED_PAYLOAD = 500 - MAX_SERIALIZED_PAYLOAD_SIZE = 1024 * 1000 - - attr_accessor :headers, :payload - - def initialize(headers, payload) - @headers = headers - @payload = payload - end - - def type - @headers[:type] || "event" - end - - # rate limits and client reports use the data_category rather than envelope item type - def self.data_category(type) - case type - when "session", "attachment", "transaction", "profile", "span" then type - when "sessions" then "session" - when "check_in" then "monitor" - when "statsd", "metric_meta" then "metric_bucket" - when "event" then "error" - when "client_report" then "internal" - else "default" - end - end - - def data_category - self.class.data_category(type) - end - - def to_s - [JSON.generate(@headers), @payload.is_a?(String) ? @payload : JSON.generate(@payload)].join("\n") - end - - def serialize - result = to_s - - if result.bytesize > MAX_SERIALIZED_PAYLOAD_SIZE - remove_breadcrumbs! - result = to_s - end - - if result.bytesize > MAX_SERIALIZED_PAYLOAD_SIZE - reduce_stacktrace! - result = to_s - end - - [result, result.bytesize > MAX_SERIALIZED_PAYLOAD_SIZE] - end - - def size_breakdown - payload.map do |key, value| - "#{key}: #{JSON.generate(value).bytesize}" - end.join(", ") - end - - private - - def remove_breadcrumbs! - if payload.key?(:breadcrumbs) - payload.delete(:breadcrumbs) - elsif payload.key?("breadcrumbs") - payload.delete("breadcrumbs") - end - end - - def reduce_stacktrace! - if exceptions = payload.dig(:exception, :values) || payload.dig("exception", "values") - exceptions.each do |exception| - # in most cases there is only one exception (2 or 3 when have multiple causes), so we won't loop through this double condition much - traces = exception.dig(:stacktrace, :frames) || exception.dig("stacktrace", "frames") - - if traces && traces.size > STACKTRACE_FRAME_LIMIT_ON_OVERSIZED_PAYLOAD - size_on_both_ends = STACKTRACE_FRAME_LIMIT_ON_OVERSIZED_PAYLOAD / 2 - traces.replace( - traces[0..(size_on_both_ends - 1)] + traces[-size_on_both_ends..-1], - ) - end - end - end - end - end - attr_accessor :headers, :items def initialize(headers = {}) @@ -108,3 +23,5 @@ def event_id end end end + +require_relative "envelope/item" diff --git a/sentry-ruby/lib/sentry/envelope/item.rb b/sentry-ruby/lib/sentry/envelope/item.rb new file mode 100644 index 000000000..e1539bf6c --- /dev/null +++ b/sentry-ruby/lib/sentry/envelope/item.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +module Sentry + # @api private + class Envelope::Item + STACKTRACE_FRAME_LIMIT_ON_OVERSIZED_PAYLOAD = 500 + MAX_SERIALIZED_PAYLOAD_SIZE = 1024 * 1000 + + SIZE_LIMITS = Hash.new(MAX_SERIALIZED_PAYLOAD_SIZE).update( + "profile" => 1024 * 1000 * 50 + ) + + attr_reader :size_limit, :headers, :payload, :type, :data_category + + # rate limits and client reports use the data_category rather than envelope item type + def self.data_category(type) + case type + when "session", "attachment", "transaction", "profile", "span" then type + when "sessions" then "session" + when "check_in" then "monitor" + when "statsd", "metric_meta" then "metric_bucket" + when "event" then "error" + when "client_report" then "internal" + else "default" + end + end + + def initialize(headers, payload) + @headers = headers + @payload = payload + @type = headers[:type] || "event" + @data_category = self.class.data_category(type) + @size_limit = SIZE_LIMITS[type] + end + + def to_s + [JSON.generate(@headers), @payload.is_a?(String) ? @payload : JSON.generate(@payload)].join("\n") + end + + def serialize + result = to_s + + if result.bytesize > size_limit + remove_breadcrumbs! + result = to_s + end + + if result.bytesize > size_limit + reduce_stacktrace! + result = to_s + end + + [result, result.bytesize > size_limit] + end + + def size_breakdown + payload.map do |key, value| + "#{key}: #{JSON.generate(value).bytesize}" + end.join(", ") + end + + private + + def remove_breadcrumbs! + if payload.key?(:breadcrumbs) + payload.delete(:breadcrumbs) + elsif payload.key?("breadcrumbs") + payload.delete("breadcrumbs") + end + end + + def reduce_stacktrace! + if exceptions = payload.dig(:exception, :values) || payload.dig("exception", "values") + exceptions.each do |exception| + # in most cases there is only one exception (2 or 3 when have multiple causes), so we won't loop through this double condition much + traces = exception.dig(:stacktrace, :frames) || exception.dig("stacktrace", "frames") + + if traces && traces.size > STACKTRACE_FRAME_LIMIT_ON_OVERSIZED_PAYLOAD + size_on_both_ends = STACKTRACE_FRAME_LIMIT_ON_OVERSIZED_PAYLOAD / 2 + traces.replace( + traces[0..(size_on_both_ends - 1)] + traces[-size_on_both_ends..-1], + ) + end + end + end + end + end +end diff --git a/sentry-ruby/lib/sentry/hub.rb b/sentry-ruby/lib/sentry/hub.rb index 66d0b379a..b9b58638d 100644 --- a/sentry-ruby/lib/sentry/hub.rb +++ b/sentry-ruby/lib/sentry/hub.rb @@ -73,7 +73,13 @@ def push_scope end def pop_scope - @stack.pop + if @stack.size > 1 + @stack.pop + else + # We never want to enter a situation where we have no scope and no client + client = current_client + @stack = [Layer.new(client, Scope.new)] + end end def start_transaction(transaction: nil, custom_sampling_context: {}, instrumenter: :sentry, **options) @@ -214,6 +220,7 @@ def capture_event(event, **options, &block) end def add_breadcrumb(breadcrumb, hint: {}) + return unless current_client return unless configuration.enabled_in_current_env? if before_breadcrumb = current_client.configuration.before_breadcrumb diff --git a/sentry-ruby/lib/sentry/interfaces/single_exception.rb b/sentry-ruby/lib/sentry/interfaces/single_exception.rb index f7126e702..db2d54e7b 100644 --- a/sentry-ruby/lib/sentry/interfaces/single_exception.rb +++ b/sentry-ruby/lib/sentry/interfaces/single_exception.rb @@ -7,8 +7,8 @@ class SingleExceptionInterface < Interface include CustomInspection SKIP_INSPECTION_ATTRIBUTES = [:@stacktrace] - PROBLEMATIC_LOCAL_VALUE_REPLACEMENT = "[ignored due to error]".freeze - OMISSION_MARK = "...".freeze + PROBLEMATIC_LOCAL_VALUE_REPLACEMENT = "[ignored due to error]" + OMISSION_MARK = "..." MAX_LOCAL_BYTES = 1024 attr_reader :type, :module, :thread_id, :stacktrace, :mechanism diff --git a/sentry-ruby/lib/sentry/interfaces/stacktrace.rb b/sentry-ruby/lib/sentry/interfaces/stacktrace.rb index eadf01188..5f4be3719 100644 --- a/sentry-ruby/lib/sentry/interfaces/stacktrace.rb +++ b/sentry-ruby/lib/sentry/interfaces/stacktrace.rb @@ -27,8 +27,9 @@ class Frame < Interface attr_accessor :abs_path, :context_line, :function, :in_app, :filename, :lineno, :module, :pre_context, :post_context, :vars - def initialize(project_root, line) + def initialize(project_root, line, strip_backtrace_load_path = true) @project_root = project_root + @strip_backtrace_load_path = strip_backtrace_load_path @abs_path = line.file @function = line.method if line.method @@ -44,6 +45,7 @@ def to_s def compute_filename return if abs_path.nil? + return abs_path unless @strip_backtrace_load_path prefix = if under_project_root? && in_app diff --git a/sentry-ruby/lib/sentry/interfaces/stacktrace_builder.rb b/sentry-ruby/lib/sentry/interfaces/stacktrace_builder.rb index 5edac90c5..d2d0758ec 100644 --- a/sentry-ruby/lib/sentry/interfaces/stacktrace_builder.rb +++ b/sentry-ruby/lib/sentry/interfaces/stacktrace_builder.rb @@ -17,22 +17,35 @@ class StacktraceBuilder # @return [Proc, nil] attr_reader :backtrace_cleanup_callback + # @return [Boolean] + attr_reader :strip_backtrace_load_path + # @param project_root [String] # @param app_dirs_pattern [Regexp, nil] # @param linecache [LineCache] # @param context_lines [Integer, nil] # @param backtrace_cleanup_callback [Proc, nil] + # @param strip_backtrace_load_path [Boolean] # @see Configuration#project_root # @see Configuration#app_dirs_pattern # @see Configuration#linecache # @see Configuration#context_lines # @see Configuration#backtrace_cleanup_callback - def initialize(project_root:, app_dirs_pattern:, linecache:, context_lines:, backtrace_cleanup_callback: nil) + # @see Configuration#strip_backtrace_load_path + def initialize( + project_root:, + app_dirs_pattern:, + linecache:, + context_lines:, + backtrace_cleanup_callback: nil, + strip_backtrace_load_path: true + ) @project_root = project_root @app_dirs_pattern = app_dirs_pattern @linecache = linecache @context_lines = context_lines @backtrace_cleanup_callback = backtrace_cleanup_callback + @strip_backtrace_load_path = strip_backtrace_load_path end # Generates a StacktraceInterface with the given backtrace. @@ -73,7 +86,7 @@ def metrics_code_location(unparsed_line) private def convert_parsed_line_into_frame(line) - frame = StacktraceInterface::Frame.new(project_root, line) + frame = StacktraceInterface::Frame.new(project_root, line, strip_backtrace_load_path) frame.set_context(linecache, context_lines) if context_lines frame end diff --git a/sentry-ruby/lib/sentry/net/http.rb b/sentry-ruby/lib/sentry/net/http.rb index c769b4c3d..04820f3d5 100644 --- a/sentry-ruby/lib/sentry/net/http.rb +++ b/sentry-ruby/lib/sentry/net/http.rb @@ -66,7 +66,7 @@ def extract_request_info(req) # IPv6 url could look like '::1/path', and that won't parse without # wrapping it in square brackets. hostname = address =~ Resolv::IPv6::Regex ? "[#{address}]" : address - uri = req.uri || URI.parse("#{use_ssl? ? 'https' : 'http'}://#{hostname}#{req.path}") + uri = req.uri || URI.parse(URI::DEFAULT_PARSER.escape("#{use_ssl? ? 'https' : 'http'}://#{hostname}#{req.path}")) url = "#{uri.scheme}://#{uri.host}#{uri.path}" rescue uri.to_s result = { method: req.method, url: url } diff --git a/sentry-ruby/lib/sentry/profiler.rb b/sentry-ruby/lib/sentry/profiler.rb index cec7c70ce..d81e46024 100644 --- a/sentry-ruby/lib/sentry/profiler.rb +++ b/sentry-ruby/lib/sentry/profiler.rb @@ -1,9 +1,12 @@ # frozen_string_literal: true require "securerandom" +require_relative "profiler/helpers" module Sentry class Profiler + include Profiler::Helpers + VERSION = "1" PLATFORM = "ruby" # 101 Hz in microseconds @@ -21,7 +24,7 @@ def initialize(configuration) @profiling_enabled = defined?(StackProf) && configuration.profiling_enabled? @profiles_sample_rate = configuration.profiles_sample_rate @project_root = configuration.project_root - @app_dirs_pattern = configuration.app_dirs_pattern || Backtrace::APP_DIRS_PATTERN + @app_dirs_pattern = configuration.app_dirs_pattern @in_app_pattern = Regexp.new("^(#{@project_root}/)?#{@app_dirs_pattern}") end @@ -44,6 +47,10 @@ def stop log("Stopped") end + def active_thread_id + "0" + end + # Sets initial sampling decision of the profile. # @return [void] def set_initial_sample_decision(transaction_sampled) @@ -90,13 +97,12 @@ def to_hash frame_map = {} - frames = results[:frames].to_enum.with_index.map do |frame, idx| - frame_id, frame_data = frame - + frames = results[:frames].map.with_index do |(frame_id, frame_data), idx| # need to map over stackprof frame ids to ours frame_map[frame_id] = idx file_path = frame_data[:file] + lineno = frame_data[:line] in_app = in_app?(file_path) filename = compute_filename(file_path, in_app) function, mod = split_module(frame_data[:name]) @@ -109,7 +115,7 @@ def to_hash } frame_hash[:module] = mod if mod - frame_hash[:lineno] = frame_data[:line] if frame_data[:line] && frame_data[:line] >= 0 + frame_hash[:lineno] = lineno if lineno && lineno >= 0 frame_hash end @@ -189,43 +195,6 @@ def log(message) Sentry.logger.debug(LOGGER_PROGNAME) { "[Profiler] #{message}" } end - def in_app?(abs_path) - abs_path.match?(@in_app_pattern) - end - - # copied from stacktrace.rb since I don't want to touch existing code - # TODO-neel-profiler try to fetch this from stackprof once we patch - # the native extension - def compute_filename(abs_path, in_app) - return nil if abs_path.nil? - - under_project_root = @project_root && abs_path.start_with?(@project_root) - - prefix = - if under_project_root && in_app - @project_root - else - longest_load_path = $LOAD_PATH.select { |path| abs_path.start_with?(path.to_s) }.max_by(&:size) - - if under_project_root - longest_load_path || @project_root - else - longest_load_path - end - end - - prefix ? abs_path[prefix.to_s.chomp(File::SEPARATOR).length + 1..-1] : abs_path - end - - def split_module(name) - # last module plus class/instance method - i = name.rindex("::") - function = i ? name[(i + 2)..-1] : name - mod = i ? name[0...i] : nil - - [function, mod] - end - def record_lost_event(reason) Sentry.get_current_client&.transport&.record_lost_event(reason, "profile") end diff --git a/sentry-ruby/lib/sentry/profiler/helpers.rb b/sentry-ruby/lib/sentry/profiler/helpers.rb new file mode 100644 index 000000000..3c446fba0 --- /dev/null +++ b/sentry-ruby/lib/sentry/profiler/helpers.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require "securerandom" + +module Sentry + class Profiler + module Helpers + def in_app?(abs_path) + abs_path.match?(@in_app_pattern) + end + + # copied from stacktrace.rb since I don't want to touch existing code + # TODO-neel-profiler try to fetch this from stackprof once we patch + # the native extension + def compute_filename(abs_path, in_app) + return nil if abs_path.nil? + + under_project_root = @project_root && abs_path.start_with?(@project_root) + + prefix = + if under_project_root && in_app + @project_root + else + longest_load_path = $LOAD_PATH.select { |path| abs_path.start_with?(path.to_s) }.max_by(&:size) + + if under_project_root + longest_load_path || @project_root + else + longest_load_path + end + end + + prefix ? abs_path[prefix.to_s.chomp(File::SEPARATOR).length + 1..-1] : abs_path + end + + def split_module(name) + # last module plus class/instance method + i = name.rindex("::") + function = i ? name[(i + 2)..-1] : name + mod = i ? name[0...i] : nil + + [function, mod] + end + end + end +end diff --git a/sentry-ruby/lib/sentry/propagation_context.rb b/sentry-ruby/lib/sentry/propagation_context.rb index 12ce55540..db2f58b8f 100644 --- a/sentry-ruby/lib/sentry/propagation_context.rb +++ b/sentry-ruby/lib/sentry/propagation_context.rb @@ -108,7 +108,7 @@ def get_baggage end # Returns the Dynamic Sampling Context from the baggage. - # @return [String, nil] + # @return [Hash, nil] def get_dynamic_sampling_context get_baggage&.dynamic_sampling_context end diff --git a/sentry-ruby/lib/sentry/rack/capture_exceptions.rb b/sentry-ruby/lib/sentry/rack/capture_exceptions.rb index 5bb8eda67..40cdfb4f8 100644 --- a/sentry-ruby/lib/sentry/rack/capture_exceptions.rb +++ b/sentry-ruby/lib/sentry/rack/capture_exceptions.rb @@ -54,7 +54,7 @@ def collect_exception(env) end def transaction_op - "http.server".freeze + "http.server" end def capture_exception(exception, env) diff --git a/sentry-ruby/lib/sentry/scope.rb b/sentry-ruby/lib/sentry/scope.rb index 73e873f43..4feb6ecdd 100644 --- a/sentry-ruby/lib/sentry/scope.rb +++ b/sentry-ruby/lib/sentry/scope.rb @@ -62,6 +62,7 @@ def apply_to_event(event, hint = nil) if span event.contexts[:trace] ||= span.get_trace_context + event.dynamic_sampling_context ||= span.get_dynamic_sampling_context else event.contexts[:trace] ||= propagation_context.get_trace_context event.dynamic_sampling_context ||= propagation_context.get_dynamic_sampling_context diff --git a/sentry-ruby/lib/sentry/span.rb b/sentry-ruby/lib/sentry/span.rb index da7232d9a..3dd2158ea 100644 --- a/sentry-ruby/lib/sentry/span.rb +++ b/sentry-ruby/lib/sentry/span.rb @@ -160,6 +160,12 @@ def to_baggage transaction.get_baggage&.serialize end + # Returns the Dynamic Sampling Context from the transaction baggage. + # @return [Hash, nil] + def get_dynamic_sampling_context + transaction.get_baggage&.dynamic_sampling_context + end + # @return [Hash] def to_hash hash = { diff --git a/sentry-ruby/lib/sentry/test_helper.rb b/sentry-ruby/lib/sentry/test_helper.rb index 212c35db5..d36dc0be0 100644 --- a/sentry-ruby/lib/sentry/test_helper.rb +++ b/sentry-ruby/lib/sentry/test_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sentry module TestHelper DUMMY_DSN = "http://12345:67890@sentry.localdomain/sentry/42" diff --git a/sentry-ruby/lib/sentry/transaction.rb b/sentry-ruby/lib/sentry/transaction.rb index ac6256555..5e3ceb982 100644 --- a/sentry-ruby/lib/sentry/transaction.rb +++ b/sentry-ruby/lib/sentry/transaction.rb @@ -9,7 +9,7 @@ class Transaction < Span # @deprecated Use Sentry::PropagationContext::SENTRY_TRACE_REGEXP instead. SENTRY_TRACE_REGEXP = PropagationContext::SENTRY_TRACE_REGEXP - UNLABELD_NAME = "".freeze + UNLABELD_NAME = "" MESSAGE_PREFIX = "[Tracing]" # https://develop.sentry.dev/sdk/event-payloads/transaction/#transaction-annotations @@ -85,7 +85,7 @@ def initialize( @effective_sample_rate = nil @contexts = {} @measurements = {} - @profiler = Profiler.new(@configuration) + @profiler = @configuration.profiler_class.new(@configuration) init_span_recorder end diff --git a/sentry-ruby/lib/sentry/transaction_event.rb b/sentry-ruby/lib/sentry/transaction_event.rb index 4136ac6aa..a1a8767d1 100644 --- a/sentry-ruby/lib/sentry/transaction_event.rb +++ b/sentry-ruby/lib/sentry/transaction_event.rb @@ -74,8 +74,7 @@ def populate_profile(transaction) id: event_id, name: transaction.name, trace_id: transaction.trace_id, - # TODO-neel-profiler stubbed for now, see thread_id note in profiler.rb - active_thead_id: "0" + active_thread_id: transaction.profiler.active_thread_id.to_s } ) diff --git a/sentry-ruby/lib/sentry/vernier/output.rb b/sentry-ruby/lib/sentry/vernier/output.rb new file mode 100644 index 000000000..7002f82a1 --- /dev/null +++ b/sentry-ruby/lib/sentry/vernier/output.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +require "json" +require "rbconfig" + +module Sentry + module Vernier + class Output + include Profiler::Helpers + + attr_reader :profile + + def initialize(profile, project_root:, in_app_pattern:, app_dirs_pattern:) + @profile = profile + @project_root = project_root + @in_app_pattern = in_app_pattern + @app_dirs_pattern = app_dirs_pattern + end + + def to_h + @to_h ||= { + frames: frames, + stacks: stacks, + samples: samples, + thread_metadata: thread_metadata + } + end + + private + + def thread_metadata + profile.threads.map { |thread_id, thread_info| + [thread_id, { name: thread_info[:name] }] + }.to_h + end + + def samples + profile.threads.flat_map { |thread_id, thread_info| + started_at = thread_info[:started_at] + samples, timestamps = thread_info.values_at(:samples, :timestamps) + + samples.zip(timestamps).map { |stack_id, timestamp| + elapsed_since_start_ns = timestamp - started_at + + next if elapsed_since_start_ns < 0 + + { + thread_id: thread_id.to_s, + stack_id: stack_id, + elapsed_since_start_ns: elapsed_since_start_ns.to_s + } + }.compact + } + end + + def frames + funcs = stack_table_hash[:frame_table].fetch(:func) + lines = stack_table_hash[:func_table].fetch(:first_line) + + funcs.map do |idx| + function, mod = split_module(stack_table_hash[:func_table][:name][idx]) + + abs_path = stack_table_hash[:func_table][:filename][idx] + in_app = in_app?(abs_path) + filename = compute_filename(abs_path, in_app) + + { + function: function, + module: mod, + filename: filename, + abs_path: abs_path, + lineno: (lineno = lines[idx]) > 0 ? lineno : nil, + in_app: in_app + }.compact + end + end + + def stacks + profile._stack_table.stack_count.times.map do |stack_id| + profile.stack(stack_id).frames.map(&:idx) + end + end + + def stack_table_hash + @stack_table_hash ||= profile._stack_table.to_h + end + end + end +end diff --git a/sentry-ruby/lib/sentry/vernier/profiler.rb b/sentry-ruby/lib/sentry/vernier/profiler.rb new file mode 100644 index 000000000..0ca8c0f39 --- /dev/null +++ b/sentry-ruby/lib/sentry/vernier/profiler.rb @@ -0,0 +1,125 @@ +# frozen_string_literal: true + +require "securerandom" +require_relative "../profiler/helpers" +require_relative "output" + +module Sentry + module Vernier + class Profiler + EMPTY_RESULT = {}.freeze + + attr_reader :started, :event_id, :result + + def initialize(configuration) + @event_id = SecureRandom.uuid.delete("-") + + @started = false + @sampled = nil + + @profiling_enabled = defined?(Vernier) && configuration.profiling_enabled? + @profiles_sample_rate = configuration.profiles_sample_rate + @project_root = configuration.project_root + @app_dirs_pattern = configuration.app_dirs_pattern + @in_app_pattern = Regexp.new("^(#{@project_root}/)?#{@app_dirs_pattern}") + end + + def set_initial_sample_decision(transaction_sampled) + unless @profiling_enabled + @sampled = false + return + end + + unless transaction_sampled + @sampled = false + log("Discarding profile because transaction not sampled") + return + end + + case @profiles_sample_rate + when 0.0 + @sampled = false + log("Discarding profile because sample_rate is 0") + return + when 1.0 + @sampled = true + return + else + @sampled = Random.rand < @profiles_sample_rate + end + + log("Discarding profile due to sampling decision") unless @sampled + end + + def start + return unless @sampled + return if @started + + ::Vernier.start_profile + @started = true + + log("Started") + + @started + rescue RuntimeError => e + # TODO: once Vernier raises something more dedicated, we should catch that instead + if e.message.include?("Profile already started") + log("Not started since running elsewhere") + else + log("Failed to start: #{e.message}") + end + end + + def stop + return unless @sampled + return unless @started + + @result = ::Vernier.stop_profile + + log("Stopped") + end + + def active_thread_id + Thread.current.object_id + end + + def to_hash + return EMPTY_RESULT unless @started + + unless @sampled + record_lost_event(:sample_rate) + return EMPTY_RESULT + end + + { **profile_meta, profile: output.to_h } + end + + private + + def log(message) + Sentry.logger.debug(LOGGER_PROGNAME) { "[Profiler::Vernier] #{message}" } + end + + def record_lost_event(reason) + Sentry.get_current_client&.transport&.record_lost_event(reason, "profile") + end + + def profile_meta + { + event_id: @event_id, + version: "1", + platform: "ruby" + } + end + + def output + @output ||= Output.new( + result, + project_root: @project_root, + app_dirs_pattern: @app_dirs_pattern, + in_app_pattern: @in_app_pattern + ) + end + end + end +end diff --git a/sentry-ruby/lib/sentry/version.rb b/sentry-ruby/lib/sentry/version.rb index a06f8cebc..cb7b82b61 100644 --- a/sentry-ruby/lib/sentry/version.rb +++ b/sentry-ruby/lib/sentry/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Sentry - VERSION = "5.19.0" + VERSION = "5.21.0" end diff --git a/sentry-ruby/sentry-ruby-core.gemspec b/sentry-ruby/sentry-ruby-core.gemspec index 76a343c28..4bd423750 100644 --- a/sentry-ruby/sentry-ruby-core.gemspec +++ b/sentry-ruby/sentry-ruby-core.gemspec @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative "lib/sentry/version" Gem::Specification.new do |spec| @@ -12,7 +14,7 @@ Gem::Specification.new do |spec| spec.platform = Gem::Platform::RUBY spec.required_ruby_version = '>= 2.4' spec.extra_rdoc_files = ["README.md", "LICENSE.txt"] - spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples)'`.split("\n") + spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples|\.rubocop\.yml)'`.split("\n") spec.metadata["homepage_uri"] = spec.homepage spec.metadata["source_code_uri"] = spec.homepage diff --git a/sentry-ruby/sentry-ruby.gemspec b/sentry-ruby/sentry-ruby.gemspec index 52cbcc180..ba183705c 100644 --- a/sentry-ruby/sentry-ruby.gemspec +++ b/sentry-ruby/sentry-ruby.gemspec @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative "lib/sentry/version" Gem::Specification.new do |spec| @@ -11,7 +13,7 @@ Gem::Specification.new do |spec| spec.platform = Gem::Platform::RUBY spec.required_ruby_version = '>= 2.4' spec.extra_rdoc_files = ["README.md", "LICENSE.txt"] - spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples)'`.split("\n") + spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples|\.rubocop\.yml)'`.split("\n") github_root_uri = 'https://github.com/getsentry/sentry-ruby' spec.homepage = "#{github_root_uri}/tree/#{spec.version}/#{spec.name}" diff --git a/sentry-ruby/spec/contexts/with_request_mock.rb b/sentry-ruby/spec/contexts/with_request_mock.rb index bc103f7dc..e6c480256 100644 --- a/sentry-ruby/spec/contexts/with_request_mock.rb +++ b/sentry-ruby/spec/contexts/with_request_mock.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # because our patch on Net::HTTP is relatively low-level, we need to stub methods on socket level # which is not supported by most of the http mocking library # so we need to put something together ourselves diff --git a/sentry-ruby/spec/initialization_check_spec.rb b/sentry-ruby/spec/initialization_check_spec.rb index 039384c1d..129d5fdff 100644 --- a/sentry-ruby/spec/initialization_check_spec.rb +++ b/sentry-ruby/spec/initialization_check_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe "with uninitialized SDK" do diff --git a/sentry-ruby/spec/isolated/puma_spec.rb b/sentry-ruby/spec/isolated/puma_spec.rb index 0e2082519..6f416d6e9 100644 --- a/sentry-ruby/spec/isolated/puma_spec.rb +++ b/sentry-ruby/spec/isolated/puma_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "puma" require_relative "../spec_helper" diff --git a/sentry-ruby/spec/sentry/background_worker_spec.rb b/sentry-ruby/spec/sentry/background_worker_spec.rb index e1b900094..9e15b43ec 100644 --- a/sentry-ruby/spec/sentry/background_worker_spec.rb +++ b/sentry-ruby/spec/sentry/background_worker_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::BackgroundWorker do diff --git a/sentry-ruby/spec/sentry/backpressure_monitor_spec.rb b/sentry-ruby/spec/sentry/backpressure_monitor_spec.rb index 1419cffdb..e0147d87c 100644 --- a/sentry-ruby/spec/sentry/backpressure_monitor_spec.rb +++ b/sentry-ruby/spec/sentry/backpressure_monitor_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::BackpressureMonitor do diff --git a/sentry-ruby/spec/sentry/backtrace/lines_spec.rb b/sentry-ruby/spec/sentry/backtrace/lines_spec.rb index cdcb9809d..8a49ea1d8 100644 --- a/sentry-ruby/spec/sentry/backtrace/lines_spec.rb +++ b/sentry-ruby/spec/sentry/backtrace/lines_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Backtrace::Line do @@ -13,7 +15,7 @@ let(:in_app_pattern) do project_root = Sentry.configuration.project_root&.to_s - Regexp.new("^(#{project_root}/)?#{Sentry::Backtrace::APP_DIRS_PATTERN}") + Regexp.new("^(#{project_root}/)?#{Sentry::Configuration::APP_DIRS_PATTERN}") end describe ".parse" do diff --git a/sentry-ruby/spec/sentry/backtrace_spec.rb b/sentry-ruby/spec/sentry/backtrace_spec.rb index b373c45f4..648e4ee8e 100644 --- a/sentry-ruby/spec/sentry/backtrace_spec.rb +++ b/sentry-ruby/spec/sentry/backtrace_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Backtrace do diff --git a/sentry-ruby/spec/sentry/baggage_spec.rb b/sentry-ruby/spec/sentry/baggage_spec.rb index 3d72a5687..a9cc44873 100644 --- a/sentry-ruby/spec/sentry/baggage_spec.rb +++ b/sentry-ruby/spec/sentry/baggage_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Baggage do diff --git a/sentry-ruby/spec/sentry/breadcrumb/http_logger_spec.rb b/sentry-ruby/spec/sentry/breadcrumb/http_logger_spec.rb index 66146ef64..a4fab84ed 100644 --- a/sentry-ruby/spec/sentry/breadcrumb/http_logger_spec.rb +++ b/sentry-ruby/spec/sentry/breadcrumb/http_logger_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" require 'contexts/with_request_mock' diff --git a/sentry-ruby/spec/sentry/breadcrumb/redis_logger_spec.rb b/sentry-ruby/spec/sentry/breadcrumb/redis_logger_spec.rb index 4d0d541df..4285a43f4 100644 --- a/sentry-ruby/spec/sentry/breadcrumb/redis_logger_spec.rb +++ b/sentry-ruby/spec/sentry/breadcrumb/redis_logger_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe :redis_logger do diff --git a/sentry-ruby/spec/sentry/breadcrumb/sentry_logger_spec.rb b/sentry-ruby/spec/sentry/breadcrumb/sentry_logger_spec.rb index baf180922..da3cd97c7 100644 --- a/sentry-ruby/spec/sentry/breadcrumb/sentry_logger_spec.rb +++ b/sentry-ruby/spec/sentry/breadcrumb/sentry_logger_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe "Sentry::Breadcrumbs::SentryLogger" do @@ -69,33 +71,35 @@ end # see https://github.com/getsentry/sentry-ruby/issues/1858 - it "noops on thread with cloned hub" do - mutex = Mutex.new - cv = ConditionVariable.new - - a = Thread.new do - expect(Sentry.get_current_hub).to be_a(Sentry::Hub) + unless RUBY_PLATFORM == "java" + it "noops on thread with cloned hub" do + mutex = Mutex.new + cv = ConditionVariable.new + + a = Thread.new do + expect(Sentry.get_current_hub).to be_a(Sentry::Hub) + + # close in another thread + b = Thread.new do + mutex.synchronize do + Sentry.close + cv.signal + end + end - # close in another thread - b = Thread.new do mutex.synchronize do - Sentry.close - cv.signal - end - end + # wait for other thread to close SDK + cv.wait(mutex) - mutex.synchronize do - # wait for other thread to close SDK - cv.wait(mutex) + expect(Sentry).not_to receive(:add_breadcrumb) + logger.info("foo") + end - expect(Sentry).not_to receive(:add_breadcrumb) - logger.info("foo") + b.join end - b.join + a.join end - - a.join end end end diff --git a/sentry-ruby/spec/sentry/breadcrumb_buffer_spec.rb b/sentry-ruby/spec/sentry/breadcrumb_buffer_spec.rb index 04a76fe3c..f68e223b3 100644 --- a/sentry-ruby/spec/sentry/breadcrumb_buffer_spec.rb +++ b/sentry-ruby/spec/sentry/breadcrumb_buffer_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::BreadcrumbBuffer do diff --git a/sentry-ruby/spec/sentry/breadcrumb_spec.rb b/sentry-ruby/spec/sentry/breadcrumb_spec.rb index 66c2d1112..2eddb7101 100644 --- a/sentry-ruby/spec/sentry/breadcrumb_spec.rb +++ b/sentry-ruby/spec/sentry/breadcrumb_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Breadcrumb do diff --git a/sentry-ruby/spec/sentry/client/event_sending_spec.rb b/sentry-ruby/spec/sentry/client/event_sending_spec.rb index b1b1a041c..86b4b6c67 100644 --- a/sentry-ruby/spec/sentry/client/event_sending_spec.rb +++ b/sentry-ruby/spec/sentry/client/event_sending_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Client do diff --git a/sentry-ruby/spec/sentry/client_spec.rb b/sentry-ruby/spec/sentry/client_spec.rb index bd1debcf2..e069ccc5b 100644 --- a/sentry-ruby/spec/sentry/client_spec.rb +++ b/sentry-ruby/spec/sentry/client_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' class ExceptionWithContext < StandardError @@ -341,7 +343,12 @@ def detailed_message(*) event = subject.event_from_exception(NonStringMessageError.new) hash = event.to_hash expect(event).to be_a(Sentry::ErrorEvent) - expect(hash[:exception][:values][0][:value]).to eq("{:foo=>\"bar\"}") + + if RUBY_VERSION >= "3.4" + expect(hash[:exception][:values][0][:value]).to eq("{foo: \"bar\"}") + else + expect(hash[:exception][:values][0][:value]).to eq("{:foo=>\"bar\"}") + end end end diff --git a/sentry-ruby/spec/sentry/configuration_spec.rb b/sentry-ruby/spec/sentry/configuration_spec.rb index 7ebd32920..afd78625b 100644 --- a/sentry-ruby/spec/sentry/configuration_spec.rb +++ b/sentry-ruby/spec/sentry/configuration_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Configuration do @@ -693,4 +695,21 @@ class SentryConfigurationSample < Sentry::Configuration expect(subject.enabled_patches).to eq(%i[redis http]) end end + + describe "#profiler_class=" do + it "sets the profiler class to Vernier when it's available", when: :vernier_installed? do + subject.profiler_class = Sentry::Vernier::Profiler + expect(subject.profiler_class).to eq(Sentry::Vernier::Profiler) + end + + it "sets the profiler class to StackProf when Vernier is not available", when: { ruby_version?: [:<, "3.2"] } do + expect { subject.profiler_class = Sentry::Vernier::Profiler } + .to raise_error( + ArgumentError, + /Please add the 'vernier' gem to your Gemfile/ + ) + + expect(subject.profiler_class).to eq(Sentry::Profiler) + end + 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 fb8212df6..48cd3e044 100644 --- a/sentry-ruby/spec/sentry/cron/monitor_check_ins_spec.rb +++ b/sentry-ruby/spec/sentry/cron/monitor_check_ins_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Cron::MonitorCheckIns do diff --git a/sentry-ruby/spec/sentry/cron/monitor_config_spec.rb b/sentry-ruby/spec/sentry/cron/monitor_config_spec.rb index 68bbbe95a..1c934e8cc 100644 --- a/sentry-ruby/spec/sentry/cron/monitor_config_spec.rb +++ b/sentry-ruby/spec/sentry/cron/monitor_config_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Cron::MonitorConfig do diff --git a/sentry-ruby/spec/sentry/cron/monitor_schedule_spec.rb b/sentry-ruby/spec/sentry/cron/monitor_schedule_spec.rb index 8e1b422d1..909a9b4fa 100644 --- a/sentry-ruby/spec/sentry/cron/monitor_schedule_spec.rb +++ b/sentry-ruby/spec/sentry/cron/monitor_schedule_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Cron::MonitorSchedule::Crontab do diff --git a/sentry-ruby/spec/sentry/dsn_spec.rb b/sentry-ruby/spec/sentry/dsn_spec.rb index 24256f291..0a0eaecb4 100644 --- a/sentry-ruby/spec/sentry/dsn_spec.rb +++ b/sentry-ruby/spec/sentry/dsn_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::DSN do diff --git a/sentry-ruby/spec/sentry/envelope_spec.rb b/sentry-ruby/spec/sentry/envelope/item_spec.rb similarity index 95% rename from sentry-ruby/spec/sentry/envelope_spec.rb rename to sentry-ruby/spec/sentry/envelope/item_spec.rb index 8936c7707..ea9cf1019 100644 --- a/sentry-ruby/spec/sentry/envelope_spec.rb +++ b/sentry-ruby/spec/sentry/envelope/item_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Envelope::Item do diff --git a/sentry-ruby/spec/sentry/event_spec.rb b/sentry-ruby/spec/sentry/event_spec.rb index ea59f95e1..90acb4da8 100644 --- a/sentry-ruby/spec/sentry/event_spec.rb +++ b/sentry-ruby/spec/sentry/event_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Event do diff --git a/sentry-ruby/spec/sentry/faraday_spec.rb b/sentry-ruby/spec/sentry/faraday_spec.rb index f4632032f..0cb69fe39 100644 --- a/sentry-ruby/spec/sentry/faraday_spec.rb +++ b/sentry-ruby/spec/sentry/faraday_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "faraday" require_relative "../spec_helper" diff --git a/sentry-ruby/spec/sentry/graphql_spec.rb b/sentry-ruby/spec/sentry/graphql_spec.rb index 5820b73d2..a90dfe6b0 100644 --- a/sentry-ruby/spec/sentry/graphql_spec.rb +++ b/sentry-ruby/spec/sentry/graphql_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' with_graphql = begin diff --git a/sentry-ruby/spec/sentry/hub_spec.rb b/sentry-ruby/spec/sentry/hub_spec.rb index 6d06595aa..735bc6acd 100644 --- a/sentry-ruby/spec/sentry/hub_spec.rb +++ b/sentry-ruby/spec/sentry/hub_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Hub do @@ -519,9 +521,25 @@ describe "#pop_scope" do it "pops the current scope" do + prev_scope = subject.current_scope + subject.push_scope + scope = subject.current_scope expect(subject.current_scope).to eq(scope) subject.pop_scope - expect(subject.current_scope).to eq(nil) + expect(subject.current_scope).to eq(prev_scope) + end + + it "doesn't pop the last layer" do + expect(subject.instance_variable_get(:@stack).count).to eq(1) + + subject.pop_scope + + expect(subject.instance_variable_get(:@stack).count).to eq(1) + + # It should be a completely new scope + expect(subject.current_scope).not_to eq(scope) + # But it should be the same client + expect(subject.current_client).to eq(client) end end @@ -543,21 +561,6 @@ expect(subject.current_scope).not_to eq(scope) expect(subject.current_scope.tags).to eq({ foo: "bar" }) end - - context "when the current_scope is nil" do - before do - subject.pop_scope - expect(subject.current_scope).to eq(nil) - end - it "creates a new scope" do - scope.set_tags({ foo: "bar" }) - - subject.push_scope - - expect(subject.current_scope).not_to eq(scope) - expect(subject.current_scope.tags).to eq({}) - end - end end describe '#configure_scope' do diff --git a/sentry-ruby/spec/sentry/integrable_spec.rb b/sentry-ruby/spec/sentry/integrable_spec.rb index 269ba821e..6e7a03a07 100644 --- a/sentry-ruby/spec/sentry/integrable_spec.rb +++ b/sentry-ruby/spec/sentry/integrable_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" require "sentry/integrable" diff --git a/sentry-ruby/spec/sentry/interface_spec.rb b/sentry-ruby/spec/sentry/interface_spec.rb index 7d95d5263..2d70cdc9b 100644 --- a/sentry-ruby/spec/sentry/interface_spec.rb +++ b/sentry-ruby/spec/sentry/interface_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'sentry/interface' diff --git a/sentry-ruby/spec/sentry/interfaces/request_interface_spec.rb b/sentry-ruby/spec/sentry/interfaces/request_interface_spec.rb index 580a610d3..a7a2225d0 100644 --- a/sentry-ruby/spec/sentry/interfaces/request_interface_spec.rb +++ b/sentry-ruby/spec/sentry/interfaces/request_interface_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' return unless defined?(Rack) diff --git a/sentry-ruby/spec/sentry/interfaces/stacktrace_builder_spec.rb b/sentry-ruby/spec/sentry/interfaces/stacktrace_builder_spec.rb index 637aff2ad..fd89360a9 100644 --- a/sentry-ruby/spec/sentry/interfaces/stacktrace_builder_spec.rb +++ b/sentry-ruby/spec/sentry/interfaces/stacktrace_builder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::StacktraceBuilder do @@ -11,8 +13,8 @@ let(:backtrace) do [ - "#{fixture_file}:6:in `bar'", - "#{fixture_file}:2:in `foo'" + "#{fixture_file}:8:in `bar'", + "#{fixture_file}:4:in `foo'" ] end @@ -36,8 +38,8 @@ expect(first_frame.filename).to match(/stacktrace_test_fixture.rb/) expect(first_frame.function).to eq("foo") - expect(first_frame.lineno).to eq(2) - expect(first_frame.pre_context).to eq([nil, nil, "def foo\n"]) + expect(first_frame.lineno).to eq(4) + expect(first_frame.pre_context).to eq(["# frozen_string_literal: true\n", "\n", "def foo\n"]) expect(first_frame.context_line).to eq(" bar\n") expect(first_frame.post_context).to eq(["end\n", "\n", "def bar\n"]) @@ -45,12 +47,27 @@ expect(second_frame.filename).to match(/stacktrace_test_fixture.rb/) expect(second_frame.function).to eq("bar") - expect(second_frame.lineno).to eq(6) + expect(second_frame.lineno).to eq(8) expect(second_frame.pre_context).to eq(["end\n", "\n", "def bar\n"]) expect(second_frame.context_line).to eq(" baz\n") expect(second_frame.post_context).to eq(["end\n", nil, nil]) end + context "when strip_backtrace_load_path is false" do + let(:configuration) do + Sentry::Configuration.new.tap do |config| + config.project_root = fixture_root + config.strip_backtrace_load_path = false + end + end + + it "does not strip load paths for filenames" do + interface = subject.build(backtrace: backtrace) + expect(interface.frames.first.filename).to eq(fixture_file) + expect(interface.frames.last.filename).to eq(fixture_file) + end + end + context "with block argument" do it "removes the frame if it's evaluated as nil" do interface = subject.build(backtrace: backtrace) do |frame| @@ -77,7 +94,7 @@ expect(second_frame.filename).to match(/stacktrace_test_fixture.rb/) expect(second_frame.function).to eq("bar") - expect(second_frame.lineno).to eq(6) + expect(second_frame.lineno).to eq(8) expect(second_frame.vars).to eq({ foo: "bar" }) end end @@ -89,7 +106,7 @@ expect(hash[:filename]).to match(/stacktrace_test_fixture.rb/) expect(hash[:function]).to eq("bar") - expect(hash[:lineno]).to eq(6) + expect(hash[:lineno]).to eq(8) expect(hash[:pre_context]).to eq(["end\n", "\n", "def bar\n"]) expect(hash[:context_line]).to eq(" baz\n") expect(hash[:post_context]).to eq(["end\n", nil, nil]) diff --git a/sentry-ruby/spec/sentry/interfaces/stacktrace_spec.rb b/sentry-ruby/spec/sentry/interfaces/stacktrace_spec.rb index 143dc369c..6ceb0b1d0 100644 --- a/sentry-ruby/spec/sentry/interfaces/stacktrace_spec.rb +++ b/sentry-ruby/spec/sentry/interfaces/stacktrace_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::StacktraceInterface::Frame do @@ -28,5 +30,15 @@ expect(second_frame.function).to eq("save_user") expect(second_frame.lineno).to eq(5) end + + it "does not strip load path when strip_backtrace_load_path is false" do + first_frame = Sentry::StacktraceInterface::Frame.new(configuration.project_root, lines.first, false) + expect(first_frame.filename).to eq(first_frame.abs_path) + expect(first_frame.filename).to eq(raw_lines.first.split(':').first) + + second_frame = Sentry::StacktraceInterface::Frame.new(configuration.project_root, lines.last, false) + expect(second_frame.filename).to eq(second_frame.abs_path) + expect(second_frame.filename).to eq(raw_lines.last.split(':').first) + end end end diff --git a/sentry-ruby/spec/sentry/linecache_spec.rb b/sentry-ruby/spec/sentry/linecache_spec.rb index 56c9e086b..097b3ed56 100644 --- a/sentry-ruby/spec/sentry/linecache_spec.rb +++ b/sentry-ruby/spec/sentry/linecache_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' # rubocop:disable Style/WordArray RSpec.describe Sentry::LineCache do diff --git a/sentry-ruby/spec/sentry/metrics/aggregator_spec.rb b/sentry-ruby/spec/sentry/metrics/aggregator_spec.rb index dcd78ab86..b54c6a0d9 100644 --- a/sentry-ruby/spec/sentry/metrics/aggregator_spec.rb +++ b/sentry-ruby/spec/sentry/metrics/aggregator_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Metrics::Aggregator do diff --git a/sentry-ruby/spec/sentry/metrics/configuration_spec.rb b/sentry-ruby/spec/sentry/metrics/configuration_spec.rb index 2c7e22fbe..3d04ad3ea 100644 --- a/sentry-ruby/spec/sentry/metrics/configuration_spec.rb +++ b/sentry-ruby/spec/sentry/metrics/configuration_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Metrics::Configuration do diff --git a/sentry-ruby/spec/sentry/metrics/counter_metric_spec.rb b/sentry-ruby/spec/sentry/metrics/counter_metric_spec.rb index f92a0135f..f1c480b45 100644 --- a/sentry-ruby/spec/sentry/metrics/counter_metric_spec.rb +++ b/sentry-ruby/spec/sentry/metrics/counter_metric_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Metrics::CounterMetric do diff --git a/sentry-ruby/spec/sentry/metrics/distribution_metric_spec.rb b/sentry-ruby/spec/sentry/metrics/distribution_metric_spec.rb index 7e5b2f2d4..e8ac709f3 100644 --- a/sentry-ruby/spec/sentry/metrics/distribution_metric_spec.rb +++ b/sentry-ruby/spec/sentry/metrics/distribution_metric_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Metrics::DistributionMetric do diff --git a/sentry-ruby/spec/sentry/metrics/gauge_metric_spec.rb b/sentry-ruby/spec/sentry/metrics/gauge_metric_spec.rb index 44be08465..fce3141c6 100644 --- a/sentry-ruby/spec/sentry/metrics/gauge_metric_spec.rb +++ b/sentry-ruby/spec/sentry/metrics/gauge_metric_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Metrics::GaugeMetric do diff --git a/sentry-ruby/spec/sentry/metrics/local_aggregator_spec.rb b/sentry-ruby/spec/sentry/metrics/local_aggregator_spec.rb index 5c5ab0583..3056808da 100644 --- a/sentry-ruby/spec/sentry/metrics/local_aggregator_spec.rb +++ b/sentry-ruby/spec/sentry/metrics/local_aggregator_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Metrics::LocalAggregator do diff --git a/sentry-ruby/spec/sentry/metrics/metric_spec.rb b/sentry-ruby/spec/sentry/metrics/metric_spec.rb index a5ed3fd93..ccb4fa222 100644 --- a/sentry-ruby/spec/sentry/metrics/metric_spec.rb +++ b/sentry-ruby/spec/sentry/metrics/metric_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Metrics::Metric do diff --git a/sentry-ruby/spec/sentry/metrics/set_metric_spec.rb b/sentry-ruby/spec/sentry/metrics/set_metric_spec.rb index fdf74dd0d..2cd01da83 100644 --- a/sentry-ruby/spec/sentry/metrics/set_metric_spec.rb +++ b/sentry-ruby/spec/sentry/metrics/set_metric_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Metrics::SetMetric do diff --git a/sentry-ruby/spec/sentry/metrics/timing_spec.rb b/sentry-ruby/spec/sentry/metrics/timing_spec.rb index 8142fbb4d..3b2ee2235 100644 --- a/sentry-ruby/spec/sentry/metrics/timing_spec.rb +++ b/sentry-ruby/spec/sentry/metrics/timing_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Metrics::Timing do diff --git a/sentry-ruby/spec/sentry/metrics_spec.rb b/sentry-ruby/spec/sentry/metrics_spec.rb index 335c31e5a..e50c55074 100644 --- a/sentry-ruby/spec/sentry/metrics_spec.rb +++ b/sentry-ruby/spec/sentry/metrics_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Metrics do diff --git a/sentry-ruby/spec/sentry/net/http_spec.rb b/sentry-ruby/spec/sentry/net/http_spec.rb index 064c4f36c..9de0a6f76 100644 --- a/sentry-ruby/spec/sentry/net/http_spec.rb +++ b/sentry-ruby/spec/sentry/net/http_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" require 'contexts/with_request_mock' @@ -107,6 +109,22 @@ end end + it "supports non-ascii characters in the path" do + stub_normal_response + + uri = URI('http://example.com') + http = Net::HTTP.new(uri.host, uri.port) + request = Net::HTTP::Get.new('/path?q=øgreyfoss&å=vær') + + transaction = Sentry.start_transaction + Sentry.get_current_scope.set_span(transaction) + + + response = http.request(request) + + expect(response.code).to eq("200") + end + it "adds sentry-trace header to the request header" do uri = URI("http://example.com/path") http = Net::HTTP.new(uri.host, uri.port) diff --git a/sentry-ruby/spec/sentry/profiler_spec.rb b/sentry-ruby/spec/sentry/profiler_spec.rb index e0cba8177..883fac025 100644 --- a/sentry-ruby/spec/sentry/profiler_spec.rb +++ b/sentry-ruby/spec/sentry/profiler_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Profiler, when: :stack_prof_installed? do @@ -174,10 +176,11 @@ subject.set_initial_sample_decision(true) subject.start subject.stop + + allow(StackProf).to receive(:results).and_return([]) end it 'returns empty' do - expect(StackProf).to receive(:results).and_call_original expect(subject.to_hash).to eq({}) end diff --git a/sentry-ruby/spec/sentry/propagation_context_spec.rb b/sentry-ruby/spec/sentry/propagation_context_spec.rb index 644fc9530..7e16404b6 100644 --- a/sentry-ruby/spec/sentry/propagation_context_spec.rb +++ b/sentry-ruby/spec/sentry/propagation_context_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::PropagationContext do diff --git a/sentry-ruby/spec/sentry/rack/capture_exceptions_spec.rb b/sentry-ruby/spec/sentry/rack/capture_exceptions_spec.rb index dfd42ab33..21e1786ef 100644 --- a/sentry-ruby/spec/sentry/rack/capture_exceptions_spec.rb +++ b/sentry-ruby/spec/sentry/rack/capture_exceptions_spec.rb @@ -1,4 +1,7 @@ +# frozen_string_literal: true + require 'spec_helper' +require 'sentry/vernier/profiler' RSpec.describe 'Sentry::Rack::CaptureExceptions', when: :rack_available? do let(:exception) { ZeroDivisionError.new("divided by 0") } @@ -679,74 +682,106 @@ def will_be_sampled_by_sdk end end - if defined?(StackProf) - describe "profiling" do - context "when profiling is enabled" do - before do - perform_basic_setup do |config| - config.traces_sample_rate = 1.0 - config.profiles_sample_rate = 1.0 - config.release = "test-release" - end - end + shared_examples "a profiled transaction" do + it "collects a profile", retry: 3 do + stack = Sentry::Rack::CaptureExceptions.new(app) + stack.call(env) + event = last_sentry_event - let(:stackprof_results) do - data = StackProf::Report.from_file('spec/support/stackprof_results.json').data - # relative dir differs on each machine - data[:frames].each { |_id, fra| fra[:file].gsub!(//, Dir.pwd) } - data - end + profile = event.profile + expect(profile).not_to be_nil - before do - StackProf.stop - allow(StackProf).to receive(:results).and_return(stackprof_results) - end + expect(profile[:event_id]).not_to be_nil + expect(profile[:platform]).to eq("ruby") + expect(profile[:version]).to eq("1") + expect(profile[:environment]).to eq("development") + expect(profile[:release]).to eq("test-release") + expect { Time.parse(profile[:timestamp]) }.not_to raise_error - it "collects a profile" do - app = ->(_) do - [200, {}, "ok"] - end + expect(profile[:device]).to include(:architecture) + expect(profile[:os]).to include(:name, :version) + expect(profile[:runtime]).to include(:name, :version) - stack = Sentry::Rack::CaptureExceptions.new(app) - stack.call(env) - event = last_sentry_event + expect(profile[:transaction]).to include(:id, :name, :trace_id, :active_thread_id) + expect(profile[:transaction][:id]).to eq(event.event_id) + expect(profile[:transaction][:name]).to eq(event.transaction) + expect(profile[:transaction][:trace_id]).to eq(event.contexts[:trace][:trace_id]) - profile = event.profile - expect(profile).not_to be_nil + thread_id_mapping = { + Sentry::Profiler => "0", + Sentry::Vernier::Profiler => Thread.current.object_id.to_s + } - expect(profile[:event_id]).not_to be_nil - expect(profile[:platform]).to eq("ruby") - expect(profile[:version]).to eq("1") - expect(profile[:environment]).to eq("development") - expect(profile[:release]).to eq("test-release") - expect { Time.parse(profile[:timestamp]) }.not_to raise_error + expect(profile[:transaction][:active_thread_id]).to eq(thread_id_mapping[Sentry.configuration.profiler_class]) - expect(profile[:device]).to include(:architecture) - expect(profile[:os]).to include(:name, :version) - expect(profile[:runtime]).to include(:name, :version) + # detailed checking of content is done in profiler_spec, + # just check basic structure here + frames = profile[:profile][:frames] + expect(frames).to be_a(Array) + expect(frames.first).to include(:function, :filename, :abs_path, :in_app) - expect(profile[:transaction]).to include(:id, :name, :trace_id, :active_thead_id) - expect(profile[:transaction][:id]).to eq(event.event_id) - expect(profile[:transaction][:name]).to eq(event.transaction) - expect(profile[:transaction][:trace_id]).to eq(event.contexts[:trace][:trace_id]) - expect(profile[:transaction][:active_thead_id]).to eq("0") + stacks = profile[:profile][:stacks] + expect(stacks).to be_a(Array) + expect(stacks.first).to be_a(Array) + expect(stacks.first.first).to be_a(Integer) - # detailed checking of content is done in profiler_spec, - # just check basic structure here - frames = profile[:profile][:frames] - expect(frames).to be_a(Array) - expect(frames.first).to include(:function, :filename, :abs_path, :in_app) + samples = profile[:profile][:samples] + expect(samples).to be_a(Array) + expect(samples.first).to include(:stack_id, :thread_id, :elapsed_since_start_ns) + end + end - stacks = profile[:profile][:stacks] - expect(stacks).to be_a(Array) - expect(stacks.first).to be_a(Array) - expect(stacks.first.first).to be_a(Integer) + describe "profiling with StackProf", when: [:stack_prof_installed?, :rack_available?] do + context "when profiling is enabled" do + let(:app) do + ->(_) do + [200, {}, "ok"] + end + end - samples = profile[:profile][:samples] - expect(samples).to be_a(Array) - expect(samples.first).to include(:stack_id, :thread_id, :elapsed_since_start_ns) + let(:stackprof_results) do + data = StackProf::Report.from_file('spec/support/stackprof_results.json').data + # relative dir differs on each machine + data[:frames].each { |_id, fra| fra[:file].gsub!(//, Dir.pwd) } + data + end + + before do + perform_basic_setup do |config| + config.traces_sample_rate = 1.0 + config.profiles_sample_rate = 1.0 + config.release = "test-release" + end + + StackProf.stop + + allow(StackProf).to receive(:results).and_return(stackprof_results) + end + + include_examples "a profiled transaction" + end + end + + describe "profiling with vernier", when: [:vernier_installed?, :rack_available?] do + context "when profiling is enabled" do + let(:app) do + ->(_) do + ProfilerTest::Bar.bar + [200, {}, "ok"] end end + + before do + perform_basic_setup do |config| + config.traces_sample_rate = 1.0 + config.profiles_sample_rate = 1.0 + config.release = "test-release" + config.profiler_class = Sentry::Vernier::Profiler + config.project_root = Dir.pwd + end + end + + include_examples "a profiled transaction" end end end diff --git a/sentry-ruby/spec/sentry/rake_spec.rb b/sentry-ruby/spec/sentry/rake_spec.rb index a1eb22998..904f19170 100644 --- a/sentry-ruby/spec/sentry/rake_spec.rb +++ b/sentry-ruby/spec/sentry/rake_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe "rake auto-reporting" do diff --git a/sentry-ruby/spec/sentry/redis_spec.rb b/sentry-ruby/spec/sentry/redis_spec.rb index 2722e0498..50e86ac55 100644 --- a/sentry-ruby/spec/sentry/redis_spec.rb +++ b/sentry-ruby/spec/sentry/redis_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Redis do diff --git a/sentry-ruby/spec/sentry/scope/setters_spec.rb b/sentry-ruby/spec/sentry/scope/setters_spec.rb index 6a5378194..39a2e25c1 100644 --- a/sentry-ruby/spec/sentry/scope/setters_spec.rb +++ b/sentry-ruby/spec/sentry/scope/setters_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Scope do diff --git a/sentry-ruby/spec/sentry/scope_spec.rb b/sentry-ruby/spec/sentry/scope_spec.rb index 9b52244a8..4bacae275 100644 --- a/sentry-ruby/spec/sentry/scope_spec.rb +++ b/sentry-ruby/spec/sentry/scope_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Scope do @@ -293,7 +295,7 @@ end end - it "sets trace context from span if there's a span" do + it "sets trace context and dynamic_sampling_context from span if there's a span" do transaction = Sentry::Transaction.new(op: "foo", hub: hub) subject.set_span(transaction) @@ -301,6 +303,7 @@ expect(event.contexts[:trace]).to eq(transaction.get_trace_context) expect(event.contexts.dig(:trace, :op)).to eq("foo") + expect(event.dynamic_sampling_context).to eq(transaction.get_dynamic_sampling_context) end it "sets trace context and dynamic_sampling_context from propagation context if there's no span" do diff --git a/sentry-ruby/spec/sentry/session_flusher_spec.rb b/sentry-ruby/spec/sentry/session_flusher_spec.rb index 0c0fbb4eb..376f71dd4 100644 --- a/sentry-ruby/spec/sentry/session_flusher_spec.rb +++ b/sentry-ruby/spec/sentry/session_flusher_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::SessionFlusher do diff --git a/sentry-ruby/spec/sentry/span_spec.rb b/sentry-ruby/spec/sentry/span_spec.rb index d890dfa25..0d1fd225c 100644 --- a/sentry-ruby/spec/sentry/span_spec.rb +++ b/sentry-ruby/spec/sentry/span_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Span do @@ -136,6 +138,35 @@ end end + describe "#get_dynamic_sampling_context" do + before do + # because initializing transactions requires an active hub + perform_basic_setup + end + + subject do + baggage = Sentry::Baggage.from_incoming_header( + "other-vendor-value-1=foo;bar;baz, "\ + "sentry-trace_id=771a43a4192642f0b136d5159a501700, "\ + "sentry-public_key=49d0f7386ad645858ae85020e393bef3, "\ + "sentry-sample_rate=0.01337, "\ + "sentry-user_id=Am%C3%A9lie, "\ + "other-vendor-value-2=foo;bar;" + ) + + Sentry::Transaction.new(hub: Sentry.get_current_hub, baggage: baggage).start_child + end + + it "propagates sentry dynamic_sampling_context" do + expect(subject.get_dynamic_sampling_context).to eq({ + "sample_rate" => "0.01337", + "public_key" => "49d0f7386ad645858ae85020e393bef3", + "trace_id" => "771a43a4192642f0b136d5159a501700", + "user_id" => "Amélie" + }) + end + end + describe "#start_child" do before do # because initializing transactions requires an active hub diff --git a/sentry-ruby/spec/sentry/test_helper_spec.rb b/sentry-ruby/spec/sentry/test_helper_spec.rb index 2753b9b64..8303464c8 100644 --- a/sentry-ruby/spec/sentry/test_helper_spec.rb +++ b/sentry-ruby/spec/sentry/test_helper_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::TestHelper do diff --git a/sentry-ruby/spec/sentry/transaction_spec.rb b/sentry-ruby/spec/sentry/transaction_spec.rb index effb249f1..7cc83aa64 100644 --- a/sentry-ruby/spec/sentry/transaction_spec.rb +++ b/sentry-ruby/spec/sentry/transaction_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Transaction do diff --git a/sentry-ruby/spec/sentry/transport/configuration_spec.rb b/sentry-ruby/spec/sentry/transport/configuration_spec.rb index 676a4800c..fa3edd87b 100644 --- a/sentry-ruby/spec/sentry/transport/configuration_spec.rb +++ b/sentry-ruby/spec/sentry/transport/configuration_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Transport::Configuration do diff --git a/sentry-ruby/spec/sentry/transport/http_transport_rate_limiting_spec.rb b/sentry-ruby/spec/sentry/transport/http_transport_rate_limiting_spec.rb index ac83e3b16..30dc42bbb 100644 --- a/sentry-ruby/spec/sentry/transport/http_transport_rate_limiting_spec.rb +++ b/sentry-ruby/spec/sentry/transport/http_transport_rate_limiting_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'contexts/with_request_mock' diff --git a/sentry-ruby/spec/sentry/transport/http_transport_spec.rb b/sentry-ruby/spec/sentry/transport/http_transport_spec.rb index 3c7b1b051..a0973ef75 100644 --- a/sentry-ruby/spec/sentry/transport/http_transport_spec.rb +++ b/sentry-ruby/spec/sentry/transport/http_transport_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' require 'contexts/with_request_mock' diff --git a/sentry-ruby/spec/sentry/transport/spotlight_transport_spec.rb b/sentry-ruby/spec/sentry/transport/spotlight_transport_spec.rb index 04de57af6..fc095efeb 100644 --- a/sentry-ruby/spec/sentry/transport/spotlight_transport_spec.rb +++ b/sentry-ruby/spec/sentry/transport/spotlight_transport_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::SpotlightTransport do diff --git a/sentry-ruby/spec/sentry/transport_spec.rb b/sentry-ruby/spec/sentry/transport_spec.rb index b78dc7878..059a8109b 100644 --- a/sentry-ruby/spec/sentry/transport_spec.rb +++ b/sentry-ruby/spec/sentry/transport_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Transport do @@ -145,6 +147,37 @@ expect(profile_payload).to eq(profile.to_json) end end + + context "allows bigger item size" do + let(:profile) do + { + environment: "test", + release: "release", + profile: { + frames: Array.new(10000) { |i| { function: "function_#{i}", filename: "file_#{i}", lineno: i } }, + stacks: Array.new(10000) { |i| [i] }, + samples: Array.new(10000) { |i| { stack_id: i, elapsed_since_start_ns: i * 1000, thread_id: i % 10 } } + } + } + end + + let(:event_with_profile) do + event.profile = profile + event + end + + let(:envelope) { subject.envelope_from_event(event_with_profile) } + + it "adds profile item to envelope" do + result, _ = subject.serialize_envelope(envelope) + + _profile_header, profile_payload_json = result.split("\n").last(2) + + profile_payload = JSON.parse(profile_payload_json) + + expect(profile_payload["profile"]).to_not be(nil) + end + end end context "client report" do @@ -250,7 +283,7 @@ let(:in_app_pattern) do project_root = "/fake/project_root" - Regexp.new("^(#{project_root}/)?#{Sentry::Backtrace::APP_DIRS_PATTERN}") + Regexp.new("^(#{project_root}/)?#{Sentry::Configuration::APP_DIRS_PATTERN}") end let(:frame_list_limit) { 500 } let(:frame_list_size) { frame_list_limit * 20 } diff --git a/sentry-ruby/spec/sentry/utils/real_ip_spec.rb b/sentry-ruby/spec/sentry/utils/real_ip_spec.rb index 7aa6c7559..42197b9f2 100644 --- a/sentry-ruby/spec/sentry/utils/real_ip_spec.rb +++ b/sentry-ruby/spec/sentry/utils/real_ip_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Utils::RealIp do diff --git a/sentry-ruby/spec/sentry/utils/request_id_spec.rb b/sentry-ruby/spec/sentry/utils/request_id_spec.rb index 7fa7a7301..955bd8894 100644 --- a/sentry-ruby/spec/sentry/utils/request_id_spec.rb +++ b/sentry-ruby/spec/sentry/utils/request_id_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Utils::RequestId do diff --git a/sentry-ruby/spec/sentry/vernier/profiler_spec.rb b/sentry-ruby/spec/sentry/vernier/profiler_spec.rb new file mode 100644 index 000000000..03fe7ebde --- /dev/null +++ b/sentry-ruby/spec/sentry/vernier/profiler_spec.rb @@ -0,0 +1,311 @@ +# frozen_string_literal: true + +require "spec_helper" + +require "sentry/vernier/profiler" + +RSpec.describe Sentry::Vernier::Profiler, when: { ruby_version?: [:>=, "3.2.1"] } do + subject(:profiler) { described_class.new(Sentry.configuration) } + + before do + # TODO: replace with some public API once available + Vernier.stop_profile if Vernier.instance_variable_get(:@collector) + + perform_basic_setup do |config| + config.traces_sample_rate = traces_sample_rate + config.profiles_sample_rate = profiles_sample_rate + config.app_dirs_pattern = %r{spec/support} + end + end + + let(:profiles_sample_rate) { 1.0 } + let(:traces_sample_rate) { 1.0 } + + describe '#start' do + context "when profiles_sample_rate is 0" do + let(:profiles_sample_rate) { 0.0 } + + it "does not start Vernier" do + profiler.set_initial_sample_decision(true) + + expect(Vernier).not_to receive(:start_profile) + profiler.start + expect(profiler.started).to eq(false) + end + end + + context "when profiles_sample_rate is between 0.0 and 1.0" do + let(:profiles_sample_rate) { 0.4 } + + it "randomizes profiling" do + profiler.set_initial_sample_decision(true) + + expect([nil, true]).to include(profiler.start) + end + end + + context "when traces_sample_rate is nil" do + let(:traces_sample_rate) { nil } + + it "does not start Vernier" do + profiler.set_initial_sample_decision(true) + + expect(Vernier).not_to receive(:start_profile) + profiler.start + expect(profiler.started).to eq(false) + end + end + + context 'without sampling decision' do + it 'does not start Vernier' do + expect(Vernier).not_to receive(:start_profile) + profiler.start + expect(profiler.started).to eq(false) + end + + it 'does not start Vernier if not sampled' do + expect(Vernier).not_to receive(:start_profile) + profiler.start + expect(profiler.started).to eq(false) + end + end + + context 'with sampling decision' do + before do + profiler.set_initial_sample_decision(true) + end + + it 'starts Vernier if sampled' do + expect(Vernier).to receive(:start_profile).and_return(true) + + profiler.start + + expect(profiler.started).to eq(true) + end + + it 'does not start Vernier again if already started' do + expect(Vernier).to receive(:start_profile).and_return(true).once + + profiler.start + profiler.start + + expect(profiler.started).to be(true) + end + end + + context "when Vernier crashes" do + it "logs the error and does not raise" do + profiler.set_initial_sample_decision(true) + + expect(Vernier).to receive(:start_profile).and_raise("boom") + + expect { profiler.start }.to_not raise_error("boom") + end + + it "doesn't start if Vernier raises that it already started" do + profiler.set_initial_sample_decision(true) + + expect(Vernier).to receive(:start_profile).and_raise(RuntimeError.new("Profile already started")) + + profiler.start + + expect(profiler.started).to eq(false) + end + end + end + + describe '#stop' do + it 'does not stop Vernier if not sampled' do + profiler.set_initial_sample_decision(false) + expect(Vernier).not_to receive(:stop_profile) + profiler.stop + end + + it 'does not stop Vernier if sampled but not started' do + profiler.set_initial_sample_decision(true) + expect(Vernier).not_to receive(:stop_profile) + profiler.stop + end + + it 'stops Vernier if sampled and started' do + profiler.set_initial_sample_decision(true) + profiler.start + expect(Vernier).to receive(:stop_profile) + profiler.stop + end + end + + describe "#to_hash" do + let (:transport) { Sentry.get_current_client.transport } + + + it "records lost event if not sampled" do + expect(transport).to receive(:record_lost_event).with(:sample_rate, "profile") + + profiler.set_initial_sample_decision(true) + profiler.start + profiler.set_initial_sample_decision(false) + + expect(profiler.to_hash).to eq({}) + end + end + + context 'with sampling decision' do + before do + profiler.set_initial_sample_decision(true) + end + + describe '#to_hash' do + it "returns empty hash if not started" do + expect(profiler.to_hash).to eq({}) + end + + context 'with single-thread profiled code' do + before do + profiler.start + ProfilerTest::Bar.bar + profiler.stop + end + + it 'has correct frames' do + frames = profiler.to_hash[:profile][:frames] + + foo_frame = frames.find { |f| f[:function] =~ /foo/ } + + expect(foo_frame[:function]).to eq('Foo.foo') + expect(foo_frame[:module]).to eq('ProfilerTest::Bar') + expect(foo_frame[:in_app]).to eq(true) + expect(foo_frame[:lineno]).to eq(6) + expect(foo_frame[:filename]).to eq('spec/support/profiler.rb') + expect(foo_frame[:abs_path]).to include('sentry-ruby/sentry-ruby/spec/support/profiler.rb') + end + + it 'has correct stacks' do + profile = profiler.to_hash[:profile] + frames = profile[:frames] + stacks = profile[:stacks] + + stack_tops = stacks.map { |s| s.take(3) }.map { |s| s.map { |i| frames[i][:function] } } + + expect(stack_tops.any? { |tops| tops.include?("Foo.foo") }).to be(true) + expect(stack_tops.any? { |tops| tops.include?("Bar.bar") }).to be(true) + expect(stack_tops.any? { |tops| tops.include?("Integer#times") }).to be(true) + + stacks.each do |stack| + stack.each do |frame_idx| + expect(frames[frame_idx][:function]).to be_a(String) + end + end + end + + it 'has correct samples' do + profile = profiler.to_hash[:profile] + samples = profile[:samples] + last_elapsed = 0 + + samples.group_by { |sample| sample[:thread_id] }.each do |thread_id, thread_samples| + expect(thread_id.to_i).to be > 0 + + last_elapsed = 0 + + thread_samples.each do |sample| + expect(sample[:stack_id]).to be > 0 + + elapsed = sample[:elapsed_since_start_ns].to_i + + expect(elapsed).to be > 0.0 + expect(elapsed).to be > last_elapsed + + last_elapsed = elapsed + end + end + end + end + + context 'with multi-thread profiled code' do + before do + profiler.start + + 2.times.map do |i| + Thread.new do + Thread.current.name = "thread-bar-#{i}" + + ProfilerTest::Bar.bar + end + end.map(&:join) + + profiler.stop + end + + it "has correct thread metadata" do + thread_metadata = profiler.to_hash[:profile][:thread_metadata] + + main_thread = thread_metadata.values.find { |metadata| metadata[:name].include?("rspec") } + thread1 = thread_metadata.values.find { |metadata| metadata[:name] == "thread-bar-0" } + thread2 = thread_metadata.values.find { |metadata| metadata[:name] == "thread-bar-1" } + + thread_metadata.each do |thread_id, metadata| + expect(thread_id.to_i).to be > 0 + end + + expect(main_thread[:name]).to include("rspec") + expect(thread1[:name]).to eq("thread-bar-0") + expect(thread2[:name]).to eq("thread-bar-1") + end + + it 'has correct frames', when: { ruby_version?: [:>=, "3.3"] } do + frames = profiler.to_hash[:profile][:frames] + + foo_frame = frames.find { |f| f[:function] =~ /foo/ } + + expect(foo_frame[:function]).to eq('Foo.foo') + expect(foo_frame[:module]).to eq('ProfilerTest::Bar') + expect(foo_frame[:in_app]).to eq(true) + expect(foo_frame[:lineno]).to eq(6) + expect(foo_frame[:filename]).to eq('spec/support/profiler.rb') + expect(foo_frame[:abs_path]).to include('sentry-ruby/sentry-ruby/spec/support/profiler.rb') + end + + it 'has correct stacks', when: { ruby_version?: [:>=, "3.3"] } do + profile = profiler.to_hash[:profile] + frames = profile[:frames] + stacks = profile[:stacks] + + stack_tops = stacks.map { |s| s.take(3) }.map { |s| s.map { |i| frames[i][:function] } } + + expect(stack_tops.any? { |tops| tops.include?("Foo.foo") }).to be(true) + expect(stack_tops.any? { |tops| tops.include?("Bar.bar") }).to be(true) + expect(stack_tops.any? { |tops| tops.include?("Integer#times") }).to be(true) + + stacks.each do |stack| + stack.each do |frame_idx| + expect(frames[frame_idx][:function]).to be_a(String) + end + end + end + + it 'has correct samples' do + profile = profiler.to_hash[:profile] + samples = profile[:samples] + + samples.group_by { |sample| sample[:thread_id] }.each do |thread_id, thread_samples| + expect(thread_id.to_i).to be > 0 + + last_elapsed = 0 + + thread_samples.each do |sample| + expect(sample[:stack_id]).to be > 0 + + elapsed = sample[:elapsed_since_start_ns].to_i + + expect(elapsed).to be > 0.0 + expect(elapsed).to be > last_elapsed + + last_elapsed = elapsed + end + end + end + end + end + end +end diff --git a/sentry-ruby/spec/sentry_spec.rb b/sentry-ruby/spec/sentry_spec.rb index dd3f85c93..dabdcd07e 100644 --- a/sentry-ruby/spec/sentry_spec.rb +++ b/sentry-ruby/spec/sentry_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" require 'contexts/with_request_mock' diff --git a/sentry-ruby/spec/spec_helper.rb b/sentry-ruby/spec/spec_helper.rb index 2758a0a1f..e0d1c9a1e 100644 --- a/sentry-ruby/spec/spec_helper.rb +++ b/sentry-ruby/spec/spec_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "bundler/setup" begin require "debug/prelude" @@ -8,6 +10,7 @@ require "rspec/retry" require "redis" require "stackprof" unless RUBY_PLATFORM == "java" +require "vernier" unless RUBY_PLATFORM == "java" || RUBY_VERSION < "3.2" SimpleCov.start do project_name "sentry-ruby" @@ -23,6 +26,8 @@ require "sentry-ruby" require "sentry/test_helper" +Dir[Pathname(__dir__).join("support/**/*.rb")].sort.each { |f| require f } + RSpec.configure do |config| # Enable flags like --only-failures and --next-failure config.example_status_persistence_file_path = ".rspec_status" @@ -47,9 +52,20 @@ end config.before(:each, when: true) do |example| - meth = example.metadata[:when] + guards = + case value = example.metadata[:when] + when Symbol then [value] + when Array then value + when Hash then value.map { |k, v| [k, v].flatten } + else + raise ArgumentError, "Invalid `when` metadata: #{value.inspect}" + end + + skip_examples = guards.any? do |meth, *args| + !TestHelpers.public_send(meth, *args) + end - skip("Skipping because `when: #{meth}` returned false") unless TestHelpers.public_send(meth, example) + skip("Skipping because one or more guards `#{guards.inspect}` returned false") if skip_examples end RSpec::Matchers.define :have_recorded_lost_event do |reason, data_category, num: 1| @@ -60,13 +76,22 @@ end module TestHelpers - def self.stack_prof_installed?(_example) + def self.stack_prof_installed? defined?(StackProf) end - def self.rack_available?(_example) + def self.vernier_installed? + require "sentry/vernier/profiler" + defined?(::Vernier) + end + + def self.rack_available? defined?(Rack) end + + def self.ruby_version?(op, version) + RUBY_VERSION.public_send(op, version) + end end def fixtures_root diff --git a/sentry-ruby/spec/support/Rakefile.rb b/sentry-ruby/spec/support/Rakefile.rb index 2304ba3a4..77b245297 100644 --- a/sentry-ruby/spec/support/Rakefile.rb +++ b/sentry-ruby/spec/support/Rakefile.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "rake" require "sentry-ruby" diff --git a/sentry-ruby/spec/support/profiler.rb b/sentry-ruby/spec/support/profiler.rb new file mode 100644 index 000000000..ee83cc4dd --- /dev/null +++ b/sentry-ruby/spec/support/profiler.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module ProfilerTest + module Bar + module Foo + def self.foo + 1e6.to_i.times { 2**2 } + end + end + + def self.bar + Foo.foo + sleep 0.1 + end + end +end diff --git a/sentry-ruby/spec/support/stackprof_results.json b/sentry-ruby/spec/support/stackprof_results.json index 1527df8cd..712c3b768 100644 --- a/sentry-ruby/spec/support/stackprof_results.json +++ b/sentry-ruby/spec/support/stackprof_results.json @@ -1 +1,718 @@ -{"version":1.2,"mode":"wall","interval":9900.990099009901,"samples":15,"gc_samples":0,"missed_samples":0,"metadata":{},"frames":{"140370219074600":{"name":"Integer#times","file":"","line":null,"total_samples":5,"samples":2},"140370222379560":{"name":"Bar::Foo.foo","file":"/spec/sentry/profiler_spec.rb","line":7,"total_samples":5,"samples":2},"140370222379480":{"name":"Bar.bar","file":"/spec/sentry/profiler_spec.rb","line":12,"total_samples":15,"samples":0},"140370262463760":{"name":"block (4 levels) in ","file":"/spec/sentry/profiler_spec.rb","line":169,"total_samples":15,"samples":0},"140370219081000":{"name":"BasicObject#instance_exec","file":"","line":null,"total_samples":15,"samples":0},"140369934628760":{"name":"RSpec::Core::Example#instance_exec","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb","line":456,"total_samples":15,"samples":0},"140370262209000":{"name":"RSpec::Core::Hooks::BeforeHook#run","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/hooks.rb","line":364,"total_samples":15,"samples":0},"140370262206960":{"name":"RSpec::Core::Hooks::HookCollections#run_owned_hooks_for","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/hooks.rb","line":527,"total_samples":15,"samples":0},"140370219016480":{"name":"Array#each","file":"","line":null,"total_samples":15,"samples":0},"140370262206440":{"name":"RSpec::Core::Hooks::HookCollections#run_example_hooks_for","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/hooks.rb","line":613,"total_samples":15,"samples":0},"140370219016360":{"name":"Array#reverse_each","file":"","line":null,"total_samples":15,"samples":0},"140370262207720":{"name":"RSpec::Core::Hooks::HookCollections#run","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/hooks.rb","line":475,"total_samples":15,"samples":0},"140369934628120":{"name":"RSpec::Core::Example#run_before_example","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb","line":503,"total_samples":15,"samples":0},"140369934656240":{"name":"RSpec::Core::Example#run","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb","line":246,"total_samples":15,"samples":0},"140369934628080":{"name":"RSpec::Core::Example#with_around_and_singleton_context_hooks","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb","line":508,"total_samples":15,"samples":0},"140369934628640":{"name":"RSpec::Core::Example#with_around_example_hooks","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb","line":466,"total_samples":15,"samples":0},"140370262206400":{"name":"RSpec::Core::Hooks::HookCollections#run_around_example_hooks_for","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/hooks.rb","line":619,"total_samples":15,"samples":0},"140369934629600":{"name":"RSpec::Core::Example::Procsy#call","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb","line":350,"total_samples":15,"samples":0},"140369936132760":{"name":"RSpec::Retry#run","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-retry-0.6.2/lib/rspec/retry.rb","line":107,"total_samples":15,"samples":0},"140370203515000":{"name":"Kernel#loop","file":"","line":null,"total_samples":15,"samples":0},"140369936134000":{"name":"RSpec::Core::Example::Procsy#run_with_retry","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-retry-0.6.2/lib/rspec_ext/rspec_ext.rb","line":11,"total_samples":15,"samples":0},"140369936133560":{"name":"RSpec::Retry.setup","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-retry-0.6.2/lib/rspec/retry.rb","line":7,"total_samples":15,"samples":0},"140370262208320":{"name":"RSpec::Core::Hooks::AroundHook#execute_with","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/hooks.rb","line":389,"total_samples":15,"samples":0},"140369934629640":{"name":"RSpec::Core::Example::Procsy#call","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb","line":350,"total_samples":15,"samples":0},"140370221599800":{"name":"RSpec::Core::ExampleGroup.run_examples","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example_group.rb","line":641,"total_samples":15,"samples":0},"140370219015440":{"name":"Array#map","file":"","line":null,"total_samples":15,"samples":0},"140370221599880":{"name":"RSpec::Core::ExampleGroup.run","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example_group.rb","line":599,"total_samples":15,"samples":0},"140369934821040":{"name":"RSpec::Core::Runner#run_specs","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/runner.rb","line":113,"total_samples":15,"samples":0},"140370221475080":{"name":"RSpec::Core::Configuration#with_suite_hooks","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/configuration.rb","line":2062,"total_samples":15,"samples":0},"140370262307680":{"name":"RSpec::Core::Reporter#report","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/reporter.rb","line":71,"total_samples":15,"samples":0},"140369934821120":{"name":"RSpec::Core::Runner#run","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/runner.rb","line":85,"total_samples":15,"samples":0},"140369934821200":{"name":"RSpec::Core::Runner.run","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/runner.rb","line":64,"total_samples":15,"samples":0},"140369934821320":{"name":"RSpec::Core::Runner.invoke","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/runner.rb","line":43,"total_samples":15,"samples":0},"140369934947600":{"name":"","file":"/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/exe/rspec","total_samples":15,"samples":0},"140370220922120":{"name":"Kernel#load","file":"","line":null,"total_samples":15,"samples":0},"140369934788840":{"name":"
","file":"/Users/neel/.rvm/gems/ruby-3.0.0/bin/rspec","line":1,"total_samples":15,"samples":0},"140370219331600":{"name":"Kernel#eval","file":"","line":null,"total_samples":15,"samples":0},"140369933326520":{"name":"
","file":"/Users/neel/.rvm/gems/ruby-3.0.0/bin/ruby_executable_hooks","total_samples":15,"samples":0},"140370218844600":{"name":"
","file":"/Users/neel/.rvm/gems/ruby-3.0.0/bin/ruby_executable_hooks","total_samples":15,"samples":0},"140370219073720":{"name":"Integer#**","file":"","line":null,"total_samples":1,"samples":1},"140370265410040":{"name":"Kernel#sleep","file":"","line":null,"total_samples":10,"samples":10}},"raw":[62,140370218844600,140369933326520,140370219331600,140369934788840,140370220922120,140369934947600,140369934821320,140369934821200,140369934821120,140369934821040,140370262307680,140369934821040,140370221475080,140369934821040,140370219015440,140369934821040,140370221599880,140370219015440,140370221599880,140370221599880,140370219015440,140370221599880,140370221599880,140370221599800,140370219015440,140370221599800,140369934656240,140369934628080,140369934628640,140370262207720,140370262206400,140369934629640,140370262206400,140370262208320,140369934628760,140370219081000,140369936133560,140369936134000,140369936132760,140370203515000,140369936132760,140369934629600,140370262206400,140370262207720,140369934628640,140369934628080,140369934656240,140369934628120,140370262207720,140370262206440,140370219016360,140370262206440,140370262206960,140370219016480,140370262206960,140370262209000,140369934628760,140370219081000,140370262463760,140370222379480,140370222379560,140370219074600,1,63,140370218844600,140369933326520,140370219331600,140369934788840,140370220922120,140369934947600,140369934821320,140369934821200,140369934821120,140369934821040,140370262307680,140369934821040,140370221475080,140369934821040,140370219015440,140369934821040,140370221599880,140370219015440,140370221599880,140370221599880,140370219015440,140370221599880,140370221599880,140370221599800,140370219015440,140370221599800,140369934656240,140369934628080,140369934628640,140370262207720,140370262206400,140369934629640,140370262206400,140370262208320,140369934628760,140370219081000,140369936133560,140369936134000,140369936132760,140370203515000,140369936132760,140369934629600,140370262206400,140370262207720,140369934628640,140369934628080,140369934656240,140369934628120,140370262207720,140370262206440,140370219016360,140370262206440,140370262206960,140370219016480,140370262206960,140370262209000,140369934628760,140370219081000,140370262463760,140370222379480,140370222379560,140370219074600,140370222379560,1,62,140370218844600,140369933326520,140370219331600,140369934788840,140370220922120,140369934947600,140369934821320,140369934821200,140369934821120,140369934821040,140370262307680,140369934821040,140370221475080,140369934821040,140370219015440,140369934821040,140370221599880,140370219015440,140370221599880,140370221599880,140370219015440,140370221599880,140370221599880,140370221599800,140370219015440,140370221599800,140369934656240,140369934628080,140369934628640,140370262207720,140370262206400,140369934629640,140370262206400,140370262208320,140369934628760,140370219081000,140369936133560,140369936134000,140369936132760,140370203515000,140369936132760,140369934629600,140370262206400,140370262207720,140369934628640,140369934628080,140369934656240,140369934628120,140370262207720,140370262206440,140370219016360,140370262206440,140370262206960,140370219016480,140370262206960,140370262209000,140369934628760,140370219081000,140370262463760,140370222379480,140370222379560,140370219074600,1,64,140370218844600,140369933326520,140370219331600,140369934788840,140370220922120,140369934947600,140369934821320,140369934821200,140369934821120,140369934821040,140370262307680,140369934821040,140370221475080,140369934821040,140370219015440,140369934821040,140370221599880,140370219015440,140370221599880,140370221599880,140370219015440,140370221599880,140370221599880,140370221599800,140370219015440,140370221599800,140369934656240,140369934628080,140369934628640,140370262207720,140370262206400,140369934629640,140370262206400,140370262208320,140369934628760,140370219081000,140369936133560,140369936134000,140369936132760,140370203515000,140369936132760,140369934629600,140370262206400,140370262207720,140369934628640,140369934628080,140369934656240,140369934628120,140370262207720,140370262206440,140370219016360,140370262206440,140370262206960,140370219016480,140370262206960,140370262209000,140369934628760,140370219081000,140370262463760,140370222379480,140370222379560,140370219074600,140370222379560,140370219073720,1,63,140370218844600,140369933326520,140370219331600,140369934788840,140370220922120,140369934947600,140369934821320,140369934821200,140369934821120,140369934821040,140370262307680,140369934821040,140370221475080,140369934821040,140370219015440,140369934821040,140370221599880,140370219015440,140370221599880,140370221599880,140370219015440,140370221599880,140370221599880,140370221599800,140370219015440,140370221599800,140369934656240,140369934628080,140369934628640,140370262207720,140370262206400,140369934629640,140370262206400,140370262208320,140369934628760,140370219081000,140369936133560,140369936134000,140369936132760,140370203515000,140369936132760,140369934629600,140370262206400,140370262207720,140369934628640,140369934628080,140369934656240,140369934628120,140370262207720,140370262206440,140370219016360,140370262206440,140370262206960,140370219016480,140370262206960,140370262209000,140369934628760,140370219081000,140370262463760,140370222379480,140370222379560,140370219074600,140370222379560,1,61,140370218844600,140369933326520,140370219331600,140369934788840,140370220922120,140369934947600,140369934821320,140369934821200,140369934821120,140369934821040,140370262307680,140369934821040,140370221475080,140369934821040,140370219015440,140369934821040,140370221599880,140370219015440,140370221599880,140370221599880,140370219015440,140370221599880,140370221599880,140370221599800,140370219015440,140370221599800,140369934656240,140369934628080,140369934628640,140370262207720,140370262206400,140369934629640,140370262206400,140370262208320,140369934628760,140370219081000,140369936133560,140369936134000,140369936132760,140370203515000,140369936132760,140369934629600,140370262206400,140370262207720,140369934628640,140369934628080,140369934656240,140369934628120,140370262207720,140370262206440,140370219016360,140370262206440,140370262206960,140370219016480,140370262206960,140370262209000,140369934628760,140370219081000,140370262463760,140370222379480,140370265410040,10],"raw_sample_timestamps":[1295905330989,1295905338595,1295905348330,1295905358336,1295905368777,1295905379129,1295905388495,1295905398492,1295905407835,1295905418826,1295905428669,1295905438609,1295905447579,1295905458008,1295905468407],"raw_timestamp_deltas":[12403,7531,9689,9986,10420,10338,9320,9949,9269,10920,9770,9864,8899,10354,10323]} +{ + "version": 1.2, + "mode": "wall", + "interval": 9900.990099009901, + "samples": 15, + "gc_samples": 0, + "missed_samples": 0, + "metadata": {}, + "frames": { + "140370219074600": { + "name": "Integer#times", + "file": "", + "line": null, + "total_samples": 5, + "samples": 2 + }, + "140370222379560": { + "name": "Bar::Foo.foo", + "file": "/spec/sentry/profiler_spec.rb", + "line": 7, + "total_samples": 5, + "samples": 2 + }, + "140370222379480": { + "name": "Bar.bar", + "file": "/spec/sentry/profiler_spec.rb", + "line": 12, + "total_samples": 15, + "samples": 0 + }, + "140370262463760": { + "name": "block (4 levels) in ", + "file": "/spec/sentry/profiler_spec.rb", + "line": 169, + "total_samples": 15, + "samples": 0 + }, + "140370219081000": { + "name": "BasicObject#instance_exec", + "file": "", + "line": null, + "total_samples": 15, + "samples": 0 + }, + "140369934628760": { + "name": "RSpec::Core::Example#instance_exec", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb", + "line": 456, + "total_samples": 15, + "samples": 0 + }, + "140370262209000": { + "name": "RSpec::Core::Hooks::BeforeHook#run", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/hooks.rb", + "line": 364, + "total_samples": 15, + "samples": 0 + }, + "140370262206960": { + "name": "RSpec::Core::Hooks::HookCollections#run_owned_hooks_for", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/hooks.rb", + "line": 527, + "total_samples": 15, + "samples": 0 + }, + "140370219016480": { + "name": "Array#each", + "file": "", + "line": null, + "total_samples": 15, + "samples": 0 + }, + "140370262206440": { + "name": "RSpec::Core::Hooks::HookCollections#run_example_hooks_for", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/hooks.rb", + "line": 613, + "total_samples": 15, + "samples": 0 + }, + "140370219016360": { + "name": "Array#reverse_each", + "file": "", + "line": null, + "total_samples": 15, + "samples": 0 + }, + "140370262207720": { + "name": "RSpec::Core::Hooks::HookCollections#run", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/hooks.rb", + "line": 475, + "total_samples": 15, + "samples": 0 + }, + "140369934628120": { + "name": "RSpec::Core::Example#run_before_example", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb", + "line": 503, + "total_samples": 15, + "samples": 0 + }, + "140369934656240": { + "name": "RSpec::Core::Example#run", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb", + "line": 246, + "total_samples": 15, + "samples": 0 + }, + "140369934628080": { + "name": "RSpec::Core::Example#with_around_and_singleton_context_hooks", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb", + "line": 508, + "total_samples": 15, + "samples": 0 + }, + "140369934628640": { + "name": "RSpec::Core::Example#with_around_example_hooks", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb", + "line": 466, + "total_samples": 15, + "samples": 0 + }, + "140370262206400": { + "name": "RSpec::Core::Hooks::HookCollections#run_around_example_hooks_for", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/hooks.rb", + "line": 619, + "total_samples": 15, + "samples": 0 + }, + "140369934629600": { + "name": "RSpec::Core::Example::Procsy#call", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb", + "line": 350, + "total_samples": 15, + "samples": 0 + }, + "140369936132760": { + "name": "RSpec::Retry#run", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-retry-0.6.2/lib/rspec/retry.rb", + "line": 107, + "total_samples": 15, + "samples": 0 + }, + "140370203515000": { + "name": "Kernel#loop", + "file": "", + "line": null, + "total_samples": 15, + "samples": 0 + }, + "140369936134000": { + "name": "RSpec::Core::Example::Procsy#run_with_retry", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-retry-0.6.2/lib/rspec_ext/rspec_ext.rb", + "line": 11, + "total_samples": 15, + "samples": 0 + }, + "140369936133560": { + "name": "RSpec::Retry.setup", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-retry-0.6.2/lib/rspec/retry.rb", + "line": 7, + "total_samples": 15, + "samples": 0 + }, + "140370262208320": { + "name": "RSpec::Core::Hooks::AroundHook#execute_with", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/hooks.rb", + "line": 389, + "total_samples": 15, + "samples": 0 + }, + "140369934629640": { + "name": "RSpec::Core::Example::Procsy#call", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example.rb", + "line": 350, + "total_samples": 15, + "samples": 0 + }, + "140370221599800": { + "name": "RSpec::Core::ExampleGroup.run_examples", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example_group.rb", + "line": 641, + "total_samples": 15, + "samples": 0 + }, + "140370219015440": { + "name": "Array#map", + "file": "", + "line": null, + "total_samples": 15, + "samples": 0 + }, + "140370221599880": { + "name": "RSpec::Core::ExampleGroup.run", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/example_group.rb", + "line": 599, + "total_samples": 15, + "samples": 0 + }, + "140369934821040": { + "name": "RSpec::Core::Runner#run_specs", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/runner.rb", + "line": 113, + "total_samples": 15, + "samples": 0 + }, + "140370221475080": { + "name": "RSpec::Core::Configuration#with_suite_hooks", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/configuration.rb", + "line": 2062, + "total_samples": 15, + "samples": 0 + }, + "140370262307680": { + "name": "RSpec::Core::Reporter#report", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/reporter.rb", + "line": 71, + "total_samples": 15, + "samples": 0 + }, + "140369934821120": { + "name": "RSpec::Core::Runner#run", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/runner.rb", + "line": 85, + "total_samples": 15, + "samples": 0 + }, + "140369934821200": { + "name": "RSpec::Core::Runner.run", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/runner.rb", + "line": 64, + "total_samples": 15, + "samples": 0 + }, + "140369934821320": { + "name": "RSpec::Core::Runner.invoke", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/lib/rspec/core/runner.rb", + "line": 43, + "total_samples": 15, + "samples": 0 + }, + "140369934947600": { + "name": "", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.11.0/exe/rspec", + "total_samples": 15, + "samples": 0 + }, + "140370220922120": { + "name": "Kernel#load", + "file": "", + "line": null, + "total_samples": 15, + "samples": 0 + }, + "140369934788840": { + "name": "
", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/bin/rspec", + "line": 1, + "total_samples": 15, + "samples": 0 + }, + "140370219331600": { + "name": "Kernel#eval", + "file": "", + "line": null, + "total_samples": 15, + "samples": 0 + }, + "140369933326520": { + "name": "
", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/bin/ruby_executable_hooks", + "total_samples": 15, + "samples": 0 + }, + "140370218844600": { + "name": "
", + "file": "/Users/neel/.rvm/gems/ruby-3.0.0/bin/ruby_executable_hooks", + "total_samples": 15, + "samples": 0 + }, + "140370219073720": { + "name": "Integer#**", + "file": "", + "line": null, + "total_samples": 1, + "samples": 1 + }, + "140370265410040": { + "name": "Kernel#sleep", + "file": "", + "line": null, + "total_samples": 10, + "samples": 10 + } + }, + "raw": [ + 62, + 140370218844600, + 140369933326520, + 140370219331600, + 140369934788840, + 140370220922120, + 140369934947600, + 140369934821320, + 140369934821200, + 140369934821120, + 140369934821040, + 140370262307680, + 140369934821040, + 140370221475080, + 140369934821040, + 140370219015440, + 140369934821040, + 140370221599880, + 140370219015440, + 140370221599880, + 140370221599880, + 140370219015440, + 140370221599880, + 140370221599880, + 140370221599800, + 140370219015440, + 140370221599800, + 140369934656240, + 140369934628080, + 140369934628640, + 140370262207720, + 140370262206400, + 140369934629640, + 140370262206400, + 140370262208320, + 140369934628760, + 140370219081000, + 140369936133560, + 140369936134000, + 140369936132760, + 140370203515000, + 140369936132760, + 140369934629600, + 140370262206400, + 140370262207720, + 140369934628640, + 140369934628080, + 140369934656240, + 140369934628120, + 140370262207720, + 140370262206440, + 140370219016360, + 140370262206440, + 140370262206960, + 140370219016480, + 140370262206960, + 140370262209000, + 140369934628760, + 140370219081000, + 140370262463760, + 140370222379480, + 140370222379560, + 140370219074600, + 1, + 63, + 140370218844600, + 140369933326520, + 140370219331600, + 140369934788840, + 140370220922120, + 140369934947600, + 140369934821320, + 140369934821200, + 140369934821120, + 140369934821040, + 140370262307680, + 140369934821040, + 140370221475080, + 140369934821040, + 140370219015440, + 140369934821040, + 140370221599880, + 140370219015440, + 140370221599880, + 140370221599880, + 140370219015440, + 140370221599880, + 140370221599880, + 140370221599800, + 140370219015440, + 140370221599800, + 140369934656240, + 140369934628080, + 140369934628640, + 140370262207720, + 140370262206400, + 140369934629640, + 140370262206400, + 140370262208320, + 140369934628760, + 140370219081000, + 140369936133560, + 140369936134000, + 140369936132760, + 140370203515000, + 140369936132760, + 140369934629600, + 140370262206400, + 140370262207720, + 140369934628640, + 140369934628080, + 140369934656240, + 140369934628120, + 140370262207720, + 140370262206440, + 140370219016360, + 140370262206440, + 140370262206960, + 140370219016480, + 140370262206960, + 140370262209000, + 140369934628760, + 140370219081000, + 140370262463760, + 140370222379480, + 140370222379560, + 140370219074600, + 140370222379560, + 1, + 62, + 140370218844600, + 140369933326520, + 140370219331600, + 140369934788840, + 140370220922120, + 140369934947600, + 140369934821320, + 140369934821200, + 140369934821120, + 140369934821040, + 140370262307680, + 140369934821040, + 140370221475080, + 140369934821040, + 140370219015440, + 140369934821040, + 140370221599880, + 140370219015440, + 140370221599880, + 140370221599880, + 140370219015440, + 140370221599880, + 140370221599880, + 140370221599800, + 140370219015440, + 140370221599800, + 140369934656240, + 140369934628080, + 140369934628640, + 140370262207720, + 140370262206400, + 140369934629640, + 140370262206400, + 140370262208320, + 140369934628760, + 140370219081000, + 140369936133560, + 140369936134000, + 140369936132760, + 140370203515000, + 140369936132760, + 140369934629600, + 140370262206400, + 140370262207720, + 140369934628640, + 140369934628080, + 140369934656240, + 140369934628120, + 140370262207720, + 140370262206440, + 140370219016360, + 140370262206440, + 140370262206960, + 140370219016480, + 140370262206960, + 140370262209000, + 140369934628760, + 140370219081000, + 140370262463760, + 140370222379480, + 140370222379560, + 140370219074600, + 1, + 64, + 140370218844600, + 140369933326520, + 140370219331600, + 140369934788840, + 140370220922120, + 140369934947600, + 140369934821320, + 140369934821200, + 140369934821120, + 140369934821040, + 140370262307680, + 140369934821040, + 140370221475080, + 140369934821040, + 140370219015440, + 140369934821040, + 140370221599880, + 140370219015440, + 140370221599880, + 140370221599880, + 140370219015440, + 140370221599880, + 140370221599880, + 140370221599800, + 140370219015440, + 140370221599800, + 140369934656240, + 140369934628080, + 140369934628640, + 140370262207720, + 140370262206400, + 140369934629640, + 140370262206400, + 140370262208320, + 140369934628760, + 140370219081000, + 140369936133560, + 140369936134000, + 140369936132760, + 140370203515000, + 140369936132760, + 140369934629600, + 140370262206400, + 140370262207720, + 140369934628640, + 140369934628080, + 140369934656240, + 140369934628120, + 140370262207720, + 140370262206440, + 140370219016360, + 140370262206440, + 140370262206960, + 140370219016480, + 140370262206960, + 140370262209000, + 140369934628760, + 140370219081000, + 140370262463760, + 140370222379480, + 140370222379560, + 140370219074600, + 140370222379560, + 140370219073720, + 1, + 63, + 140370218844600, + 140369933326520, + 140370219331600, + 140369934788840, + 140370220922120, + 140369934947600, + 140369934821320, + 140369934821200, + 140369934821120, + 140369934821040, + 140370262307680, + 140369934821040, + 140370221475080, + 140369934821040, + 140370219015440, + 140369934821040, + 140370221599880, + 140370219015440, + 140370221599880, + 140370221599880, + 140370219015440, + 140370221599880, + 140370221599880, + 140370221599800, + 140370219015440, + 140370221599800, + 140369934656240, + 140369934628080, + 140369934628640, + 140370262207720, + 140370262206400, + 140369934629640, + 140370262206400, + 140370262208320, + 140369934628760, + 140370219081000, + 140369936133560, + 140369936134000, + 140369936132760, + 140370203515000, + 140369936132760, + 140369934629600, + 140370262206400, + 140370262207720, + 140369934628640, + 140369934628080, + 140369934656240, + 140369934628120, + 140370262207720, + 140370262206440, + 140370219016360, + 140370262206440, + 140370262206960, + 140370219016480, + 140370262206960, + 140370262209000, + 140369934628760, + 140370219081000, + 140370262463760, + 140370222379480, + 140370222379560, + 140370219074600, + 140370222379560, + 1, + 61, + 140370218844600, + 140369933326520, + 140370219331600, + 140369934788840, + 140370220922120, + 140369934947600, + 140369934821320, + 140369934821200, + 140369934821120, + 140369934821040, + 140370262307680, + 140369934821040, + 140370221475080, + 140369934821040, + 140370219015440, + 140369934821040, + 140370221599880, + 140370219015440, + 140370221599880, + 140370221599880, + 140370219015440, + 140370221599880, + 140370221599880, + 140370221599800, + 140370219015440, + 140370221599800, + 140369934656240, + 140369934628080, + 140369934628640, + 140370262207720, + 140370262206400, + 140369934629640, + 140370262206400, + 140370262208320, + 140369934628760, + 140370219081000, + 140369936133560, + 140369936134000, + 140369936132760, + 140370203515000, + 140369936132760, + 140369934629600, + 140370262206400, + 140370262207720, + 140369934628640, + 140369934628080, + 140369934656240, + 140369934628120, + 140370262207720, + 140370262206440, + 140370219016360, + 140370262206440, + 140370262206960, + 140370219016480, + 140370262206960, + 140370262209000, + 140369934628760, + 140370219081000, + 140370262463760, + 140370222379480, + 140370265410040, + 10 + ], + "raw_sample_timestamps": [ + 1295905330989, + 1295905338595, + 1295905348330, + 1295905358336, + 1295905368777, + 1295905379129, + 1295905388495, + 1295905398492, + 1295905407835, + 1295905418826, + 1295905428669, + 1295905438609, + 1295905447579, + 1295905458008, + 1295905468407 + ], + "raw_timestamp_deltas": [ + 12403, + 7531, + 9689, + 9986, + 10420, + 10338, + 9320, + 9949, + 9269, + 10920, + 9770, + 9864, + 8899, + 10354, + 10323 + ] +} diff --git a/sentry-ruby/spec/support/stacktrace_test_fixture.rb b/sentry-ruby/spec/support/stacktrace_test_fixture.rb index 7921fb53b..0c8d7933e 100644 --- a/sentry-ruby/spec/support/stacktrace_test_fixture.rb +++ b/sentry-ruby/spec/support/stacktrace_test_fixture.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + def foo bar end diff --git a/sentry-sidekiq/Gemfile b/sentry-sidekiq/Gemfile index 5ce453b72..c158e85dc 100644 --- a/sentry-sidekiq/Gemfile +++ b/sentry-sidekiq/Gemfile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + source "https://rubygems.org" git_source(:github) { |name| "https://github.com/#{name}.git" } diff --git a/sentry-sidekiq/Rakefile b/sentry-sidekiq/Rakefile index 7b2756854..13afab191 100644 --- a/sentry-sidekiq/Rakefile +++ b/sentry-sidekiq/Rakefile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "bundler/gem_tasks" require "rspec/core/rake_task" diff --git a/sentry-sidekiq/bin/console b/sentry-sidekiq/bin/console index 660c7a889..f0f5a7b6a 100755 --- a/sentry-sidekiq/bin/console +++ b/sentry-sidekiq/bin/console @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true require "bundler/setup" require "sentry/ruby" diff --git a/sentry-sidekiq/example/Gemfile b/sentry-sidekiq/example/Gemfile index d038af521..9834edf07 100644 --- a/sentry-sidekiq/example/Gemfile +++ b/sentry-sidekiq/example/Gemfile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + source "https://rubygems.org" gem "sidekiq" diff --git a/sentry-sidekiq/example/error_worker.rb b/sentry-sidekiq/example/error_worker.rb index 220d80f63..8782dd2d7 100644 --- a/sentry-sidekiq/example/error_worker.rb +++ b/sentry-sidekiq/example/error_worker.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "sidekiq" require "sentry-sidekiq" diff --git a/sentry-sidekiq/lib/sentry-sidekiq.rb b/sentry-sidekiq/lib/sentry-sidekiq.rb index b7318b9f9..a126782f2 100644 --- a/sentry-sidekiq/lib/sentry-sidekiq.rb +++ b/sentry-sidekiq/lib/sentry-sidekiq.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "sidekiq" require "sentry-ruby" require "sentry/integrable" diff --git a/sentry-sidekiq/lib/sentry/sidekiq/configuration.rb b/sentry-sidekiq/lib/sentry/sidekiq/configuration.rb index cc71908b5..b6ef3856c 100644 --- a/sentry-sidekiq/lib/sentry/sidekiq/configuration.rb +++ b/sentry-sidekiq/lib/sentry/sidekiq/configuration.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Sentry class Configuration attr_reader :sidekiq diff --git a/sentry-sidekiq/lib/sentry/sidekiq/context_filter.rb b/sentry-sidekiq/lib/sentry/sidekiq/context_filter.rb index 8512b5ab5..ff9f014c3 100644 --- a/sentry-sidekiq/lib/sentry/sidekiq/context_filter.rb +++ b/sentry-sidekiq/lib/sentry/sidekiq/context_filter.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + module Sentry module Sidekiq class ContextFilter - ACTIVEJOB_RESERVED_PREFIX_REGEX = /^_aj_/.freeze - SIDEKIQ_NAME = "Sidekiq".freeze + ACTIVEJOB_RESERVED_PREFIX_REGEX = /^_aj_/ + SIDEKIQ_NAME = "Sidekiq" attr_reader :context diff --git a/sentry-sidekiq/lib/sentry/sidekiq/error_handler.rb b/sentry-sidekiq/lib/sentry/sidekiq/error_handler.rb index d1f7eaf87..50c720929 100644 --- a/sentry-sidekiq/lib/sentry/sidekiq/error_handler.rb +++ b/sentry-sidekiq/lib/sentry/sidekiq/error_handler.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "sentry/sidekiq/context_filter" module Sentry diff --git a/sentry-sidekiq/lib/sentry/sidekiq/version.rb b/sentry-sidekiq/lib/sentry/sidekiq/version.rb index b127d83ba..5028b6c59 100644 --- a/sentry-sidekiq/lib/sentry/sidekiq/version.rb +++ b/sentry-sidekiq/lib/sentry/sidekiq/version.rb @@ -1,5 +1,7 @@ +# frozen_string_literal: true + module Sentry module Sidekiq - VERSION = "5.19.0" + VERSION = "5.21.0" end end diff --git a/sentry-sidekiq/sentry-sidekiq.gemspec b/sentry-sidekiq/sentry-sidekiq.gemspec index 56f737887..375ec153c 100644 --- a/sentry-sidekiq/sentry-sidekiq.gemspec +++ b/sentry-sidekiq/sentry-sidekiq.gemspec @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require_relative "lib/sentry/sidekiq/version" Gem::Specification.new do |spec| @@ -11,7 +13,7 @@ Gem::Specification.new do |spec| spec.platform = Gem::Platform::RUBY spec.required_ruby_version = '>= 2.4' spec.extra_rdoc_files = ["README.md", "LICENSE.txt"] - spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples)'`.split("\n") + spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples|\.rubocop\.yml)'`.split("\n") github_root_uri = 'https://github.com/getsentry/sentry-ruby' spec.homepage = "#{github_root_uri}/tree/#{spec.version}/#{spec.name}" @@ -28,6 +30,6 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] - spec.add_dependency "sentry-ruby", "~> 5.19.0" + spec.add_dependency "sentry-ruby", "~> 5.21.0" spec.add_dependency "sidekiq", ">= 3.0" end diff --git a/sentry-sidekiq/spec/sentry/rails_spec.rb b/sentry-sidekiq/spec/sentry/rails_spec.rb index 87518ea06..36c6fdd31 100644 --- a/sentry-sidekiq/spec/sentry/rails_spec.rb +++ b/sentry-sidekiq/spec/sentry/rails_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + return unless ENV["WITH_SENTRY_RAILS"] require "rails" diff --git a/sentry-sidekiq/spec/sentry/sidekiq-scheduler/scheduler_spec.rb b/sentry-sidekiq/spec/sentry/sidekiq-scheduler/scheduler_spec.rb index 879e34a55..02efd1ccc 100644 --- a/sentry-sidekiq/spec/sentry/sidekiq-scheduler/scheduler_spec.rb +++ b/sentry-sidekiq/spec/sentry/sidekiq-scheduler/scheduler_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' return unless defined?(SidekiqScheduler::Scheduler) diff --git a/sentry-sidekiq/spec/sentry/sidekiq/configuration_spec.rb b/sentry-sidekiq/spec/sentry/sidekiq/configuration_spec.rb index 2fdcdfbc5..7e9066ffe 100644 --- a/sentry-sidekiq/spec/sentry/sidekiq/configuration_spec.rb +++ b/sentry-sidekiq/spec/sentry/sidekiq/configuration_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Sidekiq::Configuration do diff --git a/sentry-sidekiq/spec/sentry/sidekiq/context_filter_spec.rb b/sentry-sidekiq/spec/sentry/sidekiq/context_filter_spec.rb index dc5354b9c..099ce329b 100644 --- a/sentry-sidekiq/spec/sentry/sidekiq/context_filter_spec.rb +++ b/sentry-sidekiq/spec/sentry/sidekiq/context_filter_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.describe Sentry::Sidekiq::ContextFilter do diff --git a/sentry-sidekiq/spec/sentry/sidekiq/cron/job_spec.rb b/sentry-sidekiq/spec/sentry/sidekiq/cron/job_spec.rb index c0f223096..4e4f65202 100644 --- a/sentry-sidekiq/spec/sentry/sidekiq/cron/job_spec.rb +++ b/sentry-sidekiq/spec/sentry/sidekiq/cron/job_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' return unless defined?(Sidekiq::Cron::Job) diff --git a/sentry-sidekiq/spec/sentry/sidekiq/error_handler_spec.rb b/sentry-sidekiq/spec/sentry/sidekiq/error_handler_spec.rb index 15053609e..5e144bf9a 100644 --- a/sentry-sidekiq/spec/sentry/sidekiq/error_handler_spec.rb +++ b/sentry-sidekiq/spec/sentry/sidekiq/error_handler_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' RSpec.describe Sentry::Sidekiq::ErrorHandler do diff --git a/sentry-sidekiq/spec/sentry/sidekiq/sentry_context_middleware_spec.rb b/sentry-sidekiq/spec/sentry/sidekiq/sentry_context_middleware_spec.rb index 8d28577e7..de5e9416f 100644 --- a/sentry-sidekiq/spec/sentry/sidekiq/sentry_context_middleware_spec.rb +++ b/sentry-sidekiq/spec/sentry/sidekiq/sentry_context_middleware_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" RSpec.shared_context "sidekiq", shared_context: :metadata do diff --git a/sentry-sidekiq/spec/sentry/sidekiq_spec.rb b/sentry-sidekiq/spec/sentry/sidekiq_spec.rb index 2e7cfb99a..64fdec5c1 100644 --- a/sentry-sidekiq/spec/sentry/sidekiq_spec.rb +++ b/sentry-sidekiq/spec/sentry/sidekiq_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "spec_helper" require 'sidekiq/manager' require 'sidekiq/api' diff --git a/sentry-sidekiq/spec/spec_helper.rb b/sentry-sidekiq/spec/spec_helper.rb index 6b2287957..5e1e6a6e9 100644 --- a/sentry-sidekiq/spec/spec_helper.rb +++ b/sentry-sidekiq/spec/spec_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "bundler/setup" begin require "debug/prelude"