fluentd 1.2.6 → 1.3.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/.travis.yml +4 -4
 - data/CHANGELOG.md +27 -0
 - data/CONTRIBUTING.md +2 -0
 - data/lib/fluent/config/v1_parser.rb +1 -2
 - data/lib/fluent/plugin/buffer.rb +1 -1
 - data/lib/fluent/plugin/in_forward.rb +1 -1
 - data/lib/fluent/plugin/in_http.rb +38 -0
 - data/lib/fluent/plugin/in_syslog.rb +19 -6
 - data/lib/fluent/plugin/out_forward.rb +1 -1
 - data/lib/fluent/plugin/output.rb +61 -23
 - data/lib/fluent/plugin_helper/server.rb +16 -0
 - data/lib/fluent/version.rb +1 -1
 - data/test/plugin/test_buffer.rb +1 -1
 - data/test/plugin/test_in_http.rb +23 -0
 - data/test/plugin/test_in_syslog.rb +46 -0
 - data/test/plugin/test_output.rb +32 -23
 - data/test/plugin/test_output_as_buffered.rb +19 -0
 - data/test/plugin/test_output_as_buffered_retries.rb +8 -0
 - data/test/plugin/test_output_as_buffered_secondary.rb +1 -1
 - metadata +2 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: c973680de36bad1981b1cc6bd3c23c391a04fc66
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: eb6b2c87bd06d19c2d90050355059e6030f47c14
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 390c4766aca79e9e3e235fad17b66e5ab0d979df6d77e91ac7f03b4be9a831b60214bef63a5cf0811548a8020f4954df4f27beda58dedeb5948a0f804b6a1c42
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: cef9e1fcf326748d4a72420c5ae4f6b50f3ed8af8178ba0f405ee667a675435121de90099a27170d96ac9592ed421e71655a40b2060a1967f58f62e1c311c047
         
     | 
    
        data/.travis.yml
    CHANGED
    
    | 
         @@ -9,13 +9,13 @@ matrix: 
     | 
|
| 
       9 
9 
     | 
    
         
             
              include:
         
     | 
| 
       10 
10 
     | 
    
         
             
                - rvm: 2.1.10
         
     | 
| 
       11 
11 
     | 
    
         
             
                  os: linux
         
     | 
| 
       12 
     | 
    
         
            -
                - rvm: 2.2. 
     | 
| 
      
 12 
     | 
    
         
            +
                - rvm: 2.2.10
         
     | 
| 
       13 
13 
     | 
    
         
             
                  os: linux
         
     | 
| 
       14 
     | 
    
         
            -
                - rvm: 2.3. 
     | 
| 
      
 14 
     | 
    
         
            +
                - rvm: 2.3.8
         
     | 
| 
       15 
15 
     | 
    
         
             
                  os: linux
         
     | 
| 
       16 
     | 
    
         
            -
                - rvm: 2.4. 
     | 
| 
      
 16 
     | 
    
         
            +
                - rvm: 2.4.5
         
     | 
| 
       17 
17 
     | 
    
         
             
                  os: linux
         
     | 
| 
       18 
     | 
    
         
            -
                - rvm: 2.5. 
     | 
| 
      
 18 
     | 
    
         
            +
                - rvm: 2.5.3
         
     | 
| 
       19 
19 
     | 
    
         
             
                  os: linux
         
     | 
| 
       20 
20 
     | 
    
         
             
                - rvm: ruby-head
         
     | 
| 
       21 
21 
     | 
    
         
             
                  os: linux
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,3 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # v1.3
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            ## Release v1.3.0 - 2018/11/10
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ### New features
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            * output: Change thread execution control
         
     | 
| 
      
 8 
     | 
    
         
            +
              https://github.com/fluent/fluentd/pull/2170
         
     | 
| 
      
 9 
     | 
    
         
            +
            * in_syslog: Support octet counting frame
         
     | 
| 
      
 10 
     | 
    
         
            +
              https://github.com/fluent/fluentd/pull/2147
         
     | 
| 
      
 11 
     | 
    
         
            +
            * Use `flush_thread_count` value for `queued_chunks_limit_size` when `queued_chunks_limit_size` is not specified
         
     | 
| 
      
 12 
     | 
    
         
            +
              https://github.com/fluent/fluentd/pull/2173
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            ### Enhancements
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            * output: Show backtrace for unrecoverable errors
         
     | 
| 
      
 17 
     | 
    
         
            +
              https://github.com/fluent/fluentd/pull/2149
         
     | 
| 
      
 18 
     | 
    
         
            +
            * in_http: Implement support for CORS preflight requests
         
     | 
| 
      
 19 
     | 
    
         
            +
              https://github.com/fluent/fluentd/pull/2144
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            ### Bug fixes
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            * server: Fix deadlock between on_writable and close in sockets
         
     | 
| 
      
 24 
     | 
    
         
            +
              https://github.com/fluent/fluentd/pull/2165
         
     | 
| 
      
 25 
     | 
    
         
            +
            * output: show correct error when wrong plugin is specified for secondary
         
     | 
| 
      
 26 
     | 
    
         
            +
              https://github.com/fluent/fluentd/pull/2169
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
       1 
28 
     | 
    
         
             
            # v1.2
         
     | 
| 
       2 
29 
     | 
    
         | 
| 
       3 
30 
     | 
    
         
             
            ## Release v1.2.6 - 2018/10/03
         
     | 
    
        data/CONTRIBUTING.md
    CHANGED
    
    | 
         @@ -29,6 +29,8 @@ submitting an issue to Fluentd. Even better you can submit a Pull Request with a 
     | 
|
| 
       29 
29 
     | 
    
         
             
            If you find a bug of 3rd party plugins, please submit an issue to each plugin repository.
         
     | 
| 
       30 
