class Fluent::Plugin::Parser

Constants

AVAILABLE_PARSER_VALUE_TYPES
PARSER_TYPES
TRUTHY_VALUES

Attributes

type_converters[R]

for tests

Public Instance Methods

build_type_converters(types) click to toggle source
# File lib/fluent/plugin/parser.rb, line 145
def build_type_converters(types)
  return nil unless types

  converters = {}

  types.each_pair do |field_name, type_definition|
    type, option = type_definition.split(":", 2)
    unless AVAILABLE_PARSER_VALUE_TYPES.include?(type)
      raise Fluent::ConfigError, "unknown value conversion for key:'#{field_name}', type:'#{type}'"
    end

    conv = case type
           when 'string' then ->(v){ v.to_s }
           when 'integer' then ->(v){ v.to_i rescue v.to_s.to_i }
           when 'float' then ->(v){ v.to_f rescue v.to_s.to_f }
           when 'bool' then ->(v){ TRUTHY_VALUES.include?(v.to_s.downcase) }
           when 'time'
             # comma-separated: time:[timezone:]time_format
             # time_format is unixtime/float/string-time-format
             timep = if option
                       time_type = 'string' # estimate
                       timezone, time_format = option.split(':', 2)
                       unless Fluent::Timezone.validate(timezone)
                         timezone, time_format = nil, option
                       end
                       if Fluent::TimeMixin::TIME_TYPES.include?(time_format)
                         time_type, time_format = time_format, nil # unixtime/float
                       end
                       time_parser_create(type: time_type.to_sym, format: time_format, timezone: timezone)
                     else
                       time_parser_create(type: :string, format: nil, timezone: nil)
                     end
             ->(v){ timep.parse(v) rescue nil }
           when 'array'
             delimiter = option ? option.to_s : ','
             ->(v){ string_safe_encoding(v.to_s){|s| s.split(delimiter) } }
           else
             raise "BUG: unknown type even after check: #{type}"
           end
    converters[field_name] = conv
  end

  converters
end
call(*a, &b) click to toggle source
# File lib/fluent/plugin/parser.rb, line 74
def call(*a, &b)
  # Keep backward compatibility for existing plugins
  # TODO: warn when deprecated
  parse(*a, &b)
end
configure(conf) click to toggle source
Calls superclass method Fluent::Plugin::Base#configure
# File lib/fluent/plugin/parser.rb, line 61
def configure(conf)
  super

  @time_parser = time_parser_create
  @null_value_regexp = @null_value_pattern && Regexp.new(@null_value_pattern)
  @type_converters = build_type_converters(@types)
  @execute_convert_values = @type_converters || @null_value_regexp || @null_empty_string
end
convert_values(time, record) click to toggle source

def parse(text, &block)

time, record = convert_values(time, record)
yield time, record

end

# File lib/fluent/plugin/parser.rb, line 119
def convert_values(time, record)
  return time, record unless @execute_convert_values

  record.each_key do |key|
    value = record[key]
    next unless value # nil/null value is always left as-is.

    if value.is_a?(String) && string_like_null(value)
      record[key] = nil
      next
    end

    if @type_converters && @type_converters.has_key?(key)
      record[key] = @type_converters[key].call(value)
    end
  end

  return time, record
end
implement?(feature) click to toggle source
# File lib/fluent/plugin/parser.rb, line 80
def implement?(feature)
  methods_of_plugin = self.class.instance_methods(false)
  case feature
  when :parse_io then methods_of_plugin.include?(:parse_io)
  when :parse_partial_data then methods_of_plugin.include?(:parse_partial_data)
  else
    raise ArgumentError, "Unknown feature for parser plugin: #{feature}"
  end
end
parse(text, &block) click to toggle source
# File lib/fluent/plugin/parser.rb, line 70
def parse(text, &block)
  raise NotImplementedError, "Implement this method in child class"
end
parse_io(io, &block) click to toggle source
# File lib/fluent/plugin/parser.rb, line 90
def parse_io(io, &block)
  raise NotImplementedError, "Optional API #parse_io is not implemented"
end
parse_partial_data(data, &block) click to toggle source
# File lib/fluent/plugin/parser.rb, line 94
def parse_partial_data(data, &block)
  raise NotImplementedError, "Optional API #parse_partial_data is not implemented"
end
parse_time(record) click to toggle source
# File lib/fluent/plugin/parser.rb, line 98
def parse_time(record)
  if @time_key && record.respond_to?(:has_key?) && record.has_key?(@time_key)
    src = if @keep_time_key
            record[@time_key]
          else
            record.delete(@time_key)
          end
    @time_parser.parse(src)
  elsif @estimate_current_event
    Fluent::EventTime.now
  else
    nil
  end
rescue Fluent::TimeParser::TimeParseError => e
  raise ParserError, e.message
end
parser_type() click to toggle source
# File lib/fluent/plugin/parser.rb, line 57
def parser_type
  :text_per_line
end
string_like_null(value, null_empty_string = @null_empty_string, null_value_regexp = @null_value_regexp) click to toggle source
# File lib/fluent/plugin/parser.rb, line 139
def string_like_null(value, null_empty_string = @null_empty_string, null_value_regexp = @null_value_regexp)
  null_empty_string && value.empty? || null_value_regexp && string_safe_encoding(value){|s| null_value_regexp.match(s) }
end