fluentd 1.13.3 → 1.16.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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