30 
     | 
    
         
             
            And use [omnibus-td-agent](https://github.com/treasure-data/omnibus-td-agent) repository for td-agent releated issues.
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
      
 32 
     | 
    
         
            +
            Note: Before report the issue, check latest version first. Sometimes users report fixed bug with older version.
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
       32 
34 
     | 
    
         
             
            ## Patch Guidelines
         
     | 
| 
       33 
35 
     | 
    
         | 
| 
       34 
36 
     | 
    
         
             
            Here are some things that would increase a chance that your patch is accepted:
         
     | 
| 
         @@ -174,9 +174,8 @@ module Fluent 
     | 
|
| 
       174 
174 
     | 
    
         
             
                      ss = StringScanner.new(data)
         
     | 
| 
       175 
175 
     | 
    
         
             
                      V1Parser.new(ss, basepath, fname, @eval_context).parse_element(true, nil, attrs, elems)
         
     | 
| 
       176 
176 
     | 
    
         
             
                    end
         
     | 
| 
       177 
     | 
    
         
            -
             
     | 
| 
       178 
177 
     | 
    
         
             
                  rescue SystemCallError => e
         
     | 
| 
       179 
     | 
    
         
            -
                    cpe = ConfigParseError.new("include error #{uri}")
         
     | 
| 
      
 178 
     | 
    
         
            +
                    cpe = ConfigParseError.new("include error #{uri} - #{e}")
         
     | 
| 
       180 
179 
     | 
    
         
             
                    cpe.set_backtrace(e.backtrace)
         
     | 
| 
       181 
180 
     | 
    
         
             
                    raise cpe
         
     | 
| 
       182 
181 
     | 
    
         
             
                  end
         
     | 
    
        data/lib/fluent/plugin/buffer.rb
    CHANGED
    
    
| 
         @@ -199,7 +199,7 @@ module Fluent::Plugin 
     | 
|
| 
       199 
199 
     | 
    
         
             
                    when :pingpong
         
     | 
| 
       200 
200 
     | 
    
         
             
                      success, reason_or_salt, shared_key = check_ping(msg, conn.remote_addr, user_auth_salt, nonce)
         
     | 
| 
       201 
201 
     | 
    
         
             
                      unless success
         
     | 
| 
       202 
     | 
    
         
            -
                        conn.on(:write_complete) { |c| c. 
     | 
| 
      
 202 
     | 
    
         
            +
                        conn.on(:write_complete) { |c| c.close_after_write_complete }
         
     | 
| 
       203 
203 
     | 
    
         
             
                        send_data.call(serializer, generate_pong(false, reason_or_salt, nonce, shared_key))
         
     | 
| 
       204 
204 
     | 
    
         
             
                        next
         
     | 
| 
       205 
205 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -342,6 +342,10 @@ module Fluent::Plugin 
     | 
|
| 
       342 
342 
     | 
    
         
             
                        # For multiple X-Forwarded-For headers. Use first header value.
         
     | 
| 
       343 
343 
     | 
    
         
             
                        v = v.first if v.is_a?(Array)
         
     | 
| 
       344 
344 
     | 
    
         
             
                        @remote_addr = v.split(",").first
         
     | 
| 
      
 345 
     | 
    
         
            +
                      when /Access-Control-Request-Method/i
         
     | 
| 
      
 346 
     | 
    
         
            +
                        @access_control_request_method = v
         
     | 
| 
      
 347 
     | 
    
         
            +
                      when /Access-Control-Request-Headers/i
         
     | 
| 
      
 348 
     | 
    
         
            +
                        @access_control_request_headers = v
         
     | 
| 
       345 
349 
     | 
    
         
             
                      end
         
     | 
| 
       346 
350 
     | 
    
         
             
                    }
         
     | 
| 
       347 
351 
     | 
    
         
             
                    if expect
         
     | 
| 
         @@ -367,9 +371,43 @@ module Fluent::Plugin 
     | 
|
| 
       367 
371 
     | 
    
         
             
                    @body << chunk
         
     | 
| 
       368 
372 
     | 
    
         
             
                  end
         
     | 
| 
       369 
373 
     | 
    
         | 
| 
      
 374 
     | 
    
         
            +
                  # Web browsers can send an OPTIONS request before performing POST
         
     | 
| 
      
 375 
     | 
    
         
            +
                  # to check if cross-origin requests are supported.
         
     | 
| 
      
 376 
     | 
    
         
            +
                  def handle_options_request
         
     | 
| 
      
 377 
     | 
    
         
            +
                    # Is CORS enabled in the first place?
         
     | 
| 
      
 378 
     | 
    
         
            +
                    if @cors_allow_origins.nil?
         
     | 
| 
      
 379 
     | 
    
         
            +
                      return send_response_and_close("403 Forbidden", {}, "")
         
     | 
| 
      
 380 
     | 
    
         
            +
                    end
         
     | 
| 
      
 381 
     | 
    
         
            +
             
     | 
| 
      
 382 
     | 
    
         
            +
                    # in_http does not support HTTP methods except POST
         
     | 
| 
      
 383 
     | 
    
         
            +
                    if @access_control_request_method != 'POST'
         
     | 
| 
      
 384 
     | 
    
         
            +
                      return send_response_and_close("403 Forbidden", {}, "")
         
     | 
| 
      
 385 
     | 
    
         
            +
                    end
         
     | 
| 
      
 386 
     | 
    
         
            +
             
     | 
| 
      
 387 
     | 
    
         
            +
                    header = {
         
     | 
| 
      
 388 
     | 
    
         
            +
                      "Access-Control-Allow-Methods" => "POST",
         
     | 
| 
      
 389 
     | 
    
         
            +
                      "Access-Control-Allow-Headers" => @access_control_request_headers || "",
         
     | 
| 
      
 390 
     | 
    
         
            +
                    }
         
     | 
| 
      
 391 
     | 
    
         
            +
             
     | 
| 
      
 392 
     | 
    
         
            +
                    # Check the origin and send back a CORS response
         
     | 
| 
      
 393 
     | 
    
         
            +
                    if @cors_allow_origins.include?('*')
         
     | 
| 
      
 394 
     | 
    
         
            +
                      header["Access-Control-Allow-Origin"] = "*"
         
     | 
| 
      
 395 
     | 
    
         
            +
                      send_response_and_close("200 OK", header, "")
         
     | 
| 
      
 396 
     | 
    
         
            +
                    elsif @cors_allow_origins.include?(@origin)
         
     | 
| 
      
 397 
     | 
    
         
            +
                      header["Access-Control-Allow-Origin"] = @origin
         
     | 
| 
      
 398 
     | 
    
         
            +
                      send_response_and_close("200 OK", header, "")
         
     | 
| 
      
 399 
     | 
    
         
            +
                    else
         
     | 
| 
      
 400 
     | 
    
         
            +
                      send_response_and_close("403 Forbidden", {}, "")
         
     | 
| 
      
 401 
     | 
    
         
            +
                    end
         
     | 
| 
      
 402 
     | 
    
         
            +
                  end
         
     | 
| 
      
 403 
     | 
    
         
            +
             
     | 
| 
       370 
404 
     | 
    
         
             
                  def on_message_complete
         
     | 
| 
       371 
405 
     | 
    
         
             
                    return if closing?
         
     | 
| 
       372 
406 
     | 
    
         | 
| 
      
 407 
     | 
    
         
            +
                    if @parser.http_method == 'OPTIONS'
         
     | 
| 
      
 408 
     | 
    
         
            +
                      return handle_options_request()
         
     | 
| 
      
 409 
     | 
    
         
            +
                    end
         
     | 
| 
      
 410 
     | 
    
         
            +
             
     | 
| 
       373 
411 
     | 
    
         
             
                    # CORS check
         
     | 
| 
       374 
412 
     | 
    
         
             
                    # ==========
         
     | 
| 
       375 
413 
     | 
    
         
             
                    # For every incoming request, we check if we have some CORS
         
     | 
| 
         @@ -75,6 +75,8 @@ module Fluent::Plugin 
     | 
|
| 
       75 
75 
     | 
    
         
             
                config_param :tag, :string
         
     | 
| 
       76 
76 
     | 
    
         
             
                desc 'The transport protocol used to receive logs.(udp, tcp)'
         
     | 
| 
       77 
77 
     | 
    
         
             
                config_param :protocol_type, :enum, list: [:tcp, :udp], default: :udp
         
     | 
| 
      
 78 
     | 
    
         
            +
                desc 'The message frame type.(traditional, octet_count)'
         
     | 
| 
      
 79 
     | 
    
         
            +
                config_param :frame_type, :enum, list: [:traditional, :octet_count], default: :traditional
         
     | 
| 
       78 
80 
     | 
    
         | 
| 
       79 
81 
     | 
    
         
             
                desc 'If true, add source host to event record.'
         
     | 
| 
       80 
82 
     | 
    
         
             
                config_param :include_source_host, :bool, default: false, deprecated: 'use "source_hostname_key" or "source_address_key" instead.'
         
     | 
| 
         @@ -152,18 +154,29 @@ module Fluent::Plugin 
     | 
|
| 
       152 
154 
     | 
    
         
             
                end
         
     | 
| 
       153 
155 
     | 
    
         | 
| 
       154 
156 
     | 
    
         
             
                def start_tcp_server
         
     | 
| 
       155 
     | 
    
         
            -
                   
     | 
| 
       156 
     | 
    
         
            -
             
     | 
| 
      
 157 
     | 
    
         
            +
                  octet_count_frame = @frame_type == :octet_count
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                  # syslog family adds "\n" to each message when transport is TCP and traditional frame
         
     | 
| 
      
 160 
     | 
    
         
            +
                  delimiter = octet_count_frame ? " " : "\n"
         
     | 
| 
       157 
161 
     | 
    
         
             
                  delimiter_size = delimiter.size
         
     | 
| 
       158 
162 
     | 
    
         
             
                  server_create_connection(:in_syslog_tcp_server, @port, bind: @bind, resolve_name: @resolve_hostname) do |conn|
         
     | 
| 
       159 
163 
     | 
    
         
             
                    conn.data do |data|
         
     | 
| 
       160 
164 
     | 
    
         
             
                      buffer = conn.buffer
         
     | 
| 
       161 
165 
     | 
    
         
             
                      buffer << data
         
     | 
| 
       162 
166 
     | 
    
         
             
                      pos = 0
         
     | 
| 
       163 
     | 
    
         
            -
                       
     | 
| 
       164 
     | 
    
         
            -
                         
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
      
 167 
     | 
    
         
            +
                      if octet_count_frame
         
     | 
| 
      
 168 
     | 
    
         
            +
                        while idx = buffer.index(delimiter, pos)
         
     | 
| 
      
 169 
     | 
    
         
            +
                          num = Integer(buffer[pos..idx])
         
     | 
| 
      
 170 
     | 
    
         
            +
                          pos = idx + num
         
     | 
| 
      
 171 
     | 
    
         
            +
                          msg = buffer[idx + 1...pos]
         
     | 
| 
      
 172 
     | 
    
         
            +
                          message_handler(msg, conn)
         
     | 
| 
      
 173 
     | 
    
         
            +
                        end
         
     | 
| 
      
 174 
     | 
    
         
            +
                      else
         
     | 
| 
      
 175 
     | 
    
         
            +
                        while idx = buffer.index(delimiter, pos)
         
     | 
| 
      
 176 
     | 
    
         
            +
                          msg = buffer[pos...idx]
         
     | 
| 
      
 177 
     | 
    
         
            +
                          pos = idx + delimiter_size
         
     | 
| 
      
 178 
     | 
    
         
            +
                          message_handler(msg, conn)
         
     | 
| 
      
 179 
     | 
    
         
            +
                        end
         
     | 
| 
       167 
180 
     | 
    
         
             
                      end
         
     | 
| 
       168 
181 
     | 
    
         
             
                      buffer.slice!(0, pos) if pos > 0
         
     | 
| 
       169 
182 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -828,7 +828,7 @@ module Fluent::Plugin 
     | 
|
| 
       828 
828 
     | 
    
         
             
                    when :pingpong
         
     | 
| 
       829 
829 
     | 
    
         
             
                      succeeded, reason = check_pong(ri, data)
         
     | 
| 
       830 
830 
     | 
    
         
             
                      unless succeeded
         
     | 
| 
       831 
     | 
    
         
            -
                        @log.warn "connection refused to #{@name}: #{reason}"
         
     | 
| 
      
 831 
     | 
    
         
            +
                        @log.warn "connection refused to #{@name || @host}: #{reason}"
         
     | 
| 
       832 
832 
     | 
    
         
             
                        disable! # shutdown
         
     | 
| 
       833 
833 
     | 
    
         
             
                        return
         
     | 
| 
       834 
834 
     | 
    
         
             
                      end
         
     | 
    
        data/lib/fluent/plugin/output.rb
    CHANGED
    
    | 
         @@ -154,7 +154,7 @@ module Fluent 
     | 
|
| 
       154 
154 
     | 
    
         
             
                  end
         
     | 
| 
       155 
155 
     | 
    
         | 
| 
       156 
156 
     | 
    
         
             
                  # Internal states
         
     | 
| 
       157 
     | 
    
         
            -
                  FlushThreadState = Struct.new(:thread, :next_clock)
         
     | 
| 
      
 157 
     | 
    
         
            +
                  FlushThreadState = Struct.new(:thread, :next_clock, :mutex, :cond_var)
         
     | 
| 
       158 
158 
     | 
    
         
             
                  DequeuedChunkInfo = Struct.new(:chunk_id, :time, :timeout) do
         
     | 
| 
       159 
159 
     | 
    
         
             
                    def expired?
         
     | 
| 
       160 
160 
     | 
    
         
             
                      time + timeout < Time.now
         
     | 
| 
         @@ -354,6 +354,10 @@ module Fluent 
     | 
|
| 
       354 
354 
     | 
    
         
             
                          log.warn "'flush_interval' is ignored because default 'flush_mode' is not 'interval': '#{@flush_mode}'"
         
     | 
| 
       355 
355 
     | 
    
         
             
                        end
         
     | 
| 
       356 
356 
     | 
    
         
             
                      end
         
     | 
| 
      
 357 
     | 
    
         
            +
             
     | 
| 
      
 358 
     | 
    
         
            +
                      if @buffer.queued_chunks_limit_size.nil?
         
     | 
| 
      
 359 
     | 
    
         
            +
                        @buffer.queued_chunks_limit_size = @buffer_config.flush_thread_count
         
     | 
| 
      
 360 
     | 
    
         
            +
                      end
         
     | 
| 
       357 
361 
     | 
    
         
             
                    end
         
     | 
| 
       358 
362 
     | 
    
         | 
| 
       359 
363 
     | 
    
         
             
                    if @secondary_config
         
     | 
| 
         @@ -368,6 +372,9 @@ module Fluent 
     | 
|
| 
       368 
372 
     | 
    
         
             
                      end
         
     | 
| 
       369 
373 
     | 
    
         
             
                      secondary_conf = conf.elements(name: 'secondary').first
         
     | 
| 
       370 
374 
     | 
    
         
             
                      @secondary = Plugin.new_output(secondary_type)
         
     | 
| 
      
 375 
     | 
    
         
            +
                      unless @secondary.respond_to?(:acts_as_secondary)
         
     | 
| 
      
 376 
     | 
    
         
            +
                        raise Fluent::ConfigError, "Failed to setup secondary plugin in '#{conf['@type']}'. '#{secondary_type}' plugin in not allowed due to non buffered output"
         
     | 
| 
      
 377 
     | 
    
         
            +
                      end
         
     | 
| 
       371 
378 
     | 
    
         
             
                      @secondary.acts_as_secondary(self)
         
     | 
| 
       372 
379 
     | 
    
         
             
                      @secondary.configure(secondary_conf)
         
     | 
| 
       373 
380 
     | 
    
         
             
                      if (self.class != @secondary.class) && (@custom_format || @secondary.implement?(:custom_format))
         
     | 
| 
         @@ -440,7 +447,7 @@ module Fluent 
     | 
|
| 
       440 
447 
     | 
    
         | 
| 
       441 
448 
     | 
    
         
             
                      @buffer_config.flush_thread_count.times do |i|
         
     | 
| 
       442 
449 
     | 
    
         
             
                        thread_title = "flush_thread_#{i}".to_sym
         
     | 
| 
       443 
     | 
    
         
            -
                        thread_state = FlushThreadState.new(nil, nil)
         
     | 
| 
      
 450 
     | 
    
         
            +
                        thread_state = FlushThreadState.new(nil, nil, Mutex.new, ConditionVariable.new)
         
     | 
| 
       444 
451 
     | 
    
         
             
                        thread = thread_create(thread_title) do
         
     | 
| 
       445 
452 
     | 
    
         
             
                          flush_thread_run(thread_state)
         
     | 
| 
       446 
453 
     | 
    
         
             
                        end
         
     | 
| 
         @@ -506,9 +513,14 @@ module Fluent 
     | 
|
| 
       506 
513 
     | 
    
         
             
                      @output_flush_threads_running = false
         
     | 
| 
       507 
514 
     | 
    
         
             
                      if @output_flush_threads && !@output_flush_threads.empty?
         
     | 
| 
       508 
515 
     | 
    
         
             
                        @output_flush_threads.each do |state|
         
     | 
| 
       509 
     | 
    
         
            -
                           
     | 
| 
       510 
     | 
    
         
            -
             
     | 
| 
       511 
     | 
    
         
            -
             
     | 
| 
      
 516 
     | 
    
         
            +
                          # to wakeup thread and make it to stop by itself
         
     | 
| 
      
 517 
     | 
    
         
            +
                          state.mutex.synchronize {
         
     | 
| 
      
 518 
     | 
    
         
            +
                            if state.thread && state.thread.status
         
     | 
| 
      
 519 
     | 
    
         
            +
                              state.next_clock = 0
         
     | 
| 
      
 520 
     | 
    
         
            +
                              state.cond_var.signal
         
     | 
| 
      
 521 
     | 
    
         
            +
                            end
         
     | 
| 
      
 522 
     | 
    
         
            +
                          }
         
     | 
| 
      
 523 
     | 
    
         
            +
                          Thread.pass
         
     | 
| 
       512 
524 
     | 
    
         
             
                          state.thread.join
         
     | 
| 
       513 
525 
     | 
    
         
             
                        end
         
     | 
| 
       514 
526 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -1119,24 +1131,29 @@ module Fluent 
     | 
|
| 
       1119 
1131 
     | 
    
         
             
                      if @secondary
         
     | 
| 
       1120 
1132 
     | 
    
         
             
                        if using_secondary
         
     | 
| 
       1121 
1133 
     | 
    
         
             
                          log.warn "got unrecoverable error in secondary.", error: e
         
     | 
| 
      
 1134 
     | 
    
         
            +
                          log.warn_backtrace
         
     | 
| 
       1122 
1135 
     | 
    
         
             
                          backup_chunk(chunk, using_secondary, output.delayed_commit)
         
     | 
| 
       1123 
1136 
     | 
    
         
             
                        else
         
     | 
| 
       1124 
1137 
     | 
    
         
             
                          if (self.class == @secondary.class)
         
     | 
| 
       1125 
1138 
     | 
    
         
             
                            log.warn "got unrecoverable error in primary and secondary type is same as primary. Skip secondary", error: e
         
     | 
| 
      
 1139 
     | 
    
         
            +
                            log.warn_backtrace
         
     | 
| 
       1126 
1140 
     | 
    
         
             
                            backup_chunk(chunk, using_secondary, output.delayed_commit)
         
     | 
| 
       1127 
1141 
     | 
    
         
             
                          else
         
     | 
| 
       1128 
1142 
     | 
    
         
             
                            # Call secondary output directly without retry update.
         
     | 
| 
       1129 
1143 
     | 
    
         
             
                            # In this case, delayed commit causes inconsistent state in dequeued chunks so async output in secondary is not allowed for now.
         
     | 
| 
       1130 
1144 
     | 
    
         
             
                            if @secondary.delayed_commit
         
     | 
| 
       1131 
1145 
     | 
    
         
             
                              log.warn "got unrecoverable error in primary and secondary is async output. Skip secondary for backup", error: e
         
     | 
| 
      
 1146 
     | 
    
         
            +
                              log.warn_backtrace
         
     | 
| 
       1132 
1147 
     | 
    
         
             
                              backup_chunk(chunk, using_secondary, output.delayed_commit)
         
     | 
| 
       1133 
1148 
     | 
    
         
             
                            else
         
     | 
| 
       1134 
1149 
     | 
    
         
             
                              log.warn "got unrecoverable error in primary. Skip retry and flush chunk to secondary", error: e
         
     | 
| 
      
 1150 
     | 
    
         
            +
                              log.warn_backtrace
         
     | 
| 
       1135 
1151 
     | 
    
         
             
                              begin
         
     | 
| 
       1136 
1152 
     | 
    
         
             
                                @secondary.write(chunk)
         
     | 
| 
       1137 
1153 
     | 
    
         
             
                                commit_write(chunk_id, delayed: output.delayed_commit, secondary: true)
         
     | 
| 
       1138 
1154 
     | 
    
         
             
                              rescue => e
         
     | 
| 
       1139 
1155 
     | 
    
         
             
                                log.warn "got an error in secondary for unrecoverable error", error: e
         
     | 
| 
      
 1156 
     | 
    
         
            +
                                log.warn_backtrace
         
     | 
| 
       1140 
1157 
     | 
    
         
             
                                backup_chunk(chunk, using_secondary, output.delayed_commit)
         
     | 
| 
       1141 
1158 
     | 
    
         
             
                              end
         
     | 
| 
       1142 
1159 
     | 
    
         
             
                            end
         
     | 
| 
         @@ -1144,6 +1161,7 @@ module Fluent 
     | 
|
| 
       1144 
1161 
     | 
    
         
             
                        end
         
     | 
| 
       1145 
1162 
     | 
    
         
             
                      else
         
     | 
| 
       1146 
1163 
     | 
    
         
             
                        log.warn "got unrecoverable error in primary and no secondary", error: e
         
     | 
| 
      
 1164 
     | 
    
         
            +
                        log.warn_backtrace
         
     | 
| 
       1147 
1165 
     | 
    
         
             
                        backup_chunk(chunk, using_secondary, output.delayed_commit)
         
     | 
| 
       1148 
1166 
     | 
    
         
             
                      end
         
     | 
| 
       1149 
1167 
     | 
    
         
             
                    rescue => e
         
     | 
| 
         @@ -1254,12 +1272,15 @@ module Fluent 
     | 
|
| 
       1254 
1272 
     | 
    
         
             
                    # Without locks: it is rough but enough to select "next" writer selection
         
     | 
| 
       1255 
1273 
     | 
    
         
             
                    @output_flush_thread_current_position = (@output_flush_thread_current_position + 1) % @buffer_config.flush_thread_count
         
     | 
| 
       1256 
1274 
     | 
    
         
             
                    state = @output_flush_threads[@output_flush_thread_current_position]
         
     | 
| 
       1257 
     | 
    
         
            -
                    state. 
     | 
| 
       1258 
     | 
    
         
            -
             
     | 
| 
       1259 
     | 
    
         
            -
             
     | 
| 
       1260 
     | 
    
         
            -
             
     | 
| 
       1261 
     | 
    
         
            -
                       
     | 
| 
       1262 
     | 
    
         
            -
             
     | 
| 
      
 1275 
     | 
    
         
            +
                    state.mutex.synchronize {
         
     | 
| 
      
 1276 
     | 
    
         
            +
                      if state.thread && state.thread.status # "run"/"sleep"/"aborting" or false(successfully stop) or nil(killed by exception)
         
     | 
| 
      
 1277 
     | 
    
         
            +
                        state.next_clock = 0
         
     | 
| 
      
 1278 
     | 
    
         
            +
                        state.cond_var.signal
         
     | 
| 
      
 1279 
     | 
    
         
            +
                      else
         
     | 
| 
      
 1280 
     | 
    
         
            +
                        log.warn "thread is already dead"
         
     | 
| 
      
 1281 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1282 
     | 
    
         
            +
                    }
         
     | 
| 
      
 1283 
     | 
    
         
            +
                    Thread.pass
         
     | 
| 
       1263 
1284 
     | 
    
         
             
                  end
         
     | 
| 
       1264 
1285 
     | 
    
         | 
| 
       1265 
1286 
     | 
    
         
             
                  def force_flush
         
     | 
| 
         @@ -1296,8 +1317,13 @@ module Fluent 
     | 
|
| 
       1296 
1317 
     | 
    
         
             
                  # only for tests of output plugin
         
     | 
| 
       1297 
1318 
     | 
    
         
             
                  def flush_thread_wakeup
         
     | 
| 
       1298 
1319 
     | 
    
         
             
                    @output_flush_threads.each do |state|
         
     | 
| 
       1299 
     | 
    
         
            -
                      state. 
     | 
| 
       1300 
     | 
    
         
            -
             
     | 
| 
      
 1320 
     | 
    
         
            +
                      state.mutex.synchronize {
         
     | 
| 
      
 1321 
     | 
    
         
            +
                        if state.thread && state.thread.status
         
     | 
| 
      
 1322 
     | 
    
         
            +
                          state.next_clock = 0
         
     | 
| 
      
 1323 
     | 
    
         
            +
                          state.cond_var.signal
         
     | 
| 
      
 1324 
     | 
    
         
            +
                        end
         
     | 
| 
      
 1325 
     | 
    
         
            +
                      }
         
     | 
| 
      
 1326 
     | 
    
         
            +
                      Thread.pass
         
     | 
| 
       1301 
1327 
     | 
    
         
             
                    end
         
     | 
| 
       1302 
1328 
     | 
    
         
             
                  end
         
     | 
| 
       1303 
1329 
     | 
    
         | 
| 
         @@ -1376,6 +1402,7 @@ module Fluent 
     | 
|
| 
       1376 
1402 
     | 
    
         
             
                    end
         
     | 
| 
       1377 
1403 
     | 
    
         
             
                    log.debug "flush_thread actually running"
         
     | 
| 
       1378 
1404 
     | 
    
         | 
| 
      
 1405 
     | 
    
         
            +
                    state.mutex.lock
         
     | 
| 
       1379 
1406 
     | 
    
         
             
                    begin
         
     | 
| 
       1380 
1407 
     | 
    
         
             
                      # This thread don't use `thread_current_running?` because this thread should run in `before_shutdown` phase
         
     | 
| 
       1381 
1408 
     | 
    
         
             
                      while @output_flush_threads_running
         
     | 
| 
         @@ -1391,23 +1418,32 @@ module Fluent 
     | 
|
| 
       1391 
1418 
     | 
    
         
             
                        elsif next_retry_time && next_retry_time > Time.now
         
     | 
| 
       1392 
1419 
     | 
    
         
             
                          interval = next_retry_time.to_f - Time.now.to_f
         
     | 
| 
       1393 
1420 
     | 
    
         
             
                        else
         
     | 
| 
       1394 
     | 
    
         
            -
                           
     | 
| 
       1395 
     | 
    
         
            -
             
     | 
| 
       1396 
     | 
    
         
            -
             
     | 
| 
       1397 
     | 
    
         
            -
             
     | 
| 
       1398 
     | 
    
         
            -
             
     | 
| 
       1399 
     | 
    
         
            -
             
     | 
| 
       1400 
     | 
    
         
            -
             
     | 
| 
       1401 
     | 
    
         
            -
             
     | 
| 
      
 1421 
     | 
    
         
            +
                          state.mutex.unlock
         
     | 
| 
      
 1422 
     | 
    
         
            +
                          begin
         
     | 
| 
      
 1423 
     | 
    
         
            +
                            try_flush
         
     | 
| 
      
 1424 
     | 
    
         
            +
                            # next_flush_time uses flush_thread_interval or flush_thread_burst_interval (or retrying)
         
     | 
| 
      
 1425 
     | 
    
         
            +
                            interval = next_flush_time.to_f - Time.now.to_f
         
     | 
| 
      
 1426 
     | 
    
         
            +
                            # TODO: if secondary && delayed-commit, next_flush_time will be much longer than expected
         
     | 
| 
      
 1427 
     | 
    
         
            +
                            #       because @retry still exists (#commit_write is not called yet in #try_flush)
         
     | 
| 
      
 1428 
     | 
    
         
            +
                            #       @retry should be cleared if delayed commit is enabled? Or any other solution?
         
     | 
| 
      
 1429 
     | 
    
         
            +
                            state.next_clock = Fluent::Clock.now + interval
         
     | 
| 
      
 1430 
     | 
    
         
            +
                          ensure
         
     | 
| 
      
 1431 
     | 
    
         
            +
                            state.mutex.lock
         
     | 
| 
      
 1432 
     | 
    
         
            +
                          end
         
     | 
| 
       1402 
1433 
     | 
    
         
             
                        end
         
     | 
| 
       1403 
1434 
     | 
    
         | 
| 
       1404 
1435 
     | 
    
         
             
                        if @dequeued_chunks_mutex.synchronize{ !@dequeued_chunks.empty? && @dequeued_chunks.first.expired? }
         
     | 
| 
       1405 
1436 
     | 
    
         
             
                          unless @output_flush_interrupted
         
     | 
| 
       1406 
     | 
    
         
            -
                             
     | 
| 
      
 1437 
     | 
    
         
            +
                            state.mutex.unlock
         
     | 
| 
      
 1438 
     | 
    
         
            +
                            begin
         
     | 
| 
      
 1439 
     | 
    
         
            +
                              try_rollback_write
         
     | 
| 
      
 1440 
     | 
    
         
            +
                            ensure
         
     | 
| 
      
 1441 
     | 
    
         
            +
                              state.mutex.lock
         
     | 
| 
      
 1442 
     | 
    
         
            +
                            end
         
     | 
| 
       1407 
1443 
     | 
    
         
             
                          end
         
     | 
| 
       1408 
1444 
     | 
    
         
             
                        end
         
     | 
| 
       1409 
1445 
     | 
    
         | 
| 
       1410 
     | 
    
         
            -
                         
     | 
| 
      
 1446 
     | 
    
         
            +
                        state.cond_var.wait(state.mutex, interval) if interval > 0
         
     | 
| 
       1411 
1447 
     | 
    
         
             
                      end
         
     | 
| 
       1412 
1448 
     | 
    
         
             
                    rescue => e
         
     | 
| 
       1413 
1449 
     | 
    
         
             
                      # normal errors are rescued by output plugins in #try_flush
         
     | 
| 
         @@ -1415,6 +1451,8 @@ module Fluent 
     | 
|
| 
       1415 
1451 
     | 
    
         
             
                      log.error "error on output thread", error: e
         
     | 
| 
       1416 
1452 
     | 
    
         
             
                      log.error_backtrace
         
     | 
| 
       1417 
1453 
     | 
    
         
             
                      raise
         
     | 
| 
      
 1454 
     | 
    
         
            +
                    ensure
         
     | 
| 
      
 1455 
     | 
    
         
            +
                      state.mutex.unlock
         
     | 
| 
       1418 
1456 
     | 
    
         
             
                    end
         
     | 
| 
       1419 
1457 
     | 
    
         
             
                  end
         
     | 
| 
       1420 
1458 
     | 
    
         
             
                end
         
     | 
| 
         @@ -408,6 +408,10 @@ module Fluent 
     | 
|
| 
       408 
408 
     | 
    
         
             
                      raise "not implemented here"
         
     | 
| 
       409 
409 
     | 
    
         
             
                    end
         
     | 
| 
       410 
410 
     | 
    
         | 
| 
      
 411 
     | 
    
         
            +
                    def close_after_write_complete
         
     | 
| 
      
 412 
     | 
    
         
            +
                      @sock.close_after_write_complete = true
         
     | 
| 
      
 413 
     | 
    
         
            +
                    end
         
     | 
| 
      
 414 
     | 
    
         
            +
             
     | 
| 
       411 
415 
     | 
    
         
             
                    def close
         
     | 
| 
       412 
416 
     | 
    
         
             
                      @sock.close if @close_socket
         
     | 
| 
       413 
417 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -492,6 +496,8 @@ module Fluent 
     | 
|
| 
       492 
496 
     | 
    
         | 
| 
       493 
497 
     | 
    
         
             
                  module EventHandler
         
     | 
| 
       494 
498 
     | 
    
         
             
                    class UDPServer < Coolio::IO
         
     | 
| 
      
 499 
     | 
    
         
            +
                      attr_writer :close_after_write_complete # dummy for consistent method call in callbacks
         
     | 
| 
      
 500 
     | 
    
         
            +
             
     | 
| 
       495 
501 
     | 
    
         
             
                      def initialize(sock, max_bytes, flags, close_socket, log, under_plugin_development, &callback)
         
     | 
| 
       496 
502 
     | 
    
         
             
                        raise ArgumentError, "socket must be a UDPSocket: sock = #{sock}" unless sock.is_a?(UDPSocket)
         
     | 
| 
       497 
503 
     | 
    
         | 
| 
         @@ -543,6 +549,7 @@ module Fluent 
     | 
|
| 
       543 
549 
     | 
    
         | 
| 
       544 
550 
     | 
    
         
             
                    class TCPServer < Coolio::TCPSocket
         
     | 
| 
       545 
551 
     | 
    
         
             
                      attr_reader :closing
         
     | 
| 
      
 552 
     | 
    
         
            +
                      attr_writer :close_after_write_complete
         
     | 
| 
       546 
553 
     | 
    
         | 
| 
       547 
554 
     | 
    
         
             
                      def initialize(sock, socket_option_setter, close_callback, log, under_plugin_development, connect_callback)
         
     | 
| 
       548 
555 
     | 
    
         
             
                        raise ArgumentError, "socket must be a TCPSocket: sock=#{sock}" unless sock.is_a?(TCPSocket)
         
     | 
| 
         @@ -560,6 +567,7 @@ module Fluent 
     | 
|
| 
       560 
567 
     | 
    
         
             
                        @close_callback = close_callback
         
     | 
| 
       561 
568 
     | 
    
         | 
| 
       562 
569 
     | 
    
         
             
                        @callback_connection = nil
         
     | 
| 
      
 570 
     | 
    
         
            +
                        @close_after_write_complete = false
         
     | 
| 
       563 
571 
     | 
    
         
             
                        @closing = false
         
     | 
| 
       564 
572 
     | 
    
         | 
| 
       565 
573 
     | 
    
         
             
                        @mutex = Mutex.new # to serialize #write and #close
         
     | 
| 
         @@ -587,6 +595,11 @@ module Fluent 
     | 
|
| 
       587 
595 
     | 
    
         
             
                        end
         
     | 
| 
       588 
596 
     | 
    
         
             
                      end
         
     | 
| 
       589 
597 
     | 
    
         | 
| 
      
 598 
     | 
    
         
            +
                      def on_writable
         
     | 
| 
      
 599 
     | 
    
         
            +
                        super
         
     | 
| 
      
 600 
     | 
    
         
            +
                        close if @close_after_write_complete
         
     | 
| 
      
 601 
     | 
    
         
            +
                      end
         
     | 
| 
      
 602 
     | 
    
         
            +
             
     | 
| 
       590 
603 
     | 
    
         
             
                      def on_connect
         
     | 
| 
       591 
604 
     | 
    
         
             
                        @callback_connection = TCPCallbackSocket.new(self)
         
     | 
| 
       592 
605 
     | 
    
         
             
                        @connect_callback.call(@callback_connection)
         
     | 
| 
         @@ -625,6 +638,7 @@ module Fluent 
     | 
|
| 
       625 
638 
     | 
    
         | 
| 
       626 
639 
     | 
    
         
             
                    class TLSServer < Coolio::Socket
         
     | 
| 
       627 
640 
     | 
    
         
             
                      attr_reader :closing
         
     | 
| 
      
 641 
     | 
    
         
            +
                      attr_writer :close_after_write_complete
         
     | 
| 
       628 
642 
     | 
    
         | 
| 
       629 
643 
     | 
    
         
             
                      # It can't use Coolio::TCPSocket, because Coolio::TCPSocket checks that underlying socket (1st argument of super) is TCPSocket.
         
     | 
| 
       630 
644 
     | 
    
         
             
                      def initialize(sock, context, socket_option_setter, close_callback, log, under_plugin_development, connect_callback)
         
     | 
| 
         @@ -645,6 +659,7 @@ module Fluent 
     | 
|
| 
       645 
659 
     | 
    
         
             
                        @close_callback = close_callback
         
     | 
| 
       646 
660 
     | 
    
         | 
| 
       647 
661 
     | 
    
         
             
                        @callback_connection = nil
         
     | 
| 
      
 662 
     | 
    
         
            +
                        @close_after_write_complete = false
         
     | 
| 
       648 
663 
     | 
    
         
             
                        @closing = false
         
     | 
| 
       649 
664 
     | 
    
         | 
| 
       650 
665 
     | 
    
         
             
                        @mutex = Mutex.new # to serialize #write and #close
         
     | 
| 
         @@ -738,6 +753,7 @@ module Fluent 
     | 
|
| 
       738 
753 
     | 
    
         
             
                            @_handler_write_buffer.slice!(0, written_bytes)
         
     | 
| 
       739 
754 
     | 
    
         
             
                            super
         
     | 
| 
       740 
755 
     | 
    
         
             
                          end
         
     | 
| 
      
 756 
     | 
    
         
            +
                          close if @close_after_write_complete
         
     | 
| 
       741 
757 
     | 
    
         
             
                        rescue IO::WaitWritable, IO::WaitReadable
         
     | 
| 
       742 
758 
     | 
    
         
             
                          return
         
     | 
| 
       743 
759 
     | 
    
         
             
                        rescue Errno::EINTR
         
     | 
    
        data/lib/fluent/version.rb
    CHANGED
    
    
    
        data/test/plugin/test_buffer.rb
    CHANGED
    
    | 
         @@ -170,7 +170,7 @@ class BufferTest < Test::Unit::TestCase 
     | 
|
| 
       170 
170 
     | 
    
         | 
| 
       171 
171 
     | 
    
         
             
              sub_test_case 'with default configuration and dummy implementation' do
         
     | 
| 
       172 
172 
     | 
    
         
             
                setup do
         
     | 
| 
       173 
     | 
    
         
            -
                  @p = create_buffer({})
         
     | 
| 
      
 173 
     | 
    
         
            +
                  @p = create_buffer({'queued_chunks_limit_size' => 100})
         
     | 
| 
       174 
174 
     | 
    
         
             
                  @dm0 = create_metadata(Time.parse('2016-04-11 16:00:00 +0000').to_i, nil, nil)
         
     | 
| 
       175 
175 
     | 
    
         
             
                  @dm1 = create_metadata(Time.parse('2016-04-11 16:10:00 +0000').to_i, nil, nil)
         
     | 
| 
       176 
176 
     | 
    
         
             
                  @dm2 = create_metadata(Time.parse('2016-04-11 16:20:00 +0000').to_i, nil, nil)
         
     | 
    
        data/test/plugin/test_in_http.rb
    CHANGED
    
    | 
         @@ -624,6 +624,23 @@ class HttpInputTest < Test::Unit::TestCase 
     | 
|
| 
       624 
624 
     | 
    
         
             
                end
         
     | 
| 
       625 
625 
     | 
    
         
             
              end
         
     | 
| 
       626 
626 
     | 
    
         | 
| 
      
 627 
     | 
    
         
            +
              def test_cors_preflight
         
     | 
| 
      
 628 
     | 
    
         
            +
                d = create_driver(CONFIG + 'cors_allow_origins ["*"]')
         
     | 
| 
      
 629 
     | 
    
         
            +
             
     | 
| 
      
 630 
     | 
    
         
            +
                d.run do
         
     | 
| 
      
 631 
     | 
    
         
            +
                  header = {
         
     | 
| 
      
 632 
     | 
    
         
            +
                    "Origin" => "http://foo.com",
         
     | 
| 
      
 633 
     | 
    
         
            +
                    "Access-Control-Request-Method" => "POST",
         
     | 
| 
      
 634 
     | 
    
         
            +
                    "Access-Control-Request-Headers" => "Content-Type",
         
     | 
| 
      
 635 
     | 
    
         
            +
                  }
         
     | 
| 
      
 636 
     | 
    
         
            +
                  res = options("/cors.test", {}, header)
         
     | 
| 
      
 637 
     | 
    
         
            +
             
     | 
| 
      
 638 
     | 
    
         
            +
                  assert_equal "200", res.code
         
     | 
| 
      
 639 
     | 
    
         
            +
                  assert_equal "*", res["Access-Control-Allow-Origin"]
         
     | 
| 
      
 640 
     | 
    
         
            +
                  assert_equal "POST", res["Access-Control-Allow-Methods"]
         
     | 
| 
      
 641 
     | 
    
         
            +
                end
         
     | 
| 
      
 642 
     | 
    
         
            +
              end
         
     | 
| 
      
 643 
     | 
    
         
            +
             
     | 
| 
       627 
644 
     | 
    
         
             
              def test_content_encoding_gzip
         
     | 
| 
       628 
645 
     | 
    
         
             
                d = create_driver
         
     | 
| 
       629 
646 
     | 
    
         | 
| 
         @@ -744,6 +761,12 @@ class HttpInputTest < Test::Unit::TestCase 
     | 
|
| 
       744 
761 
     | 
    
         
             
                assert_equal $test_in_http_connection_object_ids[0], $test_in_http_connection_object_ids[1]
         
     | 
| 
       745 
762 
     | 
    
         
             
              end
         
     | 
| 
       746 
763 
     | 
    
         | 
| 
      
 764 
     | 
    
         
            +
              def options(path, params, header = {})
         
     | 
| 
      
 765 
     | 
    
         
            +
                http = Net::HTTP.new("127.0.0.1", PORT)
         
     | 
| 
      
 766 
     | 
    
         
            +
                req = Net::HTTP::Options.new(path, header)
         
     | 
| 
      
 767 
     | 
    
         
            +
                http.request(req)
         
     | 
| 
      
 768 
     | 
    
         
            +
              end
         
     | 
| 
      
 769 
     | 
    
         
            +
             
     | 
| 
       747 
770 
     | 
    
         
             
              def post(path, params, header = {}, &block)
         
     | 
| 
       748 
771 
     | 
    
         
             
                http = Net::HTTP.new("127.0.0.1", PORT)
         
     | 
| 
       749 
772 
     | 
    
         
             
                req = Net::HTTP::Post.new(path, header)
         
     | 
| 
         @@ -286,4 +286,50 @@ EOS 
     | 
|
| 
       286 
286 
     | 
    
         
             
                  assert_equal(options[:facility], events[i][2]['facility']) if options[:facility]
         
     | 
| 
       287 
287 
     | 
    
         
             
                }
         
     | 
