fluentd 1.11.5-x86-mingw32 → 1.12.4-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fluentd might be problematic. Click here for more details.

Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.deepsource.toml +13 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
  4. data/.github/ISSUE_TEMPLATE/config.yml +5 -0
  5. data/.github/workflows/linux-test.yaml +36 -0
  6. data/.github/workflows/macos-test.yaml +30 -0
  7. data/.github/workflows/stale-actions.yml +22 -0
  8. data/.github/workflows/windows-test.yaml +35 -0
  9. data/.gitlab-ci.yml +41 -19
  10. data/CHANGELOG.md +158 -0
  11. data/MAINTAINERS.md +5 -2
  12. data/README.md +7 -4
  13. data/bin/fluent-cap-ctl +7 -0
  14. data/bin/fluent-ctl +7 -0
  15. data/fluentd.gemspec +6 -4
  16. data/lib/fluent/capability.rb +87 -0
  17. data/lib/fluent/command/bundler_injection.rb +1 -1
  18. data/lib/fluent/command/ca_generate.rb +6 -3
  19. data/lib/fluent/command/cap_ctl.rb +174 -0
  20. data/lib/fluent/command/cat.rb +0 -1
  21. data/lib/fluent/command/ctl.rb +177 -0
  22. data/lib/fluent/command/fluentd.rb +4 -0
  23. data/lib/fluent/command/plugin_config_formatter.rb +18 -2
  24. data/lib/fluent/command/plugin_generator.rb +31 -1
  25. data/lib/fluent/compat/parser.rb +2 -2
  26. data/lib/fluent/config/section.rb +2 -2
  27. data/lib/fluent/config/types.rb +2 -2
  28. data/lib/fluent/env.rb +4 -0
  29. data/lib/fluent/event.rb +3 -13
  30. data/lib/fluent/load.rb +0 -1
  31. data/lib/fluent/plugin.rb +5 -0
  32. data/lib/fluent/plugin/buffer.rb +2 -21
  33. data/lib/fluent/plugin/file_wrapper.rb +39 -3
  34. data/lib/fluent/plugin/formatter.rb +2 -2
  35. data/lib/fluent/plugin/formatter_csv.rb +1 -1
  36. data/lib/fluent/plugin/formatter_hash.rb +1 -1
  37. data/lib/fluent/plugin/formatter_ltsv.rb +5 -5
  38. data/lib/fluent/plugin/formatter_out_file.rb +3 -3
  39. data/lib/fluent/plugin/formatter_single_value.rb +2 -2
  40. data/lib/fluent/plugin/formatter_tsv.rb +2 -2
  41. data/lib/fluent/plugin/in_http.rb +24 -3
  42. data/lib/fluent/plugin/in_monitor_agent.rb +1 -1
  43. data/lib/fluent/plugin/in_tail.rb +129 -41
  44. data/lib/fluent/plugin/in_tail/position_file.rb +53 -14
  45. data/lib/fluent/plugin/in_tcp.rb +1 -0
  46. data/lib/fluent/plugin/out_copy.rb +18 -5
  47. data/lib/fluent/plugin/out_exec_filter.rb +3 -3
  48. data/lib/fluent/plugin/out_forward.rb +61 -28
  49. data/lib/fluent/plugin/out_http.rb +9 -2
  50. data/lib/fluent/plugin/output.rb +18 -10
  51. data/lib/fluent/plugin/parser_csv.rb +2 -2
  52. data/lib/fluent/plugin/parser_syslog.rb +2 -2
  53. data/lib/fluent/plugin/storage_local.rb +4 -4
  54. data/lib/fluent/plugin_helper/http_server/compat/server.rb +1 -1
  55. data/lib/fluent/plugin_helper/inject.rb +4 -2
  56. data/lib/fluent/plugin_helper/retry_state.rb +4 -0
  57. data/lib/fluent/plugin_helper/server.rb +4 -2
  58. data/lib/fluent/plugin_helper/socket_option.rb +2 -2
  59. data/lib/fluent/supervisor.rb +153 -47
  60. data/lib/fluent/system_config.rb +2 -1
  61. data/lib/fluent/time.rb +58 -1
  62. data/lib/fluent/version.rb +1 -1
  63. data/lib/fluent/winsvc.rb +22 -4
  64. data/templates/new_gem/fluent-plugin.gemspec.erb +3 -3
  65. data/templates/plugin_config_formatter/param.md-table.erb +10 -0
  66. data/test/command/test_cap_ctl.rb +100 -0
  67. data/test/command/test_ctl.rb +57 -0
  68. data/test/command/test_fluentd.rb +38 -0
  69. data/test/command/test_plugin_config_formatter.rb +124 -2
  70. data/test/config/test_configurable.rb +1 -1
  71. data/test/plugin/in_tail/test_position_file.rb +100 -26
  72. data/test/plugin/test_file_wrapper.rb +105 -0
  73. data/test/plugin/test_in_exec.rb +1 -1
  74. data/test/plugin/test_in_http.rb +25 -0
  75. data/test/plugin/test_in_tail.rb +503 -42
  76. data/test/plugin/test_out_copy.rb +87 -0
  77. data/test/plugin/test_out_forward.rb +94 -6
  78. data/test/plugin/test_out_http.rb +20 -1
  79. data/test/plugin/test_output.rb +15 -3
  80. data/test/plugin/test_output_as_buffered_backup.rb +2 -0
  81. data/test/plugin/test_parser_csv.rb +14 -0
  82. data/test/plugin/test_parser_syslog.rb +16 -2
  83. data/test/plugin/test_sd_file.rb +1 -1
  84. data/test/plugin_helper/service_discovery/test_manager.rb +1 -1
  85. data/test/plugin_helper/test_child_process.rb +5 -2
  86. data/test/plugin_helper/test_http_server_helper.rb +4 -2
  87. data/test/plugin_helper/test_inject.rb +29 -0
  88. data/test/plugin_helper/test_server.rb +26 -7
  89. data/test/test_capability.rb +74 -0
  90. data/test/test_event.rb +16 -0
  91. data/test/test_formatter.rb +30 -0
  92. data/test/test_output.rb +2 -2
  93. data/test/test_supervisor.rb +133 -10
  94. data/test/test_time_parser.rb +109 -0
  95. metadata +85 -31
  96. data/.travis.yml +0 -57
  97. data/appveyor.yml +0 -28
