fluentd 0.14.12 → 0.14.13

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +2 -0
  3. data/ChangeLog +33 -0
  4. data/bin/fluent-plugin-config-format +5 -0
  5. data/bin/fluent-plugin-generate +5 -0
  6. data/lib/fluent/command/plugin_config_formatter.rb +258 -0
  7. data/lib/fluent/command/plugin_generator.rb +301 -0
  8. data/lib/fluent/compat/detach_process_mixin.rb +25 -0
  9. data/lib/fluent/compat/filter.rb +1 -1
  10. data/lib/fluent/compat/input.rb +1 -0
  11. data/lib/fluent/compat/output.rb +8 -5
  12. data/lib/fluent/config/configure_proxy.rb +31 -8
  13. data/lib/fluent/configurable.rb +2 -2
  14. data/lib/fluent/output.rb +3 -0
  15. data/lib/fluent/plugin/buffer/file_chunk.rb +52 -11
  16. data/lib/fluent/plugin/filter.rb +1 -1
  17. data/lib/fluent/plugin/filter_record_transformer.rb +5 -1
  18. data/lib/fluent/plugin/in_tail.rb +13 -6
  19. data/lib/fluent/plugin/input.rb +1 -1
  20. data/lib/fluent/plugin/output.rb +26 -6
  21. data/lib/fluent/plugin/parser_apache.rb +1 -1
  22. data/lib/fluent/plugin/parser_apache_error.rb +1 -1
  23. data/lib/fluent/plugin/parser_multiline.rb +1 -0
  24. data/lib/fluent/plugin/parser_nginx.rb +1 -1
  25. data/lib/fluent/plugin/parser_regexp.rb +18 -0
  26. data/lib/fluent/plugin_helper.rb +19 -1
  27. data/lib/fluent/plugin_helper/retry_state.rb +40 -16
  28. data/lib/fluent/process.rb +22 -0
  29. data/lib/fluent/supervisor.rb +2 -21
  30. data/lib/fluent/test/helpers.rb +14 -0
  31. data/lib/fluent/version.rb +1 -1
  32. data/templates/new_gem/Gemfile +3 -0
  33. data/templates/new_gem/README.md.erb +43 -0
  34. data/templates/new_gem/Rakefile +13 -0
  35. data/templates/new_gem/fluent-plugin.gemspec.erb +27 -0
  36. data/templates/new_gem/lib/fluent/plugin/filter.rb.erb +14 -0
  37. data/templates/new_gem/lib/fluent/plugin/formatter.rb.erb +14 -0
  38. data/templates/new_gem/lib/fluent/plugin/input.rb.erb +11 -0
  39. data/templates/new_gem/lib/fluent/plugin/output.rb.erb +11 -0
  40. data/templates/new_gem/lib/fluent/plugin/parser.rb.erb +15 -0
  41. data/templates/new_gem/test/helper.rb.erb +8 -0
  42. data/templates/new_gem/test/plugin/test_filter.rb.erb +18 -0
  43. data/templates/new_gem/test/plugin/test_formatter.rb.erb +18 -0
  44. data/templates/new_gem/test/plugin/test_input.rb.erb +18 -0
  45. data/templates/new_gem/test/plugin/test_output.rb.erb +18 -0
  46. data/templates/new_gem/test/plugin/test_parser.rb.erb +18 -0
  47. data/templates/plugin_config_formatter/param.md-compact.erb +25 -0
  48. data/templates/plugin_config_formatter/param.md.erb +34 -0
  49. data/templates/plugin_config_formatter/section.md.erb +12 -0
  50. data/test/command/test_binlog_reader.rb +0 -9
  51. data/test/command/test_plugin_config_formatter.rb +275 -0
  52. data/test/command/test_plugin_generator.rb +66 -0
  53. data/test/config/test_configure_proxy.rb +89 -45
  54. data/test/plugin/data/log/foo/bar2 +0 -0
  55. data/test/plugin/test_in_tail.rb +97 -8
  56. data/test/plugin/test_output.rb +18 -0
  57. data/test/plugin/test_output_as_buffered.rb +35 -0
  58. data/test/plugin_helper/test_compat_parameters.rb +2 -0
  59. data/test/plugin_helper/test_retry_state.rb +23 -0
  60. data/test/test_output.rb +5 -0
  61. data/test/test_process.rb +14 -0
  62. metadata +37 -3
