class Sentry::Configuration

def add_post_initialization_callback(&block)

allow extensions to add their hooks to the Configuration class
def add_post_initialization_callback(&block)
  callbacks[:initialize][:after] << block
end

def after(event, &block)

def after(event, &block)
  callbacks[event.to_sym][:after] << block
end

def before(event, &block)

def before(event, &block)
  callbacks[event.to_sym][:before] << block
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_check_in=(value)

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

def before_send_metric=(value)

def before_send_metric=(value)
  check_callable!("before_send_metric", value)
  @before_send_metric = 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 build_validation_proc(optional, type)

def build_validation_proc(optional, type)
  case type
  when :numeric
    ->(value) do
      if optional && value.nil?
        true
      else
        unless value.is_a?(Numeric)
          message = "must be a Numeric"
          message += " or nil" if optional
          { error: message, value: value }
        else
          true
        end
      end
    end
  else
    ->(value) { true }
  end
end

def callbacks

@!visibility private
def callbacks
  @callbacks ||= {
    initialize: { before: [], after: [] },
    configured: { before: [], after: [] }
  }
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 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 enabled_in_current_env?

def enabled_in_current_env?
  enabled_environments.nil? || 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
  run_callbacks(:before, :initialize)
  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
  self.include_local_variables = false
  self.environment = environment_from_env
  self.enabled_environments = nil
  self.exclude_loggers = []
  self.excluded_exceptions = IGNORE_DEFAULT + PUMA_IGNORE_DEFAULT
  self.inspect_exception_causes_for_exclusion = true
  self.linecache = ::Sentry::LineCache.new
  self.sdk_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.enable_backpressure_handling = false
  self.trusted_proxies = []
  self.dsn = ENV["SENTRY_DSN"]
  self.capture_queue_time = true
  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
  self.instrumenter = :sentry
  self.trace_propagation_targets = [PROPAGATION_TARGETS_MATCH_ALL]
  self.trace_ignore_status_codes = TRACE_IGNORE_STATUS_CODES_DEFAULT
  self.enabled_patches = DEFAULT_PATCHES.dup
  self.before_send = nil
  self.before_send_transaction = nil
  self.before_send_check_in = nil
  self.before_send_log = nil
  self.before_send_metric = nil
  self.std_lib_logger_filter = nil
  self.rack_env_whitelist = RACK_ENV_WHITELIST_DEFAULT
  self.traces_sampler = nil
  self.enable_logs = false
  self.enable_metrics = true
  self.profiler_class = Sentry::Profiler
  self.profiles_sample_interval = DEFAULT_PROFILES_SAMPLE_INTERVAL
  @transport = Transport::Configuration.new
  @cron = Cron::Configuration.new
  @structured_logging = StructuredLoggingConfiguration.new
  @gem_specs = Hash[Gem::Specification.map { |spec| [spec.name, spec.version.to_s] }] if Gem::Specification.respond_to?(:map)
  self.max_log_events = LogEventBuffer::DEFAULT_MAX_EVENTS
  self.max_metric_events = MetricEventBuffer::DEFAULT_MAX_METRICS
  run_callbacks(:after, :initialize)
  yield(self) if block_given?
  run_callbacks(:after, :configured)
end

def instrumenter=(instrumenter)

def instrumenter=(instrumenter)
  @instrumenter = INSTRUMENTERS.include?(instrumenter) ? instrumenter : :sentry
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 processor_count

def processor_count
  available_processor_count = Concurrent.available_processor_count if Concurrent.respond_to?(:available_processor_count)
  available_processor_count || Concurrent.processor_count
end

def profiler_class=(profiler_class)

def profiler_class=(profiler_class)
  if profiler_class == Sentry::Vernier::Profiler
    begin
      require "vernier"
    rescue LoadError
    end
  end
  @profiler_class = profiler_class
end

def profiles_sample_rate=(profiles_sample_rate)

def profiles_sample_rate=(profiles_sample_rate)
  @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_callbacks(hook, event)

def run_callbacks(hook, event)
  self.class.callbacks[event][hook].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?
  spotlight || sending_to_dsn_allowed?
end

def sending_to_dsn_allowed?

def sending_to_dsn_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 session_tracking?

def session_tracking?
  auto_session_tracking && enabled_in_current_env?
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,
    strip_backtrace_load_path: @strip_backtrace_load_path
  )
end

def std_lib_logger_filter=(value)

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

def trace_ignore_status_codes=(codes)

def trace_ignore_status_codes=(codes)
  unless codes.is_a?(Array) && codes.all? { |code| valid_status_code_entry?(code) }
    raise ArgumentError, "trace_ignore_status_codes must be an Array of integers or ranges between (100-599) where begin <= end"
  end
  @trace_ignore_status_codes = codes
end

def traces_sample_rate=(traces_sample_rate)

def traces_sample_rate=(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)
  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_http_status_code?(code)

def valid_http_status_code?(code)
  code.is_a?(Integer) && code >= 100 && code <= 599
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

def valid_status_code_entry?(entry)

def valid_status_code_entry?(entry)
  case entry
  when Integer
    valid_http_status_code?(entry)
  when Range
    valid_http_status_code?(entry.begin) &&
      valid_http_status_code?(entry.end) &&
      entry.begin <= entry.end
  else
    false
  end
end

def validate(attribute, optional: false, type: nil)

def validate(attribute, optional: false, type: nil)
  validations[attribute] = {
    optional: optional,
    type: type,
    proc: build_validation_proc(optional, type)
  }
end

def validate

def validate
  if profiler_class == Sentry::Profiler && profiles_sample_rate && !Sentry.dependency_installed?(:StackProf)
    log_warn("Please add the 'stackprof' gem to your Gemfile to use the StackProf profiler with Sentry.")
  end
  if profiler_class == Sentry::Vernier::Profiler && profiles_sample_rate && !Sentry.dependency_installed?(:Vernier)
    log_warn("Please add the 'vernier' gem to your Gemfile to use the Vernier profiler with Sentry.")
  end
  self.class.validations.each do |attribute, validation|
    value = public_send(attribute)
    next if (result = validation[:proc].call(value)) === true
    raise ArgumentError, result[:error]
  end
end

def validations

def validations
  @validations ||= {}
end