@@ -163,6 +163,10 @@ op.on('--conf-encoding ENCODING', "specify configuration file encoding") { |s|
163
163
  opts[:conf_encoding] = s
164
164
  }
165
165
 
166
+ op.on('--disable-shared-socket', "Don't open shared socket for multiple workers") { |b|
167
+ opts[:disable_shared_socket] = b
168
+ }
169
+
166
170
  if Fluent.windows?
167
171
  require 'windows/library'
168
172
  include Windows::Library
@@ -29,7 +29,8 @@ class FluentPluginConfigFormatter
29
29
  AVAILABLE_FORMATS = [:markdown, :txt, :json]
30
30
  SUPPORTED_TYPES = [
31
31
  "input", "output", "filter",
32
- "buffer", "parser", "formatter", "storage"
32
+ "buffer", "parser", "formatter", "storage",
33
+ "service_discovery"
33
34
  ]
34
35
 
35
36
  DOCS_BASE_URL = "https://docs.fluentd.org/v/1.0"
@@ -43,6 +44,7 @@ class FluentPluginConfigFormatter
43
44
  @verbose = false
44
45
  @libs = []
45
46
  @plugin_dirs = []
47
+ @table = false
46
48
  @options = {}
47
49
 
48
50
  prepare_option_parser
@@ -161,9 +163,20 @@ class FluentPluginConfigFormatter
161
163
  else
162
164
  sections, params = base_section.partition {|_name, value| value[:section] }
163
165
  end
166
+ if @table && (not params.empty?)
167
+ dumped << "### Configuration\n\n"
168
+ dumped << "|parameter|type|description|default|\n"
169
+ dumped << "|---|---|---|---|\n"
170
+ end
164
171
  params.each do |name, config|
165
172
  next if name == :section
166
- template_name = @compact ? "param.md-compact.erb" : "param.md.erb"
173
+ template_name = if @compact
174
+ "param.md-compact.erb"
175
+ elsif @table
176
+ "param.md-table.erb"
177
+ else
178
+ "param.md.erb"
179
+ end
167
180
  template = template_path(template_name).read
168
181
  dumped <<
169
182
  if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
@@ -256,6 +269,9 @@ BANNER
256
269
  @parser.on("-p", "--plugin=DIR", "Add plugin directory") do |s|
257
270
  @plugin_dirs << s
258
271
  end
272
+ @parser.on("-t", "--table", "Use table syntax to dump parameters") do
273
+ @table = true
274
+ end
259
275
  end
