Module: Sentry

Extended by:
Forwardable
Defined in:
lib/sentry/dsn.rb,
lib/sentry/hub.rb,
lib/sentry-ruby.rb,
lib/sentry/puma.rb,
lib/sentry/rake.rb,
lib/sentry/span.rb,
lib/sentry/event.rb,
lib/sentry/redis.rb,
lib/sentry/scope.rb,
lib/sentry/client.rb,
lib/sentry/logger.rb,
lib/sentry/sequel.rb,
lib/sentry/baggage.rb,
lib/sentry/faraday.rb,
lib/sentry/metrics.rb,
lib/sentry/session.rb,
lib/sentry/version.rb,
lib/sentry/envelope.rb,
lib/sentry/net/http.rb,
lib/sentry/profiler.rb,
lib/sentry/backtrace.rb,
lib/sentry/interface.rb,
lib/sentry/linecache.rb,
lib/sentry/log_event.rb,
lib/sentry/transport.rb,
lib/sentry/attachment.rb,
lib/sentry/breadcrumb.rb,
lib/sentry/exceptions.rb,
lib/sentry/integrable.rb,
lib/sentry/error_event.rb,
lib/sentry/test_helper.rb,
lib/sentry/transaction.rb,
lib/sentry/metric_event.rb,
lib/sentry/configuration.rb,
lib/sentry/envelope/item.rb,
lib/sentry/backtrace/line.rb,
lib/sentry/check_in_event.rb,
lib/sentry/std_lib_logger.rb,
lib/sentry/vernier/output.rb,
lib/sentry/data_collection.rb,
lib/sentry/session_flusher.rb,
lib/sentry/excon/middleware.rb,
lib/sentry/log_event_buffer.rb,
lib/sentry/profiler/helpers.rb,
lib/sentry/release_detector.rb,
lib/sentry/vernier/profiler.rb,
lib/sentry/background_worker.rb,
lib/sentry/breadcrumb_buffer.rb,
lib/sentry/structured_logger.rb,
lib/sentry/transaction_event.rb,
lib/sentry/cron/configuration.rb,
lib/sentry/interfaces/request.rb,
lib/sentry/interfaces/threads.rb,
lib/sentry/cron/monitor_config.rb,
lib/sentry/metric_event_buffer.rb,
lib/sentry/propagation_context.rb,
lib/sentry/backpressure_monitor.rb,
lib/sentry/interfaces/exception.rb,
lib/sentry/interfaces/mechanism.rb,
lib/sentry/cron/monitor_schedule.rb,
lib/sentry/interfaces/stacktrace.rb,
lib/sentry/cron/monitor_check_ins.rb,
lib/sentry/telemetry_event_buffer.rb,
lib/sentry/debug_structured_logger.rb,
lib/sentry/rack/capture_exceptions.rb,
lib/sentry/transport/configuration.rb,
lib/sentry/breadcrumb/sentry_logger.rb,
lib/sentry/threaded_periodic_worker.rb,
lib/sentry/transport/http_transport.rb,
lib/sentry/transport/debug_transport.rb,
lib/sentry/transport/dummy_transport.rb,
lib/sentry/interfaces/single_exception.rb,
lib/sentry/interfaces/stacktrace_builder.rb,
lib/sentry/transport/spotlight_transport.rb,
lib/sentry/data_collection/key_value_collection.rb

Defined Under Namespace

Modules: Cron, Excon, Faraday, Integrable, Metrics, Net, Puma, Rack, Rake, Sequel, StdLibLogger, TestHelper, Vernier Classes: Attachment, BackgroundWorker, BackpressureMonitor, Backtrace, Baggage, Breadcrumb, BreadcrumbBuffer, CheckInEvent, Client, Configuration, DSN, DataCollection, DebugStructuredLogger, DebugTransport, DummyTransport, Envelope, Error, ErrorEvent, Event, ExceptionInterface, ExternalError, HTTPTransport, Hub, Interface, LineCache, LogEvent, Logger, Mechanism, MetricEvent, Profiler, PropagationContext, Redis, ReleaseDetector, RequestInterface, Scope, Session, SessionFlusher, SingleExceptionInterface, SizeExceededError, Span, SpotlightTransport, StacktraceBuilder, StacktraceInterface, StructuredLogger, StructuredLoggingConfiguration, ThreadedPeriodicWorker, ThreadsInterface, Transaction, TransactionEvent, Transport

