class Fluent::Plugin::MultiConditionSelectorOutput

Constants

BUILTIN_CONFIGURATIONS
PATTERN_MAX_NUM

Public Instance Methods

configure(conf) click to toggle source
Calls superclass method
# File lib/fluent/plugin/out_multi_condition_selector.rb, line 54
def configure(conf)
  super
  # ここで、BUILTIN_CONFIGURATIONS に入っていないものがあった場合はerrorをraise
  conf.each_pair { |k, v|
    next if BUILTIN_CONFIGURATIONS.include?(k) || k.match(/^condition\d\d?$/) || k.match(/^tag\d\d?$/)

    raise Fluent::ConfigError, 'out_multi_condition_selector: some weird config is set {'+k.to_s+':'+v.to_s+'}'
  }

  # conditionsを読み込む
  @conditions = []
  conf.elements.select { |element| element.name.match(/^condition?$/) }
      .each do |param|
    condition = {}
    data_record = {}

    param.elements.select { |element| element.name.match(/^data?$/) }.each do |data|
      data.each_pair do |key, value|
        data_record.merge!(key => convert_value(value))
      end
    end

    param.each_pair do |key, value|
      condition.merge!(key => convert_value(value))
    end

    condition.merge!("data" => data_record)
    @conditions.push(condition)
  end


  if @remove_keys
    @remove_keys = @remove_keys.split(',')
  end
  if @keep_keys
    raise Fluent::ConfigError, 'out_multi_condition_selector: `renew_record` must be true to use `keep_keys`' unless @renew_record
    @keep_keys = @keep_keys.split(',')
  end

  placeholder_expander_params = {
      :log           => log,
      :auto_typecast => @auto_typecast, # It should always be true
  }

  @placeholder_expander =
      if @enable_ruby
        # require utilities which would be used in ruby placeholders
        require 'pathname'
        require 'uri'
        require 'cgi'
        RubyPlaceholderExpander.new(placeholder_expander_params)
      else
        p 'WARN!! Hey! You should enable ruby!!!'
        PlaceholderExpander.new(placeholder_expander_params)
      end


  @hostname = Socket.gethostname
end
process(tag, es) click to toggle source
# File lib/fluent/plugin/out_multi_condition_selector.rb, line 114
def process(tag, es)
  tag_parts = tag.split('.')
  tag_prefix = tag_prefix(tag_parts)
  tag_suffix = tag_suffix(tag_parts)
  placeholder_values = {
      'tag'        => tag,
      'tags'       => tag_parts, # for old version compatibility
      'tag_parts'  => tag_parts,
      'tag_prefix' => tag_prefix,
      'tag_suffix' => tag_suffix,
      'hostname'   => @hostname,
  }
  es.each {|time, record|
    placeholder_values.merge!({
                                  'time'     => @placeholder_expander.time_value(time),
                                  'record'   => record,
                              })
                              
    # TODO: ここの処理よくないって evaluate
    matched_conditions, aditional_data = evaluate_condition(@conditions, placeholder_values )

    if (@at_least_one && matched_conditions.size > 0) || @at_least_one == false
      new_record = reform(record, aditional_data, placeholder_values)
      if @renew_time_key && new_record.has_key?(@renew_time_key)
        time = new_record[@renew_time_key].to_i
      end
      @remove_keys.each {|k| new_record.delete(k) } if @remove_keys
      new_record.merge!("conditions" => matched_conditions)
      router.emit(@tag, time, new_record)
    end
  }
rescue => e
  log.warn "out_multi_condition_selector: #{e.class} #{e.message} #{e.backtrace.first}"
end

Private Instance Methods

convert_num(value) click to toggle source
# File lib/fluent/plugin/out_multi_condition_selector.rb, line 196
def convert_num(value)
  # Booleanがチェック
  if value == "true"
    return true
  elsif value == "false"
    return false
  end
  
  if value.to_i.to_s == value.to_s
    return value.to_i
  else
    return value
  end