260
276
 
261
277
  def parse_options!
@@ -105,7 +105,7 @@ Generate a project skeleton for creating a Fluentd plugin
105
105
 
106
106
  Arguments:
107
107
  \ttype: #{SUPPORTED_TYPES.join(",")}
108
- \tname: Your plugin name
108
+ \tname: Your plugin name (fluent-plugin- prefix will be added to <name>)
109
109
 
110
110
  Options:
111
111
  BANNER
@@ -151,6 +151,36 @@ BANNER
151
151
  underscore_name
152
152
  end
153
153
 
154
+ def gem_file_path
155
+ File.expand_path(File.join(File.dirname(__FILE__),
156
+ "../../../",
157
+ "Gemfile"))
158
+ end
159
+
160
+ def lock_file_path
161
+ File.expand_path(File.join(File.dirname(__FILE__),
162
+ "../../../",
163
+ "Gemfile.lock"))
164
+ end
165
+
166
+ def locked_gem_version(gem_name)
167
+ d = Bundler::Definition.build(gem_file_path, lock_file_path, false)
168
+ d.locked_gems.dependencies[gem_name].requirement.requirements.first.last.version
169
+ end
170
+
171
+ def rake_version
172
+ locked_gem_version("rake")
173
+ end
174
+
175
+ def test_unit_version
176
+ locked_gem_version("test-unit")
177
+ end
178
+
179
+ def bundler_version
180
+ d = Bundler::Definition.build(gem_file_path, lock_file_path, false)
181
+ d.locked_gems.bundler_version.version
182
+ end
183
+
154
184
  def class_name
155
185
  "#{capitalized_name}#{type.capitalize}"
156
186
  end
@@ -244,10 +244,10 @@ module Fluent
244
244
  end
245
245
 
246
246
  def convert_value_to_nil(value)
247
- if value and @null_empty_string
247
+ if value && @null_empty_string
248
248
  value = (value == '') ? nil : value
249
249
  end
250
- if value and @null_value_pattern
250
+ if value && @null_value_pattern
251
251
  value = ::Fluent::StringUtil.match_regexp(@null_value_pattern, value) ? nil : value
252
252
  end
253
253
  value
@@ -179,7 +179,7 @@ module Fluent
179
179
  end
180
180
 
181
181
  if section_params[varname].nil?
182
- unless proxy.defaults.has_key?(varname) and proxy.defaults[varname].nil?
182
+ unless proxy.defaults.has_key?(varname) && proxy.defaults[varname].nil?
183
183
  logger.error "config error in:\n#{conf}" if logger
184
184
  raise ConfigError, "'#{name}' parameter is required but nil is specified"
185
185
  end
@@ -247,7 +247,7 @@ module Fluent
247
247
  def self.check_unused_section(proxy, conf, plugin_class)
248
248
  elems = conf.respond_to?(:elements) ? conf.elements : []