Constant Summary collapse

META =
{ "name" => "sentry.ruby", "version" => Sentry::VERSION }.freeze
CAPTURED_SIGNATURE =
:@__sentry_captured
LOGGER_PROGNAME =
"sentry"
SENTRY_TRACE_HEADER_NAME =
"sentry-trace"
BAGGAGE_HEADER_NAME =
"baggage"
THREAD_LOCAL =
:sentry_hub
MUTEX =
Mutex.new
GLOBALS =
%i[
  main_hub
  logger
  session_flusher
  backpressure_monitor
  exception_locals_tp
].freeze
VERSION =
"7.1.0"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.background_worker ⇒ BackgroundWorker

Returns:



86
87
88
# File 'lib/sentry-ruby.rb', line 86

def background_worker
  @background_worker
end

.backpressure_monitor ⇒ Object (readonly)

Returns the value of attribute backpressure_monitor.



94
95
96
# File 'lib/sentry-ruby.rb', line 94

def backpressure_monitor
  @backpressure_monitor
end

.session_flusher ⇒ Object (readonly)

Returns the value of attribute session_flusher.



90
91
92
# File 'lib/sentry-ruby.rb', line 90

def session_flusher
  @session_flusher
end

Class Method Details

.add_attachment ⇒ Object



255
256
257
258
# File 'lib/sentry-ruby.rb', line 255

def add_attachment(**opts)
  return unless initialized?
  get_current_scope.add_attachment(**opts)
end

.add_breadcrumb(breadcrumb, **options) ⇒ Breadcrumb?

Takes an instance of Sentry::Breadcrumb and stores it to the current active scope.

Returns:



353
354
355
356
# File 'lib/sentry-ruby.rb', line 353

def add_breadcrumb(breadcrumb, **options)
  return unless initialized?
  get_current_hub.add_breadcrumb(breadcrumb, **options)
end

.add_global_event_processor {|event, hint| ... } ⇒ void

This method returns an undefined value.

Add a global event processor [Proc]. These run before scope event processors.

Examples:

Sentry.add_global_event_processor do |event, hint|
  event.tags = { foo: 42 }
  event
end

Yield Parameters:

  • event (Event)
  • hint (Hash, nil)


594
595
596
# File 'lib/sentry-ruby.rb', line 594

def add_global_event_processor(&block)
  Scope.add_global_event_processor(&block)
end

.capture_check_in(slug, status, **options) ⇒ String?

Captures a check-in and sends it to Sentry via the currently active hub.

Parameters:

Options Hash (**options):

  • check_in_id (String) —

    for updating the status of an existing monitor

  • duration (Integer) —

    seconds elapsed since this monitor started

  • monitor_config (Cron::MonitorConfig) —

    configuration for this monitor

Returns:



514
515
516
517
# File 'lib/sentry-ruby.rb', line 514

def capture_check_in(slug, status, **options)
  return unless initialized?
  get_current_hub.capture_check_in(slug, status, **options)
end

.capture_event(event) ⇒ Event?

Takes an instance of Sentry::Event and dispatches it to the currently active hub.

Returns:



498
499
500
501
# File 'lib/sentry-ruby.rb', line 498

def capture_event(event)
  return unless initialized?
  get_current_hub.capture_event(event)
end

.capture_exception(exception, **options) {|scope| ... } ⇒ Event?

Takes an exception and reports it to Sentry via the currently active hub.

Yield Parameters:

Returns:



462
463
464
465
# File 'lib/sentry-ruby.rb', line 462

def capture_exception(exception, **options, &block)
  return unless initialized?
  get_current_hub.capture_exception(exception, **options, &block)
end

.capture_log(message, **options) ⇒ LogEvent?

Captures a log event and sends it to Sentry via the currently active hub. This is the underlying method used by the StructuredLogger class.

Examples:

Direct usage (prefer using Sentry.logger instead)

Sentry.capture_log("User logged in", level: :info, user_id: 123)

