fluentd 0.12.40 → 0.14.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.md +6 -0
- data/.gitignore +2 -0
- data/.travis.yml +33 -21
- data/CONTRIBUTING.md +1 -0
- data/ChangeLog +810 -237
- data/README.md +0 -25
- data/Rakefile +2 -1
- data/Vagrantfile +17 -0
- data/appveyor.yml +35 -0
- data/example/filter_stdout.conf +5 -5
- data/example/in_forward.conf +2 -2
- data/example/in_http.conf +2 -2
- data/example/in_out_forward.conf +17 -0
- data/example/in_syslog.conf +2 -2
- data/example/in_tail.conf +2 -2
- data/example/in_tcp.conf +2 -2
- data/example/in_udp.conf +2 -2
- data/example/out_copy.conf +4 -4
- data/example/out_file.conf +2 -2
- data/example/out_forward.conf +2 -2
- data/example/out_forward_buf_file.conf +23 -0
- data/example/v0_12_filter.conf +8 -8
- data/fluent.conf +29 -0
- data/fluentd.gemspec +18 -11
- data/lib/fluent/agent.rb +60 -58
- data/lib/fluent/command/cat.rb +1 -1
- data/lib/fluent/command/debug.rb +7 -5
- data/lib/fluent/command/fluentd.rb +97 -2
- data/lib/fluent/compat/call_super_mixin.rb +67 -0
- data/lib/fluent/compat/filter.rb +50 -0
- data/lib/fluent/compat/formatter.rb +109 -0
- data/lib/fluent/compat/input.rb +50 -0
- data/lib/fluent/compat/output.rb +617 -0
- data/lib/fluent/compat/output_chain.rb +60 -0
- data/lib/fluent/compat/parser.rb +163 -0
- data/lib/fluent/compat/propagate_default.rb +62 -0
- data/lib/fluent/config.rb +23 -20
- data/lib/fluent/config/configure_proxy.rb +119 -70
- data/lib/fluent/config/dsl.rb +5 -18
- data/lib/fluent/config/element.rb +72 -8
- data/lib/fluent/config/error.rb +0 -3
- data/lib/fluent/config/literal_parser.rb +0 -2
- data/lib/fluent/config/parser.rb +4 -4
- data/lib/fluent/config/section.rb +39 -28
- data/lib/fluent/config/types.rb +2 -13
- data/lib/fluent/config/v1_parser.rb +1 -3
- data/lib/fluent/configurable.rb +48 -16
- data/lib/fluent/daemon.rb +15 -0
- data/lib/fluent/engine.rb +26 -52
- data/lib/fluent/env.rb +6 -4
- data/lib/fluent/event.rb +58 -11
- data/lib/fluent/event_router.rb +5 -5
- data/lib/fluent/filter.rb +2 -50
- data/lib/fluent/formatter.rb +4 -293
- data/lib/fluent/input.rb +2 -32
- data/lib/fluent/label.rb +2 -2
- data/lib/fluent/load.rb +3 -2
- data/lib/fluent/log.rb +107 -38
- data/lib/fluent/match.rb +0 -36
- data/lib/fluent/mixin.rb +117 -7
- data/lib/fluent/msgpack_factory.rb +62 -0
- data/lib/fluent/output.rb +7 -612
- data/lib/fluent/output_chain.rb +23 -0
- data/lib/fluent/parser.rb +4 -800
- data/lib/fluent/plugin.rb +100 -121
- data/lib/fluent/plugin/bare_output.rb +63 -0
- data/lib/fluent/plugin/base.rb +121 -0
- data/lib/fluent/plugin/buf_file.rb +101 -182
- data/lib/fluent/plugin/buf_memory.rb +9 -92
- data/lib/fluent/plugin/buffer.rb +473 -0
- data/lib/fluent/plugin/buffer/chunk.rb +135 -0
- data/lib/fluent/plugin/buffer/file_chunk.rb +339 -0
- data/lib/fluent/plugin/buffer/memory_chunk.rb +100 -0
- data/lib/fluent/plugin/exec_util.rb +80 -75
- data/lib/fluent/plugin/file_util.rb +33 -28
- data/lib/fluent/plugin/file_wrapper.rb +120 -0
- data/lib/fluent/plugin/filter.rb +51 -0
- data/lib/fluent/plugin/filter_grep.rb +13 -40
- data/lib/fluent/plugin/filter_record_transformer.rb +22 -18
- data/lib/fluent/plugin/formatter.rb +93 -0
- data/lib/fluent/plugin/formatter_csv.rb +48 -0
- data/lib/fluent/plugin/formatter_hash.rb +32 -0
- data/lib/fluent/plugin/formatter_json.rb +47 -0
- data/lib/fluent/plugin/formatter_ltsv.rb +42 -0
- data/lib/fluent/plugin/formatter_msgpack.rb +32 -0
- data/lib/fluent/plugin/formatter_out_file.rb +45 -0
- data/lib/fluent/plugin/formatter_single_value.rb +34 -0
- data/lib/fluent/plugin/formatter_stdout.rb +39 -0
- data/lib/fluent/plugin/in_debug_agent.rb +4 -0
- data/lib/fluent/plugin/in_dummy.rb +22 -18
- data/lib/fluent/plugin/in_exec.rb +18 -8
- data/lib/fluent/plugin/in_forward.rb +36 -79
- data/lib/fluent/plugin/in_gc_stat.rb +4 -0
- data/lib/fluent/plugin/in_http.rb +21 -18
- data/lib/fluent/plugin/in_monitor_agent.rb +15 -48
- data/lib/fluent/plugin/in_object_space.rb +6 -1
- data/lib/fluent/plugin/in_stream.rb +7 -3
- data/lib/fluent/plugin/in_syslog.rb +46 -95
- data/lib/fluent/plugin/in_tail.rb +51 -595
- data/lib/fluent/plugin/in_tcp.rb +8 -1
- data/lib/fluent/plugin/in_udp.rb +8 -14
- data/lib/fluent/plugin/input.rb +33 -0
- data/lib/fluent/plugin/multi_output.rb +95 -0
- data/lib/fluent/plugin/out_buffered_null.rb +59 -0
- data/lib/fluent/plugin/out_copy.rb +11 -7
- data/lib/fluent/plugin/out_exec.rb +15 -11
- data/lib/fluent/plugin/out_exec_filter.rb +18 -10
- data/lib/fluent/plugin/out_file.rb +34 -5
- data/lib/fluent/plugin/out_forward.rb +19 -9
- data/lib/fluent/plugin/out_null.rb +0 -14
- data/lib/fluent/plugin/out_roundrobin.rb +11 -7
- data/lib/fluent/plugin/out_stdout.rb +5 -7
- data/lib/fluent/plugin/out_stream.rb +3 -1
- data/lib/fluent/plugin/output.rb +979 -0
- data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
- data/lib/fluent/plugin/parser.rb +244 -0
- data/lib/fluent/plugin/parser_apache.rb +24 -0
- data/lib/fluent/plugin/parser_apache2.rb +84 -0
- data/lib/fluent/plugin/parser_apache_error.rb +21 -0
- data/lib/fluent/plugin/parser_csv.rb +31 -0
- data/lib/fluent/plugin/parser_json.rb +79 -0
- data/lib/fluent/plugin/parser_ltsv.rb +50 -0
- data/lib/fluent/plugin/parser_multiline.rb +102 -0
- data/lib/fluent/plugin/parser_nginx.rb +24 -0
- data/lib/fluent/plugin/parser_none.rb +36 -0
- data/lib/fluent/plugin/parser_syslog.rb +82 -0
- data/lib/fluent/plugin/parser_tsv.rb +37 -0
- data/lib/fluent/plugin/socket_util.rb +120 -114
- data/lib/fluent/plugin/storage.rb +84 -0
- data/lib/fluent/plugin/storage_local.rb +116 -0
- data/lib/fluent/plugin/string_util.rb +16 -13
- data/lib/fluent/plugin_helper.rb +39 -0
- data/lib/fluent/plugin_helper/child_process.rb +298 -0
- data/lib/fluent/plugin_helper/compat_parameters.rb +99 -0
- data/lib/fluent/plugin_helper/event_emitter.rb +80 -0
- data/lib/fluent/plugin_helper/event_loop.rb +118 -0
- data/lib/fluent/plugin_helper/retry_state.rb +177 -0
- data/lib/fluent/plugin_helper/storage.rb +308 -0
- data/lib/fluent/plugin_helper/thread.rb +147 -0
- data/lib/fluent/plugin_helper/timer.rb +85 -0
- data/lib/fluent/plugin_id.rb +63 -0
- data/lib/fluent/process.rb +21 -30
- data/lib/fluent/registry.rb +21 -9
- data/lib/fluent/root_agent.rb +115 -40
- data/lib/fluent/supervisor.rb +330 -320
- data/lib/fluent/system_config.rb +42 -18
- data/lib/fluent/test.rb +6 -1
- data/lib/fluent/test/base.rb +23 -3
- data/lib/fluent/test/driver/base.rb +247 -0
- data/lib/fluent/test/driver/event_feeder.rb +98 -0
- data/lib/fluent/test/driver/filter.rb +35 -0
- data/lib/fluent/test/driver/input.rb +31 -0
- data/lib/fluent/test/driver/output.rb +78 -0
- data/lib/fluent/test/driver/test_event_router.rb +45 -0
- data/lib/fluent/test/filter_test.rb +0 -1
- data/lib/fluent/test/formatter_test.rb +2 -1
- data/lib/fluent/test/input_test.rb +23 -17
- data/lib/fluent/test/output_test.rb +28 -39
- data/lib/fluent/test/parser_test.rb +1 -1
- data/lib/fluent/time.rb +104 -1
- data/lib/fluent/{status.rb → unique_id.rb} +15 -24
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +72 -0
- data/test/compat/test_calls_super.rb +164 -0
- data/test/config/test_config_parser.rb +83 -0
- data/test/config/test_configurable.rb +547 -274
- data/test/config/test_configure_proxy.rb +146 -29
- data/test/config/test_dsl.rb +3 -181
- data/test/config/test_element.rb +274 -0
- data/test/config/test_literal_parser.rb +1 -1
- data/test/config/test_section.rb +79 -7
- data/test/config/test_system_config.rb +21 -0
- data/test/config/test_types.rb +3 -26
- data/test/helper.rb +78 -8
- data/test/plugin/test_bare_output.rb +118 -0
- data/test/plugin/test_base.rb +75 -0
- data/test/plugin/test_buf_file.rb +420 -521
- data/test/plugin/test_buf_memory.rb +32 -194
- data/test/plugin/test_buffer.rb +981 -0
- data/test/plugin/test_buffer_chunk.rb +110 -0
- data/test/plugin/test_buffer_file_chunk.rb +770 -0
- data/test/plugin/test_buffer_memory_chunk.rb +265 -0
- data/test/plugin/test_filter.rb +255 -0
- data/test/plugin/test_filter_grep.rb +2 -73
- data/test/plugin/test_filter_record_transformer.rb +24 -68
- data/test/plugin/test_filter_stdout.rb +6 -6
- data/test/plugin/test_in_debug_agent.rb +2 -0
- data/test/plugin/test_in_dummy.rb +11 -17
- data/test/plugin/test_in_exec.rb +6 -25
- data/test/plugin/test_in_forward.rb +112 -151
- data/test/plugin/test_in_gc_stat.rb +2 -0
- data/test/plugin/test_in_http.rb +106 -157
- data/test/plugin/test_in_object_space.rb +21 -5
- data/test/plugin/test_in_stream.rb +14 -13
- data/test/plugin/test_in_syslog.rb +30 -275
- data/test/plugin/test_in_tail.rb +95 -234
- data/test/plugin/test_in_tcp.rb +14 -0
- data/test/plugin/test_in_udp.rb +21 -13
- data/test/plugin/test_input.rb +122 -0
- data/test/plugin/test_multi_output.rb +180 -0
- data/test/plugin/test_out_buffered_null.rb +79 -0
- data/test/plugin/test_out_copy.rb +15 -2
- data/test/plugin/test_out_exec.rb +75 -25
- data/test/plugin/test_out_exec_filter.rb +74 -8
- data/test/plugin/test_out_file.rb +61 -7
- data/test/plugin/test_out_forward.rb +92 -15
- data/test/plugin/test_out_roundrobin.rb +1 -0
- data/test/plugin/test_out_stdout.rb +22 -13
- data/test/plugin/test_out_stream.rb +18 -0
- data/test/plugin/test_output.rb +515 -0
- data/test/plugin/test_output_as_buffered.rb +1540 -0
- data/test/plugin/test_output_as_buffered_overflow.rb +247 -0
- data/test/plugin/test_output_as_buffered_retries.rb +808 -0
- data/test/plugin/test_output_as_buffered_secondary.rb +776 -0
- data/test/plugin/test_output_as_standard.rb +362 -0
- data/test/plugin/test_owned_by.rb +35 -0
- data/test/plugin/test_storage.rb +167 -0
- data/test/plugin/test_storage_local.rb +8 -0
- data/test/plugin_helper/test_child_process.rb +599 -0
- data/test/plugin_helper/test_compat_parameters.rb +175 -0
- data/test/plugin_helper/test_event_emitter.rb +51 -0
- data/test/plugin_helper/test_event_loop.rb +52 -0
- data/test/plugin_helper/test_retry_state.rb +399 -0
- data/test/plugin_helper/test_storage.rb +411 -0
- data/test/plugin_helper/test_thread.rb +164 -0
- data/test/plugin_helper/test_timer.rb +100 -0
- data/test/scripts/exec_script.rb +0 -6
- data/test/scripts/fluent/plugin/out_test.rb +3 -0
- data/test/test_config.rb +13 -4
- data/test/test_event.rb +24 -13
- data/test/test_event_router.rb +8 -7
- data/test/test_event_time.rb +187 -0
- data/test/test_formatter.rb +13 -51
- data/test/test_input.rb +1 -1
- data/test/test_log.rb +239 -16
- data/test/test_mixin.rb +1 -1
- data/test/test_output.rb +53 -66
- data/test/test_parser.rb +105 -323
- data/test/test_plugin_helper.rb +81 -0
- data/test/test_root_agent.rb +4 -52
- data/test/test_supervisor.rb +272 -0
- data/test/test_unique_id.rb +47 -0
- metadata +180 -54
- data/lib/fluent/buffer.rb +0 -365
- data/lib/fluent/plugin/filter_parser.rb +0 -107
- data/lib/fluent/plugin/in_status.rb +0 -76
- data/lib/fluent/test/helpers.rb +0 -86
- data/test/plugin/data/log/foo/bar2 +0 -0
- data/test/plugin/test_filter_parser.rb +0 -744
- data/test/plugin/test_in_status.rb +0 -38
- data/test/test_buffer.rb +0 -624
@@ -0,0 +1,79 @@
|
|
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 'fluent/plugin/parser'
|
18
|
+
require 'fluent/time'
|
19
|
+
|
20
|
+
require 'yajl'
|
21
|
+
|
22
|
+
module Fluent
|
23
|
+
module Plugin
|
24
|
+
class JSONParser < Parser
|
25
|
+
Plugin.register_parser('json', self)
|
26
|
+
|
27
|
+
config_param :time_key, :string, default: 'time'
|
28
|
+
config_param :time_format, :string, default: nil
|
29
|
+
config_param :json_parser, :string, default: 'oj'
|
30
|
+
|
31
|
+
def configure(conf)
|
32
|
+
super
|
33
|
+
|
34
|
+
unless @time_format.nil?
|
35
|
+
@time_parser = TimeParser.new(@time_format)
|
36
|
+
@mutex = Mutex.new
|
37
|
+
end
|
38
|
+
|
39
|
+
begin
|
40
|
+
raise LoadError unless @json_parser == 'oj'
|
41
|
+
require 'oj'
|
42
|
+
Oj.default_options = {bigdecimal_load: :float}
|
43
|
+
@load_proc = Oj.method(:load)
|
44
|
+
@error_class = Oj::ParseError
|
45
|
+
rescue LoadError
|
46
|
+
@load_proc = Yajl.method(:load)
|
47
|
+
@error_class = Yajl::ParseError
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def parse(text)
|
52
|
+
record = @load_proc.call(text)
|
53
|
+
|
54
|
+
value = @keep_time_key ? record[@time_key] : record.delete(@time_key)
|
55
|
+
if value
|
56
|
+
if @time_format
|
57
|
+
time = @mutex.synchronize { @time_parser.parse(value) }
|
58
|
+
else
|
59
|
+
begin
|
60
|
+
time = Fluent::EventTime.from_time(Time.at(value.to_f))
|
61
|
+
rescue => e
|
62
|
+
raise ParserError, "invalid time value: value = #{value}, error_class = #{e.class.name}, error = #{e.message}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
else
|
66
|
+
if @estimate_current_event
|
67
|
+
time = Fluent::EventTime.now
|
68
|
+
else
|
69
|
+
time = nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
yield time, record
|
74
|
+
rescue @error_class
|
75
|
+
yield nil, nil
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,50 @@
|
|
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 'fluent/plugin/parser'
|
18
|
+
require 'fluent/time'
|
19
|
+
|
20
|
+
module Fluent
|
21
|
+
module Plugin
|
22
|
+
class LabeledTSVParser < ValuesParser
|
23
|
+
Plugin.register_parser('ltsv', self)
|
24
|
+
|
25
|
+
config_param :delimiter, :string, default: "\t"
|
26
|
+
config_param :label_delimiter, :string, default: ":"
|
27
|
+
config_param :time_key, :string, default: "time"
|
28
|
+
|
29
|
+
def configure(conf)
|
30
|
+
# this assignment is not to raise ConfigError in ValuesParser#configure
|
31
|
+
conf['keys'] = conf['time_key'] || 'time'
|
32
|
+
super(conf)
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse(text)
|
36
|
+
# TODO: thread unsafe: @keys might be changed by other threads
|
37
|
+
@keys = []
|
38
|
+
values = []
|
39
|
+
|
40
|
+
text.split(delimiter).each do |pair|
|
41
|
+
key, value = pair.split(label_delimiter, 2)
|
42
|
+
@keys.push(key)
|
43
|
+
values.push(value)
|
44
|
+
end
|
45
|
+
|
46
|
+
yield values_map(values)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,102 @@
|
|
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 'fluent/plugin/parser'
|
18
|
+
|
19
|
+
module Fluent
|
20
|
+
module Plugin
|
21
|
+
class MultilineParser < Parser
|
22
|
+
Plugin.register_parser('multiline', self)
|
23
|
+
|
24
|
+
config_param :format_firstline, :string, default: nil
|
25
|
+
|
26
|
+
FORMAT_MAX_NUM = 20
|
27
|
+
|
28
|
+
def configure(conf)
|
29
|
+
super
|
30
|
+
|
31
|
+
formats = parse_formats(conf).compact.map { |f| f[1..-2] }.join
|
32
|
+
begin
|
33
|
+
@regex = Regexp.new(formats, Regexp::MULTILINE)
|
34
|
+
if @regex.named_captures.empty?
|
35
|
+
raise "No named captures"
|
36
|
+
end
|
37
|
+
@parser = RegexpParser.new(@regex, conf)
|
38
|
+
rescue => e
|
39
|
+
raise ConfigError, "Invalid regexp '#{formats}': #{e}"
|
40
|
+
end
|
41
|
+
|
42
|
+
if @format_firstline
|
43
|
+
check_format_regexp(@format_firstline, 'format_firstline')
|
44
|
+
@firstline_regex = Regexp.new(@format_firstline[1..-2])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def parse(text, &block)
|
49
|
+
@parser.call(text, &block)
|
50
|
+
end
|
51
|
+
|
52
|
+
def has_firstline?
|
53
|
+
!!@format_firstline
|
54
|
+
end
|
55
|
+
|
56
|
+
def firstline?(text)
|
57
|
+
@firstline_regex.match(text)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def parse_formats(conf)
|
63
|
+
check_format_range(conf)
|
64
|
+
|
65
|
+
prev_format = nil
|
66
|
+
(1..FORMAT_MAX_NUM).map { |i|
|
67
|
+
format = conf["format#{i}"]
|
68
|
+
if (i > 1) && prev_format.nil? && !format.nil?
|
69
|
+
raise ConfigError, "Jump of format index found. format#{i - 1} is missing."
|
70
|
+
end
|
71
|
+
prev_format = format
|
72
|
+
next if format.nil?
|
73
|
+
|
74
|
+
check_format_regexp(format, "format#{i}")
|
75
|
+
format
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
def check_format_range(conf)
|
80
|
+
invalid_formats = conf.keys.select { |k|
|
81
|
+
m = k.match(/^format(\d+)$/)
|
82
|
+
m ? !((1..FORMAT_MAX_NUM).include?(m[1].to_i)) : false
|
83
|
+
}
|
84
|
+
unless invalid_formats.empty?
|
85
|
+
raise ConfigError, "Invalid formatN found. N should be 1 - #{FORMAT_MAX_NUM}: " + invalid_formats.join(",")
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def check_format_regexp(format, key)
|
90
|
+
if format[0] == '/' && format[-1] == '/'
|
91
|
+
begin
|
92
|
+
Regexp.new(format[1..-2], Regexp::MULTILINE)
|
93
|
+
rescue => e
|
94
|
+
raise ConfigError, "Invalid regexp in #{key}: #{e}"
|
95
|
+
end
|
96
|
+
else
|
97
|
+
raise ConfigError, "format should be Regexp, need //, in #{key}: '#{format}'"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,24 @@
|
|
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 'fluent/plugin/parser'
|
18
|
+
|
19
|
+
Fluent::Plugin.register_parser('nginx', Proc.new {
|
20
|
+
Fluent::Plugin::RegexpParser.new(
|
21
|
+
/^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/,
|
22
|
+
{'time_format'=>"%d/%b/%Y:%H:%M:%S %z"}
|
23
|
+
)
|
24
|
+
})
|
@@ -0,0 +1,36 @@
|
|
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 'fluent/plugin/parser'
|
18
|
+
|
19
|
+
require 'fluent/time'
|
20
|
+
|
21
|
+
module Fluent
|
22
|
+
module Plugin
|
23
|
+
class NoneParser < Parser
|
24
|
+
Plugin.register_parser('none', self)
|
25
|
+
|
26
|
+
config_param :message_key, :string, default: 'message'
|
27
|
+
|
28
|
+
def parse(text)
|
29
|
+
record = {}
|
30
|
+
record[@message_key] = text
|
31
|
+
time = @estimate_current_event ? Fluent::EventTime.now : nil
|
32
|
+
yield time, record
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,82 @@
|
|
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 'fluent/plugin/parser'
|
18
|
+
|
19
|
+
require 'fluent/time'
|
20
|
+
|
21
|
+
module Fluent
|
22
|
+
module Plugin
|
23
|
+
class SyslogParser < Parser
|
24
|
+
Plugin.register_parser('syslog', self)
|
25
|
+
|
26
|
+
# From existence TextParser pattern
|
27
|
+
REGEXP = /^(?<time>[^ ]*\s*[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$/
|
28
|
+
# From in_syslog default pattern
|
29
|
+
REGEXP_WITH_PRI = /^\<(?<pri>[0-9]+)\>(?<time>[^ ]* {1,2}[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$/
|
30
|
+
|
31
|
+
config_param :time_format, :string, default: "%b %d %H:%M:%S"
|
32
|
+
config_param :with_priority, :bool, default: false
|
33
|
+
|
34
|
+
def initialize
|
35
|
+
super
|
36
|
+
@mutex = Mutex.new
|
37
|
+
end
|
38
|
+
|
39
|
+
def configure(conf)
|
40
|
+
super
|
41
|
+
|
42
|
+
@regexp = @with_priority ? REGEXP_WITH_PRI : REGEXP
|
43
|
+
@time_parser = TimeParser.new(@time_format)
|
44
|
+
end
|
45
|
+
|
46
|
+
def patterns
|
47
|
+
{'format' => @regexp, 'time_format' => @time_format}
|
48
|
+
end
|
49
|
+
|
50
|
+
def parse(text)
|
51
|
+
m = @regexp.match(text)
|
52
|
+
unless m
|
53
|
+
yield nil, nil
|
54
|
+
return
|
55
|
+
end
|
56
|
+
|
57
|
+
time = nil
|
58
|
+
record = {}
|
59
|
+
|
60
|
+
m.names.each { |name|
|
61
|
+
if value = m[name]
|
62
|
+
case name
|
63
|
+
when "pri"
|
64
|
+
record['pri'] = value.to_i
|
65
|
+
when "time"
|
66
|
+
time = @mutex.synchronize { @time_parser.parse(value.gsub(/ +/, ' ')) }
|
67
|
+
record[name] = value if @keep_time_key
|
68
|
+
else
|
69
|
+
record[name] = value
|
70
|
+
end
|
71
|
+
end
|
72
|
+
}
|
73
|
+
|
74
|
+
if @estimate_current_event
|
75
|
+
time ||= Fluent::EventTime.now
|
76
|
+
end
|
77
|
+
|
78
|
+
yield time, record
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,37 @@
|
|
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 'fluent/plugin/parser'
|
18
|
+
require 'fluent/time'
|
19
|
+
|
20
|
+
module Fluent
|
21
|
+
module Plugin
|
22
|
+
class TSVParser < ValuesParser
|
23
|
+
Plugin.register_parser('tsv', self)
|
24
|
+
|
25
|
+
config_param :delimiter, :string, default: "\t"
|
26
|
+
|
27
|
+
def configure(conf)
|
28
|
+
super
|
29
|
+
@key_num = @keys.length
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse(text)
|
33
|
+
yield values_map(text.split(@delimiter, @key_num))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -19,144 +19,150 @@ require 'ipaddr'
|
|
19
19
|
require 'cool.io'
|
20
20
|
|
21
21
|
require 'fluent/plugin'
|
22
|
+
require 'fluent/input'
|
22
23
|
|
23
24
|
module Fluent
|
24
|
-
module
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
module_function :create_udp_socket
|
33
|
-
|
34
|
-
class UdpHandler < Coolio::IO
|
35
|
-
def initialize(io, log, body_size_limit, callback, resolve_hostname = false)
|
36
|
-
super(io)
|
37
|
-
@io = io
|
38
|
-
@io.do_not_reverse_lookup = !resolve_hostname
|
39
|
-
@log = log
|
40
|
-
@body_size_limit = body_size_limit
|
41
|
-
@callback = callback
|
25
|
+
module Plugin
|
26
|
+
module SocketUtil
|
27
|
+
def create_udp_socket(host)
|
28
|
+
if IPAddr.new(IPSocket.getaddress(host)).ipv4?
|
29
|
+
UDPSocket.new
|
30
|
+
else
|
31
|
+
UDPSocket.new(Socket::AF_INET6)
|
32
|
+
end
|
42
33
|
end
|
34
|
+
module_function :create_udp_socket
|
35
|
+
|
36
|
+
class UdpHandler < Coolio::IO
|
37
|
+
def initialize(io, log, body_size_limit, callback)
|
38
|
+
super(io)
|
39
|
+
@io = io
|
40
|
+
@log = log
|
41
|
+
@body_size_limit = body_size_limit
|
42
|
+
@callback = callback
|
43
|
+
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
def on_readable
|
46
|
+
msg, addr = @io.recvfrom_nonblock(@body_size_limit)
|
47
|
+
msg.chomp!
|
48
|
+
@callback.call(msg, addr)
|
49
|
+
rescue => e
|
50
|
+
@log.error "unexpected error", error: e
|
51
|
+
end
|
50
52
|
end
|
51
|
-
end
|
52
53
|
|
53
|
-
|
54
|
-
|
54
|
+
class TcpHandler < Coolio::Socket
|
55
|
+
PEERADDR_FAILED = ["?", "?", "name resolusion failed", "?"]
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
io.
|
60
|
-
|
57
|
+
def initialize(io, log, delimiter, callback)
|
58
|
+
super(io)
|
59
|
+
@timeout = 0
|
60
|
+
if io.is_a?(TCPSocket)
|
61
|
+
@addr = (io.peeraddr rescue PEERADDR_FAILED)
|
61
62
|
|
62
|
-
|
63
|
-
|
63
|
+
opt = [1, @timeout.to_i].pack('I!I!') # { int l_onoff; int l_linger; }
|
64
|
+
io.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, opt)
|
65
|
+
end
|
66
|
+
@delimiter = delimiter
|
67
|
+
@callback = callback
|
68
|
+
@log = log
|
69
|
+
@log.trace { "accepted fluent socket object_id=#{self.object_id}" }
|
70
|
+
@buffer = "".force_encoding('ASCII-8BIT')
|
64
71
|
end
|
65
|
-
@delimiter = delimiter
|
66
|
-
@callback = callback
|
67
|
-
@log = log
|
68
|
-
@log.trace { "accepted fluent socket object_id=#{self.object_id}" }
|
69
|
-
@buffer = "".force_encoding('ASCII-8BIT')
|
70
|
-
end
|
71
72
|
|
72
|
-
|
73
|
-
|
73
|
+
def on_connect
|
74
|
+
end
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
76
|
+
def on_read(data)
|
77
|
+
@buffer << data
|
78
|
+
pos = 0
|
78
79
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
80
|
+
while i = @buffer.index(@delimiter, pos)
|
81
|
+
msg = @buffer[pos...i]
|
82
|
+
@callback.call(msg, @addr)
|
83
|
+
pos = i + @delimiter.length
|
84
|
+
end
|
85
|
+
@buffer.slice!(0, pos) if pos > 0
|
86
|
+
rescue => e
|
87
|
+
@log.error "unexpected error", error: e
|
88
|
+
close
|
83
89
|
end
|
84
|
-
@buffer.slice!(0, pos) if pos > 0
|
85
|
-
rescue => e
|
86
|
-
@log.error "unexpected error", error: e, error_class: e.class
|
87
|
-
close
|
88
|
-
end
|
89
90
|
|
90
|
-
|
91
|
-
|
91
|
+
def on_close
|
92
|
+
@log.trace { "closed fluent socket object_id=#{self.object_id}" }
|
93
|
+
end
|
92
94
|
end
|
93
|
-
end
|
94
95
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
96
|
+
class BaseInput < Fluent::Input
|
97
|
+
def initialize
|
98
|
+
super
|
99
|
+
require 'fluent/parser'
|
100
|
+
end
|
100
101
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
@parser = Plugin.new_parser(@format)
|
120
|
-
@parser.configure(conf)
|
121
|
-
end
|
102
|
+
desc 'Tag of output events.'
|
103
|
+
config_param :tag, :string
|
104
|
+
desc 'The format of the payload.'
|
105
|
+
config_param :format, :string
|
106
|
+
desc 'The port to listen to.'
|
107
|
+
config_param :port, :integer, default: 5150
|
108
|
+
desc 'The bind address to listen to.'
|
109
|
+
config_param :bind, :string, default: '0.0.0.0'
|
110
|
+
desc "The field name of the client's hostname."
|
111
|
+
config_param :source_host_key, :string, default: nil
|
112
|
+
config_param :blocking_timeout, :time, default: 0.5
|
113
|
+
|
114
|
+
def configure(conf)
|
115
|
+
super
|
116
|
+
|
117
|
+
@parser = Plugin.new_parser(@format)
|
118
|
+
@parser.configure(conf)
|
119
|
+
end
|
122
120
|
|
123
|
-
|
124
|
-
|
125
|
-
@handler = listen(method(:on_message))
|
126
|
-
@loop.attach(@handler)
|
127
|
-
@thread = Thread.new(&method(:run))
|
128
|
-
end
|
121
|
+
def start
|
122
|
+
super
|
129
123
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
end
|
124
|
+
@loop = Coolio::Loop.new
|
125
|
+
@handler = listen(method(:on_message))
|
126
|
+
@loop.attach(@handler)
|
127
|
+
@thread = Thread.new(&method(:run))
|
128
|
+
end
|
136
129
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
end
|
130
|
+
def shutdown
|
131
|
+
@loop.watchers.each { |w| w.detach }
|
132
|
+
@loop.stop if @loop.instance_variable_get("@running")
|
133
|
+
@handler.close
|
134
|
+
@thread.join
|
143
135
|
|
144
|
-
|
136
|
+
super
|
137
|
+
end
|
145
138
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
139
|
+
def run
|
140
|
+
@loop.run(@blocking_timeout)
|
141
|
+
rescue => e
|
142
|
+
log.error "unexpected error", error: e
|
143
|
+
log.error_backtrace
|
144
|
+
end
|
152
145
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
146
|
+
private
|
147
|
+
|
148
|
+
def on_message(msg, addr)
|
149
|
+
@parser.parse(msg) { |time, record|
|
150
|
+
unless time && record
|
151
|
+
log.warn "pattern not match: #{msg.inspect}"
|
152
|
+
return
|
153
|
+
end
|
154
|
+
|
155
|
+
record[@source_host_key] = addr[3] if @source_host_key
|
156
|
+
router.emit(@tag, time, record)
|
157
|
+
}
|
158
|
+
rescue => e
|
159
|
+
log.error msg.dump, error: e, host: addr[3]
|
160
|
+
log.error_backtrace
|
161
|
+
end
|
159
162
|
end
|
160
163
|
end
|
161
164
|
end
|
165
|
+
|
166
|
+
# obsolete
|
167
|
+
SocketUtil = Fluent::Plugin::SocketUtil
|
162
168
|
end
|