| 
       288 
288 
     | 
    
         
             
              end
         
     | 
| 
      
 289 
     | 
    
         
            +
             
     | 
| 
      
 290 
     | 
    
         
            +
              sub_test_case 'octet counting frame' do
         
     | 
| 
      
 291 
     | 
    
         
            +
                def test_msg_size_with_tcp
         
     | 
| 
      
 292 
     | 
    
         
            +
                  d = create_driver([CONFIG, 'protocol_type tcp', 'frame_type octet_count'].join("\n"))
         
     | 
| 
      
 293 
     | 
    
         
            +
                  tests = create_test_case
         
     | 
| 
      
 294 
     | 
    
         
            +
             
     | 
| 
      
 295 
     | 
    
         
            +
                  d.run(expect_emits: 2) do
         
     | 
| 
      
 296 
     | 
    
         
            +
                    tests.each {|test|
         
     | 
| 
      
 297 
     | 
    
         
            +
                      TCPSocket.open('127.0.0.1', PORT) do |s|
         
     | 
| 
      
 298 
     | 
    
         
            +
                        s.send(test['msg'], 0)
         
     | 
| 
      
 299 
     | 
    
         
            +
                      end
         
     | 
| 
      
 300 
     | 
    
         
            +
                    }
         
     | 
| 
      
 301 
     | 
    
         
            +
                  end
         
     | 