Parameters:

  • message (String) —

    the log message

  • options (Hash) —

    Extra log event options

Options Hash (**options):

  • level (Symbol) —

    The log level (:trace, :debug, :info, :warn, :error, :fatal)

  • severity (Integer) —

    The severity number according to the Sentry Logs Protocol

  • origin (String) —

    The origin of the log event (e.g., "auto.db.rails", "manual")

  • Additional (Hash) —

    attributes to include with the log

Returns:

  • (LogEvent, nil) —

    The created log event or nil if Sentry is not initialized

See Also:



534
535
536
537
# File 'lib/sentry-ruby.rb', line 534

def capture_log(message, **options)
  return unless initialized?
  get_current_hub.capture_log_event(message, **options)
end

.capture_message(message, **options) {|scope| ... } ⇒ Event?

Takes a message string and reports it to Sentry via the currently active hub.

Yield Parameters:

Returns:



490
491
492
493
# File 'lib/sentry-ruby.rb', line 490

def capture_message(message, **options, &block)
  return unless initialized?
  get_current_hub.capture_message(message, **options, &block)
end

.clear_external_propagation_context ⇒ Object



719
720
721
# File 'lib/sentry-ruby.rb', line 719

def clear_external_propagation_context
  @external_propagation_context_callback = nil
end

.clone_hub_to_current_thread ⇒ void

This method returns an undefined value.

Clones the main hub and stores it for the current execution context (the current thread, or the current fiber when config.hub_isolation_level is :fiber).



392
393
394
395
# File 'lib/sentry-ruby.rb', line 392

def clone_hub_to_current_thread
  return unless initialized?
  set_current_hub_internal(get_main_hub.clone)
end

.close ⇒ void

This method returns an undefined value.

Flushes pending events and cleans up SDK state. SDK will stop sending events and all top-level APIs will be no-ops after this.



289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# File 'lib/sentry-ruby.rb', line 289

def close
  if @session_flusher
    @session_flusher.flush
    @session_flusher.kill
    @session_flusher = nil
  end

  if @backpressure_monitor
    @backpressure_monitor.kill
    @backpressure_monitor = nil
  end

  if client = get_current_client
    client.configuration.run_after_close_callbacks
    client.flush
    client.log_event_buffer.kill
    client.metric_event_buffer.kill

    if client.configuration.data_collection.collect_stack_frame_variables?
      exception_locals_tp.disable
    end
  end

  @background_worker.shutdown

  MUTEX.synchronize do
    @main_hub = nil
    set_current_hub_internal(nil)
  end
end

.configuration ⇒ Object



166
167
168
169
# File 'lib/sentry-ruby.rb', line 166

def configuration
  return unless initialized?
  get_current_client.configuration
end

.configure_scope {|scope| ... } ⇒ void

This method returns an undefined value.

Takes a block and yields the current active scope.

Examples:

Sentry.configure_scope do |scope|
  scope.set_tags(foo: "bar")
end

Sentry.capture_message("test message") # this event will have tags { foo: "bar" }

Yield Parameters:



408
409
410
411
# File 'lib/sentry-ruby.rb', line 408

def configure_scope(&block)
  return unless initialized?
  get_current_hub.configure_scope(&block)
end

.continue_trace(env, **options) ⇒ Transaction?

Continue an incoming trace from a rack env like hash.

Parameters:

  • env (Hash)

Returns:



638
639
640
641
# File 'lib/sentry-ruby.rb', line 638

def continue_trace(env, **options)
  return nil unless initialized?
  get_current_hub.continue_trace(env, **options)
end

.csp_report_uri ⇒ String?

Returns an uri for security policy reporting that's generated from the given DSN (To learn more about security policy reporting: https://docs.sentry.io/product/security-policy-reporting/)

It returns nil if

  • The SDK is not initialized yet.
  • The DSN is not provided or is invalid.

Returns:

  • (String, nil)


335
336
337
338
# File 'lib/sentry-ruby.rb', line 335

def csp_report_uri
  return unless initialized?
  configuration.csp_report_uri
end

.exception_captured?(exc) ⇒ Boolean

Checks if the exception object has been captured by the SDK.

Returns:

  • (Boolean)


576
577
578
579
# File 'lib/sentry-ruby.rb', line 576

