fluentd 1.11.3 → 1.12.0
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.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
- data/.github/ISSUE_TEMPLATE/config.yml +5 -0
- data/.github/workflows/stale-actions.yml +22 -0
- data/.travis.yml +22 -2
- data/CHANGELOG.md +66 -0
- data/README.md +1 -1
- data/appveyor.yml +3 -0
- data/bin/fluent-cap-ctl +7 -0
- data/bin/fluent-ctl +7 -0
- data/fluentd.gemspec +2 -1
- data/lib/fluent/capability.rb +87 -0
- data/lib/fluent/command/cap_ctl.rb +174 -0
- data/lib/fluent/command/ctl.rb +177 -0
- data/lib/fluent/command/plugin_config_formatter.rb +2 -1
- data/lib/fluent/env.rb +4 -0
- data/lib/fluent/plugin.rb +5 -0
- data/lib/fluent/plugin/buffer.rb +2 -21
- data/lib/fluent/plugin/formatter.rb +24 -0
- data/lib/fluent/plugin/formatter_csv.rb +1 -1
- data/lib/fluent/plugin/formatter_hash.rb +3 -1
- data/lib/fluent/plugin/formatter_json.rb +3 -1
- data/lib/fluent/plugin/formatter_ltsv.rb +5 -3
- data/lib/fluent/plugin/formatter_out_file.rb +6 -4
- data/lib/fluent/plugin/formatter_single_value.rb +4 -2
- data/lib/fluent/plugin/formatter_tsv.rb +4 -2
- data/lib/fluent/plugin/in_http.rb +23 -2
- data/lib/fluent/plugin/in_tail.rb +109 -41
- data/lib/fluent/plugin/in_tail/position_file.rb +39 -14
- data/lib/fluent/plugin/in_tcp.rb +1 -0
- data/lib/fluent/plugin/out_http.rb +20 -2
- data/lib/fluent/plugin/output.rb +14 -6
- data/lib/fluent/plugin_helper/http_server/compat/server.rb +1 -1
- data/lib/fluent/plugin_helper/inject.rb +4 -1
- data/lib/fluent/plugin_helper/retry_state.rb +4 -0
- data/lib/fluent/supervisor.rb +140 -43
- data/lib/fluent/time.rb +1 -0
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +22 -4
- data/test/command/test_binlog_reader.rb +22 -6
- data/test/command/test_cap_ctl.rb +100 -0
- data/test/command/test_ctl.rb +57 -0
- data/test/command/test_plugin_config_formatter.rb +57 -2
- data/test/plugin/in_tail/test_position_file.rb +45 -25
- data/test/plugin/test_filter_stdout.rb +6 -1
- data/test/plugin/test_formatter_hash.rb +6 -3
- data/test/plugin/test_formatter_json.rb +14 -4
- data/test/plugin/test_formatter_ltsv.rb +13 -5
- data/test/plugin/test_formatter_out_file.rb +35 -14
- data/test/plugin/test_formatter_single_value.rb +12 -6
- data/test/plugin/test_formatter_tsv.rb +12 -4
- data/test/plugin/test_in_http.rb +25 -0
- data/test/plugin/test_in_tail.rb +430 -30
- data/test/plugin/test_out_file.rb +23 -18
- data/test/plugin/test_output.rb +12 -0
- data/test/plugin/test_parser_syslog.rb +2 -2
- data/test/plugin_helper/test_compat_parameters.rb +7 -2
- data/test/plugin_helper/test_inject.rb +42 -0
- data/test/test_capability.rb +74 -0
- data/test/test_formatter.rb +34 -10
- data/test/test_output.rb +6 -1
- data/test/test_supervisor.rb +119 -1
- metadata +33 -4
@@ -0,0 +1,177 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'optparse'
|
18
|
+
require 'fluent/env'
|
19
|
+
require 'fluent/version'
|
20
|
+
if Fluent.windows?
|
21
|
+
require 'win32/event'
|
22
|
+
require 'win32/service'
|
23
|
+
end
|
24
|
+
|
25
|
+
module Fluent
|
26
|
+
class Ctl
|
27
|
+
DEFAULT_OPTIONS = {}
|
28
|
+
|
29
|
+
if Fluent.windows?
|
30
|
+
include Windows::ServiceConstants
|
31
|
+
include Windows::ServiceStructs
|
32
|
+
include Windows::ServiceFunctions
|
33
|
+
|
34
|
+
COMMAND_MAP = {
|
35
|
+
shutdown: "",
|
36
|
+
restart: "HUP",
|
37
|
+
flush: "USR1",
|
38
|
+
reload: "USR2",
|
39
|
+
}
|
40
|
+
WINSVC_CONTROL_CODE_MAP = {
|
41
|
+
shutdown: SERVICE_CONTROL_STOP,
|
42
|
+
# 128 - 255: user-defined control code
|
43
|
+
# See https://docs.microsoft.com/en-us/windows/win32/api/winsvc/nf-winsvc-controlservice
|
44
|
+
restart: 128,
|
45
|
+
flush: 129,
|
46
|
+
reload: SERVICE_CONTROL_PARAMCHANGE,
|
47
|
+
}
|
48
|
+
else
|
49
|
+
COMMAND_MAP = {
|
50
|
+
shutdown: :TERM,
|
51
|
+
restart: :HUP,
|
52
|
+
flush: :USR1,
|
53
|
+
reload: :USR2,
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
def initialize(argv = ARGV)
|
58
|
+
@argv = argv
|
59
|
+
@options = {}
|
60
|
+
@opt_parser = OptionParser.new
|
61
|
+
configure_option_parser
|
62
|
+
@options.merge!(DEFAULT_OPTIONS)
|
63
|
+
parse_options!
|
64
|
+
end
|
65
|
+
|
66
|
+
def help_text
|
67
|
+
text = "\n"
|
68
|
+
if Fluent.windows?
|
69
|
+
text << "Usage: #{$PROGRAM_NAME} COMMAND [PID_OR_SVCNAME]\n"
|
70
|
+
else
|
71
|
+
text << "Usage: #{$PROGRAM_NAME} COMMAND PID\n"
|
72
|
+
end
|
73
|
+
text << "\n"
|
74
|
+
text << "Commands: \n"
|
75
|
+
COMMAND_MAP.each do |key, value|
|
76
|
+
text << " #{key}\n"
|
77
|
+
end
|
78
|
+
text
|
79
|
+
end
|
80
|
+
|
81
|
+
def usage(msg = nil)
|
82
|
+
puts help_text
|
83
|
+
if msg
|
84
|
+
puts
|
85
|
+
puts "Error: #{msg}"
|
86
|
+
end
|
87
|
+
exit 1
|
88
|
+
end
|
89
|
+
|
90
|
+
def call
|
91
|
+
if Fluent.windows?
|
92
|
+
if @pid_or_svcname =~ /^[0-9]+$/
|
93
|
+
# Use as PID
|
94
|
+
return call_windows_event(@command, "fluentd_#{@pid_or_svcname}")
|
95
|
+
end
|
96
|
+
|
97
|
+
unless call_winsvc_control_code(@command, @pid_or_svcname)
|
98
|
+
puts "Cannot send control code to #{@pid_or_svcname} service, try to send an event with this name ..."
|
99
|
+
call_windows_event(@command, @pid_or_svcname)
|
100
|
+
end
|
101
|
+
else
|
102
|
+
call_signal(@command, @pid_or_svcname)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def call_signal(command, pid)
|
109
|
+
signal = COMMAND_MAP[command.to_sym]
|
110
|
+
Process.kill(signal, pid.to_i)
|
111
|
+
end
|
112
|
+
|
113
|
+
def call_winsvc_control_code(command, pid_or_svcname)
|
114
|
+
status = SERVICE_STATUS.new
|
115
|
+
|
116
|
+
begin
|
117
|
+
handle_scm = OpenSCManager(nil, nil, SC_MANAGER_CONNECT)
|
118
|
+
FFI.raise_windows_error('OpenSCManager') if handle_scm == 0
|
119
|
+
|
120
|
+
handle_scs = OpenService(handle_scm, "fluentdwinsvc", SERVICE_STOP | SERVICE_PAUSE_CONTINUE | SERVICE_USER_DEFINED_CONTROL)
|
121
|
+
FFI.raise_windows_error('OpenService') if handle_scs == 0
|
122
|
+
|
123
|
+
control_code = WINSVC_CONTROL_CODE_MAP[command.to_sym]
|
124
|
+
|
125
|
+
unless ControlService(handle_scs, control_code, status)
|
126
|
+
FFI.raise_windows_error('ControlService')
|
127
|
+
end
|
128
|
+
rescue => e
|
129
|
+
puts e
|
130
|
+
state = status[:dwCurrentState]
|
131
|
+
return state == SERVICE_STOPPED || state == SERVICE_STOP_PENDING
|
132
|
+
ensure
|
133
|
+
CloseServiceHandle(handle_scs)
|
134
|
+
CloseServiceHandle(handle_scm)
|
135
|
+
end
|
136
|
+
|
137
|
+
return true
|
138
|
+
end
|
139
|
+
|
140
|
+
def call_windows_event(command, pid_or_svcname)
|
141
|
+
prefix = pid_or_svcname
|
142
|
+
event_name = COMMAND_MAP[command.to_sym]
|
143
|
+
suffix = event_name.empty? ? "" : "_#{event_name}"
|
144
|
+
|
145
|
+
begin
|
146
|
+
event = Win32::Event.open("#{prefix}#{suffix}")
|
147
|
+
event.set
|
148
|
+
event.close
|
149
|
+
rescue Errno::ENOENT => e
|
150
|
+
puts "Error: Cannot find the fluentd process with the event name: \"#{prefix}\""
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def configure_option_parser
|
155
|
+
@opt_parser.banner = help_text
|
156
|
+
@opt_parser.version = Fluent::VERSION
|
157
|
+
end
|
158
|
+
|
159
|
+
def parse_options!
|
160
|
+
@opt_parser.parse!(@argv)
|
161
|
+
|
162
|
+
@command = @argv[0]
|
163
|
+
@pid_or_svcname = @argv[1] || "fluentdwinsvc"
|
164
|
+
|
165
|
+
usage("Command isn't specified!") if @command.nil? || @command.empty?
|
166
|
+
usage("Unknown command: #{@command}") unless COMMAND_MAP.has_key?(@command.to_sym)
|
167
|
+
|
168
|
+
if Fluent.windows?
|
169
|
+
usage("PID or SVCNAME isn't specified!") if @pid_or_svcname.nil? || @pid_or_svcname.empty?
|
170
|
+
else
|
171
|
+
usage("PID isn't specified!") if @pid_or_svcname.nil? || @pid_or_svcname.empty?
|
172
|
+
usage("Invalid PID: #{pid}") unless @pid_or_svcname =~ /^[0-9]+$/
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
@@ -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"
|
data/lib/fluent/env.rb
CHANGED
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
|
data/lib/fluent/plugin/buffer.rb
CHANGED
@@ -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.
|
172
|
-
end
|
152
|
+
timekey.hash
|
153
|
+
end
|
173
154
|
end
|
174
155
|
|
175
156
|
# for tests
|
@@ -46,5 +46,29 @@ module Fluent
|
|
46
46
|
@proc.call(tag, time, record)
|
47
47
|
end
|
48
48
|
end
|
49
|
+
|
50
|
+
module Newline
|
51
|
+
module Mixin
|
52
|
+
include Fluent::Configurable
|
53
|
+
|
54
|
+
DEFAULT_NEWLINE = if Fluent.windows?
|
55
|
+
:crlf
|
56
|
+
else
|
57
|
+
:lf
|
58
|
+
end
|
59
|
+
|
60
|
+
config_param :newline, :enum, list: [:lf, :crlf], default: DEFAULT_NEWLINE
|
61
|
+
|
62
|
+
def configure(conf)
|
63
|
+
super
|
64
|
+
@newline = case newline
|
65
|
+
when :lf
|
66
|
+
"\n".freeze
|
67
|
+
when :crlf
|
68
|
+
"\r\n".freeze
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
49
73
|
end
|
50
74
|
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
|
@@ -19,13 +19,15 @@ require 'fluent/plugin/formatter'
|
|
19
19
|
module Fluent
|
20
20
|
module Plugin
|
21
21
|
class HashFormatter < Formatter
|
22
|
+
include Fluent::Plugin::Newline::Mixin
|
23
|
+
|
22
24
|
Plugin.register_formatter('hash', self)
|
23
25
|
|
24
26
|
config_param :add_newline, :bool, default: true
|
25
27
|
|
26
28
|
def format(tag, time, record)
|
27
29
|
line = record.to_s
|
28
|
-
line <<
|
30
|
+
line << @newline if @add_newline
|
29
31
|
line
|
30
32
|
end
|
31
33
|
end
|
@@ -20,6 +20,8 @@ require 'fluent/env'
|
|
20
20
|
module Fluent
|
21
21
|
module Plugin
|
22
22
|
class JSONFormatter < Formatter
|
23
|
+
include Fluent::Plugin::Newline::Mixin
|
24
|
+
|
23
25
|
Plugin.register_formatter('json', self)
|
24
26
|
|
25
27
|
config_param :json_parser, :string, default: 'oj'
|
@@ -44,7 +46,7 @@ module Fluent
|
|
44
46
|
end
|
45
47
|
|
46
48
|
def format(tag, time, record)
|
47
|
-
"#{@dump_proc.call(record)}
|
49
|
+
"#{@dump_proc.call(record)}#{@newline}"
|
48
50
|
end
|
49
51
|
|
50
52
|
def format_without_nl(tag, time, record)
|
@@ -19,12 +19,14 @@ require 'fluent/plugin/formatter'
|
|
19
19
|
module Fluent
|
20
20
|
module Plugin
|
21
21
|
class LabeledTSVFormatter < Formatter
|
22
|
+
include Fluent::Plugin::Newline::Mixin
|
23
|
+
|
22
24
|
Plugin.register_formatter('ltsv', self)
|
23
25
|
|
24
26
|
# http://ltsv.org/
|
25
27
|
|
26
|
-
config_param :delimiter, :string, default: "\t"
|
27
|
-
config_param :label_delimiter, :string, default: ":"
|
28
|
+
config_param :delimiter, :string, default: "\t".freeze
|
29
|
+
config_param :label_delimiter, :string, default: ":".freeze
|
28
30
|
config_param :add_newline, :bool, default: true
|
29
31
|
|
30
32
|
# TODO: escaping for \t in values
|
@@ -34,7 +36,7 @@ module Fluent
|
|
34
36
|
formatted << @delimiter if formatted.length.nonzero?
|
35
37
|
formatted << "#{label}#{@label_delimiter}#{value}"
|
36
38
|
end
|
37
|
-
formatted <<
|
39
|
+
formatted << @newline if @add_newline
|
38
40
|
formatted
|
39
41
|
end
|
40
42
|
end
|
@@ -21,15 +21,17 @@ require 'yajl'
|
|
21
21
|
module Fluent
|
22
22
|
module Plugin
|
23
23
|
class OutFileFormatter < Formatter
|
24
|
+
include Fluent::Plugin::Newline::Mixin
|
25
|
+
|
24
26
|
Plugin.register_formatter('out_file', self)
|
25
27
|
|
26
28
|
config_param :output_time, :bool, default: true
|
27
29
|
config_param :output_tag, :bool, default: true
|
28
30
|
config_param :delimiter, default: "\t" do |val|
|
29
31
|
case val
|
30
|
-
when /SPACE/i then ' '
|
31
|
-
when /COMMA/i then ','
|
32
|
-
else "\t"
|
32
|
+
when /SPACE/i then ' '.freeze
|
33
|
+
when /COMMA/i then ','.freeze
|
34
|
+
else "\t".freeze
|
33
35
|
end
|
34
36
|
end
|
35
37
|
config_set_default :time_type, :string
|
@@ -44,7 +46,7 @@ module Fluent
|
|
44
46
|
header = ''
|
45
47
|
header << "#{@timef.format(time)}#{@delimiter}" if @output_time
|
46
48
|
header << "#{tag}#{@delimiter}" if @output_tag
|
47
|
-
"#{header}#{Yajl.dump(record)}
|
49
|
+
"#{header}#{Yajl.dump(record)}#{@newline}"
|
48
50
|
end
|
49
51
|
end
|
50
52
|
end
|
@@ -19,14 +19,16 @@ require 'fluent/plugin/formatter'
|
|
19
19
|
module Fluent
|
20
20
|
module Plugin
|
21
21
|
class SingleValueFormatter < Formatter
|
22
|
+
include Fluent::Plugin::Newline::Mixin
|
23
|
+
|
22
24
|
Plugin.register_formatter('single_value', self)
|
23
25
|
|
24
|
-
config_param :message_key, :string, default: 'message'
|
26
|
+
config_param :message_key, :string, default: 'message'.freeze
|
25
27
|
config_param :add_newline, :bool, default: true
|
26
28
|
|
27
29
|
def format(tag, time, record)
|
28
30
|
text = record[@message_key].to_s.dup
|
29
|
-
text <<
|
31
|
+
text << @newline if @add_newline
|
30
32
|
text
|
31
33
|
end
|
32
34
|
end
|
@@ -19,18 +19,20 @@ require 'fluent/plugin/formatter'
|
|
19
19
|
module Fluent
|
20
20
|
module Plugin
|
21
21
|
class TSVFormatter < Formatter
|
22
|
+
include Fluent::Plugin::Newline::Mixin
|
23
|
+
|
22
24
|
Plugin.register_formatter('tsv', self)
|
23
25
|
|
24
26
|
desc 'Field names included in each lines'
|
25
27
|
config_param :keys, :array, value_type: :string
|
26
28
|
desc 'The delimiter character (or string) of TSV values'
|
27
|
-
config_param :delimiter, :string, default: "\t"
|
29
|
+
config_param :delimiter, :string, default: "\t".freeze
|
28
30
|
desc 'The parameter to enable writing to new lines'
|
29
31
|
config_param :add_newline, :bool, default: true
|
30
32
|
|
31
33
|
def format(tag, time, record)
|
32
34
|
formatted = @keys.map{|k| record[k].to_s }.join(@delimiter)
|
33
|
-
formatted <<
|
35
|
+
formatted << @newline if @add_newline
|
34
36
|
formatted
|
35
37
|
end
|
36
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
|
@@ -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)
|