@@ -0,0 +1,18 @@
1
+ require "helper"
2
+ require "fluent/plugin/<%= plugin_filename %>"
3
+
4
+ class <%= class_name %>Test < Test::Unit::TestCase
5
+ setup do
6
+ Fluent::Test.setup
7
+ end
8
+
9
+ test "failure" do
10
+ flunk
11
+ end
12
+
13
+ private
14
+
15
+ def create_driver(conf)
16
+ Fluent::Test::Driver::Input.new(Fluent::Plugin::<%= class_name %>).configure(conf)
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require "helper"
2
+ require "fluent/plugin/<%= plugin_filename %>"
3
+
4
+ class <%= class_name %>Test < Test::Unit::TestCase
5
+ setup do
6
+ Fluent::Test.setup
7
+ end
8
+
9
+ test "failure" do
10
+ flunk
11
+ end
12
+
13
+ private
14
+
15
+ def create_driver(conf)
16
+ Fluent::Test::Driver::Output.new(Fluent::Plugin::<%= class_name %>).configure(conf)
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require "helper"
2
+ require "fluent/plugin/<%= plugin_filename %>"
3
+
4
+ class <%= class_name %>Test < Test::Unit::TestCase
5
+ setup do
6
+ Fluent::Test.setup
7
+ end
8
+
9
+ test "failure" do
10
+ flunk
11
+ end
12
+
13
+ private
14
+
15
+ def create_driver(conf)
16
+ Fluent::Test::Driver::Parser.new(Fluent::Plugin::<%= class_name %>).configure(conf)
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ <%-
2
+ type = config[:type]
3
+ required_label = config[:required] ? "required" : "optional"
4
+ default = config[:default]
5
+ alias_name = config[:alias]
6
+ deprecated = config[:deprecated]
7
+ obsoleted = config[:obsoleted]
8
+ description = config[:desc]
9
+ -%>
10
+ * **<%= name %>** (<%= type %>) (<%= required_label %>): <%= description %>
11
+ <%- if type == :enum -%>
12
+ * Available values: <%= config[:list].join(", ") %>
13
+ <%- end -%>
14
+ <%- if default -%>
15
+ * Default value: `<%= default %>`.
16
+ <%- end -%>
17
+ <%- if alias_name -%>
18
+ * Alias: <%= alias_name %>
19
+ <%- end -%>
20
+ <%- if deprecated -%>
21
+ * Deprecated: <%= deprecated %>
22
+ <%- end -%>
23
+ <%- if obsoleted -%>
24
+ * Obsoleted: <%= :obsoleted %>
25
+ <%- end -%>
@@ -0,0 +1,34 @@
1
+ <%-
2
+ type = config[:type]
3
+ required_label = config[:required] ? "required" : "optional"
4
+ default = config[:default]
5
+ alias_name = config[:alias]
6
+ deprecated = config[:deprecated]
7
+ obsoleted = config[:obsoleted]
8
+ description = config[:desc]
9
+ param_header = "#" * (3 + level)
10
+ -%>
11
+ <%= param_header %> <%= name %> (<%= type %>) (<%= required_label %>)
12
+
13
+ <%= description %>
14
+ <%- if type == :enum -%>
15
+
16
+ Available values: <%= config[:list].join(", ") %>
17
+ <%- end -%>
18
+ <%- if default -%>
19
+
20
+ Default value: `<%= default %>`.
21
+ <%- end -%>
22
+ <%- if alias_name -%>
23
+
24
+ Alias: <%= alias_name %>
25
+ <%- end -%>
26
+ <%- if deprecated -%>
27
+
28
+ Deprecated: <%= deprecated %>
29
+ <%- end -%>
30
+ <%- if obsoleted -%>
31
+
32
+ Obsoleted: <%= :obsoleted %>
33
+ <%- end -%>
34
+
@@ -0,0 +1,12 @@
1
+ <%-
2
+ section_header = "#" * (3 + level)
3
+ required_label = required ? "required" : "optional"
4
+ multiple_label = multi ? "multiple" : "single"
5
+ -%>
6
+ <%= section_header %> \<<%= section_name %>\> section (<%= required_label %>) (<%= multiple_label %>)
7
+ <%- if alias_name -%>
8
+
9
+ Alias: <%= alias_name %>
10
+ <%- end -%>
11
+
12
+ <%= dump_section_markdown(sub_section, level + 1) %>
@@ -79,15 +79,6 @@ class TestBaseCommand < ::Test::Unit::TestCase
79
79
  ensure