| 
      
 302 
     | 
    
         
            +
             
     | 
| 
      
 303 
     | 
    
         
            +
                  assert(d.events.size > 0)
         
     | 
| 
      
 304 
     | 
    
         
            +
                  compare_test_result(d.events, tests)
         
     | 
| 
      
 305 
     | 
    
         
            +
                end
         
     | 
| 
      
 306 
     | 
    
         
            +
             
     | 
| 
      
 307 
     | 
    
         
            +
                def test_msg_size_with_same_tcp_connection
         
     | 
| 
      
 308 
     | 
    
         
            +
                  d = create_driver([CONFIG, 'protocol_type tcp', 'frame_type octet_count'].join("\n"))
         
     | 
| 
      
 309 
     | 
    
         
            +
                  tests = create_test_case
         
     | 
| 
      
 310 
     | 
    
         
            +
             
     | 
| 
      
 311 
     | 
    
         
            +
                  d.run(expect_emits: 2) do
         
     | 
| 
      
 312 
     | 
    
         
            +
                    TCPSocket.open('127.0.0.1', PORT) do |s|
         
     | 
| 
      
 313 
     | 
    
         
            +
                      tests.each {|test|
         
     | 
| 
      
 314 
     | 
    
         
            +
                        s.send(test['msg'], 0)
         
     | 
| 
      
 315 
     | 
    
         
            +
                      }
         
     | 