def exception_captured?(exc)
  return false unless initialized?
  !!exc.instance_variable_get(CAPTURED_SIGNATURE)
end

.get_baggage ⇒ String?

Returns the baggage header for distributed tracing. Can be either from the currently active span or the propagation context.

Returns:

  • (String, nil)


611
612
613
614
# File 'lib/sentry-ruby.rb', line 611

def get_baggage
  return nil unless initialized?
  get_current_hub.get_baggage
end

.get_current_client ⇒ Client?

Returns the current active client.

Returns:



374
375
376
377
# File 'lib/sentry-ruby.rb', line 374

def get_current_client
  return unless initialized?
  get_current_hub.current_client
end

.get_current_hub ⇒ Hub

Returns the current active hub. If the current thread doesn't have an active hub, it will clone the main thread's active hub, stores it in the current thread, and then returns it.

Returns:



363
364
365
366
367
368
369
370
# File 'lib/sentry-ruby.rb', line 363

def get_current_hub
  # we need to assign a hub to the current thread if it doesn't have one yet
  #
  # ideally, we should do this proactively whenever a new thread is created
  # but it's impossible for the SDK to keep track every new thread
  # so we need to use this rather passive way to make sure the app doesn't crash
  get_current_hub_internal || clone_hub_to_current_thread
end

.get_current_scope ⇒ Scope?

Returns the current active scope.

Returns:



382
383
384
385
# File 'lib/sentry-ruby.rb', line 382

def get_current_scope
  return unless initialized?
  get_current_hub.current_scope
end

.get_external_propagation_context ⇒ Array<String>?

Returns the external propagation context (trace_id, span_id) if a callback is registered.

Returns:

  • (Array<String>, nil) —

    A tuple of [trace_id, span_id] or nil if no context is available



710
711
712
713
714
715
716
717
# File 'lib/sentry-ruby.rb', line 710

def get_external_propagation_context
  return nil unless @external_propagation_context_callback

  @external_propagation_context_callback.call
rescue => e
  sdk_logger&.debug(LOGGER_PROGNAME) { "Error getting external propagation context: #{e.message}" } if initialized?
  nil
end

.get_main_hub ⇒ Hub

Returns the main thread's active hub.

Returns:



343
344
345
346
347
348
# File 'lib/sentry-ruby.rb', line 343

def get_main_hub
  MUTEX.synchronize { @main_hub }
rescue ThreadError
  # In some rare cases this may be called in a trap context so we need to handle it gracefully
  @main_hub
end

.get_trace_propagation_headers ⇒ Hash?

Returns the a Hash containing sentry-trace and baggage. Can be either from the currently active span or the propagation context.

Returns:

  • (Hash, nil)


620
621
622
623
# File 'lib/sentry-ruby.rb', line 620

def get_trace_propagation_headers
  return nil unless initialized?
  get_current_hub.get_trace_propagation_headers
end

.get_trace_propagation_meta ⇒ String

Returns the a Hash containing sentry-trace and baggage. Can be either from the currently active span or the propagation context.

Returns:

  • (String)


629
630
631
632
# File 'lib/sentry-ruby.rb', line 629

def get_trace_propagation_meta
  return "" unless initialized?
  get_current_hub.get_trace_propagation_meta
end

.get_traceparent ⇒ String?

Returns the traceparent (sentry-trace) header for distributed tracing. Can be either from the currently active span or the propagation context.

Returns:

  • (String, nil)


602
603
604
605
# File 'lib/sentry-ruby.rb', line 602

def get_traceparent
  return nil unless initialized?
  get_current_hub.get_traceparent
end

.init {|config| ... } ⇒ void

This method returns an undefined value.

Initializes the SDK with given configuration.

Yield Parameters:



266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/sentry-ruby.rb', line 266

def init(&block)
  config = Configuration.new(&block)

  config.detect_release
  apply_patches(config)
  config.validate
  client = Client.new(config)
  scope = Scope.new(max_breadcrumbs: config.max_breadcrumbs)
  hub = Hub.new(client, scope)
  @hub_isolation_level = config.hub_isolation_level
  set_current_hub_internal(hub)
  @main_hub = hub
  @background_worker = Sentry::BackgroundWorker.new(config)
  @session_flusher = config.session_tracking? ? Sentry::SessionFlusher.new(config, client) : nil
  @backpressure_monitor = config.enable_backpressure_handling ? Sentry::BackpressureMonitor.new(config, client) : nil
  exception_locals_tp.enable if config.data_collection.collect_stack_frame_variables?
  at_exit { close }