80
80
  ENV['TZ'] = old
81
81
  end
82
-
83
- def capture_stdout
84
- out = StringIO.new
85
- $stdout = out
86
- yield
87
- out.string.force_encoding('utf-8')
88
- ensure
89
- $stdout = STDOUT
90
- end
91
82
  end
92
83
 
93
84
  class TestHead < TestBaseCommand
@@ -0,0 +1,275 @@
1
+ require_relative '../helper'
2
+
3
+ require 'pathname'
4
+ require 'fluent/command/plugin_config_formatter'
5
+ require 'fluent/plugin/input'
6
+ require 'fluent/plugin/output'
7
+ require 'fluent/plugin/filter'
8
+ require 'fluent/plugin/parser'
9
+ require 'fluent/plugin/formatter'
10
+
11
+ class TestFluentPluginConfigFormatter < Test::Unit::TestCase
12
+ class FakeInput < ::Fluent::Plugin::Input
13
+ ::Fluent::Plugin.register_input("fake", self)
14
+
15
+ desc "path to something"
16
+ config_param :path, :string
17
+ end
18
+
19
+ class FakeOutput < ::Fluent::Plugin::Output
20
+ ::Fluent::Plugin.register_output("fake", self)
21
+
22
+ desc "path to something"
23
+ config_param :path, :string
24
+
25
+ def process(tag, es)
26
+ end
27
+ end
28
+
29
+ class FakeFilter < ::Fluent::Plugin::Filter
30
+ ::Fluent::Plugin.register_filter("fake", self)
31
+
32
+ desc "path to something"
33
+ config_param :path, :string
34
+
35
+ def filter(tag, time, record)
36
+ end
37
+ end
38
+
39
+ class FakeParser < ::Fluent::Plugin::Parser
40
+ ::Fluent::Plugin.register_parser("fake", self)
41
+
42
+ desc "path to something"
43
+ config_param :path, :string
44
+
45
+ def parse(text)
46
+ end
47
+ end
48
+
49
+ class FakeFormatter < ::Fluent::Plugin::Formatter
50
+ ::Fluent::Plugin.register_formatter("fake", self)
51
+
52
+ desc "path to something"
53
+ config_param :path, :string
54
+
55
+ def format(tag, time, record)
56
+ end
57
+ end
58
+
59
+ class SimpleInput < ::Fluent::Plugin::Input
60
+ ::Fluent::Plugin.register_input("simple", self)
61
+ helpers :inject, :compat_parameters
62
+
63
+ desc "path to something"
64
+ config_param :path, :string
65
+ end
66
+
67
+ class ComplexOutput < ::Fluent::Plugin::Output
68
+ ::Fluent::Plugin.register_output("complex", self)
69
+ helpers :inject, :compat_parameters
70
+
71
+ config_section :authentication, required: true, multi: false do
72
+ desc "username"
73
+ config_param :username, :string
74
+ desc "password"
75
+ config_param :passowrd, :string, secret: true
76
+ end
77
+
78
+ config_section :parent do
79
+ config_section :child do
80
+ desc "names"
81
+ config_param :names, :array
82
+ desc "difficulty"
83
+ config_param :difficulty, :enum, list: [:easy, :normal, :hard], default: :normal
84
+ end
85
+ end
86
+
87
+ def process(tag, es)
88
+ end
89
+ end
90
+
91
+ sub_test_case "json" do
92
+ data(input: [FakeInput, "input"],
93
+ output: [FakeOutput, "output"],
94
+ filter: [FakeFilter, "filter"],
95
+ parser: [FakeParser, "parser"],
96
+ formatter: [FakeFormatter, "formatter"])
97
+ test "dumped config should be valid JSON" do |(klass, type)|
98
+ dumped_config = capture_stdout do
99
+ FluentPluginConfigFormatter.new(["--format=json", type, "fake"]).call
100
+ end
101
+ expected = {
102
+ path: {
103
+ desc: "path to something",
104
+ type: "string",
105
+ required: true
106
+ }
107
+ }
108
+ assert_equal(expected, JSON.parse(dumped_config, symbolize_names: true)[klass.name.to_sym])
109
+ end
110
+ end
111
+
112
+ sub_test_case "text" do
113
+ test "input simple" do
114
+ dumped_config = capture_stdout do
115
+ FluentPluginConfigFormatter.new(["--format=txt", "input", "simple"]).call
116
+ end
117
+ expected = <<TEXT
118
+ helpers: inject,compat_parameters
119
+ @log_level: string: (nil)
120
+ path: string: (nil)
121
+ TEXT
122
+ assert_equal(expected, dumped_config)
123
+ end
124
+
125
+ test "output complex" do
126
+ dumped_config = capture_stdout do
127
+ FluentPluginConfigFormatter.new(["--format=txt", "output", "complex"]).call
128
+ end
129
+ expected = <<TEXT
130
+ helpers: inject,compat_parameters
131
+ @log_level: string: (nil)
132
+ time_as_integer: bool: (false)
133
+ slow_flush_log_threshold: float: (20.0)
134
+ <buffer>: optional, single
135
+ @type: string: ("memory")
136
+ timekey: time: (nil)
137
+ timekey_wait: time: (600)
138
+ timekey_use_utc: bool: (false)
139
+ timekey_zone: string: ("#{Time.now.strftime('%z')}")
140
+ flush_at_shutdown: bool: (nil)
141
+ flush_mode: enum: (:default)
142
+ flush_interval: time: (60)
143
+ flush_thread_count: integer: (1)
144
+ flush_thread_interval: float: (1.0)
145
+ flush_thread_burst_interval: float: (1.0)
146
+ delayed_commit_timeout: time: (60)
147
+ overflow_action: enum: (:throw_exception)
148
+ retry_forever: bool: (false)
149
+ retry_timeout: time: (259200)
150
+ retry_max_times: integer: (nil)
151
+ retry_secondary_threshold: float: (0.8)
152
+ retry_type: enum: (:exponential_backoff)
153
+ retry_wait: time: (1)
154
+ retry_exponential_backoff_base: float: (2)
155
+ retry_max_interval: time: (nil)
156
+ retry_randomize: bool: (true)
157
+ chunk_keys: : ([])
158
+ <secondary>: optional, single
159
+ @type: string: (nil)
160
+ <buffer>: optional, single
161
+ <secondary>: optional, single
162
+ <authentication>: required, single
163
+ username: string: (nil)
164
+ passowrd: string: (nil)
165
+ <parent>: optional, multiple
166
+ <child>: optional, multiple
167
+ names: array: (nil)
168
+ difficulty: enum: (:normal)
169
+ TEXT
170
+ assert_equal(expected, dumped_config)
171
+ end
172
+ end
173
+
174
+ sub_test_case "markdown" do
175
+ test "input simple" do
176
+ dumped_config = capture_stdout do
177
+ FluentPluginConfigFormatter.new(["--format=markdown", "input", "simple"]).call
178
+ end
179
+ expected = <<TEXT
180
+ ## Plugin helpers
181
+
182
+ * inject
183
+ * compat_parameters
184
+
185
+ * See also: Fluent::Plugin::Input
186
+
187
+ ## TestFluentPluginConfigFormatter::SimpleInput
188
+
189
+ ### path (string) (required)
190
+
191
+ path to something
192
+
193
+
194
+ TEXT
195
+ assert_equal(expected, dumped_config)
196
+ end
197
+
198
+ test "output complex" do
199
+ dumped_config = capture_stdout do
200
+ FluentPluginConfigFormatter.new(["--format=markdown", "output", "complex"]).call
201
+ end
202
+ expected = <<TEXT
203
+ ## Plugin helpers
204
+
205
+ * inject
206
+ * compat_parameters
207
+
208
+ * See also: Fluent::Plugin::Output
209
+
210
+ ## TestFluentPluginConfigFormatter::ComplexOutput
211
+
212
+
213
+ ### \\<authentication\\> section (required) (single)
214
+
215
+ #### username (string) (required)
216
+
217
+ username
218
+
219
+ #### passowrd (string) (required)
220
+
221
+ password
222
+
223
+
224
+
225
+ ### \\<parent\\> section (optional) (multiple)
226
+
227
+
228
+ #### \\<child\\> section (optional) (multiple)
229
+
230
+ ##### names (array) (required)
231
+
232
+ names
233
+
234
+ ##### difficulty (enum) (optional)
235
+
236
+ difficulty
237
+
238
+ Available values: easy, normal, hard
239
+
240
+ Default value: `normal`.
241
+
242
+
243
+
244
+
245
+ TEXT
246
+ assert_equal(expected, dumped_config)
247
+ end
248
+ end
249
+
250
+ sub_test_case "arguments" do
251
+ data do
252
+ hash = {}
253
+ ["input", "output", "filter", "parser", "formatter"].each do |type|
254
+ ["txt", "json", "markdown"].each do |format|
255
+ argv = ["--format=#{format}"]
256
+ [
257
+ ["--verbose", "--compact"],
258
+ ["--verbose"],
259
+ ["--compact"]
260
+ ].each do |options|
261
+ hash[(argv + options).join(" ")] = argv + options + [type, "fake"]
262
+ end
263
+ end
264
+ end
265
+ hash
266
+ end
267
+ test "dump txt" do |argv|
268
+ capture_stdout do
269
+ assert_nothing_raised do
270
+ FluentPluginConfigFormatter.new(argv).call
271
+ end
272
+ end
273
+ end
274
+ end
275
+ end
@@ -0,0 +1,66 @@
1
+ require_relative '../helper'
2
+
3
+ require 'pathname'
4
+ require 'fluent/command/plugin_generator'
5
+
6
+ class TestFluentPluginGenerator < Test::Unit::TestCase
7
+ TEMP_DIR = "tmp/plugin_generator"
8
+ setup do
9
+ FileUtils.mkdir_p(TEMP_DIR)
10
+ @pwd = Dir.pwd
11
+ Dir.chdir(TEMP_DIR)
12
+ end
13
+
14
+ teardown do
15
+ Dir.chdir(@pwd)
16
+ FileUtils.rm_rf(TEMP_DIR)
17
+ end
18
+
19
+ data(input: ["input", "in"],
20
+ output: ["output", "out"],
21
+ filter: ["filter", "filter"],
22
+ parser: ["parser", "parser"],
23
+ formatter: ["formatter", "formatter"])
24
+ test "generate plugin" do |(type, part)|
25
+ capture_stdout do
26
+ FluentPluginGenerator.new([type, "fake"]).call
27
+ end
28
+ plugin_base_dir = Pathname("fluent-plugin-fake")
29
+ assert { plugin_base_dir.directory? }
30
+ expected = [
31
+ "fluent-plugin-fake",
32
+ "fluent-plugin-fake/Gemfile",
33
+ "fluent-plugin-fake/LICENSE",
34
+ "fluent-plugin-fake/README.md",
35
+ "fluent-plugin-fake/Rakefile",
36
+ "fluent-plugin-fake/fluent-plugin-fake.gemspec",
37
+ "fluent-plugin-fake/lib",
38
+ "fluent-plugin-fake/lib/fluent",
39
+ "fluent-plugin-fake/lib/fluent/plugin",
40
+ "fluent-plugin-fake/lib/fluent/plugin/#{part}_fake.rb",
41
+ "fluent-plugin-fake/test",
42
+ "fluent-plugin-fake/test/helper.rb",
43
+ "fluent-plugin-fake/test/plugin",
44
+ "fluent-plugin-fake/test/plugin/test_#{part}_fake.rb",
45
+ ]
46
+ actual = plugin_base_dir.find.reject {|f| f.fnmatch("*/.git*") }.map(&:to_s).sort
47
+ assert_equal(expected, actual)
48
+ end
49
+
50
+ test "no license" do
51
+ capture_stdout do
52
+ FluentPluginGenerator.new(["--no-license", "filter", "fake"]).call
53
+ end
54
+ assert { !Pathname("fluent-plugin-fake/LICENSE").exist? }
55
+ assert { Pathname("fluent-plugin-fake/Gemfile").exist? }
56
+ end
57
+
58
+ test "unknown license" do
59
+ out = capture_stdout do
60
+ assert_raise(SystemExit) do
61
+ FluentPluginGenerator.new(["--license=unknown", "filter", "fake"]).call
62
+ end
63
+ end
64
+ assert { out.lines.include?("License: unknown\n") }
65
+ end
66
+ end