class Fluent::SyslogInput

Constants

FACILITY_MAP
PRIORITY_MAP
SYSLOG_REGEXP

Public Class Methods

new() click to toggle source
Calls superclass method Fluent::Input.new
# File lib/fluent/plugin/in_syslog.rb, line 61
def initialize
  super
  require 'cool.io'
  require 'fluent/plugin/socket_util'
end

Public Instance Methods

configure(conf) click to toggle source
Calls superclass method Fluent::Input#configure
# File lib/fluent/plugin/in_syslog.rb, line 84
def configure(conf)
  super

  if conf.has_key?('format')
    @parser = Plugin.new_parser(conf['format'])
    @parser.configure(conf)
  else
    conf['with_priority'] = true
    @parser = TextParser::SyslogParser.new
    @parser.configure(conf)
    @use_default = true
  end
end
run() click to toggle source
# File lib/fluent/plugin/in_syslog.rb, line 119
def run
  @loop.run(@blocking_timeout)
rescue
  log.error "unexpected error", :error=>$!.to_s
  log.error_backtrace
end
shutdown() click to toggle source
# File lib/fluent/plugin/in_syslog.rb, line 112
def shutdown
  @loop.watchers.each {|w| w.detach }
  @loop.stop
  @handler.close
  @thread.join
end
start() click to toggle source
# File lib/fluent/plugin/in_syslog.rb, line 98
def start
  callback = if @use_default
               method(:receive_data)
             else
               method(:receive_data_parser)
             end

  @loop = Coolio::Loop.new
  @handler = listen(callback)
  @loop.attach(@handler)

  @thread = Thread.new(&method(:run))
end

Private Instance Methods

emit(pri, time, record) click to toggle source
# File lib/fluent/plugin/in_syslog.rb, line 181
def emit(pri, time, record)
  facility = FACILITY_MAP[pri >> 3]
  priority = PRIORITY_MAP[pri & 0b111]

  tag = "#{@tag}.#{facility}.#{priority}"

  router.emit(tag, time, record)
rescue => e
  log.error "syslog failed to emit", :error => e.to_s, :error_class => e.class.to_s, :tag => tag, :record => Yajl.dump(record)
end
listen(callback) click to toggle source
# File lib/fluent/plugin/in_syslog.rb, line 169
def listen(callback)
  log.debug "listening syslog socket on #{@bind}:#{@port} with #{@protocol_type}"
  if @protocol_type == :udp
    @usock = SocketUtil.create_udp_socket(@bind)
    @usock.bind(@bind, @port)
    SocketUtil::UdpHandler.new(@usock, log, 2048, callback)
  else
    # syslog family add "\n" to each message and this seems only way to split messages in tcp stream
    Coolio::TCPServer.new(@bind, @port, SocketUtil::TcpHandler, log, "\n", callback)
  end
end
receive_data(data, addr) click to toggle source
# File lib/fluent/plugin/in_syslog.rb, line 151
def receive_data(data, addr)
  @parser.parse(data) { |time, record|
    unless time && record
      log.warn "invalid syslog message", :data => data
      return
    end

    pri = record.delete('pri')
    record[@source_host_key] = addr[2] if @include_source_host
    emit(pri, time, record)
  }
rescue => e
  log.error data.dump, :error => e.to_s
  log.error_backtrace
end
receive_data_parser(data, addr) click to toggle source
# File lib/fluent/plugin/in_syslog.rb, line 128
def receive_data_parser(data, addr)
  m = SYSLOG_REGEXP.match(data)
  unless m
    log.warn "invalid syslog message: #{data.dump}"
    return
  end
  pri = m[1].to_i
  text = m[2]

  @parser.parse(text) { |time, record|
    unless time && record
      log.warn "pattern not match: #{text.inspect}"
      return
    end

    record[@source_host_key] = addr[2] if @include_source_host
    emit(pri, time, record)
  }
rescue => e
  log.error data.dump, :error => e.to_s
  log.error_backtrace
end