class Fluent::Plugin::SentryOutput

Public Class Methods

new() click to toggle source
Calls superclass method
# File lib/fluent/plugin/out_sentry.rb, line 25
def initialize
  require 'time'

  super
end

Public Instance Methods

configure(conf) click to toggle source
Calls superclass method
# File lib/fluent/plugin/out_sentry.rb, line 31
def configure(conf)
  super

  config = Sentry::Configuration.new
  config.dsn = @dsn
  config.send_modules = false
  config.transport.timeout = 5

  @client = Sentry::Client.new(config)
end
format(tag, time, record) click to toggle source
# File lib/fluent/plugin/out_sentry.rb, line 107
def format(tag, time, record)
  [tag, time, record].to_msgpack
end
formatted_to_msgpack_binary() click to toggle source
# File lib/fluent/plugin/out_sentry.rb, line 111
def formatted_to_msgpack_binary
  true
end
write(chunk) click to toggle source
# File lib/fluent/plugin/out_sentry.rb, line 42
def write(chunk)
  chunk.msgpack_each do |tag, time, record|
    begin
      event = Sentry::Event.new(configuration: @client.configuration)

      event.level = (record['level'] || @level).downcase
      event.environment = record['env'] || @environment

      if @type === :event
        event.message = record['message'] || tag
        event.user = record.select{ |key| @user_keys.include?(key) }
        event.extra = @data_keys.length() > 0 ? record.select{ |key| @data_keys.include?(key) } : record
        event.contexts = {'data' => { origin_data: record }}
        event.tags = event.tags.merge({ :timestamp => Time.at(time).strftime('%Y-%m-%d %H:%M:%S %Z') })
          .merge(record.select{ |key| (@tag_keys + @user_keys).include?(key) })
        event = event.to_hash

        event['logger'] = tag
      elsif @type === :exception
        event.tags = { :timestamp => Time.at(time).strftime('%Y-%m-%d %H:%M:%S %Z') }
          .merge(record.select{ |key| (@tag_keys + @user_keys).include?(key) })

        event = event.to_hash

        event['logger'] = tag

        frame = Array.new
        if record.include?(@e_stack)
          record[@e_stack].split("\n") do |value|
            match = value.match(/\#(?<no>\d+) (?<filename>.*?)\((?<lineno>\d+)\): (?<context_line>[\s\S]+)/)
            if match != nil
              frame.unshift(Sentry::CustomStacktraceFrame.new(
                filename: match[:filename],
                context_line: match[:context_line],
                pre_context: "//...\n",
                post_context: "//...\n",
                lineno: Integer(match[:lineno]),
              ))
            end
          end
        elsif
          frame.push(Sentry::CustomStacktraceFrame.new(
            filename: record.include?(@e_filename) ? record[@e_filename] : '',
            context_line: record.include?(@e_describe) ? record[@e_describe] : '',
            pre_context: "//...\n",
            post_context: "//...\n",
            lineno: record.include?(@e_line) ? Integer(record[@e_line]) : 1
          ))
        end

        event['exception'] = Sentry::CustomExceptionInterface.new(
          type: record['message'] || '',
          message: record.include?(@e_describe) ? record[@e_describe] : '',
          stacktrace: Sentry::StacktraceInterface.new(frames: frame)
        ).to_hash
        event['message'] = record.include?(@e_describe) ? (record[@e_describe] + ' in ' + record[@e_filename] + ' on line ' + record[@e_line]) : ''
      end

      @client.send_event(event)
    rescue => e
      log.error("Sentry Error:", :error_class => e.class, :error => e.message)
    end
  end
end