class LogStash::Outputs::Seq

An output that sends events to Seq.

Public Instance Methods

multi_receive(events) click to toggle source
# File lib/logstash/outputs/seq.rb, line 49
def multi_receive(events)
  payload = {
      'Events' => events.map {|event| to_seq_payload(event)}
  }
  post_to_seq(payload)

  "#{events.length} events received"
end
receive(event) click to toggle source
# File lib/logstash/outputs/seq.rb, line 59
def receive(event)
  payload = {
      'Events' => [to_seq_payload(event)]
  }
  post_to_seq(payload)

  'Event received'
end
register() click to toggle source
# File lib/logstash/outputs/seq.rb, line 29
def register
  url = @url

  url += '/' unless url.end_with? '/'
  url += 'api/events/raw'

  @url = url

  @default_headers = {
      'X-Seq-ApiKey' => @api_key,
      'Content-Type' => 'application/json'
  }

  # We count outstanding requests with this queue; it tracks outstanding requests to create backpressure
  # When this queue is empty no new requests may be sent, tokens must be added back by the client on success
  @request_tokens = SizedQueue.new(@pool_max)
  @pool_max.times {|t| @request_tokens << true }
end

Private Instance Methods

get_level(event) click to toggle source
# File lib/logstash/outputs/seq.rb, line 130
def get_level(event)
  level = event.get('@level')

  level ? level : 'Verbose'
end
post_to_seq(payload) click to toggle source
# File lib/logstash/outputs/seq.rb, line 69
def post_to_seq(payload)
  token = @request_tokens.pop

  request = client.post(@url, {
    headers: @default_headers,
    body:    JrJackson::Json.dump(payload),
    async:   true
  })

  request.on_complete do
    @request_tokens << token
  end

  request.on_success do |response|
    if response.code < 200 || response.code > 299
      log_failure("Encountered non-200 HTTP code #{200}",
        :response_code => response.code,
        :url => url,
        :event => event
      )
    end
  end

  request.on_failure do |exception|
    log_failure("Could not submit POST request.",
      :url => url,
      :method => @http_method,
      :body => body,
      :headers => headers,
      :message => exception.message,
      :class => exception.class.name,
      :backtrace => exception.backtrace
    )
  end

  request_async_background(request)
end
request_async_background(request) click to toggle source

Manticore doesn't provide a way to attach handlers to background or async requests well It wants you to use futures. The async method kinda works but expects single thread batches and background only returns futures. Proposed fix to manticore here: github.com/cheald/manticore/issues/32

# File lib/logstash/outputs/seq.rb, line 141
def request_async_background(request)
  @method ||= client.executor.java_method(:submit, [java.util.concurrent.Callable.java_class])
  @method.call(request)
end
to_seq_payload(event) click to toggle source

Convert a Logstash event to a Seq event payload.

Note that we return a hash here, not the JSON, because it's more efficient to convert batched events to JSON all-in-one go.

# File lib/logstash/outputs/seq.rb, line 111
def to_seq_payload(event)
  props = {
      '@Version' => event.get('@version')
  }
  payload = {
      :Timestamp => event.get('@timestamp'),
      :Level => get_level(event),
      :MessageTemplate => event.get('message'),
      :Properties => props
  }

  event.to_hash.each do |property, value|
    props[property] = value unless @@ignore_properties.has_key? property
  end

  payload
end