Class: Fluent::Config::Element

Inherits:
Hash
  • Object
show all
Defined in:
lib/fluent/config/element.rb

Constant Summary collapse

RESERVED_PARAMETERS_COMPAT =
{
  '@type' => 'type',
  '@id' => 'id',
  '@log_level' => 'log_level',
  '@label' => nil,
}
RESERVED_PARAMETERS =
RESERVED_PARAMETERS_COMPAT.keys

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, arg, attrs, elements, unused = nil) ⇒ Element

Returns a new instance of Element.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/fluent/config/element.rb', line 23

def initialize(name, arg, attrs, elements, unused = nil)
  @name = name
  @arg = arg
  @elements = elements
  super()
  attrs.each { |k, v|
    self[k] = v
  }
  @unused = unused || attrs.keys
  @v1_config = false
  @corresponding_proxies = [] # some plugins use flat parameters, e.g. in_http doesn't provide <format> section for parser.
  @unused_in = nil # if this element is not used in plugins, correspoing plugin name and parent element name is set, e.g. [source, plugin class].

  # it's global logger, not plugin logger: deprecated message should be global warning, not plugin level.
  @logger = defined?($log) ? $log : nil

  @target_worker_ids = []
end

Instance Attribute Details

#argObject

Returns the value of attribute arg.



42
43
44
# File 'lib/fluent/config/element.rb', line 42

def arg
  @arg
end

#corresponding_proxiesObject

Returns the value of attribute corresponding_proxies.



42
43
44
# File 'lib/fluent/config/element.rb', line 42

def corresponding_proxies
  @corresponding_proxies
end

#elements(*names, name: nil, arg: nil) ⇒ Object

Raises:

  • (ArgumentError)


54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/fluent/config/element.rb', line 54

def elements(*names, name: nil, arg: nil)
  raise ArgumentError, "name and names are exclusive" if name && !names.empty?
  raise ArgumentError, "arg is available only with name" if arg && !name

  if name
    @elements.select{|e| e.name == name && (!arg || e.arg == arg) }
  elsif !names.empty?
    @elements.select{|e| names.include?(e.name) }
  else
    @elements
  end
end

#nameObject

Returns the value of attribute name.



42
43
44
# File 'lib/fluent/config/element.rb', line 42

def name
  @name
end

#target_worker_idsObject (readonly)

Returns the value of attribute target_worker_ids.



44
45
46
# File 'lib/fluent/config/element.rb', line 44

def target_worker_ids
  @target_worker_ids
end

#unusedObject

Returns the value of attribute unused.



42
43
44
# File 'lib/fluent/config/element.rb', line 42

def unused
  @unused
end

#unused_inObject

Returns the value of attribute unused_in.



42
43
44
# File 'lib/fluent/config/element.rb', line 42

def unused_in
  @unused_in
end

#v1_configObject

Returns the value of attribute v1_config.



42
43
44
# File 'lib/fluent/config/element.rb', line 42

def v1_config
  @v1_config
end

Class Method Details

.unescape_parameter(v) ⇒ Object



232
233
234
235
236
# File 'lib/fluent/config/element.rb', line 232

def self.unescape_parameter(v)
  result = ''
  v.each_char { |c| result << LiteralParser.unescape_char(c) }
  result
end

Instance Method Details

#+(o) ⇒ Object



93
94
95
96
97
# File 'lib/fluent/config/element.rb', line 93

def +(o)
  e = Element.new(@name.dup, @arg.dup, o.merge(self), @elements + o.elements, (@unused + o.unused).uniq)
  e.v1_config = @v1_config
  e
end

#==(o) ⇒ Object

This method assumes o is an Element object. Should return false for nil or other object



85
86
87
88
89
90
91
# File 'lib/fluent/config/element.rb', line 85

def ==(o)
  self.name == o.name && self.arg == o.arg &&
    self.keys.size == o.keys.size &&
    self.keys.reduce(true){|r, k| r && self[k] == o[k] } &&
    self.elements.size == o.elements.size &&
    [self.elements, o.elements].transpose.reduce(true){|r, e| r && e[0] == e[1] }
end

#[](key) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
# File 'lib/fluent/config/element.rb', line 118

def [](key)
  @unused_in = [] # ditto
  @unused.delete(key)

  if RESERVED_PARAMETERS.include?(key) && !has_key?(key) && has_key?(RESERVED_PARAMETERS_COMPAT[key])
    @logger.warn "'#{RESERVED_PARAMETERS_COMPAT[key]}' is deprecated parameter name. use '#{key}' instead." if @logger
    return self[RESERVED_PARAMETERS_COMPAT[key]]
  end

  super
end

#add_element(name, arg = '') ⇒ Object



67
68
69
70
71
72
# File 'lib/fluent/config/element.rb', line 67

def add_element(name, arg = '')
  e = Element.new(name, arg, {}, [])
  e.v1_config = @v1_config
  @elements << e
  e
end

#check_not_fetched(&block) ⇒ Object



130
131
132
133
134
135
136
137
138
139
# File 'lib/fluent/config/element.rb', line 130

def check_not_fetched(&block)
  each_key { |key|
    if @unused.include?(key)
      block.call(key, self)
    end
  }
  @elements.each { |e|
    e.check_not_fetched(&block)
  }
end

#default_value(key) ⇒ Object



197
198
199
200
201
202
203
204
205
206
# File 'lib/fluent/config/element.rb', line 197