| 
      
 316 
     | 
    
         
            +
                    end
         
     | 
| 
      
 317 
     | 
    
         
            +
                  end
         
     | 
| 
      
 318 
     | 
    
         
            +
             
     | 
| 
      
 319 
     | 
    
         
            +
                  assert(d.events.size > 0)
         
     | 
| 
      
 320 
     | 
    
         
            +
                  compare_test_result(d.events, tests)
         
     | 
| 
      
 321 
     | 
    
         
            +
                end
         
     | 
| 
      
 322 
     | 
    
         
            +
             
     | 
| 
      
 323 
     | 
    
         
            +
                def create_test_case(large_message: false)
         
     | 
| 
      
 324 
     | 
    
         
            +
                  msgs = [
         
     | 
| 
      
 325 
     | 
    
         
            +
                    {'msg' => '<6>Sep 10 00:00:00 localhost logger: ' + 'x' * 100, 'expected' => 'x' * 100},
         
     | 
| 
      
 326 
     | 
    
         
            +
                    {'msg' => '<6>Sep 10 00:00:00 localhost logger: ' + 'x' * 1024, 'expected' => 'x' * 1024},
         
     | 
| 
      
 327 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 328 
     | 
    
         
            +
                  msgs.each { |msg|
         
     | 
| 
      
 329 
     | 
    
         
            +
                    m = msg['msg']
         
     | 
| 
      
 330 
     | 
    
         
            +
                    msg['msg'] = "#{m.size + 1} #{m}"
         
     | 
| 
      
 331 
     | 
    
         
            +
                  }
         
     | 
| 
      
 332 
     | 
    
         
            +
                  msgs
         
     | 
| 
      
 333 
     | 
    
         
            +
                end
         
     | 
| 
      
 334 
     | 
    
         
            +
              end
         
     | 
| 
       289 
335 
     | 
    
         
             
            end
         
     | 
    
        data/test/plugin/test_output.rb
    CHANGED
    
    | 
         @@ -828,34 +828,43 @@ class OutputTest < Test::Unit::TestCase 
     | 
|
| 
       828 
828 
     | 
    
         
             
                  assert_equal :interval, @i.instance_variable_get(:@flush_mode)
         
     | 
| 
       829 
829 
     | 
    
         
             
                end
         
     | 
| 
       830 
830 
     | 
    
         | 
| 
       831 
     | 
    
         
            -
                 
     | 
| 
       832 
     | 
    
         
            -
                   
     | 
| 
       833 
     | 
    
         
            -
             
     | 
| 
       834 
     | 
    
         
            -
             
     | 
| 
      
 831 
     | 
    
         
            +
                sub_test_case 'configure secondary' do
         
     | 
| 
      
 832 
     | 
    
         
            +
                  test "Warn if primary type is different from secondary type and either primary or secondary has custom_format" do
         
     | 
| 
      
 833 
     | 
    
         
            +
                    o = create_output(:buffered)
         
     | 
| 
      
 834 
     | 
    
         
            +
                    mock(o.log).warn("secondary type should be same with primary one",
         
     | 
| 
      
 835 
     | 
    
         
            +
                                     { primary: o.class.to_s, secondary: "Fluent::Plugin::TestOutput" })
         
     | 
| 
      
 836 
     | 
    
         
            +
             
     | 
| 
      
 837 
     | 
    
         
            +
                    o.configure(config_element('ROOT','',{},[config_element('secondary','',{'@type'=>'test', 'name' => "cool"})]))
         
     | 
| 
      
 838 
     | 
    
         
            +
                    assert_not_nil o.instance_variable_get(:@secondary)
         
     | 
| 
      
 839 
     | 
    
         
            +
                  end
         
     | 
| 
       835 
840 
     | 
    
         | 
| 
       836 
     | 
    
         
            -
                   
     | 
| 
       837 
     | 
    
         
            -
             
     | 
| 
       838 
     | 
    
         
            -
             
     | 
| 
      
 841 
     | 
    
         
            +
                  test "don't warn if primary type is the same as secondary type" do
         
     | 
| 
      
 842 
     | 
    
         
            +
                    o = Fluent::Plugin::TestOutput.new
         
     | 
| 
      
 843 
     | 
    
         
            +
                    mock(o.log).warn("secondary type should be same with primary one",
         
     | 
| 
      
 844 
     | 
    
         
            +
                                     { primary: o.class.to_s, secondary: "Fluent::Plugin::TestOutput" }).never
         
     | 
| 
       839 
845 
     | 
    
         | 
| 
       840 
     | 
    
         
            -
             
     | 
| 
       841 
     | 
    
         
            -
             
     | 
| 
       842 
     | 
    
         
            -
             
     | 
| 
       843 
     | 
    
         
            -
             
     | 
| 
      
 846 
     | 
    
         
            +
                    o.configure(config_element('ROOT','',{'name' => "cool2"},
         
     | 
| 
      
 847 
     | 
    
         
            +
                                               [config_element('secondary','',{'@type'=>'test', 'name' => "cool"}),
         
     | 
| 
      
 848 
     | 
    
         
            +
                                                config_element('buffer','',{'@type'=>'memory'})]
         
     | 
| 
      
 849 
     | 
    
         
            +
                                              ))
         
     | 
| 
      
 850 
     | 
    
         
            +
                    assert_not_nil o.instance_variable_get(:@secondary)
         
     | 
| 
      
 851 
     | 
    
         
            +
                  end
         
     | 
| 
       844 
852 
     | 
    
         | 
| 
       845 
     | 
    
         
            -
                   
     | 
| 
       846 
     | 
    
         
            -
             
     | 
| 
       847 
     | 
    
         
            -
             
     | 
| 
       848 
     | 
    
         
            -
             
     | 
| 
       849 
     | 
    
         
            -
                  assert_not_nil o.instance_variable_get(:@secondary)
         
     | 
| 
       850 
     | 
    
         
            -
                end
         
     | 
| 
      
 853 
     | 
    
         
            +
                  test "don't warn if primary type is different from secondary type and both don't have custom_format" do
         
     | 
| 
      
 854 
     | 
    
         
            +
                    o = create_output(:standard)
         
     | 
| 
      
 855 
     | 
    
         
            +
                    mock(o.log).warn("secondary type should be same with primary one",
         
     | 
| 
      
 856 
     | 
    
         
            +
                                     { primary: o.class.to_s, secondary: "Fluent::Plugin::TestOutput" }).never
         
     | 
| 
       851 
857 
     | 
    
         | 
| 
       852 
     | 
    
         
            -
             
     | 
| 
       853 
     | 
    
         
            -
             
     | 
| 
       854 
     | 
    
         
            -
                   
     | 
| 
       855 
     | 
    
         
            -
                                            { primary: o.class.to_s, secondary: "Fluent::Plugin::TestOutput" }).never
         
     | 