end

.initialized? ⇒ Boolean

Returns true if the SDK is initialized.

Returns:

  • (Boolean)


323
324
325
# File 'lib/sentry-ruby.rb', line 323

def initialized?
  !!get_main_hub
end

.integrations ⇒ Hash{String=>Hash}

Returns a hash that contains all the integrations that have been registered to the main SDK.

Returns:

  • (Hash{String=>Hash})


130
131
132
# File 'lib/sentry-ruby.rb', line 130

def integrations
  @integrations ||= {}
end

.last_event_id ⇒ String?

Returns the id of the lastly reported Sentry::Event.

Returns:

  • (String, nil)


568
569
570
571
# File 'lib/sentry-ruby.rb', line 568

def last_event_id
  return unless initialized?
  get_current_hub.last_event_id
end

.logger ⇒ StructuredLogger

Returns the structured logger instance that implements Sentry's SDK telemetry logs protocol.

Examples:

Basic usage

Sentry.logger.info("User logged in successfully", user_id: 123)
Sentry.logger.error("Failed to process payment",
  transaction_id: "tx_123",
  error_code: "PAYMENT_FAILED"
)

Returns:

See Also:



655
656
657
# File 'lib/sentry-ruby.rb', line 655

def logger
  @logger ||= configuration.structured_logging.logger_class.new(configuration)
end

.metrics ⇒ Metrics

Returns the metrics API for capturing custom metrics.

Examples:

Usage

Sentry.metrics.count("button.click", 1, attributes: { button_id: "submit" })
Sentry.metrics.distribution("response.time", 120.5, unit: "millisecond")
Sentry.metrics.gauge("cpu.usage", 75.2, unit: "percent")

Returns:



667
668
669
# File 'lib/sentry-ruby.rb', line 667

def metrics
  Metrics
end

.register_external_propagation_context(&callback) ⇒ void

This method returns an undefined value.

Registers a callback function that retrieves the current external propagation context. This is used by OpenTelemetry integration to provide trace_id and span_id from OTel context.

Examples:

Sentry.register_external_propagation_context do
  span_context = OpenTelemetry::Trace.current_span.context
  return nil unless span_context.valid?
  [span_context.hex_trace_id, span_context.hex_span_id]
end

Parameters:

  • callback (Proc, nil) —

    A callable that returns [trace_id, span_id] or nil



703
704
705
# File 'lib/sentry-ruby.rb', line 703

def register_external_propagation_context(&callback)
  @external_propagation_context_callback = callback
end

.register_integration(name, version) ⇒ Object

Registers the SDK integration with its name and version.

Parameters:

  • name (String) —

    name of the integration

  • version (String) —

    version of the integration



138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/sentry-ruby.rb', line 138

def register_integration(name, version)
  if initialized?
    sdk_logger.warn(LOGGER_PROGNAME) do
      <<~MSG
        Integration '#{name}' is loaded after the SDK is initialized, which can cause unexpected behavior.  Please make sure all integrations are loaded before SDK initialization.
      MSG
    end
  end

  meta = { name: "sentry.ruby.#{name}", version: version }.freeze
  integrations[name.to_s] = meta
end

.remove_attribute ⇒ Object



248
249
250
251
# File 'lib/sentry-ruby.rb', line 248

def remove_attribute(key)
  return unless initialized?
  get_current_scope.remove_attribute(key)
end

.send_event ⇒ Object



173
174
175
176
# File 'lib/sentry-ruby.rb', line 173

def send_event(*args)
  return unless initialized?
  get_current_client.send_event(*args)
end

.set_attribute ⇒ Object



239
240
241
242
# File 'lib/sentry-ruby.rb', line 239

def set_attribute(key, value, unit: nil)
  return unless initialized?
  get_current_scope.set_attribute(key, value, unit: unit)
end