249
249
  elems.each { |e|
250
- next if plugin_class.nil? && Fluent::Config::V1Parser::ELEM_SYMBOLS.include?(e.name) # skip pre-defined non-plugin elements because it doens't have proxy section
250
+ next if plugin_class.nil? && Fluent::Config::V1Parser::ELEM_SYMBOLS.include?(e.name) # skip pre-defined non-plugin elements because it doesn't have proxy section
251
251
  next if e.unused_in && e.unused_in.empty? # the section is used at least once
252
252
 
253
253
  if proxy.sections.any? { |name, subproxy| e.name == subproxy.name.to_s || e.name == subproxy.alias.to_s }
@@ -186,7 +186,7 @@ module Fluent
186
186
  return nil if val.nil?
187
187
 
188
188
  param = if val.is_a?(String)
189
- val.start_with?('{') ? JSON.load(val) : Hash[val.strip.split(/\s*,\s*/).map{|v| v.split(':', 2)}]
189
+ val.start_with?('{') ? JSON.parse(val) : Hash[val.strip.split(/\s*,\s*/).map{|v| v.split(':', 2)}]
190
190
  else
191
191
  val
192
192
  end
@@ -213,7 +213,7 @@ module Fluent
213
213
  return nil if val.nil?
214
214
 
215
215
  param = if val.is_a?(String)
216
- val.start_with?('[') ? JSON.load(val) : val.strip.split(/\s*,\s*/)
216
+ val.start_with?('[') ? JSON.parse(val) : val.strip.split(/\s*,\s*/)
217
217
  else
218
218
  val
219
219
  end
data/lib/fluent/env.rb CHANGED
@@ -28,4 +28,8 @@ module Fluent
28
28
  def self.windows?
29
29
  ServerEngine.windows?
30
30
  end
31
+
32
+ def self.linux?
33
+ /linux/ === RUBY_PLATFORM
34
+ end
31
35
  end
data/lib/fluent/event.rb CHANGED
@@ -254,19 +254,9 @@ module Fluent
254
254
  end
255
255
 
256
256
  def each(unpacker: nil, &block)
257
- if @unpacked_times
258
- @unpacked_times.each_with_index do |time, i|
259
- block.call(time, @unpacked_records[i])
260
- end
261
- else
262
- @unpacked_times = []
263
- @unpacked_records = []
264
- (unpacker || Fluent::MessagePackFactory.msgpack_unpacker).feed_each(@data) do |time, record|
265
- @unpacked_times << time
266
- @unpacked_records << record
267
- block.call(time, record)
268
- end
269
- @size = @unpacked_times.size
257
+ ensure_unpacked!(unpacker: unpacker)
258
+ @unpacked_times.each_with_index do |time, i|
259
+ block.call(time, @unpacked_records[i])
270
260
  end
271
261
  nil
272
262
  end
data/lib/fluent/load.rb CHANGED
@@ -1,4 +1,3 @@
1
- require 'thread'
2
1
  require 'socket'
3
2
  require 'fcntl'
4
3
  require 'time'
data/lib/fluent/plugin.rb CHANGED
@@ -121,6 +121,11 @@ module Fluent
121
121
  new_impl('sd', SD_REGISTRY, type, parent)
122
122
  end
123
123
 
124
+ class << self
125
+ # This should be defined for fluent-plugin-config-formatter type arguments.
126
+ alias_method :new_service_discovery, :new_sd
127
+ end
128
+
124
129
  def self.new_parser(type, parent: nil)
125
130
  if type[0] == '/' && type[-1] == '/'
126
131
  # This usage is not recommended for new API... create RegexpParser directly
@@ -143,33 +143,14 @@ module Fluent
143
143
  end
144
144
  end
145
145
 
146
- # timekey should be unixtime as usual.
147
- # So, unixtime should be bigger than 2^30 - 1 (= 1073741823) nowadays.
148
- # We should check object_id stability to use object_id as optimization for comparing operations.
149
- # e.g.)
150
- # irb> Time.parse("2020/07/31 18:30:00+09:00").to_i
151
- # => 1596187800
152
- # irb> Time.parse("2020/07/31 18:30:00+09:00").to_i > 2**30 -1
153
- # => true
154
- def self.enable_optimize?
155
- a1 = 2**30 - 1
156
- a2 = 2**30 - 1
157
- b1 = 2**62 - 1
158
- b2 = 2**62 - 1
159
- (a1.object_id == a2.object_id) && (b1.object_id == b2.object_id)
160
- end
161
-
162
146
  # This is an optimization code. Current Struct's implementation is comparing all data.
163
147
  # https://github.com/ruby/ruby/blob/0623e2b7cc621b1733a760b72af246b06c30cf96/struct.c#L1200-L1203
164
148
  # Actually this overhead is very small but this class is generated *per chunk* (and used in hash object).
165
149
  # This means that this class is one of the most called object in Fluentd.
166
150
  # See https://github.com/fluent/fluentd/pull/2560
167
- # But, this optimization has a side effect on Windows and 32bit environment(s) due to differing object_id.
168
- # This difference causes flood of buffer files.
169
- # So, this optimization should be enabled on `enable_optimize?` as true platforms.
170
151
  def hash
171
- timekey.object_id
172
- end if enable_optimize?
152
+ timekey.hash
153
+ end
173
154
  end
174
155
 
175
156
  # for tests
@@ -46,6 +46,42 @@ module Fluent
46
46
  end
47
47
  end
48
48
 
49
+ class Win32Error < StandardError
50
+ require 'windows/error'
51
+ include Windows::Error
52
+
53
+ attr_reader :errcode, :msg
54
+
55
+ def initialize(errcode, msg = nil)
56
+ @errcode = errcode
57
+ @msg = msg
58
+ end
59
+
60
+ def format_english_message(errcode)
61
+ buf = 0.chr * 260
62
+ flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY
63
+ english_lang_id = 1033 # The result of MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)
64
+ FormatMessageA.call(flags, 0, errcode, english_lang_id, buf, buf.size, 0)
65
+ buf.force_encoding(Encoding.default_external).strip
66
+ end
67
+
68
+ def to_s
69
+ msg = super
70
+ msg << ": code: #{@errcode}, #{format_english_message(@errcode)}"
71
+ msg << " - #{@msg}" if @msg
72
+ msg
73
+ end
74
+
75
+ def inspect
76
+ "#<#{to_s}>"
77
+ end
78
+
79
+ def ==(other)
80
+ return false if other.class != Win32Error
81
+ @errcode == other.errcode && @msg == other.msg
82
+ end
83
+ end
84
+
49
85
  # To open and get stat with setting FILE_SHARE_DELETE
50
86
  class WindowsFile
51
87
  require 'windows/file'
@@ -77,11 +113,11 @@ module Fluent
77
113
  @file_handle = CreateFile.call(@path, access, sharemode,
78
114
  0, creationdisposition, FILE_ATTRIBUTE_NORMAL, 0)
79
115
  if @file_handle == INVALID_HANDLE_VALUE
80
- err = GetLastError.call
116
+ err = Win32::API.last_error
81
117
  if err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND || err == ERROR_ACCESS_DENIED
82
- raise SystemCallError.new(2)
118
+ raise Errno::ENOENT
83
119
  end
84
- raise SystemCallError.new(err)
120
+ raise Win32Error.new(err, path)
85
121
  end
86
122
  end
87
123
 
@@ -63,9 +63,9 @@ module Fluent
63
63
  super
64
64
  @newline = case newline
65
65
  when :lf
66
- "\n"
66
+ "\n".freeze
67
67
  when :crlf
68
- "\r\n"
68
+ "\r\n".freeze
69
69
  end
70
70
  end
71
71
  end
@@ -27,7 +27,7 @@ module Fluent
27
27
  helpers :record_accessor
28
28
 
29
29
  config_param :delimiter, default: ',' do |val|
30
- ['\t', 'TAB'].include?(val) ? "\t" : val
30
+ ['\t', 'TAB'].include?(val) ? "\t".freeze : val.freeze
31
31
  end
32
32
  config_param :force_quotes, :bool, default: true
33
33
  # "array" looks good for type of :fields, but this implementation removes tailing comma
@@ -27,7 +27,7 @@ module Fluent
27
27
 
28
28
  def format(tag, time, record)
29
29
  line = record.to_s
30
- line << @newline.freeze if @add_newline
30
+ line << @newline if @add_newline
31
31
  line
32
32
  end
33
33
  end
@@ -25,18 +25,18 @@ module Fluent
25
25
 
26
26
  # http://ltsv.org/
27
27
 
28
- config_param :delimiter, :string, default: "\t"
29
- config_param :label_delimiter, :string, default: ":"
28
+ config_param :delimiter, :string, default: "\t".freeze
29
+ config_param :label_delimiter, :string, default: ":".freeze
30
+ config_param :replacement, :string, default: " ".freeze
30
31
  config_param :add_newline, :bool, default: true
31
32
 
32
- # TODO: escaping for \t in values
33
33
  def format(tag, time, record)
34
34
  formatted = ""
35
35
  record.each do |label, value|
36
36
  formatted << @delimiter if formatted.length.nonzero?
37
- formatted << "#{label}#{@label_delimiter}#{value}"
37
+ formatted << "#{label}#{@label_delimiter}#{value.to_s.gsub(@delimiter, @replacement)}"
38
38
  end
39
- formatted << @newline.freeze if @add_newline
39
+ formatted << @newline if @add_newline
40
40
  formatted
41
41
  end
42
42
  end
@@ -29,9 +29,9 @@ module Fluent
29
29
  config_param :output_tag, :bool, default: true
30
30
  config_param :delimiter, default: "\t" do |val|
31
31
  case val
32
- when /SPACE/i then ' '
33
- when /COMMA/i then ','
34
- else "\t"
32
+ when /SPACE/i then ' '.freeze
33
+ when /COMMA/i then ','.freeze
34
+ else "\t".freeze
35
35
  end
36
36
  end
37
37
  config_set_default :time_type, :string
@@ -23,12 +23,12 @@ module Fluent
23
23
 
24
24
  Plugin.register_formatter('single_value', self)
25
25
 
26
- config_param :message_key, :string, default: 'message'
26
+ config_param :message_key, :string, default: 'message'.freeze
27
27
  config_param :add_newline, :bool, default: true
28
28
 
29
29
  def format(tag, time, record)
30
30
  text = record[@message_key].to_s.dup
31
- text << @newline.freeze if @add_newline
31
+ text << @newline if @add_newline
32
32
  text
33
33
  end
34
34
  end
@@ -26,13 +26,13 @@ module Fluent
26
26
  desc 'Field names included in each lines'
27
27
  config_param :keys, :array, value_type: :string
28
28
  desc 'The delimiter character (or string) of TSV values'
29
- config_param :delimiter, :string, default: "\t"
29
+ config_param :delimiter, :string, default: "\t".freeze
30
30
  desc 'The parameter to enable writing to new lines'
31
31
  config_param :add_newline, :bool, default: true
32
32
 
33
33
  def format(tag, time, record)
34
34
  formatted = @keys.map{|k| record[k].to_s }.join(@delimiter)
35
- formatted << @newline.freeze if @add_newline
35
+ formatted << @newline if @add_newline
36
36
  formatted
37
37
  end
38
38
  end
@@ -80,6 +80,8 @@ module Fluent::Plugin
80
80
  config_param :use_204_response, :bool, default: false
81
81
  desc 'Dump error log or not'
82
82
  config_param :dump_error_log, :bool, default: true
83
+ desc 'Add QUERY_ prefix query params to record'
84
+ config_param :add_query_params, :bool, default: false
83
85
 
84
86
  config_section :parse do
85
87
  config_set_default :@type, 'in_http'
@@ -277,7 +279,7 @@ module Fluent::Plugin
277
279
  private
278
280
 
279
281
  def on_server_connect(conn)
280
- handler = Handler.new(conn, @km, method(:on_request), @body_size_limit, @format_name, log, @cors_allow_origins)
282
+ handler = Handler.new(conn, @km, method(:on_request), @body_size_limit, @format_name, log, @cors_allow_origins, @add_query_params)
281
283
 
282
284
  conn.on(:data) do |data|
283
285
  handler.on_read(data)
@@ -326,6 +328,14 @@ module Fluent::Plugin
326
328
  }
