fluentd 1.14.6 → 1.15.0
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.
Potentially problematic release.
This version of fluentd might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.github/workflows/linux-test.yaml +1 -1
- data/.github/workflows/windows-test.yaml +4 -1
- data/CHANGELOG.md +53 -1
- data/fluentd.gemspec +2 -1
- data/lib/fluent/command/ctl.rb +4 -1
- data/lib/fluent/command/fluentd.rb +10 -0
- data/lib/fluent/config/literal_parser.rb +2 -2
- data/lib/fluent/config/yaml_parser/fluent_value.rb +47 -0
- data/lib/fluent/config/yaml_parser/loader.rb +91 -0
- data/lib/fluent/config/yaml_parser/parser.rb +166 -0
- data/lib/fluent/config/yaml_parser/section_builder.rb +107 -0
- data/lib/fluent/config/yaml_parser.rb +56 -0
- data/lib/fluent/config.rb +14 -1
- data/lib/fluent/plugin/file_wrapper.rb +52 -107
- data/lib/fluent/plugin/in_tail/group_watch.rb +204 -0
- data/lib/fluent/plugin/in_tail/position_file.rb +1 -15
- data/lib/fluent/plugin/in_tail.rb +66 -47
- data/lib/fluent/plugin/out_forward/socket_cache.rb +2 -0
- data/lib/fluent/plugin/output.rb +2 -1
- data/lib/fluent/plugin/parser_syslog.rb +1 -1
- data/lib/fluent/plugin_helper/server.rb +3 -1
- data/lib/fluent/plugin_helper/service_discovery.rb +2 -2
- data/lib/fluent/supervisor.rb +109 -25
- data/lib/fluent/system_config.rb +2 -1
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +2 -0
- data/test/command/test_ctl.rb +0 -1
- data/test/command/test_fluentd.rb +33 -0
- data/test/config/test_system_config.rb +3 -1
- data/test/config/test_types.rb +1 -1
- data/test/plugin/in_tail/test_io_handler.rb +14 -4
- data/test/plugin/in_tail/test_position_file.rb +0 -63
- data/test/plugin/out_forward/test_socket_cache.rb +26 -1
- data/test/plugin/test_file_wrapper.rb +0 -68
- data/test/plugin/test_in_object_space.rb +9 -3
- data/test/plugin/test_in_syslog.rb +1 -1
- data/test/plugin/test_in_tail.rb +629 -353
- data/test/plugin/test_out_forward.rb +30 -20
- data/test/plugin/test_parser_syslog.rb +1 -1
- data/test/plugin_helper/test_cert_option.rb +1 -1
- data/test/plugin_helper/test_child_process.rb +16 -4
- data/test/test_config.rb +135 -4
- data/test/test_supervisor.rb +155 -0
- metadata +11 -5
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 7bc368532203bcfd7b189e51e26a60f500db1306e6f5a4f94a03f333fb9af22d
         | 
| 4 | 
            +
              data.tar.gz: b87ab437598cb9a41bdf6301e137baadcfc27c709d3e28354c2ba4e8ff8859ed
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 45e167be3ee4b62e444b9f789694f7891590836b7e8888382a6368d3b49ddbece59f614b6eb20eb4b51f62b5e8fd4563e79304163fc78b3aaf4cc57d62a71546
         | 
| 7 | 
            +
              data.tar.gz: 44112f3c79c48e09fb6c791a0edf6a465815d6ff3f3ccaa500cb4e6b7411c39a3ac7b587c11587b57568777786e3781e2ab68cc7e78088d4af386556b699e247
         | 
| @@ -13,11 +13,14 @@ jobs: | |
| 13 13 | 
             
                strategy:
         | 
| 14 14 | 
             
                  fail-fast: false
         | 
| 15 15 | 
             
                  matrix:
         | 
