class Fluent::Plugin::Parser
Constants
- AVAILABLE_PARSER_VALUE_TYPES
- PARSER_TYPES
- TRUTHY_VALUES
Attributes
type_converters[R]
for tests
Public Class Methods
new()
click to toggle source
Calls superclass method
Fluent::Plugin::Base::new
# File lib/fluent/plugin/parser.rb, line 108 def initialize super @timeout_checker = nil end
Public Instance Methods
build_type_converters(types)
click to toggle source
# File lib/fluent/plugin/parser.rb, line 228 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 157 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 114 def configure(conf) super @time_parser = time_parser_create @type_converters = build_type_converters(@types) @execute_convert_values = @type_converters || @null_value_pattern || @null_empty_string @timeout_checker = if @timeout class << self alias_method :parse_orig, :parse alias_method :parse, :parse_with_timeout end TimeoutChecker.new(@timeout) else nil end 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 202 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 163 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 143 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 173 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 177 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 181 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
parse_with_timeout(text) { |nil, nil| ... }
click to toggle source
# File lib/fluent/plugin/parser.rb, line 147 def parse_with_timeout(text, &block) @timeout_checker.execute { parse_orig(text, &block) } rescue UncatchableError log.warn "parsing timed out with #{self.class}: text = #{text}" # Return nil instead of raising error. in_tail or other plugin can emit broken line. yield nil, nil end
parser_type()
click to toggle source
# File lib/fluent/plugin/parser.rb, line 104 def parser_type :text_per_line end
start()
click to toggle source
Calls superclass method
Fluent::Plugin::Base#start
# File lib/fluent/plugin/parser.rb, line 131 def start super @timeout_checker.start if @timeout_checker end
stop()
click to toggle source
Calls superclass method
Fluent::Plugin::Base#stop
# File lib/fluent/plugin/parser.rb, line 137 def stop super @timeout_checker.stop if @timeout_checker end
string_like_null(value, null_empty_string = @null_empty_string, null_value_regexp = @null_value_pattern)
click to toggle source
# File lib/fluent/plugin/parser.rb, line 222 def string_like_null(value, null_empty_string = @null_empty_string, null_value_regexp = @null_value_pattern) null_empty_string && value.empty? || null_value_regexp && string_safe_encoding(value){|s| null_value_regexp.match(s) } end