fluentd 1.13.3 → 1.16.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/{bug_report.yaml → bug_report.yml} +2 -0
  3. data/.github/ISSUE_TEMPLATE/config.yml +2 -2
  4. data/.github/ISSUE_TEMPLATE/{feature_request.yaml → feature_request.yml} +1 -0
  5. data/.github/workflows/stale-actions.yml +11 -9
  6. data/.github/workflows/test.yml +32 -0
  7. data/CHANGELOG.md +490 -10
  8. data/CONTRIBUTING.md +2 -2
  9. data/MAINTAINERS.md +7 -5
  10. data/README.md +3 -23
  11. data/Rakefile +1 -1
  12. data/SECURITY.md +14 -0
  13. data/fluentd.gemspec +7 -8
  14. data/lib/fluent/command/cat.rb +13 -3
  15. data/lib/fluent/command/ctl.rb +6 -3
  16. data/lib/fluent/command/fluentd.rb +73 -65
  17. data/lib/fluent/command/plugin_config_formatter.rb +1 -1
  18. data/lib/fluent/compat/output.rb +9 -6
  19. data/lib/fluent/config/dsl.rb +1 -1
  20. data/lib/fluent/config/error.rb +12 -0
  21. data/lib/fluent/config/literal_parser.rb +2 -2
  22. data/lib/fluent/config/parser.rb +1 -1
  23. data/lib/fluent/config/v1_parser.rb +3 -3
  24. data/lib/fluent/config/yaml_parser/fluent_value.rb +47 -0
  25. data/lib/fluent/config/yaml_parser/loader.rb +108 -0
  26. data/lib/fluent/config/yaml_parser/parser.rb +166 -0
  27. data/lib/fluent/config/yaml_parser/section_builder.rb +107 -0
  28. data/lib/fluent/config/yaml_parser.rb +56 -0
  29. data/lib/fluent/config.rb +14 -1
  30. data/lib/fluent/counter/server.rb +1 -1
  31. data/lib/fluent/counter/validator.rb +3 -3
  32. data/lib/fluent/daemon.rb +2 -4
  33. data/lib/fluent/engine.rb +1 -1
  34. data/lib/fluent/env.rb +4 -0
  35. data/lib/fluent/error.rb +3 -0
  36. data/lib/fluent/event.rb +8 -4
  37. data/lib/fluent/event_router.rb +47 -2
  38. data/lib/fluent/file_wrapper.rb +137 -0
  39. data/lib/fluent/log/console_adapter.rb +66 -0
  40. data/lib/fluent/log.rb +44 -5
  41. data/lib/fluent/match.rb +1 -1
  42. data/lib/fluent/msgpack_factory.rb +6 -1
  43. data/lib/fluent/oj_options.rb +1 -2
  44. data/lib/fluent/plugin/bare_output.rb +49 -8
  45. data/lib/fluent/plugin/base.rb +26 -9
  46. data/lib/fluent/plugin/buf_file.rb +34 -5
  47. data/lib/fluent/plugin/buf_file_single.rb +32 -3
  48. data/lib/fluent/plugin/buffer/file_chunk.rb +1 -1
  49. data/lib/fluent/plugin/buffer.rb +216 -70
  50. data/lib/fluent/plugin/filter.rb +35 -1
  51. data/lib/fluent/plugin/filter_record_transformer.rb +1 -1
  52. data/lib/fluent/plugin/in_forward.rb +2 -2
  53. data/lib/fluent/plugin/in_http.rb +39 -10
  54. data/lib/fluent/plugin/in_monitor_agent.rb +4 -2
  55. data/lib/fluent/plugin/in_sample.rb +1 -1
  56. data/lib/fluent/plugin/in_syslog.rb +13 -1
  57. data/lib/fluent/plugin/in_tail/group_watch.rb +204 -0
  58. data/lib/fluent/plugin/in_tail/position_file.rb +33 -33
  59. data/lib/fluent/plugin/in_tail.rb +216 -84
  60. data/lib/fluent/plugin/in_tcp.rb +47 -2
  61. data/lib/fluent/plugin/input.rb +39 -1
  62. data/lib/fluent/plugin/metrics.rb +119 -0
  63. data/lib/fluent/plugin/metrics_local.rb +96 -0
  64. data/lib/fluent/plugin/multi_output.rb +43 -6
  65. data/lib/fluent/plugin/out_copy.rb +1 -1
  66. data/lib/fluent/plugin/out_exec_filter.rb +2 -2
  67. data/lib/fluent/plugin/out_file.rb +20 -2
  68. data/lib/fluent/plugin/out_forward/ack_handler.rb +19 -4
  69. data/lib/fluent/plugin/out_forward/socket_cache.rb +2 -0
  70. data/lib/fluent/plugin/out_forward.rb +17 -9
  71. data/lib/fluent/plugin/out_secondary_file.rb +39 -22
  72. data/lib/fluent/plugin/output.rb +167 -78
  73. data/lib/fluent/plugin/parser.rb +3 -4
  74. data/lib/fluent/plugin/parser_apache2.rb +1 -1
  75. data/lib/fluent/plugin/parser_json.rb +1 -1
  76. data/lib/fluent/plugin/parser_syslog.rb +1 -1
  77. data/lib/fluent/plugin/storage_local.rb +3 -5
  78. data/lib/fluent/plugin.rb +10 -1
  79. data/lib/fluent/plugin_helper/child_process.rb +3 -0
  80. data/lib/fluent/plugin_helper/event_emitter.rb +8 -1
  81. data/lib/fluent/plugin_helper/event_loop.rb +2 -2
  82. data/lib/fluent/plugin_helper/http_server/server.rb +2 -1
  83. data/lib/fluent/plugin_helper/metrics.rb +129 -0
  84. data/lib/fluent/plugin_helper/record_accessor.rb +1 -1
  85. data/lib/fluent/plugin_helper/retry_state.rb +14 -4
  86. data/lib/fluent/plugin_helper/server.rb +35 -6
  87. data/lib/fluent/plugin_helper/service_discovery.rb +2 -2
  88. data/lib/fluent/plugin_helper/socket.rb +13 -2
  89. data/lib/fluent/plugin_helper/thread.rb +3 -3
  90. data/lib/fluent/plugin_helper.rb +1 -0
  91. data/lib/fluent/plugin_id.rb +3 -2
  92. data/lib/fluent/registry.rb +2 -1
  93. data/lib/fluent/root_agent.rb +6 -0
  94. data/lib/fluent/rpc.rb +4 -3
  95. data/lib/fluent/supervisor.rb +283 -259
  96. data/lib/fluent/system_config.rb +13 -3
  97. data/lib/fluent/test/driver/base.rb +11 -5
  98. data/lib/fluent/test/driver/filter.rb +4 -0
  99. data/lib/fluent/test/startup_shutdown.rb +6 -8
  100. data/lib/fluent/time.rb +21 -20
  101. data/lib/fluent/version.rb +1 -1
  102. data/lib/fluent/win32api.rb +38 -0
  103. data/lib/fluent/winsvc.rb +5 -8
  104. data/templates/new_gem/test/helper.rb.erb +0 -1
  105. data/test/command/test_cat.rb +31 -2
  106. data/test/command/test_ctl.rb +1 -2
  107. data/test/command/test_fluentd.rb +209 -24
  108. data/test/command/test_plugin_config_formatter.rb +0 -1
  109. data/test/compat/test_parser.rb +6 -6
  110. data/test/config/test_system_config.rb +13 -11
  111. data/test/config/test_types.rb +1 -1
  112. data/test/log/test_console_adapter.rb +110 -0
  113. data/test/plugin/in_tail/test_io_handler.rb +26 -8
  114. data/test/plugin/in_tail/test_position_file.rb +48 -59
  115. data/test/plugin/out_forward/test_ack_handler.rb +39 -0
  116. data/test/plugin/out_forward/test_socket_cache.rb +26 -1
  117. data/test/plugin/test_bare_output.rb +14 -1
  118. data/test/plugin/test_base.rb +133 -1
  119. data/test/plugin/test_buf_file.rb +62 -23
  120. data/test/plugin/test_buf_file_single.rb +65 -0
  121. data/test/plugin/test_buffer.rb +267 -3
  122. data/test/plugin/test_buffer_chunk.rb +11 -0
  123. data/test/plugin/test_filter.rb +12 -1
  124. data/test/plugin/test_filter_parser.rb +1 -1
  125. data/test/plugin/test_filter_stdout.rb +2 -2
  126. data/test/plugin/test_in_forward.rb +9 -11
  127. data/test/plugin/test_in_http.rb +65 -3
  128. data/test/plugin/test_in_monitor_agent.rb +216 -11
  129. data/test/plugin/test_in_object_space.rb +9 -3
  130. data/test/plugin/test_in_syslog.rb +35 -0
  131. data/test/plugin/test_in_tail.rb +1393 -385
  132. data/test/plugin/test_in_tcp.rb +87 -2
  133. data/test/plugin/test_in_udp.rb +28 -0
  134. data/test/plugin/test_in_unix.rb +2 -2
  135. data/test/plugin/test_input.rb +12 -1
  136. data/test/plugin/test_metrics.rb +294 -0
  137. data/test/plugin/test_metrics_local.rb +96 -0
  138. data/test/plugin/test_multi_output.rb +25 -1
  139. data/test/plugin/test_out_exec.rb +6 -4
  140. data/test/plugin/test_out_exec_filter.rb +6 -2
  141. data/test/plugin/test_out_file.rb +34 -17
  142. data/test/plugin/test_out_forward.rb +78 -77
  143. data/test/plugin/test_out_http.rb +1 -0
  144. data/test/plugin/test_out_stdout.rb +2 -2
  145. data/test/plugin/test_output.rb +297 -12
  146. data/test/plugin/test_output_as_buffered.rb +44 -44
  147. data/test/plugin/test_output_as_buffered_compress.rb +32 -18
  148. data/test/plugin/test_output_as_buffered_retries.rb +54 -7
  149. data/test/plugin/test_output_as_buffered_secondary.rb +4 -4
  150. data/test/plugin/test_parser_regexp.rb +1 -6
  151. data/test/plugin/test_parser_syslog.rb +1 -1
  152. data/test/plugin_helper/test_cert_option.rb +1 -1
  153. data/test/plugin_helper/test_child_process.rb +38 -16
  154. data/test/plugin_helper/test_event_emitter.rb +29 -0
  155. data/test/plugin_helper/test_http_server_helper.rb +1 -1
  156. data/test/plugin_helper/test_metrics.rb +137 -0
  157. data/test/plugin_helper/test_retry_state.rb +602 -38
  158. data/test/plugin_helper/test_server.rb +78 -6
  159. data/test/plugin_helper/test_timer.rb +2 -2
  160. data/test/test_config.rb +191 -24
  161. data/test/test_event_router.rb +17 -0
  162. data/test/test_file_wrapper.rb +53 -0
  163. data/test/test_formatter.rb +24 -21
  164. data/test/test_log.rb +122 -40
  165. data/test/test_msgpack_factory.rb +32 -0
  166. data/test/test_plugin_classes.rb +102 -0
  167. data/test/test_root_agent.rb +30 -1
  168. data/test/test_supervisor.rb +477 -257
  169. data/test/test_time_parser.rb +22 -0
  170. metadata +55 -34
  171. data/.drone.yml +0 -35
  172. data/.github/workflows/issue-auto-closer.yml +0 -12
  173. data/.github/workflows/linux-test.yaml +0 -36
  174. data/.github/workflows/macos-test.yaml +0 -30
  175. data/.github/workflows/windows-test.yaml +0 -46
  176. data/.gitlab-ci.yml +0 -103
  177. data/lib/fluent/plugin/file_wrapper.rb +0 -187
  178. data/test/plugin/test_file_wrapper.rb +0 -126
  179. data/test/test_logger_initializer.rb +0 -46
