class Sentry::Configuration

Experimental RBS support (using type sampling data from the type_fusion project).

# sig/sentry/configuration.rbs

class Sentry::Configuration
  def enabled_in_current_env?: () -> true
end

def add_post_initialization_callback(&block)

allow extensions to add their hooks to the Configuration class
def add_post_initialization_callback(&block)
  post_initialization_callbacks << block
end

def async=(value)

def async=(value)
  check_callable!("async", value)
  log_warn <<~MSG
    sentry-ruby now sends events asynchronously by default with its background worker (supported since 4.1.0).
    The `config.async` callback has become redundant while continuing to cause issues.
    (The problems of `async` are detailed in https://github.com/getsentry/sentry-ruby/issues/1522)
    Therefore, we encourage you to remove it and let the background worker take care of async job sending.
  It's deprecation is planned in the next major release (6.0), which is scheduled around the 3rd quarter of 2022.
  MSG
  @async = value
end

def before_breadcrumb=(value)

def before_breadcrumb=(value)
  check_callable!("before_breadcrumb", value)
  @before_breadcrumb = value
end

def before_send=(value)

def before_send=(value)
  check_callable!("before_send", value)
  @before_send = value
end

def before_send_transaction=(value)

def before_send_transaction=(value)
  check_callable!("before_send_transaction", value)
  @before_send_transaction = value
end

def breadcrumbs_logger=(logger)

def breadcrumbs_logger=(logger)
  loggers =
    if logger.is_a?(Array)
      logger
    else
      Array(logger)
    end
  require "sentry/breadcrumb/sentry_logger" if loggers.include?(:sentry_logger)
  @breadcrumbs_logger = logger
end

def capture_exception_frame_locals=(value)

Deprecated:
  • Use {#include_local_variables=} instead.
def capture_exception_frame_locals=(value)
  log_warn <<~MSG
    `capture_exception_frame_locals` is now deprecated in favor of `include_local_variables`.
  MSG
  self.include_local_variables = value
end

def capture_in_environment?

def capture_in_environment?
  return true if enabled_in_current_env?
  @errors << "Not configured to send/capture in environment '#{environment}'"
  false
end

def check_callable!(name, value)

def check_callable!(name, value)
  unless value == nil || value.respond_to?(:call)
    raise ArgumentError, "#{name} must be callable (or nil to disable)"
  end
end

def csp_report_uri

Returns:
  • (String, nil) -
def csp_report_uri
  if dsn && dsn.valid?
    uri = dsn.csp_report_uri
    uri += "&sentry_release=#{CGI.escape(release)}" if release && !release.empty?
    uri += "&sentry_environment=#{CGI.escape(environment)}" if environment && !environment.empty?
    uri
  end
end

def detect_release

Other tags:
    Api: - private
def detect_release
  return unless sending_allowed?
  @release ||= ReleaseDetector.detect_release(project_root: project_root, running_on_heroku: running_on_heroku?)
  if running_on_heroku? && release.nil?
    log_warn(HEROKU_DYNO_METADATA_MESSAGE)
  end
rescue => e
  log_error("Error detecting release", e, debug: debug)
end

def dsn=(value)

def dsn=(value)
  @dsn = init_dsn(value)
end

def enable_tracing=(enable_tracing)

def enable_tracing=(enable_tracing)
  @enable_tracing = enable_tracing
  @traces_sample_rate ||= 1.0 if enable_tracing
end

def enabled_in_current_env?

Experimental RBS support (using type sampling data from the type_fusion project).

def enabled_in_current_env?: () -> true

This signature was generated using 3 samples from 1 application.

def enabled_in_current_env?
  enabled_environments.empty? || enabled_environments.include?(environment)
end

def environment=(environment)

def environment=(environment)
  @environment = environment.to_s
end

def environment_from_env

def environment_from_env
  ENV['SENTRY_CURRENT_ENV'] || ENV['SENTRY_ENVIRONMENT'] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
end

def error_messages

Other tags:
    Api: - private
def error_messages
  @errors = [@errors[0]] + @errors[1..-1].map(&:downcase) # fix case of all but first
  @errors.join(", ")
end

def exception_class_allowed?(exc)

def exception_class_allowed?(exc)
  if exc.is_a?(Sentry::Error)
    # Try to prevent error reporting loops
    log_debug("Refusing to capture Sentry error: #{exc.inspect}")
    false
  elsif excluded_exception?(exc)
    log_debug("User excluded error: #{exc.inspect}")
    false
  else
    true
  end
end

def excluded_exception?(incoming_exception)

def excluded_exception?(incoming_exception)
  excluded_exception_classes.any? do |excluded_exception|
    matches_exception?(excluded_exception, incoming_exception)
  end
end

def excluded_exception_classes

def excluded_exception_classes
  @excluded_exception_classes ||= excluded_exceptions.map { |e| get_exception_class(e) }
end

def get_exception_class(x)

def get_exception_class(x)
  x.is_a?(Module) ? x : safe_const_get(x)
end

def init_dsn(dsn_string)

def init_dsn(dsn_string)
  return if dsn_string.nil? || dsn_string.empty?
  DSN.new(dsn_string)
end

def initialize

def initialize
  self.app_dirs_pattern = nil
  self.debug = false
  self.background_worker_threads = Concurrent.processor_count
  self.backtrace_cleanup_callback = nil
  self.max_breadcrumbs = BreadcrumbBuffer::DEFAULT_SIZE
  self.breadcrumbs_logger = []
  self.context_lines = 3
  self.include_local_variables = false
  self.environment = environment_from_env
  self.enabled_environments = []
  self.exclude_loggers = []
  self.excluded_exceptions = IGNORE_DEFAULT + PUMA_IGNORE_DEFAULT
  self.inspect_exception_causes_for_exclusion = true
  self.linecache = ::Sentry::LineCache.new
  self.logger = ::Sentry::Logger.new(STDOUT)
  self.project_root = Dir.pwd
  self.propagate_traces = true
  self.sample_rate = 1.0
  self.send_modules = true
  self.send_default_pii = false
  self.skip_rake_integration = false
  self.send_client_reports = true
  self.auto_session_tracking = true
  self.trusted_proxies = []
  self.dsn = ENV['SENTRY_DSN']
  self.server_name = server_name_from_env
  self.instrumenter = :sentry
  self.before_send = nil
  self.before_send_transaction = nil
  self.rack_env_whitelist = RACK_ENV_WHITELIST_DEFAULT
  self.traces_sampler = nil
  self.enable_tracing = nil
  @transport = Transport::Configuration.new
  @gem_specs = Hash[Gem::Specification.map { |spec| [spec.name, spec.version.to_s] }] if Gem::Specification.respond_to?(:map)
  run_post_initialization_callbacks
end

def instrumenter=(instrumenter)

def instrumenter=(instrumenter)
  @instrumenter = INSTRUMENTERS.include?(instrumenter) ? instrumenter : :sentry
end

def is_numeric_or_nil?(value)

def is_numeric_or_nil?(value)
  value.is_a?(Numeric) || value.nil?
end

def matches_exception?(excluded_exception_class, incoming_exception)

def matches_exception?(excluded_exception_class, incoming_exception)
  if inspect_exception_causes_for_exclusion?
    Sentry::Utils::ExceptionCauseChain.exception_to_array(incoming_exception).any? { |cause| excluded_exception_class === cause }
  else
    excluded_exception_class === incoming_exception
  end
end

def post_initialization_callbacks

allowing extending the configuration of sentry-ruby by multiple extensions
Post initialization callbacks are called at the end of initialization process
def post_initialization_callbacks
  @post_initialization_callbacks ||= []
end

def profiles_sample_rate=(profiles_sample_rate)

def profiles_sample_rate=(profiles_sample_rate)
  raise ArgumentError, "profiles_sample_rate must be a Numeric or nil" unless is_numeric_or_nil?(profiles_sample_rate)
  log_info("Please make sure to include the 'stackprof' gem in your Gemfile to use Profiling with Sentry.") unless defined?(StackProf)
  @profiles_sample_rate = profiles_sample_rate
end

def profiling_enabled?

def profiling_enabled?
  valid_sampler = !!(valid_sample_rate?(@profiles_sample_rate))
  tracing_enabled? && valid_sampler && sending_allowed?
end

def release=(value)

def release=(value)
  check_argument_type!(value, String, NilClass)
  @release = value
end

def run_post_initialization_callbacks

def run_post_initialization_callbacks
  self.class.post_initialization_callbacks.each do |hook|
    instance_eval(&hook)
  end
end

def running_on_heroku?

def running_on_heroku?
  File.directory?("/etc/heroku") && !ENV["CI"]
end

def safe_const_get(x)

def safe_const_get(x)
  x = x.to_s unless x.is_a?(String)
  Object.const_get(x)
rescue NameError # There's no way to safely ask if a constant exist for an unknown string
  nil
end

def sample_allowed?

def sample_allowed?
  return true if sample_rate == 1.0
  Random.rand < sample_rate
end

def sending_allowed?

def sending_allowed?
  @errors = []
  valid? && capture_in_environment?
end

def server_name_from_env

def server_name_from_env
  if running_on_heroku?
    ENV['DYNO']
  else
    # Try to resolve the hostname to an FQDN, but fall back to whatever
    # the load name is.
    Socket.gethostname || Socket.gethostbyname(hostname).first rescue server_name
  end
end

def stacktrace_builder

Other tags:
    Api: - private
def stacktrace_builder
  @stacktrace_builder ||= StacktraceBuilder.new(
    project_root: @project_root.to_s,
    app_dirs_pattern: @app_dirs_pattern,
    linecache: @linecache,
    context_lines: @context_lines,
    backtrace_cleanup_callback: @backtrace_cleanup_callback
  )
end

def traces_sample_rate=(traces_sample_rate)

def traces_sample_rate=(traces_sample_rate)
  raise ArgumentError, "traces_sample_rate must be a Numeric or nil" unless is_numeric_or_nil?(traces_sample_rate)
  @traces_sample_rate = traces_sample_rate
end

def tracing_enabled?

def tracing_enabled?
  valid_sampler = !!((valid_sample_rate?(@traces_sample_rate)) || @traces_sampler)
  (@enable_tracing != false) && valid_sampler && sending_allowed?
end

def valid?

def valid?
  if @dsn&.valid?
    true
  else
    @errors << "DSN not set or not valid"
    false
  end
end

def valid_sample_rate?(sample_rate)

def valid_sample_rate?(sample_rate)
  return false unless sample_rate.is_a?(Numeric)
  sample_rate >= 0.0 && sample_rate <= 1.0
end