class Raven::Client

Encodes events and sends them to the Sentry server.

Constants

CONTENT_TYPE
PROTOCOL_VERSION
USER_AGENT

Attributes

configuration[RW]

Public Class Methods

new(configuration) click to toggle source
# File lib/raven/client.rb, line 18
def initialize(configuration)
  @configuration = configuration
  @processors = configuration.processors.map { |v| v.new(self) }
  @state = ClientState.new
end

Public Instance Methods

send_event(event, hint = nil) click to toggle source
# File lib/raven/client.rb, line 24
def send_event(event, hint = nil)
  return false unless configuration.sending_allowed?(event)

  event = configuration.before_send.call(event, hint) if configuration.before_send
  if event.nil?
    configuration.logger.info "Discarded event because before_send returned nil"
    return
  end

  # Convert to hash
  event = event.to_hash

  unless @state.should_try?
    failed_send(nil, event)
    return
  end

  event_id = event[:event_id] || event['event_id']
  configuration.logger.info "Sending event #{event_id} to Sentry"

  content_type, encoded_data = encode(event)

  begin
    transport.send_event(generate_auth_header, encoded_data,
                         :content_type => content_type)
    successful_send
  rescue => e
    failed_send(e, event)
    return
  end

  event
end
transport() click to toggle source
# File lib/raven/client.rb, line 58
def transport
  @transport ||=
    case configuration.scheme
    when 'http', 'https'
      Transports::HTTP.new(configuration)
    when 'stdout'
      Transports::Stdout.new(configuration)
    when 'dummy'
      Transports::Dummy.new(configuration)
    else
      fail "Unknown transport scheme '#{configuration.scheme}'"
    end
end

Private Instance Methods

encode(event) click to toggle source
# File lib/raven/client.rb, line 74
def encode(event)
  hash = @processors.reduce(event.to_hash) { |a, e| e.process(a) }
  encoded = JSON.fast_generate(hash)

  case configuration.encoding
  when 'gzip'
    ['application/octet-stream', Base64.strict_encode64(Zlib::Deflate.deflate(encoded))]
  else
    ['application/json', encoded]
  end
end
failed_send(e, event) click to toggle source
# File lib/raven/client.rb, line 118
def failed_send(e, event)
  if e # exception was raised
    @state.failure
    configuration.logger.warn "Unable to record event with remote Sentry server (#{e.class} - #{e.message}):\n#{e.backtrace[0..10].join("\n")}"
  else
    configuration.logger.warn "Not sending event due to previous failure(s)."
  end
  configuration.logger.warn("Failed to submit event: #{get_log_message(event)}")

  # configuration.transport_failure_callback can be false & nil
  configuration.transport_failure_callback.call(event, e) if configuration.transport_failure_callback # rubocop:disable Style/SafeNavigation
end
generate_auth_header() click to toggle source
# File lib/raven/client.rb, line 102
def generate_auth_header
  now = Time.now.to_i.to_s
  fields = {
    'sentry_version' => PROTOCOL_VERSION,
    'sentry_client' => USER_AGENT,
    'sentry_timestamp' => now,
    'sentry_key' => configuration.public_key
  }
  fields['sentry_secret'] = configuration.secret_key unless configuration.secret_key.nil?
  'Sentry ' + fields.map { |key, value| "#{key}=#{value}" }.join(', ')
end
get_log_message(event) click to toggle source
# File lib/raven/client.rb, line 98
def get_log_message(event)
  (event && event[:message]) || (event && event['message']) || get_message_from_exception(event) || '<no message value>'
end
get_message_from_exception(event) click to toggle source
# File lib/raven/client.rb, line 86
def get_message_from_exception(event)
  (
    event &&
    event[:exception] &&
    event[:exception][:values] &&
    event[:exception][:values][0] &&
    event[:exception][:values][0][:type] &&
    event[:exception][:values][0][:value] &&
    "#{event[:exception][:values][0][:type]}: #{event[:exception][:values][0][:value]}"
  )
end
successful_send() click to toggle source
# File lib/raven/client.rb, line 114
def successful_send
  @state.success
end