| 16 | 
            -
                    ruby-version: [' | 
| 16 | 
            +
                    ruby-version: ['3.1', '2.7']
         | 
| 17 17 | 
             
                    os:
         | 
| 18 18 | 
             
                      - windows-latest
         | 
| 19 19 | 
             
                    experimental: [false]
         | 
| 20 20 | 
             
                    include:
         | 
| 21 | 
            +
                      - ruby-version: head
         | 
| 22 | 
            +
                        os: windows-latest
         | 
| 23 | 
            +
                        experimental: true
         | 
| 21 24 | 
             
                      - ruby-version: '3.0.3'
         | 
| 22 25 | 
             
                        os: windows-latest
         | 
| 23 26 | 
             
                        experimental: false
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,55 @@ | |
| 1 | 
            +
            # v1.15
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            ## Release v1.15.0 - 2022/06/29
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            ### Enhancement
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            * in_tail: Add log throttling in files based on group rules
         | 
| 8 | 
            +
              https://github.com/fluent/fluentd/pull/3535
         | 
| 9 | 
            +
              https://github.com/fluent/fluentd/pull/3771
         | 
| 10 | 
            +
            * Add `dump` command to fluent-ctl
         | 
| 11 | 
            +
              https://github.com/fluent/fluentd/pull/3680
         | 
| 12 | 
            +
            * Handle YAML configuration format on configuration file
         | 
| 13 | 
            +
              https://github.com/fluent/fluentd/pull/3712
         | 
| 14 | 
            +
            * Add `restart_worker_interval` parameter in `<system>` directive to set
         | 
| 15 | 
            +
              interval to restart workers that has stopped for some reason.
         | 
| 16 | 
            +
              https://github.com/fluent/fluentd/pull/3768
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            ### Bug fixes
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            * out_forward: Fix to update timeout of cached sockets
         | 
| 21 | 
            +
              https://github.com/fluent/fluentd/pull/3711
         | 
| 22 | 
            +
            * in_tail: Fix a possible crash on file rotation when `follow_inodes true`
         | 
| 23 | 
            +
              https://github.com/fluent/fluentd/pull/3754
         | 
| 24 | 
            +
            * output: Fix a possible crash of flush thread
         | 
| 25 | 
            +
              https://github.com/fluent/fluentd/pull/3755
         | 
| 26 | 
            +
            * in_tail: Fix crash bugs on Ruby 3.1 on Windows
         | 
| 27 | 
            +
              https://github.com/fluent/fluentd/pull/3766
         | 
| 28 | 
            +
            * in_tail: Fix a bug that in_tail cannot open non-ascii path on Windows
         | 
| 29 | 
            +
              https://github.com/fluent/fluentd/pull/3774
         | 
| 30 | 
            +
            * Fix a bug that fluentd doesn't release its own log file even after rotated by
         | 
| 31 | 
            +
              external tools
         | 
| 32 | 
            +
              https://github.com/fluent/fluentd/pull/3782
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            ### Misc
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            * in_tail: Simplify TargetInfo related code
         | 
| 37 | 
            +
              https://github.com/fluent/fluentd/pull/3489
         | 
| 38 | 
            +
            * Fix a wrong issue number in CHANGELOG
         | 
| 39 | 
            +
              https://github.com/fluent/fluentd/pull/3700
         | 
| 40 | 
            +
            * server helper: Add comments to linger_timeout behavior about Windows
         | 
| 41 | 
            +
              https://github.com/fluent/fluentd/pull/3701
         | 
| 42 | 
            +
            * service_discovery: Fix typo
         | 
| 43 | 
            +
              https://github.com/fluent/fluentd/pull/3724
         | 
| 44 | 
            +
            * test: Fix unstable tests and warnings
         | 
| 45 | 
            +
              https://github.com/fluent/fluentd/pull/3745
         | 
| 46 | 
            +
              https://github.com/fluent/fluentd/pull/3753
         | 
| 47 | 
            +
              https://github.com/fluent/fluentd/pull/3767
         | 
| 48 | 
            +
              https://github.com/fluent/fluentd/pull/3783
         | 
| 49 | 
            +
              https://github.com/fluent/fluentd/pull/3784
         | 
| 50 | 
            +
              https://github.com/fluent/fluentd/pull/3785
         | 
| 51 | 
            +
              https://github.com/fluent/fluentd/pull/3787
         | 
| 52 | 
            +
             | 
| 1 53 | 
             
            # v1.14
         | 
| 2 54 |  | 
| 3 55 | 
             
            ## Release v1.14.6 - 2022/03/31
         | 
| @@ -443,7 +495,7 @@ We recommend to upgrade Fluentd to v1.14.2 or use patched version of | |
| 443 495 | 
             
            ### New feature
         | 
| 444 496 |  | 
| 445 497 | 
             
            * in_tail: Add `follow_inode` to support log rotation with wild card
         | 
| 446 | 
            -
              https://github.com/fluent/fluentd/pull/ | 
| 498 | 
            +
              https://github.com/fluent/fluentd/pull/3182
         | 
| 447 499 | 
             
            * in_tail: Handle linux capability
         | 
| 448 500 | 
             
              https://github.com/fluent/fluentd/pull/3155
         | 
| 449 501 | 
             
              https://github.com/fluent/fluentd/pull/3162
         | 
    
        data/fluentd.gemspec
    CHANGED
    
    | @@ -22,7 +22,7 @@ Gem::Specification.new do |gem| | |
| 22 22 | 
             
              gem.add_runtime_dependency("msgpack", [">= 1.3.1", "< 2.0.0"])
         | 
| 23 23 | 
             
              gem.add_runtime_dependency("yajl-ruby", ["~> 1.0"])
         | 
| 24 24 | 
             
              gem.add_runtime_dependency("cool.io", [">= 1.4.5", "< 2.0.0"])
         | 
| 25 | 
            -
              gem.add_runtime_dependency("serverengine", [">= 2. | 
| 25 | 
            +
              gem.add_runtime_dependency("serverengine", [">= 2.3.0", "< 3.0.0"])
         | 
| 26 26 | 
             
              gem.add_runtime_dependency("http_parser.rb", [">= 0.5.1", "< 0.9.0"])
         | 
| 27 27 | 
             
              gem.add_runtime_dependency("sigdump", ["~> 0.2.2"])
         | 
| 28 28 | 
             
              gem.add_runtime_dependency("tzinfo", [">= 1.0", "< 3.0"])
         | 
| @@ -38,6 +38,7 @@ Gem::Specification.new do |gem| | |
| 38 38 | 
             
                gem.add_runtime_dependency("win32-service", ["~> 2.3.0"])
         | 
| 39 39 | 
             
                gem.add_runtime_dependency("win32-ipc", ["~> 0.7.0"])
         | 
| 40 40 | 
             
                gem.add_runtime_dependency("win32-event", ["~> 0.6.3"])
         | 
| 41 | 
            +
                gem.add_runtime_dependency("windows-api", ["~> 0.4.5"])
         | 
| 41 42 | 
             
                gem.add_runtime_dependency("windows-pr", ["~> 1.2.6"])
         | 
| 42 43 | 
             
                gem.add_runtime_dependency("certstore_c", ["~> 0.1.7"])
         | 
| 43 44 | 
             
              end
         | 
    
        data/lib/fluent/command/ctl.rb
    CHANGED
    
    | @@ -36,6 +36,7 @@ module Fluent | |
| 36 36 | 
             
                    restart: "HUP",
         | 
| 37 37 | 
             
                    flush: "USR1",
         | 
| 38 38 | 
             
                    reload: "USR2",
         | 
| 39 | 
            +
                    dump: "CONT",
         | 
| 39 40 | 
             
                  }
         | 
| 40 41 | 
             
                  WINSVC_CONTROL_CODE_MAP = {
         | 
| 41 42 | 
             
                    shutdown: SERVICE_CONTROL_STOP,
         | 
| @@ -44,6 +45,7 @@ module Fluent | |
| 44 45 | 
             
                    restart: 128,
         | 
| 45 46 | 
             
                    flush: 129,
         | 
| 46 47 | 
             
                    reload: SERVICE_CONTROL_PARAMCHANGE,
         | 
| 48 | 
            +
                    dump: 130,
         | 
| 47 49 | 
             
                  }
         | 
| 48 50 | 
             
                else
         | 
| 49 51 | 
             
                  COMMAND_MAP = {
         | 
| @@ -51,6 +53,7 @@ module Fluent | |
| 51 53 | 
             
                    restart: :HUP,
         | 
| 52 54 | 
             
                    flush: :USR1,
         | 
| 53 55 | 
             
                    reload: :USR2,
         | 
| 56 | 
            +
                    dump: :CONT,
         | 
| 54 57 | 
             
                  }
         | 
| 55 58 | 
             
                end
         | 
| 56 59 |  | 
| @@ -146,7 +149,7 @@ module Fluent | |
| 146 149 | 
             
                    event = Win32::Event.open("#{prefix}#{suffix}")
         | 
| 147 150 | 
             
                    event.set
         | 
| 148 151 | 
             
                    event.close
         | 
| 149 | 
            -
                  rescue Errno::ENOENT | 
| 152 | 
            +
                  rescue Errno::ENOENT
         | 
| 150 153 | 
             
                    puts "Error: Cannot find the fluentd process with the event name: \"#{prefix}\""
         | 
| 151 154 | 
             
                  end
         | 
| 152 155 | 
             
                end
         | 
| @@ -126,6 +126,16 @@ op.on('--without-source', "invoke a fluentd without input plugins", TrueClass) { | |
| 126 126 | 
             
              opts[:without_source] = b
         | 
| 127 127 | 
             
            }
         | 
| 128 128 |  | 
| 129 | 
            +
            op.on('--config-file-type VALU', 'guessing file type of fluentd configuration. yaml/yml or guess') { |s|
         | 
| 130 | 
            +
              if (s == 'yaml') || (s == 'yml')
         | 
| 131 | 
            +
                opts[:config_file_type] = s.to_sym
         | 
| 132 | 
            +
              elsif (s == 'guess')
         | 
| 133 | 
            +
                opts[:config_file_type] = s.to_sym
         | 
| 134 | 
            +
              else
         | 
| 135 | 
            +
                usage '--config-file-type accepts yaml/yml or guess'
         | 
| 136 | 
            +
              end
         | 
| 137 | 
            +
            }
         | 
| 138 | 
            +
             | 
| 129 139 | 
             
            op.on('--use-v1-config', "Use v1 configuration format (default)", TrueClass) {|b|
         | 
| 130 140 | 
             
              opts[:use_v1_config] = b
         | 
| 131 141 | 
             
            }
         | 
| @@ -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,91 @@ | |
| 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 | 
            +
                        load(path.parent.join(val))
         | 
| 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 | 
            +
                    class Visitor < Psych::Visitors::ToRuby
         | 
| 64 | 
            +
                      def initialize(scanner, class_loader)
         | 
| 65 | 
            +
                        super(scanner, class_loader)
         | 
| 66 | 
            +
                      end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                      def _register_domain(name, &block)
         | 
| 69 | 
            +
                        @domain_types.merge!({ name => [name, block] })
         | 
| 70 | 
            +
                      end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                      def revive_hash(hash, o)
         | 
| 73 | 
            +
                        super(hash, o).tap do |r|
         | 
| 74 | 
            +
                          if r[SHOVEL].is_a?(Hash)
         | 
| 75 | 
            +
                            h2 = {}
         | 
| 76 | 
            +
                            r.each do |k, v|
         | 
| 77 | 
            +
                              if k == SHOVEL
         | 
| 78 | 
            +
                                h2.merge!(v)
         | 
| 79 | 
            +
                              else
         | 
| 80 | 
            +
                                h2[k] = v
         | 
| 81 | 
            +
                              end
         | 
| 82 | 
            +
                            end
         | 
| 83 | 
            +
                            r.replace(h2)
         | 
| 84 | 
            +
                          end
         | 
| 85 | 
            +
                        end
         | 
| 86 | 
            +
                      end
         | 
| 87 | 
            +
                    end
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
              end
         | 
| 91 | 
            +
            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 |  |