def default_value(key)
  return nil if @corresponding_proxies.empty?

  param_key = key.to_sym
  proxy = @corresponding_proxies.detect do |_proxy|
    _proxy.params.has_key?(param_key)
  end
  return nil unless proxy
  proxy.defaults[param_key]
end

#dump_value(k, v, nindent) ⇒ Object



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/fluent/config/element.rb', line 208

def dump_value(k, v, nindent)
  return "#{nindent}#{k} xxxxxx\n" if secret_param?(k)
  return "#{nindent}#{k} #{v}\n" unless @v1_config

  # for v1 config
  if v.nil?
    "#{nindent}#{k} \n"
  elsif v == :default
    "#{nindent}#{k} #{default_value(k)}\n"
  else
    case param_type(k)
    when :string
      "#{nindent}#{k} \"#{self.class.unescape_parameter(v)}\"\n"
    when :enum, :integer, :float, :size, :bool, :time
      "#{nindent}#{k} #{v}\n"
    when :hash, :array
      "#{nindent}#{k} #{v}\n"
    else
      # Unknown type
      "#{nindent}#{k} #{v}\n"
    end
  end
end

#each_element(*names, &block) ⇒ Object

no code in fluentd uses this method



100
101
102
103
104
105
106
107
108
109
110
# File 'lib/fluent/config/element.rb', line 100

def each_element(*names, &block)
  if names.empty?
    @elements.each(&block)
  else
    @elements.each { |e|
      if names.include?(e.name)
        block.yield(e)
      end
    }
  end
end

#for_another_worker?Boolean

Returns:

  • (Boolean)


260
261
262
# File 'lib/fluent/config/element.rb', line 260

def for_another_worker?
  !@target_worker_ids.empty? && !@target_worker_ids.include?(Fluent::Engine.worker_id)
end

#for_every_workers?Boolean

Returns:

  • (Boolean)


252
253
254
# File 'lib/fluent/config/element.rb', line 252

def for_every_workers?
  @target_worker_ids.empty?
end

#for_this_worker?Boolean

Returns:

  • (Boolean)


256
257
258
# File 'lib/fluent/config/element.rb', line 256

def for_this_worker?
  @target_worker_ids.include?(Fluent::Engine.worker_id)
end

#has_key?(key) ⇒ Boolean

Returns:

  • (Boolean)


112
113
114
115
116
# File 'lib/fluent/config/element.rb', line 112

def has_key?(key)
  @unused_in = [] # some sections, e.g. <store> in copy, is not defined by config_section so clear unused flag for better warning message in check_not_fetched.
  @unused.delete(key)
  super
end

#inspectObject



74
75
76
77
# File 'lib/fluent/config/element.rb', line 74

def inspect
  attrs = super
  "name:#{@name}, arg:#{@arg}, " + attrs + ", " + @elements.inspect
end

#param_type(key) ⇒ Object



185
186
187
188
189
190
191
192
193
194
195
# File 'lib/fluent/config/element.rb', line 185

def param_type(key)
  return nil if @corresponding_proxies.empty?

  param_key = key.to_sym
  proxy = @corresponding_proxies.detect do |_proxy|
    _proxy.params.has_key?(param_key)
  end
  return nil unless proxy
  _block, opts = proxy.params[param_key]
  opts[:type]
end

#pretty_print(q) ⇒ Object

Used by PP and Pry



80
81
82
# File 'lib/fluent/config/element.rb', line 80

def pretty_print(q)
  q.text(inspect)
end

#secret_param?(key) ⇒ Boolean

Returns:

  • (Boolean)


171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/fluent/config/element.rb', line 171

def secret_param?(key)
  return false if @corresponding_proxies.empty?

  param_key = key.to_sym
  @corresponding_proxies.each { |proxy|
    _block, opts = proxy.params[param_key]
    if opts && opts.has_key?(:secret)
      return opts[:secret]
    end
  }

  false
end

#set_target_worker_id(worker_id) ⇒ Object



238
239
240
241
242
243
# File 'lib/fluent/config/element.rb', line 238

def set_target_worker_id(worker_id)
  @target_worker_ids = [worker_id]
  @elements.each { |e|
    e.set_target_worker_id(worker_id)
  }
end

#set_target_worker_ids(worker_ids) ⇒ Object



245
246
247
248
249
250
# File 'lib/fluent/config/element.rb', line 245

def set_target_worker_ids(worker_ids)
  @target_worker_ids = worker_ids.uniq
  @elements.each { |e|
    e.set_target_worker_ids(worker_ids.uniq)
  }
end

#to_masked_elementObject



160
161
162
163
164
165
166
167
168
169
# File 'lib/fluent/config/element.rb', line 160

def to_masked_element
  new_elems = @elements.map { |e| e.to_masked_element }
  new_elem = Element.new(@name, @arg, {}, new_elems, @unused)
  new_elem.v1_config = @v1_config
  new_elem.corresponding_proxies = @corresponding_proxies
  each_pair { |k, v|
    new_elem[k] = secret_param?(k) ? 'xxxxxx' : v
  }
  new_elem
end

#to_s(nest = 0) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/fluent/config/element.rb', line 141

def to_s(nest = 0)
  indent = "  " * nest
  nindent = "  " * (nest + 1)
  out = ""
  if @arg.nil? || @arg.empty?
    out << "#{indent}<#{@name}>\n"
  else
    out << "#{indent}<#{@name} #{@arg}>\n"
  end
  each_pair { |k, v|
    out << dump_value(k, v, nindent)
  }
  @elements.each { |e|
    out << e.to_s(nest + 1)
  }
  out << "#{indent}</#{@name}>\n"
  out
end