@@ -93,7 +93,7 @@ module Fluent
93
93
  basepath = '/'
94
94
  fname = path
95
95
  require 'open-uri'
96
- open(uri) {|f|
96
+ URI.open(uri) {|f|
97
97
  Parser.new(basepath, f.each_line, fname).parse!(allow_include, nil, attrs, elems)
98
98
  }
99
99
  end
@@ -150,8 +150,8 @@ module Fluent
150
150
  def eval_include(attrs, elems, uri)
151
151
  # replace space(s)(' ') with '+' to prevent invalid uri due to space(s).
152
152
  # See: https://github.com/fluent/fluentd/pull/2780#issuecomment-576081212
153
- u = URI.parse(uri.gsub(/ /, '+'))
154
- if u.scheme == 'file' || (!u.scheme.nil? && u.scheme.length == 1) || u.path == uri.gsub(/ /, '+') # file path
153
+ u = URI.parse(uri.tr(' ', '+'))
154
+ if u.scheme == 'file' || (!u.scheme.nil? && u.scheme.length == 1) || u.path == uri.tr(' ', '+') # file path
155
155
  # When the Windows absolute path then u.scheme.length == 1
156
156
  # e.g. C:
157
157
  path = URI.decode_www_form_component(u.path)
@@ -172,7 +172,7 @@ module Fluent
172
172
  require 'open-uri'
173
173
  basepath = '/'
174
174
  fname = path
175
- data = open(uri) { |f| f.read }
175
+ data = URI.open(uri) { |f| f.read }
176
176
  data.force_encoding('UTF-8')
177
177
  ss = StringScanner.new(data)
178
178
  V1Parser.new(ss, basepath, fname, @eval_context).parse_element(true, nil, attrs, elems)
@@ -0,0 +1,47 @@
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
+ module Fluent
18
+ module Config
19
+ module YamlParser
20
+ module FluentValue
21
+ JsonValue = Struct.new(:val) do
22
+ def to_s
23
+ val.to_json
24
+ end
25
+
26
+ def to_element
27
+ to_s
28
+ end
29
+ end
30
+
31
+ StringValue = Struct.new(:val, :context) do
32
+ def to_s
33
+ context.instance_eval("\"#{val}\"")
34
+ rescue Fluent::SetNil => _
35
+ ''
36
+ rescue Fluent::SetDefault => _
37
+ ':default'
38
+ end
39
+
40
+ def to_element
41
+ to_s
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,108 @@
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 'psych'
18
+ require 'json'
19
+ require 'fluent/config/error'
20
+ require 'fluent/config/yaml_parser/fluent_value'
21
+
22
+ # Based on https://github.com/eagletmt/hako/blob/34cdde06fe8f3aeafd794be830180c3cedfbb4dc/lib/hako/yaml_loader.rb
23
+
24
+ module Fluent
25
+ module Config
26
+ module YamlParser
27
+ class Loader
28
+ INCLUDE_TAG = 'tag:include'.freeze
29
+ FLUENT_JSON_TAG = 'tag:fluent/json'.freeze
30
+ FLUENT_STR_TAG = 'tag:fluent/s'.freeze
31
+ SHOVEL = '<<'.freeze
32
+
33
+ def initialize(context = Kernel.binding)
34
+ @context = context
35
+ @current_path = nil
36
+ end
37
+
38
+ # @param [String] path
39
+ # @return [Hash]
40
+ def load(path)
41
+ class_loader = Psych::ClassLoader.new
42
+ scanner = Psych::ScalarScanner.new(class_loader)
43
+
44
+ visitor = Visitor.new(scanner, class_loader)
45
+
46
+ visitor._register_domain(INCLUDE_TAG) do |_, val|
47
+ eval_include(Pathname.new(val), path.parent)
48
+ end
49
+
50
+ visitor._register_domain(FLUENT_JSON_TAG) do |_, val|
51
+ Fluent::Config::YamlParser::FluentValue::JsonValue.new(val)
52
+ end
53
+
54
+ visitor._register_domain(FLUENT_STR_TAG) do |_, val|
55
+ Fluent::Config::YamlParser::FluentValue::StringValue.new(val, @context)
56
+ end
57
+
58
+ path.open do |f|
59
+ visitor.accept(Psych.parse(f))
60
+ end
61
+ end
62
+
63
+ def eval_include(path, parent)
64
+ if path.relative?
65
+ pattern = parent.join(path)
66
+ else
67
+ pattern = path
68
+ end
69
+ result = []
70
+ Dir.glob(pattern).sort.each do |path|
71
+ result.concat(load(Pathname.new(path)))
72
+ end
73
+ result
74
+ rescue SystemCallError => e
75
+ parse_error = ConfigParseError.new("include error #{path} - #{e}")
76
+ parse_error.set_backtrace(e.backtrace)
77
+ raise parse_error
78
+ end
79
+
80
+ class Visitor < Psych::Visitors::ToRuby
81
+ def initialize(scanner, class_loader)
82
+ super(scanner, class_loader)
83
+ end
84
+
85
+ def _register_domain(name, &block)
86
+ @domain_types.merge!({ name => [name, block] })
87
+ end
88
+
89
+ def revive_hash(hash, o)
90
+ super(hash, o).tap do |r|
91
+ if r[SHOVEL].is_a?(Hash)
92
+ h2 = {}
93
+ r.each do |k, v|
94
+ if k == SHOVEL
95
+ h2.merge!(v)
96
+ else
97
+ h2[k] = v
98
+ end
99
+ end
100
+ r.replace(h2)
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,166 @@
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/config/yaml_parser/section_builder'
18
+
19
+ module Fluent
20
+ module Config
21
+ module YamlParser
22
+ class Parser
23
+ def initialize(config, indent: 2)
24
+ @base_indent = indent
25
+ @config = config
26
+ end
27
+
28
+ def build
29
+ s = @config['system'] && system_config_build(@config['system'])
30
+ c = @config['config'] && config_build(@config['config'], root: true)
31
+ RootBuilder.new(s, c)
32
+ end
33
+
34
+ private
35
+
36
+ def system_config_build(config)
37
+ section_build('system', config)
38
+ end
39
+
40
+ def config_build(config, indent: 0, root: false)
41
+ sb = SectionBodyBuilder.new(indent, root: root)
42
+ config.each do |c|
43
+ if (lc = c.delete('label'))
44
+ sb.add_section(label_build(lc, indent: indent))
45
+ end
46
+
47
+ if (sc = c.delete('source'))
48
+ sb.add_section(source_build(sc, indent: indent))
49
+ end
50
+
51
+ if (fc = c.delete('filter'))
52
+ sb.add_section(filter_build(fc, indent: indent))
53
+ end
54
+
55
+ if (mc = c.delete('match'))
56
+ sb.add_section(match_build(mc, indent: indent))
57
+ end
58
+
59
+ if (wc = c.delete('worker'))
60
+ sb.add_section(worker_build(wc, indent: indent))
61
+ end
62
+
63
+ included_sections_build(c, sb, indent: indent)
64
+ end
65
+
66
+ sb
67
+ end
68
+
69
+ def label_build(config, indent: 0)
70
+ config = config.dup
71
+ name = config.delete('$name')
72
+ c = config.delete('config')
73
+ SectionBuilder.new('label', config_build(c, indent: indent + @base_indent), indent, name)
74
+ end
75
+
76
+ def worker_build(config, indent: 0)
77
+ config = config.dup
78
+ num = config.delete('$arg')
79
+ c = config.delete('config')
80
+ SectionBuilder.new('worker', config_build(c, indent: indent + @base_indent), indent, num)
81
+ end
82
+
83
+ def source_build(config, indent: 0)
84
+ section_build('source', config, indent: indent)
85
+ end
86
+
87
+ def filter_build(config, indent: 0)
88
+ config = config.dup
89
+ tag = config.delete('$tag')
90
+ if tag.is_a?(Array)
91
+ section_build('filter', config, indent: indent, arg: tag&.join(','))
92
+ else
93
+ section_build('filter', config, indent: indent, arg: tag)
94
+ end
95
+ end
96
+
97
+ def match_build(config, indent: 0)
98
+ config = config.dup
99
+ tag = config.delete('$tag')
100
+ if tag.is_a?(Array)
101
+ section_build('match', config, indent: indent, arg: tag&.join(','))
102
+ else
103
+ section_build('match', config, indent: indent, arg: tag)
104
+ end
105
+ end
106
+
107
+ def included_sections_build(config, section_builder, indent: 0)
108
+ config.each_entry do |e|
109
+ k = e.keys.first
110
+ cc = e.delete(k)
111
+ case k
112
+ when 'label'
113
+ section_builder.add_section(label_build(cc, indent: indent))
114
+ when 'worker'
115
+ section_builder.add_section(worker_build(cc, indent: indent))
116
+ when 'source'
117
+ section_builder.add_section(source_build(cc, indent: indent))
118
+ when 'filter'
119
+ section_builder.add_section(filter_build(cc, indent: indent))
120
+ when 'match'
121
+ section_builder.add_section(match_build(cc, indent: indent))
122
+ end
123
+ end
124
+ end
125
+
126
+ def section_build(name, config, indent: 0, arg: nil)
127
+ sb = SectionBodyBuilder.new(indent + @base_indent)
128
+
129
+ if (v = config.delete('$type'))
130
+ sb.add_line('@type', v)
131
+ end
132
+
133
+ if (v = config.delete('$label'))
134
+ sb.add_line('@label', v)
135
+ end
136
+
137
+ if (v = config.delete('$id'))
138
+ sb.add_line('@id', v)
139
+ end
140
+
141
+ config.each do |key, val|
142
+ if val.is_a?(Array)
143
+ val.each do |v|
144
+ sb.add_section(section_build(key, v, indent: indent + @base_indent))
145
+ end
146
+ elsif val.is_a?(Hash)
147
+ harg = val.delete('$arg')
148
+ if harg.is_a?(Array)
149
+ # To prevent to generate invalid configuration for arg.
150
+ # "arg" should be String object and concatenated by ","
151
+ # when two or more objects are specified there.
152
+ sb.add_section(section_build(key, val, indent: indent + @base_indent, arg: harg&.join(',')))
153
+ else
154
+ sb.add_section(section_build(key, val, indent: indent + @base_indent, arg: harg))
155
+ end
156
+ else
157
+ sb.add_line(key, val)
158
+ end
159
+ end
160
+
161
+ SectionBuilder.new(name, sb, indent, arg)
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,107 @@
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
+ module Fluent
18
+ module Config
19
+ module YamlParser
20
+ SectionBuilder = Struct.new(:name, :body, :indent_size, :arg) do
21
+ def to_s
22
+ indent = ' ' * indent_size
23
+
24
+ if arg && !arg.to_s.empty?
25
+ "#{indent}<#{name} #{arg}>\n#{body}\n#{indent}</#{name}>"
26
+ else
27
+ "#{indent}<#{name}>\n#{body}\n#{indent}</#{name}>"
28
+ end
29
+ end
30
+
31
+ def to_element
32
+ elem = body.to_element
33
+ elem.name = name
34
+ elem.arg = arg.to_s if arg
35
+ elem.v1_config = true
36
+ elem
37
+ end
38
+ end
39
+
40
+ class RootBuilder
41
+ def initialize(system, conf)
42
+ @system = system
43
+ @conf = conf
44
+ end
45
+
46
+ attr_reader :system, :conf
47
+
48
+ def to_element
49
+ Fluent::Config::Element.new('ROOT', '', {}, [@system, @conf].compact.map(&:to_element).flatten)
50
+ end
51
+
52
+ def to_s
53
+ s = StringIO.new(+'')
54
+ s.puts(@system.to_s) if @system
55
+ s.puts(@conf.to_s) if @conf
56
+
57
+ s.string
58
+ end
59
+ end
60
+
61
+ class SectionBodyBuilder
62
+ Row = Struct.new(:key, :value, :indent) do
63
+ def to_s
64
+ "#{indent}#{key} #{value}"
65
+ end
66
+ end
67
+
68
+ def initialize(indent, root: false)
69
+ @indent = ' ' * indent
70
+ @bodies = []
71
+ @root = root
72
+ end
73
+
74
+ def add_line(k, v)
75
+ @bodies << Row.new(k, v, @indent)
76
+ end
77
+
78
+ def add_section(section)
79
+ @bodies << section
80
+ end
81
+
82
+ def to_element
83
+ if @root
84
+ return @bodies.map(&:to_element)
85
+ end
86
+
87
+ not_section, section = @bodies.partition { |e| e.is_a?(Row) }
88
+ r = {}
89
+ not_section.each do |e|
90
+ v = e.value
91
+ r[e.key] = v.respond_to?(:to_element) ? v.to_element : v
92
+ end
93
+
94
+ if @root
95
+ section.map(&:to_element)
96
+ else
97
+ Fluent::Config::Element.new('', '', r, section.map(&:to_element))
98
+ end
99
+ end
100
+
101
+ def to_s
102
+ @bodies.map(&:to_s).join("\n")
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,56 @@
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/config/yaml_parser/loader'
18
+ require 'fluent/config/yaml_parser/parser'
19
+ require 'pathname'
20
+
21
+ module Fluent
22
+ module Config
23
+ module YamlParser
24
+ def self.parse(path)
25
+ context = Kernel.binding
26
+
27
+ unless context.respond_to?(:use_nil)
28
+ context.define_singleton_method(:use_nil) do
29
+ raise Fluent::SetNil
30
+ end
31
+ end
32
+
33
+ unless context.respond_to?(:use_default)
34
+ context.define_singleton_method(:use_default) do
35
+ raise Fluent::SetDefault
36
+ end
37
+ end
38
+
39
+ unless context.respond_to?(:hostname)
40
+ context.define_singleton_method(:hostname) do
41
+ Socket.gethostname
42
+ end
43
+ end
44
+
45
+ unless context.respond_to?(:worker_id)
46
+ context.define_singleton_method(:worker_id) do
47
+ ENV['SERVERENGINE_WORKER_ID'] || ''
48
+ end
49
+ end
50
+
51
+ s = Fluent::Config::YamlParser::Loader.new(context).load(Pathname.new(path))
52
+ Fluent::Config::YamlParser::Parser.new(s).build.to_element
53
+ end
54
+ end
55
+ end
56
+ end
data/lib/fluent/config.rb CHANGED
@@ -17,6 +17,7 @@
17
17
  require 'fluent/config/error'
18
18
  require 'fluent/config/element'
19
19
  require 'fluent/configurable'
20
+ require 'fluent/config/yaml_parser'
20
21
 
21
22
  module Fluent
22
23
  module Config
@@ -25,7 +26,18 @@ module Fluent
25
26
  # @param additional_config [String] config which is added to last of config body
26
27
  # @param use_v1_config [Bool] config is formatted with v1 or not
27
28
  # @return [Fluent::Config]
28
- def self.build(config_path:, encoding: 'utf-8', additional_config: nil, use_v1_config: true)
29
+ def self.build(config_path:, encoding: 'utf-8', additional_config: nil, use_v1_config: true, type: nil)
30
+ if type == :guess
31
+ config_file_ext = File.extname(config_path)
32
+ if config_file_ext == '.yaml' || config_file_ext == '.yml'
33
+ type = :yaml
34
+ end
35
+ end
36
+
37
+ if type == :yaml || type == :yml
38
+ return Fluent::Config::YamlParser.parse(config_path)
39
+ end
40
+
29
41
  config_fname = File.basename(config_path)
30
42
  config_basedir = File.dirname(config_path)
31
43
  config_data = File.open(config_path, "r:#{encoding}:utf-8") do |f|
@@ -36,6 +48,7 @@ module Fluent
36
48
  end
37
49
  s
38
50
  end
51
+
39
52
  Fluent::Config.parse(config_data, config_fname, config_basedir, use_v1_config)
40
53
  end
41
54
 
@@ -27,7 +27,7 @@ module Fluent
27
27
  DEFAULT_PORT = 24321
28
28
 
29
29
  def initialize(name, opt = {})
30
- raise 'Counter server name is invalid' unless Validator::VALID_NAME =~ name
30
+ raise 'Counter server name is invalid' unless Validator::VALID_NAME.match?(name)
31
31
  @name = name
32
32
  @opt = opt
33
33
  @addr = @opt[:addr] || DEFAULT_ADDR
@@ -82,7 +82,7 @@ module Fluent
82
82
  raise Fluent::Counter::InvalidParams.new('The type of `key` should be String')
83
83
  end
84
84
 
85
- unless VALID_NAME =~ name
85
+ unless VALID_NAME.match?(name)
86
86
  raise Fluent::Counter::InvalidParams.new('`key` is the invalid format')
87
87
  end
88
88
  end
@@ -92,7 +92,7 @@ module Fluent
92
92
  raise Fluent::Counter::InvalidParams.new('The type of `scope` should be String')
93
93
  end
94
94
 
95
- unless VALID_SCOPE_NAME =~ name
95
+ unless VALID_SCOPE_NAME.match?(name)
96
96
  raise Fluent::Counter::InvalidParams.new('`scope` is the invalid format')
97
97
  end
98
98
  end
@@ -109,7 +109,7 @@ module Fluent
109
109
  raise Fluent::Counter::InvalidParams.new('The type of `name` should be String')
110
110
  end
111
111
 
112
- unless VALID_NAME =~ name
112
+ unless VALID_NAME.match?(name)
113
113
  raise Fluent::Counter::InvalidParams.new("`name` is the invalid format")
114
114
  end
115
115
  end
data/lib/fluent/daemon.rb CHANGED
@@ -9,7 +9,5 @@ require 'fluent/supervisor'
9
9
 
10
10
  server_module = Fluent.const_get(ARGV[0])
11
11
  worker_module = Fluent.const_get(ARGV[1])
12
- # it doesn't call ARGV in block because when reloading config, params will be initialized and then it can't use previous config.
13
- config_path = ARGV[2]
14
- params = JSON.parse(ARGV[3])
15
- ServerEngine::Daemon.run_server(server_module, worker_module) { Fluent::Supervisor.load_config(config_path, params) }
12
+ params = JSON.parse(ARGV[2])
13
+ ServerEngine::Daemon.run_server(server_module, worker_module) { Fluent::Supervisor.serverengine_config(params) }
data/lib/fluent/engine.rb CHANGED
@@ -68,7 +68,7 @@ module Fluent
68
68
  end
69
69
 
70
70
  def parse_config(io, fname, basepath = Dir.pwd, v1_config = false)
71
- if fname =~ /\.rb$/
71
+ if /\.rb$/.match?(fname)
72
72
  require 'fluent/config/dsl'
73
73
  Config::DSL::Parser.parse(io, File.join(basepath, fname))
74
74
  else
data/lib/fluent/env.rb CHANGED
@@ -33,4 +33,8 @@ module Fluent
33
33
  def self.linux?
34
34
  /linux/ === RUBY_PLATFORM
35
35
  end
36
+
37
+ def self.macos?
38
+ /darwin/ =~ RUBY_PLATFORM
39
+ end
36
40
  end
data/lib/fluent/error.rb CHANGED
@@ -28,6 +28,9 @@ module Fluent
28
28
  class InvalidRootDirectory < UnrecoverableError
29
29
  end
30
30
 
31
+ class InvalidLockDirectory < UnrecoverableError
32
+ end
33
+
31
34
  # For internal use
32
35
  class UncatchableError < Exception
33
36
  end
data/lib/fluent/event.rb CHANGED
@@ -49,7 +49,7 @@ module Fluent
49
49
  raise NotImplementedError, "DO NOT USE THIS CLASS directly."
50
50
  end
51
51
 
52
- def each(unapcker: nil, &block)
52
+ def each(unpacker: nil, &block)
53
53
  raise NotImplementedError, "DO NOT USE THIS CLASS directly."
54
54
  end
55
55
 
@@ -294,7 +294,7 @@ module Fluent
294
294
  super
295
295
  end
296
296
 
297
- def to_compressed_msgpack_stream(time_int: false)
297
+ def to_compressed_msgpack_stream(time_int: false, packer: nil)
298
298
  # time_int is always ignored because @data is always packed binary in this class
299
299
  @compressed_data
300
300
  end
@@ -308,11 +308,15 @@ module Fluent
308
308
  end
309
309
 
310
310
  module ChunkMessagePackEventStreamer
311
- # chunk.extend(ChunkEventStreamer)
311
+ # chunk.extend(ChunkMessagePackEventStreamer)
312
312
  # => chunk.each{|time, record| ... }
313
313
  def each(unpacker: nil, &block)
314
+ # Note: If need to use `unpacker`, then implement it,
315
+ # e.g., `unpacker.feed_each(io.read, &block)` (Not tested)
316
+ raise NotImplementedError, "'unpacker' argument is not implemented." if unpacker
317
+
314
318
  open do |io|
315
- (unpacker || Fluent::MessagePackFactory.msgpack_unpacker(io)).each(&block)
319
+ Fluent::MessagePackFactory.msgpack_unpacker(io).each(&block)
316
320
  end
317
321
  nil
318
322
  end