327
329
  end
328
330
 
331
+ if @add_query_params
332
+ params.each_pair { |k, v|
333
+ if k.start_with?("QUERY_".freeze)
334
+ record[k] = v
335
+ end
336
+ }
337
+ end
338
+
329
339
  if @add_remote_addr
330
340
  record['REMOTE_ADDR'] = params['REMOTE_ADDR']
331
341
  end
@@ -346,7 +356,7 @@ module Fluent::Plugin
346
356
  class Handler
347
357
  attr_reader :content_type
348
358
 
349
- def initialize(io, km, callback, body_size_limit, format_name, log, cors_allow_origins)
359
+ def initialize(io, km, callback, body_size_limit, format_name, log, cors_allow_origins, add_query_params)
350
360
  @io = io
351
361
  @km = km
352
362
  @callback = callback
@@ -356,6 +366,7 @@ module Fluent::Plugin
356
366
  @log = log
357
367
  @cors_allow_origins = cors_allow_origins
358
368
  @idle = 0
369
+ @add_query_params = add_query_params
359
370
  @km.add(self)
360
371
 
361
372
  @remote_port, @remote_addr = io.remote_port, io.remote_addr
@@ -492,7 +503,7 @@ module Fluent::Plugin
492
503
  # For every incoming request, we check if we have some CORS
493
504
  # restrictions and allow listed origins through @cors_allow_origins.
494
505
  unless @cors_allow_origins.nil?
495
- unless @cors_allow_origins.include?('*') or include_cors_allow_origin
506
+ unless @cors_allow_origins.include?('*') || include_cors_allow_origin
496
507
  send_response_and_close(RES_403_STATUS, {'Connection' => 'close'}, "")
497
508
  return
498
509
  end
@@ -533,7 +544,17 @@ module Fluent::Plugin
533
544
  end
534
545
  path_info = uri.path
535
546
 
547
+ if (@add_query_params)
548
+
549
+ query_params = WEBrick::HTTPUtils.parse_query(uri.query)
550
+
551
+ query_params.each_pair {|k,v|
552
+ params["QUERY_#{k.gsub('-','_').upcase}"] = v
553
+ }
554
+ end
555
+
536
556
  params.merge!(@env)
557
+
537
558
  @env.clear
538
559
 
539
560
  code, header, body = @callback.call(path_info, params)