| 
      
 858 
     | 
    
         
            +
                    o.configure(config_element('ROOT','',{},[config_element('secondary','',{'@type'=>'test', 'name' => "cool"})]))
         
     | 
| 
      
 859 
     | 
    
         
            +
                    assert_not_nil o.instance_variable_get(:@secondary)
         
     | 
| 
      
 860 
     | 
    
         
            +
                  end
         
     | 
| 
       856 
861 
     | 
    
         | 
| 
       857 
     | 
    
         
            -
                   
     | 
| 
       858 
     | 
    
         
            -
             
     | 
| 
      
 862 
     | 
    
         
            +
                  test "raise configuration error if secondary type specifies non buffered output" do
         
     | 
| 
      
 863 
     | 
    
         
            +
                    o = create_output(:standard)
         
     | 
| 
      
 864 
     | 
    
         
            +
                    assert_raise Fluent::ConfigError do
         
     | 
| 
      
 865 
     | 
    
         
            +
                      o.configure(config_element('ROOT','',{},[config_element('secondary','',{'@type'=>'copy'})]))
         
     | 
| 
      
 866 
     | 
    
         
            +
                    end
         
     | 
| 
      
 867 
     | 
    
         
            +
                  end
         
     | 
| 
       859 
868 
     | 
    
         
             
                end
         
     | 
