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 68
def initialize
  super
  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 114
def configure(conf)
  super

  if @default_priority < 0 && @default_priority > 191
    raise ConfigError, "default_priority must be 0 ~ 191"
  end

  if @allow_without_priority && conf['message_format'] == 'auto'
    raise ConfigError, "message_format auto isn't allowed when allow_without_priority is true"
  end

  conf['with_priority'] = !@allow_without_priority
  if conf.has_key?('format')
    @parser = Plugin.new_parser(conf['format'])
    @parser.configure(conf)
  else
    @parser = TextParser::SyslogParser.new
    @parser.configure(conf)
    @use_default = true
  end

  if @source_hostname_key.nil? && @include_source_host
    @source_hostname_key = @source_host_key
  end
  if @source_hostname_key
    if @resolve_hostname.nil?
      @resolve_hostname = true
    elsif !@resolve_hostname # user specifies "false" in configure
      raise Fluent::ConfigError, "resolve_hostname must be true with source_hostname_key"
    end
  end
end
run() click to toggle source
# File lib/fluent/plugin/in_syslog.rb, line 171
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 164
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 147
def start
  callback = if @allow_without_priority
               method(:receive_data_allow_without_priority)
             else
               if @use_default
                 method(:receive_data_default)
               else
                 method(:receive_data_with_format)
               end
             end
  @loop = Coolio::Loop.new
  @handler = listen(callback)
  @loop.attach(@handler)

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

Private Instance Methods

emit(tag, time, record) click to toggle source
# File lib/fluent/plugin/in_syslog.rb, line 258
def emit(tag, time, record)
  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 246
def listen(callback)
  log.info "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, @message_length_limit, callback, @resolve_hostname)
  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, @resolve_hostname)
  end
end
parse_text(text, addr, pri = nil) click to toggle source
# File lib/fluent/plugin/in_syslog.rb, line 221
def parse_text(text, addr, pri = nil)
  @parser.parse(text) { |time, record|
    unless time && record
      log.warn "pattern not match: #{text.inspect}"
      return
    end

    ## from receive_data_default
    pri = record.delete('pri'.freeze) unless pri

    facility = FACILITY_MAP[pri >> 3]
    priority = PRIORITY_MAP[pri & 0b111]

    record[@priority_key] = priority if @priority_key
    record[@facility_key] = facility if @facility_key
    record[@source_hostname_key] = addr[2] if @source_hostname_key
    record[@source_address_key] = addr[3] if @source_address_key

    tag = "#{@tag}.#{facility}.#{priority}"
    emit(tag, time, record)
  }
end
receive_data_allow_without_priority(data, addr) click to toggle source

PRI part parser + SyslogParser without PRI part | custom parser without PRI part

# File lib/fluent/plugin/in_syslog.rb, line 205
def receive_data_allow_without_priority(data, addr)
  m = SYSLOG_REGEXP.match(data)
  if m
    pri = m[1].to_i
    text = m[2]
  else
    pri = @default_priority
    text = data
  end

  parse_text(text, addr, pri)
rescue => e
  log.error data.dump, error: e.to_s
  log.error_backtrace
end
receive_data_default(data, addr) click to toggle source

SyslogParser with PRI part

# File lib/fluent/plugin/in_syslog.rb, line 181
def receive_data_default(data, addr)
  parse_text(data, addr)
rescue => e
  log.error data.dump, error: e.to_s
  log.error_backtrace
end
receive_data_with_format(data, addr) click to toggle source

PRI part parser + custom parser without PRI part

# File lib/fluent/plugin/in_syslog.rb, line 189
def receive_data_with_format(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]

  parse_text(text, addr, pri)
rescue => e
  log.error data.dump, error: e.to_s
  log.error_backtrace
end