.set_attributes ⇒ Object



228
229
230
231
# File 'lib/sentry-ruby.rb', line 228

def set_attributes(attributes_hash)
  return unless initialized?
  get_current_scope.set_attributes(attributes_hash)
end

.set_context ⇒ Object



219
220
221
222
# File 'lib/sentry-ruby.rb', line 219

def set_context(*args)
  return unless initialized?
  get_current_scope.set_context(*args)
end

.set_extras ⇒ Object



205
206
207
208
# File 'lib/sentry-ruby.rb', line 205

def set_extras(*args)
  return unless initialized?
  get_current_scope.set_extras(*args)
end

.set_tags ⇒ Object



198
199
200
201
# File 'lib/sentry-ruby.rb', line 198

def set_tags(*args)
  return unless initialized?
  get_current_scope.set_tags(*args)
end

.set_user ⇒ Object



212
213
214
215
# File 'lib/sentry-ruby.rb', line 212

def set_user(*args)
  return unless initialized?
  get_current_scope.set_user(*args)
end

.start_transaction(**options) ⇒ Transaction?

Takes or initializes a new Sentry::Transaction and makes a sampling decision for it.

Returns:



542
543
544
545
# File 'lib/sentry-ruby.rb', line 542

def start_transaction(**options)
  return unless initialized?
  get_current_hub.start_transaction(**options)
end

.with_child_span(**attributes) {|child_span| ... } ⇒ Object

Records the block's execution as a child of the current span. If the current scope doesn't have a span, the block would still be executed but the yield param will be nil.

Examples:

Sentry.with_child_span(op: "my operation") do |child_span|
  child_span.set_data(operation_data)
  child_span.set_description(operation_detail)
  # result will be returned
end

Parameters:

  • attributes (Hash) —

    attributes for the child span.

Yield Parameters:

  • child_span (Span, nil)

Returns:

  • yield result



560
561
562
563
# File 'lib/sentry-ruby.rb', line 560

def with_child_span(**attributes, &block)
  return yield(nil) unless Sentry.initialized?
  get_current_hub.with_child_span(**attributes, &block)
end

.with_exception_captured(**options, &block) ⇒ Object

Takes a block and evaluates it. If the block raised an exception, it reports the exception to Sentry and re-raises it. If the block ran without exception, it returns the evaluation result.

Examples:

Sentry.with_exception_captured do
  1/1 #=> 1 will be returned
end

Sentry.with_exception_captured do
  1/0 #=> ZeroDivisionError will be reported and re-raised
end


479
480
481
482
483
484
# File 'lib/sentry-ruby.rb', line 479

def with_exception_captured(**options, &block)
  yield
rescue Exception => e
  capture_exception(e, **options)
  raise
end

.with_scope {|scope| ... } ⇒ void

This method returns an undefined value.

Takes a block and yields a temporary scope. The temporary scope will inherit all the attributes from the current active scope and replace it to be the active scope inside the block.

Examples:

Sentry.configure_scope do |scope|
  scope.set_tags(foo: "bar")
end

Sentry.capture_message("test message") # this event will have tags { foo: "bar" }

Sentry.with_scope do |temp_scope|
  temp_scope.set_tags(foo: "baz")
  Sentry.capture_message("test message 2") # this event will have tags { foo: "baz" }
end

Sentry.capture_message("test message 3") # this event will have tags { foo: "bar" }

Yield Parameters:



433
434
435
436
# File 'lib/sentry-ruby.rb', line 433

def with_scope(&block)
  return yield unless initialized?
  get_current_hub.with_scope(&block)
end

.with_session_tracking(&block) ⇒ void

This method returns an undefined value.

Wrap a given block with session tracking. Aggregate sessions in minutely buckets will be recorded around this block and flushed every minute.

Examples:

Sentry.with_session_tracking do
  a = 1 + 1 # new session recorded with :exited status
end

Sentry.with_session_tracking do
  1 / 0
rescue => e
  Sentry.capture_exception(e) # new session recorded with :errored status
end


453
454
455
456
# File 'lib/sentry-ruby.rb', line 453

def with_session_tracking(&block)
  return yield unless initialized?
  get_current_hub.with_session_tracking(&block)
end