| 
       860 
869 
     | 
    
         
             
              end
         
     | 
| 
       861 
870 
     | 
    
         | 
| 
         @@ -219,6 +219,24 @@ class BufferedOutputTest < Test::Unit::TestCase 
     | 
|
| 
       219 
219 
     | 
    
         
             
                Timecop.return
         
     | 
| 
       220 
220 
     | 
    
         
             
              end
         
     | 
| 
       221 
221 
     | 
    
         | 
| 
      
 222 
     | 
    
         
            +
              test 'queued_chunks_limit_size is same as flush_thread_count by default' do
         
     | 
| 
      
 223 
     | 
    
         
            +
                hash = {'flush_thread_count' => 4}
         
     | 
| 
      
 224 
     | 
    
         
            +
                i = create_output
         
     | 
| 
      
 225 
     | 
    
         
            +
                i.register(:prefer_buffered_processing) { true }
         
     | 
| 
      
 226 
     | 
    
         
            +
                i.configure(config_element('ROOT', '', {}, [config_element('buffer','tag',hash)]))
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
                assert_equal 4, i.buffer.queued_chunks_limit_size
         
     | 
| 
      
 229 
     | 
    
         
            +
              end
         
     | 
| 
      
 230 
     | 
    
         
            +
             
     | 
| 
      
 231 
     | 
    
         
            +
              test 'prefer queued_chunks_limit_size parameter than flush_thread_count' do
         
     | 
| 
      
 232 
     | 
    
         
            +
                hash = {'flush_thread_count' => 4, 'queued_chunks_limit_size' => 2}
         
     | 
| 
      
 233 
     | 
    
         
            +
                i = create_output
         
     | 
| 
      
 234 
     | 
    
         
            +
                i.register(:prefer_buffered_processing) { true }
         
     | 
| 
      
 235 
     | 
    
         
            +
                i.configure(config_element('ROOT', '', {}, [config_element('buffer','tag',hash)]))
         
     | 
| 
      
 236 
     | 
    
         
            +
             
     | 
| 
      
 237 
     | 
    
         
            +
                assert_equal 2, i.buffer.queued_chunks_limit_size
         
     | 
| 
      
 238 
     | 
    
         
            +
              end
         
     | 
| 
      
 239 
     | 
    
         
            +
             
     | 
| 
       222 
240 
     | 
    
         
             
              sub_test_case 'chunk feature in #write for output plugins' do
         
     | 
| 
       223 
241 
     | 
    
         
             
                setup do
         
     | 
| 
       224 