end
convert_value(value) click to toggle source
# File lib/fluent/plugin/out_multi_condition_selector.rb, line 211
def convert_value(value)
  # Booleanがチェック
  return true if value == 'true'

  return false if value == 'false'

  # 数値データなら数値で返す
  return value.to_i if value.to_i.to_s == value.to_s
  return value.to_f if value.to_f.to_s == value.to_s

  value
end
create_record(map, placeholders) click to toggle source
# File lib/fluent/plugin/out_multi_condition_selector.rb, line 182
def create_record(map, placeholders)
  new_record = {}
  map.each do |k, v|
    value = @placeholder_expander.expand(v, placeholders, true)
    if value.nil?
      new_record.merge!({ k => convert_num(v) })
    else
      new_record.merge!({ k => convert_num(value) })
    end
  end

  new_record
end
evaluate_condition(conditions, placeholders) click to toggle source
# File lib/fluent/plugin/out_multi_condition_selector.rb, line 151
def evaluate_condition(conditions, placeholders)
  matched_conditions = []
  aditional_data = {}
  conditions.each_with_index{ |condition, idx|
    result = expand_placeholders(condition["rule"], placeholders)
    if result
      matched_conditions.push(condition["condition"])
       aditional_data.merge!(condition["data"])
    end
  }
  return matched_conditions, aditional_data
end
expand_placeholders(value, placeholders) click to toggle source
# File lib/fluent/plugin/out_multi_condition_selector.rb, line 224
def expand_placeholders(value, placeholders)
  if value.is_a?(String)
    new_value = @placeholder_expander.expand(value, placeholders)
  elsif value.is_a?(Hash)
    new_value = {}
    value.each_pair do |k, v|
      new_key = @placeholder_expander.expand(k, placeholders, true)
      new_value[new_key] = expand_placeholders(v, placeholders)
    end
  elsif value.is_a?(Array)
    new_value = []
    value.each_with_index do |v, i|
      new_value[i] = expand_placeholders(v, placeholders)
    end
  else
    new_value = value
  end
  new_value
end
parse_value(value_str) click to toggle source
# File lib/fluent/plugin/out_multi_condition_selector.rb, line 164
def parse_value(value_str)
  if value_str.start_with?('{', '[')
    JSON.parse(value_str)
  else
    value_str
  end
rescue => e
  log.warn "failed to parse #{value_str} as json. Assuming #{value_str} is a string", :error_class => e.class, :error => e.message
  value_str # emit as string
end
reform(record, aditional_data, placeholder_values) click to toggle source
# File lib/fluent/plugin/out_multi_condition_selector.rb, line 175
def reform(record, aditional_data, placeholder_values)
  new_record = @renew_record ? {} : record.dup
  new_record.merge!(create_record(aditional_data, placeholder_values))
  @keep_keys.each {|k| new_record[k] = record[k]} if @keep_keys and @renew_record
  return new_record
end
tag_prefix(tag_parts) click to toggle source
# File lib/fluent/plugin/out_multi_condition_selector.rb, line 244
def tag_prefix(tag_parts)
  return [] if tag_parts.empty?
  tag_prefix = [tag_parts.first]
  1.upto(tag_parts.size-1).each do |i|
    tag_prefix[i] = "#{tag_prefix[i-1]}.#{tag_parts[i]}"
  end
  tag_prefix
end
tag_suffix(tag_parts) click to toggle source
# File lib/fluent/plugin/out_multi_condition_selector.rb, line 253
def tag_suffix(tag_parts)
  return [] if tag_parts.empty?
  rev_tag_parts = tag_parts.reverse
  rev_tag_suffix = [rev_tag_parts.first]
  1.upto(tag_parts.size-1).each do |i|
    rev_tag_suffix[i] = "#{rev_tag_parts[i]}.#{rev_tag_suffix[i-1]}"
  end
  rev_tag_suffix.reverse!
end