class LogStash::Outputs::NewRelic

Constants

NON_RETRYABLE_CODES

Public Instance Methods

encode(event_hash) click to toggle source
# File lib/logstash/outputs/newrelic.rb, line 67
def encode(event_hash)
  log_message_hash = {
    # non-intrinsic attributes get put into 'attributes'
    :attributes => event_hash
  }

  # intrinsic attributes go at the top level
  if event_hash['message']
    log_message_hash['message'] = event_hash['message']
    log_message_hash[:attributes].delete('message')
  end
  if event_hash['timestamp']
    log_message_hash['timestamp'] = event_hash['timestamp']
    log_message_hash[:attributes].delete('timestamp')
  end

  log_message_hash
end
handle_response(response) click to toggle source
# File lib/logstash/outputs/newrelic.rb, line 121
def handle_response(response)
  if !(200 <= response.code.to_i && response.code.to_i < 300)
    raise Error::BadResponseCodeError.new(response.code.to_i, @base_uri)
  end
end
is_retryable_code(response_error) click to toggle source
# File lib/logstash/outputs/newrelic.rb, line 173
def is_retryable_code(response_error)
  error_code = response_error.response_code
  !NON_RETRYABLE_CODES.include?(error_code)
end
multi_receive(events) click to toggle source
# File lib/logstash/outputs/newrelic.rb, line 86
def multi_receive(events)
  if events.size == 0
    return
  end

  payload = []
  events.each do |event|
    payload.push(encode(event.to_hash))
  end
  payload = {
    :common => {
      :attributes => {
        :plugin => {
          :type => 'logstash',
          :version => LogStash::Outputs::NewRelicVersion::VERSION,
        }
      }
    },
    :logs => payload
  }
  @semaphor.acquire()
  execute = @executor.java_method :submit, [java.lang.Runnable]
  execute.call do
    begin
      io = StringIO.new
      gzip = Zlib::GzipWriter.new(io)
      gzip << [payload].to_json
      gzip.close
      nr_send(io.string)
    ensure
      @semaphor.release()
    end
  end
end
nr_send(payload) click to toggle source
# File lib/logstash/outputs/newrelic.rb, line 127
def nr_send(payload)
  retries = 0
  begin
    http = Net::HTTP.new(@end_point.host, 443)
    request = Net::HTTP::Post.new(@end_point.request_uri)
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER
    @header.each { |k, v| request[k] = v }
    request.body = payload
    handle_response(http.request(request))
  rescue Error::BadResponseCodeError => e
    @logger.error(e.message)
    if (should_retry(retries) && is_retryable_code(e))
      retries += 1
      sleep(1)
      retry
    end
  rescue => e
    # Stuff that should never happen
    # For all other errors print out full issues
    if (should_retry(retries))
      retries += 1
      @logger.warn(
        "An unknown error occurred sending a bulk request to NewRelic. Retrying...",
        :retries => "attempt #{retries} of #{@max_retries}",
        :error_message => e.message,
        :error_class => e.class.name,
        :backtrace => e.backtrace
      )
      sleep(1)
      retry
    else
      @logger.error(
        "An unknown error occurred sending a bulk request to NewRelic. Maximum of attempts reached, dropping logs.",
        :error_message => e.message,
        :error_class => e.class.name,
        :backtrace => e.backtrace
      )
    end
  end
end
register() click to toggle source
# File lib/logstash/outputs/newrelic.rb, line 29
def register
  @end_point = URI.parse(@base_uri)
  if @api_key.nil? && @license_key.nil?
    raise LogStash::ConfigurationError, "Must provide a license key or api key", caller
  end
  auth = {
    @api_key.nil? ? 'X-License-Key' : 'X-Insert-Key' =>
      @api_key.nil? ? @license_key.value : @api_key.value
  }
  @header = {
    'X-Event-Source' => 'logs',
    'Content-Encoding' => 'gzip'
  }.merge(auth).freeze
  @executor = java.util.concurrent.Executors.newFixedThreadPool(@concurrent_requests)
  @semaphor = java.util.concurrent.Semaphore.new(@concurrent_requests)
end
should_retry(retries) click to toggle source
# File lib/logstash/outputs/newrelic.rb, line 169
def should_retry(retries)
  retries < @max_retries
end
shutdown() click to toggle source

Used by tests so that the test run can complete (background threads prevent JVM exit)

# File lib/logstash/outputs/newrelic.rb, line 47
def shutdown
  if @executor
    @executor.shutdown
    # We want this long enough to not have threading issues
    terminationWaitInSeconds = 10
    terminatedInTime = @executor.awaitTermination(terminationWaitInSeconds, java.util.concurrent.TimeUnit::SECONDS)
    if !terminatedInTime
      raise "Did not shut down within #{terminationWaitInSeconds} seconds"
    end
  end
end
time_to_logstash_timestamp(time) click to toggle source
# File lib/logstash/outputs/newrelic.rb, line 59
def time_to_logstash_timestamp(time)
  begin
    LogStash::Timestamp.coerce(time)
  rescue
    nil
  end
end