242 
     | 
    
         
             
                  @stored_global_logger = $log
         
     | 
| 
         @@ -1064,6 +1082,7 @@ class BufferedOutputTest < Test::Unit::TestCase 
     | 
|
| 
       1064 
1082 
     | 
    
         
             
                    'flush_thread_count' => 1,
         
     | 
| 
       1065 
1083 
     | 
    
         
             
                    'flush_thread_burst_interval' => 0.1,
         
     | 
| 
       1066 
1084 
     | 
    
         
             
                    'chunk_limit_size' => 1024,
         
     | 
| 
      
 1085 
     | 
    
         
            +
                    'queued_chunks_limit_size' => 100
         
     | 
| 
       1067 
1086 
     | 
    
         
             
                  }
         
     | 
| 
       1068 
1087 
     | 
    
         
             
                  @i = create_output(:buffered)
         
     | 
| 
       1069 
1088 
     | 
    
         
             
                  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_key,hash)]))
         
     | 
| 
         @@ -123,6 +123,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase 
     | 
|
| 
       123 
123 
     | 
    
         
             
                    'flush_interval' => 1,
         
     | 
| 
       124 
124 
     | 
    
         
             
                    'flush_thread_burst_interval' => 0.1,
         
     | 
| 
       125 
125 
     | 
    
         
             
                    'retry_randomize' => false,
         
     | 
| 
      
 126 
     | 
    
         
            +
                    'queued_chunks_limit_size' => 100
         
     | 
| 
       126 
127 
     | 
    
         
             
                  }
         
     | 
| 
       127 
128 
     | 
    
         
             
                  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_key,hash)]))
         
     | 
| 
       128 
129 
     | 
    
         
             
                  @i.register(:prefer_buffered_processing){ true }
         
     | 
| 
         @@ -252,6 +253,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase 
     | 
|
| 
       252 
253 
     | 
    
         
             
                    'flush_thread_burst_interval' => 0.1,
         
     | 
| 
       253 
254 
     | 
    
         
             
                    'retry_randomize' => false,
         
     | 
| 
       254 
255 
     | 
    
         
             
                    'retry_timeout' => 3600,
         
     | 
| 
      
 256 
     | 
    
         
            +
                    'queued_chunks_limit_size' => 100
         
     | 
| 
       255 
257 
     | 
    
         
             
                  }
         
     | 
| 
       256 
258 
     | 
    
         
             
                  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_key,hash)]))
         
     | 
| 
       257 
259 
     | 
    
         
             
                  @i.register(:prefer_buffered_processing){ true }
         
     | 
| 
         @@ -342,6 +344,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase 
     | 
|
| 
       342 
344 
     | 
    
         
             
                    'flush_thread_burst_interval' => 0.1,
         
     | 
| 
       343 
345 
     | 
    
         
             
                    'retry_randomize' => false,
         
     | 
| 
       344 
346 
     | 
    
         
             
                    'retry_max_times' => 10,
         
     | 
| 
      
 347 
     | 
    
         
            +
                    'queued_chunks_limit_size' => 100
         
     | 
| 
       345 
348 
     | 
    
         
             
                  }
         
     | 
| 
       346 
349 
     | 
    
         
             
                  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_key,hash)]))
         
     | 
| 
       347 
350 
     | 
    
         
             
                  @i.register(:prefer_buffered_processing){ true }
         
     | 
| 
         @@ -485,6 +488,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase 
     | 
|
| 
       485 
488 
     | 
    
         
             
                    'retry_type' => :periodic,
         
     | 
| 
       486 
489 
     | 
    
         
             
                    'retry_wait' => 3,
         
     | 
| 
       487 
490 
     | 
    
         
             
                    'retry_randomize' => false,
         
     | 
| 
      
 491 
     | 
    
         
            +
                    'queued_chunks_limit_size' => 100
         
     | 
| 
       488 
492 
     | 
    
         
             
                  }
         
     | 
| 
       489 
493 
     | 
    
         
             
                  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_key,hash)]))
         
     | 
| 
       490 
494 
     | 
    
         
             
                  @i.register(:prefer_buffered_processing){ true }
         
     | 
| 
         @@ -531,6 +535,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase 
     | 
|
| 
       531 
535 
     | 
    
         
             
                    'retry_wait' => 30,
         
     | 
| 
       532 
536 
     | 
    
         
             
                    'retry_randomize' => false,
         
     | 
| 
       533 
537 
     | 
    
         
             
                    'retry_timeout' => 120,
         
     | 
| 
      
 538 
     | 
    
         
            +
                    'queued_chunks_limit_size' => 100
         
     | 
| 
       534 
539 
     | 
    
         
             
                  }
         
     | 
| 
       535 
540 
     | 
    
         
             
                  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_key,hash)]))
         
     | 
| 
       536 
541 
     | 
    
         
             
                  @i.register(:prefer_buffered_processing){ true }
         
     | 
| 
         @@ -626,6 +631,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase 
     | 
|
| 
       626 
631 
     | 
    
         
             
                    'retry_wait' => 3,
         
     | 
| 
       627 
632 
     | 
    
         
             
                    'retry_randomize' => false,
         
     | 
| 
       628 
633 
     | 
    
         
             
                    'retry_max_times' => 10,
         
     | 
| 
      
 634 
     | 
    
         
            +
                    'queued_chunks_limit_size' => 100
         
     | 
| 
       629 
635 
     | 
    
         
             
                  }
         
     | 
| 
       630 
636 
     | 
    
         
             
                  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_key,hash)]))
         
     | 
| 
       631 
637 
     | 
    
         
             
                  @i.register(:prefer_buffered_processing){ true }
         
     | 
| 
         @@ -724,6 +730,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase 
     | 
|
| 
       724 
730 
     | 
    
         
             
                    'retry_randomize' => false,
         
     | 
| 
       725 
731 
     | 
    
         
             
                    'retry_timeout' => 3600,
         
     | 
| 
       726 
732 
     | 
    
         
             
                    'retry_max_times' => 10,
         
     | 
| 
      
 733 
     | 
    
         
            +
                    'queued_chunks_limit_size' => 100
         
     | 
| 
       727 
734 
     | 
    
         
             
                  }
         
     | 
| 
       728 
735 
     | 
    
         
             
                  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_key,hash)]))
         
     | 
| 
       729 
736 
     | 
    
         
             
                  @i.register(:prefer_buffered_processing){ true }
         
     | 
| 
         @@ -795,6 +802,7 @@ class BufferedOutputRetryTest < Test::Unit::TestCase 
     | 
|
| 
       795 
802 
     | 
    
         
             
                    'retry_wait' => 30,
         
     | 
| 
       796 
803 
     | 
    
         
             
                    'retry_timeout' => 360,
         
     | 
| 
       797 
804 
     | 
    
         
             
                    'retry_max_times' => 10,
         
     | 
| 
      
 805 
     | 
    
         
            +
                    'queued_chunks_limit_size' => 100
         
     | 
| 
       798 
806 
     | 
    
         
             
                  }
         
     | 
| 
       799 
807 
     | 
    
         
             
                  @i.configure(config_element('ROOT','',{},[config_element('buffer',chunk_key,hash)]))
         
     | 
| 
       800 
808 
     | 
    
         
             
                  @i.register(:prefer_buffered_processing){ true }
         
     | 
| 
         @@ -544,7 +544,7 @@ class BufferedOutputSecondaryTest < Test::Unit::TestCase 
     | 
|
| 
       544 
544 
     | 
    
         
             
                test 'secondary plugin can do delayed commit even if primary does not do it, and non-committed chunks will be rollbacked by primary' do
         
     | 
| 
       545 
545 
     | 
    
         
             
                  written = []
         
     | 
| 
       546 
546 
     | 
    
         
             
                  chunks = []
         
     | 
| 
       547 
     | 
    
         
            -
                  priconf = config_element('buffer','tag',{'flush_interval' => 1, 'retry_type' => :periodic, 'retry_wait' => 3, 'retry_timeout' => 60, 'delayed_commit_timeout' => 2, 'retry_randomize' => false})
         
     | 
| 
      
 547 
     | 
    
         
            +
                  priconf = config_element('buffer','tag',{'flush_interval' => 1, 'retry_type' => :periodic, 'retry_wait' => 3, 'retry_timeout' => 60, 'delayed_commit_timeout' => 2, 'retry_randomize' => false, 'queued_chunks_limit_size' => 10})
         
     | 
| 
       548 
548 
     | 
    
         
             
                  secconf = config_element('secondary','',{'@type' => 'output_secondary_test2'})
         
     | 
| 
       549 
549 
     | 
    
         
             
                  @i.configure(config_element('ROOT','',{},[priconf,secconf]))
         
     | 
| 
       550 
550 
     | 
    
         
             
                  @i.register(:prefer_buffered_processing){ true }
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: fluentd
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 1. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.3.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Sadayuki Furuhashi
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2018-10 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2018-11-10 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: msgpack
         
     |