Class: Raven::Instance

Inherits:
Object show all
Defined in:
lib/raven/instance.rb

Overview

A copy of Raven's base module class methods, minus some of the integration and global hooks since it's meant to be used explicitly. Useful for sending errors to multiple sentry projects in a large application.

Examples:

class Foo
  def initialize
    @other_raven = Raven::Instance.new
    @other_raven.configure do |config|
      config.server = 'http://...'
    end
  end

  def foo
    # ...
  rescue => e
    @other_raven.capture_exception(e)
  end
end

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(context = nil, config = nil) ⇒ Instance

Returns a new instance of Instance.


28
29
30
31
# File 'lib/raven/instance.rb', line 28

def initialize(context = nil, config = nil)
  @context = @explicit_context = context
  self.configuration = config || Configuration.new
end

Instance Attribute Details

#clientObject

The client object is responsible for delivering formatted data to the Sentry server.


47
48
49
# File 'lib/raven/instance.rb', line 47

def client
  @client ||= Client.new(configuration)
end

#configurationObject

See Raven::Configuration.


26
27
28
# File 'lib/raven/instance.rb', line 26

def configuration
  @configuration
end

Instance Method Details

#annotate_exception(exc, options = {}) ⇒ Object

Provides extra context to the exception prior to it being handled by Raven. An exception can have multiple annotations, which are merged together.

The options (annotation) is treated the same as the “options“ parameter to “capture_exception“ or “Event.from_exception“, and can contain the same “:user“, “:tags“, etc. options as these methods.

These will be merged with the “options“ parameter to “Event.from_exception“ at the top of execution.

Examples:

begin
  raise "Hello"
rescue => exc
  Raven.annotate_exception(exc, :user => { 'id' => 1,
                           'email' => '[email protected]' })
end

164
165
166
167
168
169
# File 'lib/raven/instance.rb', line 164

def annotate_exception(exc, options = {})
  notes = (exc.instance_variable_defined?(:@__raven_context) && exc.instance_variable_get(:@__raven_context)) || {}
  Raven::Utils::DeepMergeHash.deep_merge!(notes, options)
  exc.instance_variable_set(:@__raven_context, notes)
  exc
end

218
219
220
# File 'lib/raven/instance.rb', line 218

def breadcrumbs
  BreadcrumbBuffer.current
end

#capture(options = {}) ⇒ Object

Capture and process any exceptions from the given block.

Examples:

Raven.capture do
  MyApp.run
end

92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/raven/instance.rb', line 92

def capture(options = {})
  if block_given?
    begin
      yield
    rescue Error
      raise # Don't capture Raven errors
    rescue Exception => e
      capture_type(e, options)
      raise
    end
  else
    install_at_exit_hook(options)
  end
end

#capture_type(obj, options = {}) ⇒ Object Also known as: capture_message, capture_exception


107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/raven/instance.rb', line 107

def capture_type(obj, options = {})
  unless configuration.capture_allowed?(obj)
    logger.debug("#{obj} excluded from capture: #{configuration.error_messages}")
    return false
  end

  message_or_exc = obj.is_a?(String) ? "message" : "exception"
  options = options.deep_dup
  options[:configuration] = configuration
  options[:context] = context
  options[:breadcrumbs] = breadcrumbs

  if evt = Event.send("from_" + message_or_exc, obj, options)
    yield evt if block_given?
    if configuration.async?
      begin
        # We have to convert to a JSON-like hash, because background job
        # processors (esp ActiveJob) may not like weird types in the event hash
        configuration.async.call(evt.to_json_compatible)
      rescue => e
        logger.error("async event sending failed: #{e.message}")
        send_event(evt, make_hint(obj))
      end
    else
      send_event(evt, make_hint(obj))
    end
    Thread.current["sentry_#{object_id}_last_event_id".to_sym] = evt.id
    evt
  end
end

#configure {|configuration| ... } ⇒ Object

Call this method to modify defaults in your initializers.

Examples:

Raven.configure do |config|
  config.server = 'http://...'
end

Yields:


69
70
71
72
73
74
75
# File 'lib/raven/instance.rb', line 69

def configure
  yield(configuration) if block_given?

  self.client = Client.new(configuration)
  report_status
  client
end

#contextObject


33
34
35
36
37
38
39
# File 'lib/raven/instance.rb', line 33

def context
  if @explicit_context
    @context ||= Context.new
  else
    Context.current
  end
end

#extra_context(options = nil) ⇒ Object

Bind extra context. Merges with existing context (if any).

Extra context shows up as Additional Data within Sentry, and is completely arbitrary.

Examples:

Raven.extra_context('my_custom_data' => 'value')

204
205
206
207
208
209
210
# File 'lib/raven/instance.rb', line 204

def extra_context(options = nil)
  context.extra.merge!(options || {})
  yield if block_given?
  context.extra
ensure
  context.extra.delete_if { |k, _| options.keys.include? k } if block_given?
end

#last_event_idObject


141
142
143
# File 'lib/raven/instance.rb', line 141

def last_event_id
  Thread.current["sentry_#{object_id}_last_event_id".to_sym]
end

#loggerObject


41
42
43
# File 'lib/raven/instance.rb', line 41

def logger
  configuration.logger
end

#rack_context(env) ⇒ Object


212
213
214
215
216
# File 'lib/raven/instance.rb', line 212

def rack_context(env)
  env = nil if env.empty?

  context.rack_env = env
end

#report_statusObject

Tell the log that the client is good to go


52
53
54
55
56
57
58
59
60
61
# File 'lib/raven/instance.rb', line 52

def report_status
  return unless configuration.enabled_in_current_env?
  return if configuration.silence_ready

  if configuration.capture_allowed?
    logger.info "Raven #{VERSION} ready to catch errors"
  else
    logger.info "Raven #{VERSION} configured not to capture errors: #{configuration.error_messages}"
  end
end

#send_event(event, hint = nil) ⇒ Object

Send an event to the configured Sentry server

Examples:

evt = Raven::Event.new(:message => "An errore)
Raven.send_event(evt)

82
83
84
# File 'lib/raven/instance.rb', line 82

def send_event(event, hint = nil)
  client.send_event(event, hint)
end

#tags_context(options = nil) ⇒ Object

Bind tags context. Merges with existing context (if any).

Tags are key / value pairs which generally represent things like application version, environment, role, and server names.

Examples:

Raven.tags_context('my_custom_tag' => 'tag_value')

189
190
191
192
193
194
195
# File 'lib/raven/instance.rb', line 189

def tags_context(options = nil)
  context.tags.merge!(options || {})
  yield if block_given?
  context.tags
ensure
  context.tags.delete_if { |k, _| options.keys.include? k } if block_given?
end

#user_context(options = nil) ⇒ Object

Bind user context. Merges with existing context (if any).

It is recommending that you send at least the “id“ and “email“ values. All other values are arbitrary.

Examples:

Raven.user_context('id' => 1, 'email' => '[email protected]')

178
179
180
# File 'lib/raven/instance.rb', line 178

def user_context(options = nil)
  context.user = options || {}
end