logstash-input-kafka 2.1.0 → 3.0.0.beta1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +0 -22
- data/Gemfile +2 -1
- data/LICENSE +1 -1
- data/README.md +3 -12
- data/lib/logstash/inputs/kafka.rb +174 -177
- data/lib/logstash-input-kafka_jars.rb +5 -0
- data/logstash-input-kafka.gemspec +3 -6
- data/spec/integration/inputs/kafka_spec.rb +21 -0
- data/spec/unit/inputs/kafka_spec.rb +56 -0
- data/vendor/jar-dependencies/runtime-jars/kafka-clients-0.9.0.0.jar +0 -0
- data/vendor/jar-dependencies/runtime-jars/slf4j-api-1.7.13.jar +0 -0
- data/vendor/jar-dependencies/runtime-jars/slf4j-noop-1.7.13.jar +0 -0
- metadata +36 -38
- data/spec/inputs/kafka_spec.rb +0 -133
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 9c608112bad7e897363c4d3328b7979746f5825e
         | 
| 4 | 
            +
              data.tar.gz: 67cc809f94c52b10bad640ab916601958824ed83
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 2df9dd8df82666322cbbced05a00cb930b489c640a121d57dbe947d2ecb9ba9f025c9457fba0ae085bbe0c4fb47c95cebca3727531da36b70df43d6d54001c20
         | 
| 7 | 
            +
              data.tar.gz: b3c4d7f98f3a81932279bc157665862a71ae1f3f62e6d88f0fb8a56dac5f82cb3984fa00ae904496dad4eef1528e0b885f2ff56046e671f6293956d606c02998
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,25 +1,3 @@ | |
| 1 | 
            -
            # 2.1.0
         | 
| 2 | 
            -
             - Users can now use custom log4j file to control logging output.
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            # 2.0.9
         | 
| 5 | 
            -
             - Fix shutdown sequence bug where a shutdown event found itself in queue after a shutdown was initiated
         | 
| 6 | 
            -
             | 
| 7 | 
            -
            # 2.0.7
         | 
| 8 | 
            -
             - Update to jruby-kafka 1.6 which includes Kafka 0.8.2.2 enabling LZ4 decompression.
         | 
| 9 | 
            -
             | 
| 10 | 
            -
            # 2.0.6
         | 
| 11 | 
            -
              - Depend on logstash-core-plugin-api instead of logstash-core, removing the need to mass update plugins on major releases of logstash
         | 
| 12 | 
            -
             | 
| 13 | 
            -
            # 2.0.5
         | 
| 14 | 
            -
              - New dependency requirements for logstash-core for the 5.0 release
         | 
| 15 | 
            -
             | 
| 16 | 
            -
            ## 2.0.4
         | 
| 17 | 
            -
             - Fix safe shutdown while plugin waits on Kafka for new events
         | 
| 18 | 
            -
             - Expose auto_commit_interval_ms to control offset commit frequency
         | 
| 19 | 
            -
             | 
| 20 | 
            -
            ## 2.0.3
         | 
| 21 | 
            -
             - Fix infinite loop when no new messages are found in Kafka
         | 
| 22 | 
            -
             | 
| 23 1 | 
             
            ## 2.0.0
         | 
| 24 2 | 
             
             - Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully, 
         | 
| 25 3 | 
             
               instead of using Thread.raise on the plugins' threads. Ref: https://github.com/elastic/logstash/pull/3895
         | 
    
        data/Gemfile
    CHANGED
    
    
    
        data/LICENSE
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -1,6 +1,7 @@ | |
| 1 1 | 
             
            # Logstash Plugin
         | 
| 2 2 |  | 
| 3 | 
            -
            [](http://build-eu-00.elastic.co/view/LS%20Plugins/view/LS%20Inputs/job/logstash-plugin-input-kafka-unit/)
         | 
| 4 5 |  | 
| 5 6 | 
             
            This is a plugin for [Logstash](https://github.com/elastic/logstash).
         | 
| 6 7 |  | 
| @@ -55,12 +56,7 @@ gem "logstash-filter-awesome", :path => "/your/local/logstash-filter-awesome" | |
| 55 56 | 
             
            ```
         | 
| 56 57 | 
             
            - Install plugin
         | 
| 57 58 | 
             
            ```sh
         | 
| 58 | 
            -
            # Logstash 2.3 and higher
         | 
| 59 | 
            -
            bin/logstash-plugin install --no-verify
         | 
| 60 | 
            -
             | 
| 61 | 
            -
            # Prior to Logstash 2.3
         | 
| 62 59 | 
             
            bin/plugin install --no-verify
         | 
| 63 | 
            -
             | 
| 64 60 | 
             
            ```
         | 
| 65 61 | 
             
            - Run Logstash with your plugin
         | 
| 66 62 | 
             
            ```sh
         | 
| @@ -78,12 +74,7 @@ gem build logstash-filter-awesome.gemspec | |
| 78 74 | 
             
            ```
         | 
| 79 75 | 
             
            - Install the plugin from the Logstash home
         | 
| 80 76 | 
             
            ```sh
         | 
| 81 | 
            -
             | 
| 82 | 
            -
            bin/logstash-plugin install --no-verify
         | 
| 83 | 
            -
             | 
| 84 | 
            -
            # Prior to Logstash 2.3
         | 
| 85 | 
            -
            bin/plugin install --no-verify
         | 
| 86 | 
            -
             | 
| 77 | 
            +
            bin/plugin install /your/local/plugin/logstash-filter-awesome.gem
         | 
| 87 78 | 
             
            ```
         | 
| 88 79 | 
             
            - Start Logstash and proceed to test the plugin
         | 
| 89 80 |  | 
| @@ -1,30 +1,23 @@ | |
| 1 1 | 
             
            require 'logstash/namespace'
         | 
| 2 2 | 
             
            require 'logstash/inputs/base'
         | 
| 3 | 
            -
            require 'jruby-kafka'
         | 
| 4 3 | 
             
            require 'stud/interval'
         | 
| 4 | 
            +
            require 'java'
         | 
| 5 | 
            +
            require 'logstash-input-kafka_jars.rb'
         | 
| 5 6 |  | 
| 6 | 
            -
            # This input will read events from a Kafka topic. It uses the  | 
| 7 | 
            -
            #  | 
| 8 | 
            -
            #  | 
| 7 | 
            +
            # This input will read events from a Kafka topic. It uses the the newly designed
         | 
| 8 | 
            +
            # 0.9 version of consumer API[https://cwiki.apache.org/confluence/display/KAFKA/Kafka+0.9+Consumer+Rewrite+Design] 
         | 
| 9 | 
            +
            # provided by Kafka to read messages from the broker. This consumer is backward compatible and can
         | 
| 10 | 
            +
            # be used with 0.8.x brokers. 
         | 
| 9 11 | 
             
            #
         | 
| 10 | 
            -
            #  | 
| 11 | 
            -
            #  | 
| 12 | 
            -
            #
         | 
| 13 | 
            -
            # [options="header"]
         | 
| 14 | 
            -
            # |==========================================================
         | 
| 15 | 
            -
            # |Kafka Broker Version |Kafka Client Version |Logstash Version |Plugin Version |Why?
         | 
| 16 | 
            -
            # |0.8       |0.8       |2.0.0 - 2.x.x   |<3.0.0 |Legacy, 0.8 is still popular
         | 
| 17 | 
            -
            # |0.9       |0.9       |2.0.0 - 2.3.x   | 3.x.x |Works with the old Ruby Event API (`event['product']['price'] = 10`)
         | 
| 18 | 
            -
            # |0.9       |0.9       |2.4.0 - 5.0.x   | 4.x.x |Works with the new getter/setter APIs (`event.set('[product][price]', 10)`)
         | 
| 19 | 
            -
            # |0.10      |0.10      |2.4.0 - 5.0.x   | 5.x.x |Not compatible with the 0.9 broker
         | 
| 20 | 
            -
            # |==========================================================
         | 
| 21 | 
            -
            #
         | 
| 22 | 
            -
            # NOTE: It's a good idea to upgrade brokers before consumers/producers because brokers target backwards compatibility.
         | 
| 23 | 
            -
            # For example, the 0.9 broker will work with both the 0.8 consumer and 0.9 consumer APIs, but not the other way around.
         | 
| 24 | 
            -
            #
         | 
| 25 | 
            -
            # You must configure `topic_id`, `white_list` or `black_list`. By default it will connect to a
         | 
| 26 | 
            -
            # Zookeeper running on localhost. All the broker information is read from Zookeeper state.
         | 
| 12 | 
            +
            # The Logstash consumer handles group management and uses the default Kafka offset management
         | 
| 13 | 
            +
            # strategy using Kafka topics.
         | 
| 27 14 | 
             
            #
         | 
| 15 | 
            +
            # Logstash instances by default form a single logical group to subscribe to Kafka topics
         | 
| 16 | 
            +
            # Each Logstash Kafka consumer can run multiple threads to increase read throughput. Alternatively, 
         | 
| 17 | 
            +
            # you could run multiple Logstash instances with the same `group_id` to spread the load across
         | 
| 18 | 
            +
            # physical machines. Messages in a topic will be distributed to all Logstash instances with 
         | 
| 19 | 
            +
            # the same `group_id`.
         | 
| 20 | 
            +
            # 
         | 
| 28 21 | 
             
            # Ideally you should have as many threads as the number of partitions for a perfect balance --
         | 
| 29 22 | 
             
            # more threads than partitions means that some threads will be idle
         | 
| 30 23 | 
             
            #
         | 
| @@ -35,180 +28,184 @@ require 'stud/interval' | |
| 35 28 | 
             
            class LogStash::Inputs::Kafka < LogStash::Inputs::Base
         | 
| 36 29 | 
             
              config_name 'kafka'
         | 
| 37 30 |  | 
| 38 | 
            -
              default :codec, ' | 
| 31 | 
            +
              default :codec, 'plain'
         | 
| 39 32 |  | 
| 40 | 
            -
              #  | 
| 41 | 
            -
               | 
| 42 | 
            -
              #  | 
| 33 | 
            +
              # The frequency in milliseconds that the consumer offsets are committed to Kafka.
         | 
| 34 | 
            +
              config :auto_commit_interval_ms, :validate => :string, :default => "10"
         | 
| 35 | 
            +
              # What to do when there is no initial offset in Kafka or if an offset is out of range:
         | 
| 43 36 | 
             
              #
         | 
| 44 | 
            -
              #  | 
| 45 | 
            -
              #  | 
| 46 | 
            -
              #  | 
| 47 | 
            -
              #  | 
| 48 | 
            -
               | 
| 49 | 
            -
               | 
| 50 | 
            -
              #  | 
| 51 | 
            -
              #  | 
| 52 | 
            -
              # the  | 
| 53 | 
            -
               | 
| 54 | 
            -
               | 
| 55 | 
            -
               | 
| 56 | 
            -
              #  | 
| 57 | 
            -
               | 
| 58 | 
            -
               | 
| 59 | 
            -
               | 
| 60 | 
            -
              #  | 
| 61 | 
            -
              #  | 
| 62 | 
            -
               | 
| 63 | 
            -
               | 
| 64 | 
            -
               | 
| 65 | 
            -
              #  | 
| 66 | 
            -
              #  | 
| 67 | 
            -
               | 
| 68 | 
            -
               | 
| 69 | 
            -
               | 
| 70 | 
            -
              #  | 
| 71 | 
            -
              #  | 
| 72 | 
            -
               | 
| 73 | 
            -
              #  | 
| 74 | 
            -
               | 
| 75 | 
            -
              #  | 
| 76 | 
            -
              config : | 
| 77 | 
            -
              #  | 
| 78 | 
            -
              #  | 
| 79 | 
            -
              #  | 
| 80 | 
            -
               | 
| 81 | 
            -
               | 
| 82 | 
            -
              #  | 
| 83 | 
            -
               | 
| 84 | 
            -
              #  | 
| 85 | 
            -
              # the  | 
| 86 | 
            -
              config : | 
| 87 | 
            -
              #  | 
| 88 | 
            -
              config : | 
| 89 | 
            -
              #  | 
| 90 | 
            -
               | 
| 91 | 
            -
              #  | 
| 92 | 
            -
              #  | 
| 93 | 
            -
              # | 
| 94 | 
            -
               | 
| 95 | 
            -
              # | 
| 96 | 
            -
              # | 
| 97 | 
            -
               | 
| 98 | 
            -
              # | 
| 99 | 
            -
              config : | 
| 100 | 
            -
              #  | 
| 101 | 
            -
               | 
| 102 | 
            -
              #  | 
| 103 | 
            -
               | 
| 104 | 
            -
              #  | 
| 105 | 
            -
              #  | 
| 106 | 
            -
              #  | 
| 107 | 
            -
               | 
| 108 | 
            -
               | 
| 109 | 
            -
               | 
| 110 | 
            -
              #  | 
| 111 | 
            -
              config : | 
| 112 | 
            -
             | 
| 113 | 
            -
               | 
| 114 | 
            -
               | 
| 37 | 
            +
              # * earliest: automatically reset the offset to the earliest offset
         | 
| 38 | 
            +
              # * latest: automatically reset the offset to the latest offset
         | 
| 39 | 
            +
              # * none: throw exception to the consumer if no previous offset is found for the consumer's group
         | 
| 40 | 
            +
              # * anything else: throw exception to the consumer.
         | 
| 41 | 
            +
              config :auto_offset_reset, :validate => :string
         | 
| 42 | 
            +
              # A list of URLs to use for establishing the initial connection to the cluster. 
         | 
| 43 | 
            +
              # This list should be in the form of `host1:port1,host2:port2` These urls are just used 
         | 
| 44 | 
            +
              # for the initial connection to discover the full cluster membership (which may change dynamically) 
         | 
| 45 | 
            +
              # so this list need not contain the full set of servers (you may want more than one, though, in 
         | 
| 46 | 
            +
              # case a server is down).
         | 
| 47 | 
            +
              config :bootstrap_servers, :validate => :string, :default => "localhost:9092"
         | 
| 48 | 
            +
              # Automatically check the CRC32 of the records consumed. This ensures no on-the-wire or on-disk 
         | 
| 49 | 
            +
              # corruption to the messages occurred. This check adds some overhead, so it may be 
         | 
| 50 | 
            +
              # disabled in cases seeking extreme performance.
         | 
| 51 | 
            +
              config :check_crcs, :validate => :string
         | 
| 52 | 
            +
              # The id string to pass to the server when making requests. The purpose of this 
         | 
| 53 | 
            +
              # is to be able to track the source of requests beyond just ip/port by allowing 
         | 
| 54 | 
            +
              # a logical application name to be included.
         | 
| 55 | 
            +
              config :client_id, :validate => :string, :default => "logstash"
         | 
| 56 | 
            +
              # Close idle connections after the number of milliseconds specified by this config.
         | 
| 57 | 
            +
              config :connections_max_idle_ms, :validate => :string
         | 
| 58 | 
            +
              # If true, periodically commit to Kafka the offsets of messages already returned by the consumer. 
         | 
| 59 | 
            +
              # This committed offset will be used when the process fails as the position from 
         | 
| 60 | 
            +
              # which the consumption will begin.
         | 
| 61 | 
            +
              config :enable_auto_commit, :validate => :string, :default => "true"
         | 
| 62 | 
            +
              # The maximum amount of time the server will block before answering the fetch request if 
         | 
| 63 | 
            +
              # there isn't sufficient data to immediately satisfy `fetch_min_bytes`. This 
         | 
| 64 | 
            +
              # should be less than or equal to the timeout used in `poll_timeout_ms`
         | 
| 65 | 
            +
              config :fetch_max_wait_ms, :validate => :string
         | 
| 66 | 
            +
              # The minimum amount of data the server should return for a fetch request. If insufficient 
         | 
| 67 | 
            +
              # data is available the request will wait for that much data to accumulate
         | 
| 68 | 
            +
              # before answering the request.
         | 
| 69 | 
            +
              config :fetch_min_bytes, :validate => :string
         | 
| 70 | 
            +
              # The identifier of the group this consumer belongs to. Consumer group is a single logical subscriber 
         | 
| 71 | 
            +
              # that happens to be made up of multiple processors. Messages in a topic will be distributed to all 
         | 
| 72 | 
            +
              # Logstash instances with the same `group_id`
         | 
| 73 | 
            +
              config :group_id, :validate => :string, :default => "logstash"
         | 
| 74 | 
            +
              # The expected time between heartbeats to the consumer coordinator. Heartbeats are used to ensure 
         | 
| 75 | 
            +
              # that the consumer's session stays active and to facilitate rebalancing when new
         | 
| 76 | 
            +
              # consumers join or leave the group. The value must be set lower than 
         | 
| 77 | 
            +
              # `session.timeout.ms`, but typically should be set no higher than 1/3 of that value. 
         | 
| 78 | 
            +
              # It can be adjusted even lower to control the expected time for normal rebalances.
         | 
| 79 | 
            +
              config :heartbeat_interval_ms, :validate => :string
         | 
| 80 | 
            +
              # Java Class used to deserialize the record's key
         | 
| 81 | 
            +
              config :key_deserializer_class, :validate => :string, :default => "org.apache.kafka.common.serialization.StringDeserializer"
         | 
| 82 | 
            +
              # The maximum amount of data per-partition the server will return. The maximum total memory used for a 
         | 
| 83 | 
            +
              # request will be <code>#partitions * max.partition.fetch.bytes</code>. This size must be at least 
         | 
| 84 | 
            +
              # as large as the maximum message size the server allows or else it is possible for the producer to 
         | 
| 85 | 
            +
              # send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying 
         | 
| 86 | 
            +
              # to fetch a large message on a certain partition.
         | 
| 87 | 
            +
              config :max_partition_fetch_bytes, :validate => :string
         | 
| 88 | 
            +
              # The class name of the partition assignment strategy that the client will use to distribute 
         | 
| 89 | 
            +
              # partition ownership amongst consumer instances
         | 
| 90 | 
            +
              config :partition_assignment_strategy, :validate => :string
         | 
| 91 | 
            +
              # The size of the TCP receive buffer (SO_RCVBUF) to use when reading data.
         | 
| 92 | 
            +
              config :receive_buffer_bytes, :validate => :string
         | 
| 93 | 
            +
              # The amount of time to wait before attempting to reconnect to a given host. 
         | 
| 94 | 
            +
              # This avoids repeatedly connecting to a host in a tight loop. 
         | 
| 95 | 
            +
              # This backoff applies to all requests sent by the consumer to the broker.
         | 
| 96 | 
            +
              config :reconnect_backoff_ms, :validate => :string
         | 
| 97 | 
            +
              # The configuration controls the maximum amount of time the client will wait 
         | 
| 98 | 
            +
              # for the response of a request. If the response is not received before the timeout 
         | 
| 99 | 
            +
              # elapses the client will resend the request if necessary or fail the request if 
         | 
| 100 | 
            +
              # retries are exhausted.
         | 
| 101 | 
            +
              config :request_timeout_ms, :validate => :string
         | 
| 102 | 
            +
              # The amount of time to wait before attempting to retry a failed fetch request 
         | 
| 103 | 
            +
              # to a given topic partition. This avoids repeated fetching-and-failing in a tight loop.
         | 
| 104 | 
            +
              config :retry_backoff_ms, :validate => :string
         | 
| 105 | 
            +
              # The timeout after which, if the `poll_timeout_ms` is not invoked, the consumer is marked dead 
         | 
| 106 | 
            +
              # and a rebalance operation is triggered for the group identified by `group_id`
         | 
| 107 | 
            +
              config :session_timeout_ms, :validate => :string, :default => "30000"
         | 
| 108 | 
            +
              # Java Class used to deserialize the record's value
         | 
| 109 | 
            +
              config :value_deserializer_class, :validate => :string, :default => "org.apache.kafka.common.serialization.StringDeserializer"
         | 
| 110 | 
            +
              # Ideally you should have as many threads as the number of partitions for a perfect 
         | 
| 111 | 
            +
              # balance — more threads than partitions means that some threads will be idle
         | 
| 112 | 
            +
              config :num_threads, :validate => :number, :default => 1
         | 
| 113 | 
            +
              # A list of topics to subscribe to.
         | 
| 114 | 
            +
              config :topics, :validate => :array, :required => true
         | 
| 115 | 
            +
              # Time kafka consumer will wait to receive new messages from topics
         | 
| 116 | 
            +
              config :poll_timeout_ms, :validate => :number, :default => 100
         | 
| 117 | 
            +
              # Enable SSL/TLS secured communication to Kafka broker. Note that secure communication 
         | 
| 118 | 
            +
              # is only available with a broker running v0.9 of Kafka.
         | 
| 119 | 
            +
              config :ssl, :validate => :boolean, :default => false
         | 
| 120 | 
            +
              # The JKS truststore path to validate the Kafka broker's certificate.
         | 
| 121 | 
            +
              config :ssl_truststore_location, :validate => :path
         | 
| 122 | 
            +
              # The truststore password
         | 
| 123 | 
            +
              config :ssl_truststore_password, :validate => :password
         | 
| 124 | 
            +
              # If client authentication is required, this setting stores the keystore path.
         | 
| 125 | 
            +
              config :ssl_keystore_location, :validate => :path
         | 
| 126 | 
            +
              # If client authentication is required, this setting stores the keystore password
         | 
| 127 | 
            +
              config :ssl_keystore_password, :validate => :password
         | 
| 115 128 |  | 
| 129 | 
            +
              
         | 
| 116 130 | 
             
              public
         | 
| 117 131 | 
             
              def register
         | 
| 118 | 
            -
                 | 
| 119 | 
            -
                    :zk_connect => @zk_connect,
         | 
| 120 | 
            -
                    :group_id => @group_id,
         | 
| 121 | 
            -
                    :topic_id => @topic_id,
         | 
| 122 | 
            -
                    :auto_offset_reset => @auto_offset_reset,
         | 
| 123 | 
            -
                    :auto_commit_interval => @auto_commit_interval_ms,
         | 
| 124 | 
            -
                    :rebalance_max_retries => @rebalance_max_retries,
         | 
| 125 | 
            -
                    :rebalance_backoff_ms => @rebalance_backoff_ms,
         | 
| 126 | 
            -
                    :consumer_timeout_ms => @consumer_timeout_ms,
         | 
| 127 | 
            -
                    :consumer_restart_on_error => @consumer_restart_on_error,
         | 
| 128 | 
            -
                    :consumer_restart_sleep_ms => @consumer_restart_sleep_ms,
         | 
| 129 | 
            -
                    :consumer_id => @consumer_id,
         | 
| 130 | 
            -
                    :fetch_message_max_bytes => @fetch_message_max_bytes,
         | 
| 131 | 
            -
                    :allow_topics => @white_list,
         | 
| 132 | 
            -
                    :filter_topics => @black_list,
         | 
| 133 | 
            -
                    :value_decoder_class => @decoder_class,
         | 
| 134 | 
            -
                    :key_decoder_class => @key_decoder_class
         | 
| 135 | 
            -
                }
         | 
| 136 | 
            -
                if @reset_beginning
         | 
| 137 | 
            -
                  options[:reset_beginning] = 'from-beginning'
         | 
| 138 | 
            -
                end # if :reset_beginning
         | 
| 139 | 
            -
                topic_or_filter = [@topic_id, @white_list, @black_list].compact
         | 
| 140 | 
            -
                if topic_or_filter.count == 0
         | 
| 141 | 
            -
                  raise LogStash::ConfigurationError, 'topic_id, white_list or black_list required.'
         | 
| 142 | 
            -
                elsif topic_or_filter.count > 1
         | 
| 143 | 
            -
                  raise LogStash::ConfigurationError, 'Invalid combination of topic_id, white_list or black_list. Use only one.'
         | 
| 144 | 
            -
                end
         | 
| 145 | 
            -
                @kafka_client_queue = SizedQueue.new(@queue_size)
         | 
| 146 | 
            -
                @consumer_group = create_consumer_group(options)
         | 
| 147 | 
            -
                @logger.info('Registering kafka', :group_id => @group_id, :topic_id => @topic_id, :zk_connect => @zk_connect)
         | 
| 132 | 
            +
                @runner_threads = []
         | 
| 148 133 | 
             
              end # def register
         | 
| 149 134 |  | 
| 150 135 | 
             
              public
         | 
| 151 136 | 
             
              def run(logstash_queue)
         | 
| 152 | 
            -
                 | 
| 153 | 
            -
                 | 
| 154 | 
            -
                @ | 
| 155 | 
            -
                begin
         | 
| 156 | 
            -
                  @consumer_group.run(@consumer_threads,@kafka_client_queue)
         | 
| 157 | 
            -
             | 
| 158 | 
            -
                  while !stop?
         | 
| 159 | 
            -
                    event = @kafka_client_queue.pop
         | 
| 160 | 
            -
                    if event == KAFKA_SHUTDOWN_EVENT
         | 
| 161 | 
            -
                      break
         | 
| 162 | 
            -
                    end
         | 
| 163 | 
            -
                    queue_event(event, logstash_queue)
         | 
| 164 | 
            -
                  end
         | 
| 165 | 
            -
             | 
| 166 | 
            -
                  until @kafka_client_queue.empty?
         | 
| 167 | 
            -
                    event = @kafka_client_queue.pop
         | 
| 168 | 
            -
                    if event == KAFKA_SHUTDOWN_EVENT
         | 
| 169 | 
            -
                      break
         | 
| 170 | 
            -
                    end
         | 
| 171 | 
            -
                    queue_event(event, logstash_queue)
         | 
| 172 | 
            -
                  end
         | 
| 173 | 
            -
             | 
| 174 | 
            -
                  @logger.info('Done running kafka input')
         | 
| 175 | 
            -
                rescue => e
         | 
| 176 | 
            -
                  @logger.warn('kafka client threw exception, restarting',
         | 
| 177 | 
            -
                               :exception => e)
         | 
| 178 | 
            -
                  Stud.stoppable_sleep(Float(@consumer_restart_sleep_ms) * 1 / 1000) { stop? }
         | 
| 179 | 
            -
                  retry if !stop?
         | 
| 180 | 
            -
                end
         | 
| 137 | 
            +
                @runner_consumers = num_threads.times.map { || create_consumer }
         | 
| 138 | 
            +
                @runner_threads = @runner_consumers.map { |consumer| thread_runner(logstash_queue, consumer) }
         | 
| 139 | 
            +
                @runner_threads.each { |t| t.join }
         | 
| 181 140 | 
             
              end # def run
         | 
| 182 141 |  | 
| 183 142 | 
             
              public
         | 
| 184 143 | 
             
              def stop
         | 
| 185 | 
            -
                @ | 
| 186 | 
            -
                @consumer_group.shutdown if @consumer_group.running?
         | 
| 144 | 
            +
                @runner_consumers.each { |c| c.wakeup }
         | 
| 187 145 | 
             
              end
         | 
| 188 146 |  | 
| 189 147 | 
             
              private
         | 
| 190 | 
            -
              def  | 
| 191 | 
            -
                 | 
| 148 | 
            +
              def thread_runner(logstash_queue, consumer)
         | 
| 149 | 
            +
                Thread.new do
         | 
| 150 | 
            +
                  begin
         | 
| 151 | 
            +
                    consumer.subscribe(topics);
         | 
| 152 | 
            +
                    while !stop?
         | 
| 153 | 
            +
                      records = consumer.poll(poll_timeout_ms);
         | 
| 154 | 
            +
                      for record in records do
         | 
| 155 | 
            +
                        @codec.decode(record.value.to_s) do |event|
         | 
| 156 | 
            +
                          logstash_queue << event
         | 
| 157 | 
            +
                        end
         | 
| 158 | 
            +
                      end
         | 
| 159 | 
            +
                    end
         | 
| 160 | 
            +
                  rescue org.apache.kafka.common.errors.WakeupException => e
         | 
| 161 | 
            +
                    raise e if !stop?
         | 
| 162 | 
            +
                  ensure
         | 
| 163 | 
            +
                    consumer.close
         | 
| 164 | 
            +
                  end
         | 
| 165 | 
            +
                end
         | 
| 192 166 | 
             
              end
         | 
| 193 167 |  | 
| 194 168 | 
             
              private
         | 
| 195 | 
            -
              def  | 
| 169 | 
            +
              def create_consumer
         | 
| 196 170 | 
             
                begin
         | 
| 197 | 
            -
                   | 
| 198 | 
            -
             | 
| 199 | 
            -
             | 
| 200 | 
            -
             | 
| 201 | 
            -
             | 
| 202 | 
            -
             | 
| 203 | 
            -
             | 
| 204 | 
            -
             | 
| 205 | 
            -
             | 
| 206 | 
            -
             | 
| 207 | 
            -
             | 
| 208 | 
            -
                   | 
| 209 | 
            -
             | 
| 210 | 
            -
                   | 
| 211 | 
            -
             | 
| 212 | 
            -
             | 
| 213 | 
            -
             | 
| 171 | 
            +
                  props = java.util.Properties.new
         | 
| 172 | 
            +
                  kafka = org.apache.kafka.clients.consumer.ConsumerConfig
         | 
| 173 | 
            +
             | 
| 174 | 
            +
                  props.put(kafka::AUTO_COMMIT_INTERVAL_MS_CONFIG, auto_commit_interval_ms)
         | 
| 175 | 
            +
                  props.put(kafka::AUTO_OFFSET_RESET_CONFIG, auto_offset_reset) unless auto_offset_reset.nil?
         | 
| 176 | 
            +
                  props.put(kafka::BOOTSTRAP_SERVERS_CONFIG, bootstrap_servers)
         | 
| 177 | 
            +
                  props.put(kafka::CHECK_CRCS_CONFIG, check_crcs) unless check_crcs.nil?
         | 
| 178 | 
            +
                  props.put(kafka::CLIENT_ID_CONFIG, client_id)
         | 
| 179 | 
            +
                  props.put(kafka::CONNECTIONS_MAX_IDLE_MS_CONFIG, connections_max_idle_ms) unless connections_max_idle_ms.nil?
         | 
| 180 | 
            +
                  props.put(kafka::ENABLE_AUTO_COMMIT_CONFIG, enable_auto_commit)
         | 
| 181 | 
            +
                  props.put(kafka::FETCH_MAX_WAIT_MS_CONFIG, fetch_max_wait_ms) unless fetch_max_wait_ms.nil?
         | 
| 182 | 
            +
                  props.put(kafka::FETCH_MIN_BYTES_CONFIG, fetch_min_bytes) unless fetch_min_bytes.nil?
         | 
| 183 | 
            +
                  props.put(kafka::GROUP_ID_CONFIG, group_id)
         | 
| 184 | 
            +
                  props.put(kafka::HEARTBEAT_INTERVAL_MS_CONFIG, heartbeat_interval_ms) unless heartbeat_interval_ms.nil?
         | 
| 185 | 
            +
                  props.put(kafka::KEY_DESERIALIZER_CLASS_CONFIG, key_deserializer_class)
         | 
| 186 | 
            +
                  props.put(kafka::MAX_PARTITION_FETCH_BYTES_CONFIG, max_partition_fetch_bytes) unless max_partition_fetch_bytes.nil?
         | 
| 187 | 
            +
                  props.put(kafka::PARTITION_ASSIGNMENT_STRATEGY_CONFIG, partition_assignment_strategy) unless partition_assignment_strategy.nil?
         | 
| 188 | 
            +
                  props.put(kafka::RECEIVE_BUFFER_CONFIG, receive_buffer_bytes) unless receive_buffer_bytes.nil?
         | 
| 189 | 
            +
                  props.put(kafka::RECONNECT_BACKOFF_MS_CONFIG, reconnect_backoff_ms) unless reconnect_backoff_ms.nil?
         | 
| 190 | 
            +
                  props.put(kafka::REQUEST_TIMEOUT_MS_CONFIG, request_timeout_ms) unless request_timeout_ms.nil?
         | 
| 191 | 
            +
                  props.put(kafka::RETRY_BACKOFF_MS_CONFIG, retry_backoff_ms) unless retry_backoff_ms.nil?
         | 
| 192 | 
            +
                  props.put(kafka::SESSION_TIMEOUT_MS_CONFIG, session_timeout_ms) unless session_timeout_ms.nil?
         | 
| 193 | 
            +
                  props.put(kafka::VALUE_DESERIALIZER_CLASS_CONFIG, value_deserializer_class)
         | 
| 194 | 
            +
             | 
| 195 | 
            +
                  if ssl
         | 
| 196 | 
            +
                    props.put("security.protocol", "SSL")
         | 
| 197 | 
            +
                    props.put("ssl.truststore.location", ssl_truststore_location)
         | 
| 198 | 
            +
                    props.put("ssl.truststore.password", ssl_truststore_password.value) unless ssl_truststore_password.nil?
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                    #Client auth stuff
         | 
| 201 | 
            +
                    props.put("ssl.keystore.location", ssl_keystore_location) unless ssl_keystore_location.nil?
         | 
| 202 | 
            +
                    props.put("ssl.keystore.password", ssl_keystore_password.value) unless ssl_keystore_password.nil?
         | 
| 203 | 
            +
                  end
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                  org.apache.kafka.clients.consumer.KafkaConsumer.new(props)
         | 
| 206 | 
            +
                rescue => e
         | 
| 207 | 
            +
                  logger.error("Unable to create Kafka consumer from given configuration", :kafka_error_message => e)
         | 
| 208 | 
            +
                  throw e
         | 
| 209 | 
            +
                end
         | 
| 210 | 
            +
              end
         | 
| 214 211 | 
             
            end #class LogStash::Inputs::Kafka
         | 
| @@ -1,10 +1,10 @@ | |
| 1 1 | 
             
            Gem::Specification.new do |s|
         | 
| 2 2 |  | 
| 3 3 | 
             
              s.name            = 'logstash-input-kafka'
         | 
| 4 | 
            -
              s.version         = ' | 
| 4 | 
            +
              s.version         = '3.0.0.beta1'
         | 
| 5 5 | 
             
              s.licenses        = ['Apache License (2.0)']
         | 
| 6 6 | 
             
              s.summary         = 'This input will read events from a Kafka topic. It uses the high level consumer API provided by Kafka to read messages from the broker'
         | 
| 7 | 
            -
              s.description     = "This gem is a  | 
| 7 | 
            +
              s.description     = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
         | 
| 8 8 | 
             
              s.authors         = ['Elasticsearch']
         | 
| 9 9 | 
             
              s.email           = 'info@elastic.co'
         | 
| 10 10 | 
             
              s.homepage        = "http://www.elastic.co/guide/en/logstash/current/index.html"
         | 
| @@ -20,13 +20,10 @@ Gem::Specification.new do |s| | |
| 20 20 | 
             
              s.metadata = { 'logstash_plugin' => 'true', 'group' => 'input'}
         | 
| 21 21 |  | 
| 22 22 | 
             
              # Gem dependencies
         | 
| 23 | 
            -
              s.add_runtime_dependency  | 
| 23 | 
            +
              s.add_runtime_dependency 'logstash-core', ">= 2.0.0.beta2", "< 3.0.0"
         | 
| 24 24 | 
             
              s.add_runtime_dependency 'logstash-codec-json'
         | 
| 25 25 | 
             
              s.add_runtime_dependency 'logstash-codec-plain'
         | 
| 26 26 | 
             
              s.add_runtime_dependency 'stud', '>= 0.0.22', '< 0.1.0'
         | 
| 27 | 
            -
             | 
| 28 | 
            -
              s.add_runtime_dependency 'jruby-kafka', '1.5.0'
         | 
| 29 | 
            -
             | 
| 30 27 | 
             
              s.add_development_dependency 'logstash-devutils'
         | 
| 31 28 | 
             
            end
         | 
| 32 29 |  | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            # encoding: utf-8
         | 
| 2 | 
            +
            require "logstash/devutils/rspec/spec_helper"
         | 
| 3 | 
            +
            require "logstash/inputs/kafka"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            describe "input/kafka", :integration => true do
         | 
| 6 | 
            +
              before do
         | 
| 7 | 
            +
                props = java.util.Properties.new
         | 
| 8 | 
            +
                props.put("bootstrap.servers", bootstrap_servers)
         | 
| 9 | 
            +
                props.put("acks", "all")
         | 
| 10 | 
            +
                props.put("retries", "0")
         | 
| 11 | 
            +
                props.put("batch.size", "16384")
         | 
| 12 | 
            +
                props.put("linger.ms", "1")
         | 
| 13 | 
            +
                props.put("buffer.memory", "33554432")
         | 
| 14 | 
            +
                props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer")
         | 
| 15 | 
            +
                props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer")
         | 
| 16 | 
            +
                producer = org.apache.kafka.clients.producer.KafkaProducer.new(props)
         | 
| 17 | 
            +
                1000.times do |i|
         | 
| 18 | 
            +
                  producer.send(org.apache.kafka.clients.producer.ProducerRecord("test", i.to_s, i.to_s))
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
| @@ -0,0 +1,56 @@ | |
| 1 | 
            +
            # encoding: utf-8
         | 
| 2 | 
            +
            require "logstash/devutils/rspec/spec_helper"
         | 
| 3 | 
            +
            require "logstash/inputs/kafka"
         | 
| 4 | 
            +
            require "concurrent"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            class MockConsumer
         | 
| 7 | 
            +
              def initialize
         | 
| 8 | 
            +
                @wake = Concurrent::AtomicBoolean.new(false)
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              def subscribe(topics)
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
              
         | 
| 14 | 
            +
              def poll(ms)
         | 
| 15 | 
            +
                if @wake.value
         | 
| 16 | 
            +
                  raise org.apache.kafka.common.errors.WakeupException.new
         | 
| 17 | 
            +
                else
         | 
| 18 | 
            +
                  10.times.map do
         | 
| 19 | 
            +
                    org.apache.kafka.clients.consumer.ConsumerRecord.new("test", 0, 0, "key", "value")
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              def close
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              def wakeup
         | 
| 28 | 
            +
                @wake.make_true
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            describe LogStash::Inputs::Kafka do
         | 
| 33 | 
            +
              let(:config) { { 'topics' => ['test'], 'num_threads' => 4 } }
         | 
| 34 | 
            +
              subject { LogStash::Inputs::Kafka.new(config) }
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              it "should register" do
         | 
| 37 | 
            +
                expect {subject.register}.to_not raise_error
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              it "should run" do
         | 
| 41 | 
            +
                expect(subject).to receive(:new_consumer) do
         | 
| 42 | 
            +
                  MockConsumer.new
         | 
| 43 | 
            +
                end.exactly(4).times
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                subject.register
         | 
| 46 | 
            +
                q = Queue.new
         | 
| 47 | 
            +
                Thread.new do
         | 
| 48 | 
            +
                  while q.size < 13
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                  subject.do_stop
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
                subject.run(q)
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                expect(q.size).to eq(40)
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
            end
         | 
| Binary file | 
| Binary file | 
| Binary file | 
    
        metadata
    CHANGED
    
    | @@ -1,33 +1,39 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: logstash-input-kafka
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version:  | 
| 4 | 
            +
              version: 3.0.0.beta1
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Elasticsearch
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2016- | 
| 11 | 
            +
            date: 2016-01-14 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 15 15 | 
             
                requirements:
         | 
| 16 | 
            -
                - -  | 
| 16 | 
            +
                - - '>='
         | 
| 17 17 | 
             
                  - !ruby/object:Gem::Version
         | 
| 18 | 
            -
                    version:  | 
| 19 | 
            -
             | 
| 18 | 
            +
                    version: 2.0.0.beta2
         | 
| 19 | 
            +
                - - <
         | 
| 20 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 21 | 
            +
                    version: 3.0.0
         | 
| 22 | 
            +
              name: logstash-core
         | 
| 20 23 | 
             
              prerelease: false
         | 
| 21 24 | 
             
              type: :runtime
         | 
| 22 25 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 26 | 
             
                requirements:
         | 
| 24 | 
            -
                - -  | 
| 27 | 
            +
                - - '>='
         | 
| 28 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 29 | 
            +
                    version: 2.0.0.beta2
         | 
| 30 | 
            +
                - - <
         | 
| 25 31 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            -
                    version:  | 
| 32 | 
            +
                    version: 3.0.0
         | 
| 27 33 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 34 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 29 35 | 
             
                requirements:
         | 
| 30 | 
            -
                - -  | 
| 36 | 
            +
                - - '>='
         | 
| 31 37 | 
             
                  - !ruby/object:Gem::Version
         | 
| 32 38 | 
             
                    version: '0'
         | 
| 33 39 | 
             
              name: logstash-codec-json
         | 
| @@ -35,13 +41,13 @@ dependencies: | |
| 35 41 | 
             
              type: :runtime
         | 
| 36 42 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 43 | 
             
                requirements:
         | 
| 38 | 
            -
                - -  | 
| 44 | 
            +
                - - '>='
         | 
| 39 45 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 46 | 
             
                    version: '0'
         | 
| 41 47 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 48 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 43 49 | 
             
                requirements:
         | 
| 44 | 
            -
                - -  | 
| 50 | 
            +
                - - '>='
         | 
| 45 51 | 
             
                  - !ruby/object:Gem::Version
         | 
| 46 52 | 
             
                    version: '0'
         | 
| 47 53 | 
             
              name: logstash-codec-plain
         | 
| @@ -49,16 +55,16 @@ dependencies: | |
| 49 55 | 
             
              type: :runtime
         | 
| 50 56 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 57 | 
             
                requirements:
         | 
| 52 | 
            -
                - -  | 
| 58 | 
            +
                - - '>='
         | 
| 53 59 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 60 | 
             
                    version: '0'
         | 
| 55 61 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 56 62 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 57 63 | 
             
                requirements:
         | 
| 58 | 
            -
                - -  | 
| 64 | 
            +
                - - '>='
         | 
| 59 65 | 
             
                  - !ruby/object:Gem::Version
         | 
| 60 66 | 
             
                    version: 0.0.22
         | 
| 61 | 
            -
                - -  | 
| 67 | 
            +
                - - <
         | 
| 62 68 | 
             
                  - !ruby/object:Gem::Version
         | 
| 63 69 | 
             
                    version: 0.1.0
         | 
| 64 70 | 
             
              name: stud
         | 
| @@ -66,30 +72,16 @@ dependencies: | |
| 66 72 | 
             
              type: :runtime
         | 
| 67 73 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 68 74 | 
             
                requirements:
         | 
| 69 | 
            -
                - -  | 
| 75 | 
            +
                - - '>='
         | 
| 70 76 | 
             
                  - !ruby/object:Gem::Version
         | 
| 71 77 | 
             
                    version: 0.0.22
         | 
| 72 | 
            -
                - -  | 
| 78 | 
            +
                - - <
         | 
| 73 79 | 
             
                  - !ruby/object:Gem::Version
         | 
| 74 80 | 
             
                    version: 0.1.0
         | 
| 75 81 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 76 82 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 77 83 | 
             
                requirements:
         | 
| 78 | 
            -
                - - ' | 
| 79 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 80 | 
            -
                    version: 1.5.0
         | 
| 81 | 
            -
              name: jruby-kafka
         | 
| 82 | 
            -
              prerelease: false
         | 
| 83 | 
            -
              type: :runtime
         | 
| 84 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 85 | 
            -
                requirements:
         | 
| 86 | 
            -
                - - '='
         | 
| 87 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 88 | 
            -
                    version: 1.5.0
         | 
| 89 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 90 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 91 | 
            -
                requirements:
         | 
| 92 | 
            -
                - - ">="
         | 
| 84 | 
            +
                - - '>='
         | 
| 93 85 | 
             
                  - !ruby/object:Gem::Version
         | 
| 94 86 | 
             
                    version: '0'
         | 
| 95 87 | 
             
              name: logstash-devutils
         | 
| @@ -97,10 +89,10 @@ dependencies: | |
| 97 89 | 
             
              type: :development
         | 
| 98 90 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 99 91 | 
             
                requirements:
         | 
| 100 | 
            -
                - -  | 
| 92 | 
            +
                - - '>='
         | 
| 101 93 | 
             
                  - !ruby/object:Gem::Version
         | 
| 102 94 | 
             
                    version: '0'
         | 
| 103 | 
            -
            description: This gem is a  | 
| 95 | 
            +
            description: This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program
         | 
| 104 96 | 
             
            email: info@elastic.co
         | 
| 105 97 | 
             
            executables: []
         | 
| 106 98 | 
             
            extensions: []
         | 
| @@ -113,9 +105,14 @@ files: | |
| 113 105 | 
             
            - LICENSE
         | 
| 114 106 | 
             
            - NOTICE.TXT
         | 
| 115 107 | 
             
            - README.md
         | 
| 108 | 
            +
            - lib/logstash-input-kafka_jars.rb
         | 
| 116 109 | 
             
            - lib/logstash/inputs/kafka.rb
         | 
| 117 110 | 
             
            - logstash-input-kafka.gemspec
         | 
| 118 | 
            -
            - spec/inputs/kafka_spec.rb
         | 
| 111 | 
            +
            - spec/integration/inputs/kafka_spec.rb
         | 
| 112 | 
            +
            - spec/unit/inputs/kafka_spec.rb
         | 
| 113 | 
            +
            - vendor/jar-dependencies/runtime-jars/kafka-clients-0.9.0.0.jar
         | 
| 114 | 
            +
            - vendor/jar-dependencies/runtime-jars/slf4j-api-1.7.13.jar
         | 
| 115 | 
            +
            - vendor/jar-dependencies/runtime-jars/slf4j-noop-1.7.13.jar
         | 
| 119 116 | 
             
            homepage: http://www.elastic.co/guide/en/logstash/current/index.html
         | 
| 120 117 | 
             
            licenses:
         | 
| 121 118 | 
             
            - Apache License (2.0)
         | 
| @@ -128,19 +125,20 @@ require_paths: | |
| 128 125 | 
             
            - lib
         | 
| 129 126 | 
             
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 130 127 | 
             
              requirements:
         | 
| 131 | 
            -
              - -  | 
| 128 | 
            +
              - - '>='
         | 
| 132 129 | 
             
                - !ruby/object:Gem::Version
         | 
| 133 130 | 
             
                  version: '0'
         | 
| 134 131 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 135 132 | 
             
              requirements:
         | 
| 136 | 
            -
              - -  | 
| 133 | 
            +
              - - '>'
         | 
| 137 134 | 
             
                - !ruby/object:Gem::Version
         | 
| 138 | 
            -
                  version:  | 
| 135 | 
            +
                  version: 1.3.1
         | 
| 139 136 | 
             
            requirements: []
         | 
| 140 137 | 
             
            rubyforge_project:
         | 
| 141 | 
            -
            rubygems_version: 2.4. | 
| 138 | 
            +
            rubygems_version: 2.4.5
         | 
| 142 139 | 
             
            signing_key:
         | 
| 143 140 | 
             
            specification_version: 4
         | 
| 144 141 | 
             
            summary: This input will read events from a Kafka topic. It uses the high level consumer API provided by Kafka to read messages from the broker
         | 
| 145 142 | 
             
            test_files:
         | 
| 146 | 
            -
            - spec/inputs/kafka_spec.rb
         | 
| 143 | 
            +
            - spec/integration/inputs/kafka_spec.rb
         | 
| 144 | 
            +
            - spec/unit/inputs/kafka_spec.rb
         | 
    
        data/spec/inputs/kafka_spec.rb
    DELETED
    
    | @@ -1,133 +0,0 @@ | |
| 1 | 
            -
            # encoding: utf-8
         | 
| 2 | 
            -
            require "logstash/devutils/rspec/spec_helper"
         | 
| 3 | 
            -
            require "logstash/inputs/kafka"
         | 
| 4 | 
            -
            require 'jruby-kafka'
         | 
| 5 | 
            -
             | 
| 6 | 
            -
            class LogStash::Inputs::TestKafka < LogStash::Inputs::Kafka
         | 
| 7 | 
            -
              private
         | 
| 8 | 
            -
              def queue_event(msg, output_queue)
         | 
| 9 | 
            -
                super(msg, output_queue)
         | 
| 10 | 
            -
                do_stop
         | 
| 11 | 
            -
              end
         | 
| 12 | 
            -
            end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
            class TestMessageAndMetadata
         | 
| 15 | 
            -
              attr_reader :topic, :partition, :key, :message, :offset
         | 
| 16 | 
            -
              def initialize(topic, partition, key, message, offset)
         | 
| 17 | 
            -
                @topic = topic
         | 
| 18 | 
            -
                @partition = partition
         | 
| 19 | 
            -
                @key = key
         | 
| 20 | 
            -
                @message = message
         | 
| 21 | 
            -
                @offset = offset
         | 
| 22 | 
            -
              end
         | 
| 23 | 
            -
            end
         | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
            class TestKafkaGroup < Kafka::Group
         | 
| 27 | 
            -
              def run(a_num_threads, a_queue)
         | 
| 28 | 
            -
                blah = TestMessageAndMetadata.new(@topic, 0, nil, 'Kafka message', 1)
         | 
| 29 | 
            -
                a_queue << blah
         | 
| 30 | 
            -
              end
         | 
| 31 | 
            -
            end
         | 
| 32 | 
            -
             | 
| 33 | 
            -
            class LogStash::Inputs::TestInfiniteKafka < LogStash::Inputs::Kafka
         | 
| 34 | 
            -
              private
         | 
| 35 | 
            -
              def queue_event(msg, output_queue)
         | 
| 36 | 
            -
                super(msg, output_queue)
         | 
| 37 | 
            -
              end
         | 
| 38 | 
            -
            end
         | 
| 39 | 
            -
             | 
| 40 | 
            -
            class TestInfiniteKafkaGroup < Kafka::Group
         | 
| 41 | 
            -
              def run(a_num_threads, a_queue)
         | 
| 42 | 
            -
                blah = TestMessageAndMetadata.new(@topic, 0, nil, 'Kafka message', 1)
         | 
| 43 | 
            -
                Thread.new do
         | 
| 44 | 
            -
                  while true
         | 
| 45 | 
            -
                    a_queue << blah
         | 
| 46 | 
            -
                    sleep 10
         | 
| 47 | 
            -
                  end
         | 
| 48 | 
            -
                end
         | 
| 49 | 
            -
              end
         | 
| 50 | 
            -
            end
         | 
| 51 | 
            -
             | 
| 52 | 
            -
            describe LogStash::Inputs::Kafka do
         | 
| 53 | 
            -
              let (:kafka_config) {{'topic_id' => 'test'}}
         | 
| 54 | 
            -
              let (:empty_config) {{}}
         | 
| 55 | 
            -
              let (:bad_kafka_config) {{'topic_id' => 'test', 'white_list' => 'other_topic'}}
         | 
| 56 | 
            -
              let (:white_list_kafka_config) {{'white_list' => 'other_topic'}}
         | 
| 57 | 
            -
              let (:decorated_kafka_config) {{'topic_id' => 'test', 'decorate_events' => true}}
         | 
| 58 | 
            -
             | 
| 59 | 
            -
              it "should register" do
         | 
| 60 | 
            -
                input = LogStash::Plugin.lookup("input", "kafka").new(kafka_config)
         | 
| 61 | 
            -
                expect {input.register}.to_not raise_error
         | 
| 62 | 
            -
              end
         | 
| 63 | 
            -
             | 
| 64 | 
            -
              it "should register with whitelist" do
         | 
| 65 | 
            -
                input = LogStash::Plugin.lookup("input", "kafka").new(white_list_kafka_config)
         | 
| 66 | 
            -
                expect {input.register}.to_not raise_error
         | 
| 67 | 
            -
              end
         | 
| 68 | 
            -
             | 
| 69 | 
            -
              it "should fail with multiple topic configs" do
         | 
| 70 | 
            -
                input = LogStash::Plugin.lookup("input", "kafka").new(empty_config)
         | 
| 71 | 
            -
                expect {input.register}.to raise_error
         | 
| 72 | 
            -
              end
         | 
| 73 | 
            -
             | 
| 74 | 
            -
              it "should fail without topic configs" do
         | 
| 75 | 
            -
                input = LogStash::Plugin.lookup("input", "kafka").new(bad_kafka_config)
         | 
| 76 | 
            -
                expect {input.register}.to raise_error
         | 
| 77 | 
            -
              end
         | 
| 78 | 
            -
             | 
| 79 | 
            -
              it_behaves_like "an interruptible input plugin" do
         | 
| 80 | 
            -
                let(:config) { kafka_config }
         | 
| 81 | 
            -
                let(:mock_kafka_plugin) { LogStash::Inputs::TestInfiniteKafka.new(config) }
         | 
| 82 | 
            -
             | 
| 83 | 
            -
                before :each do
         | 
| 84 | 
            -
                  allow(LogStash::Inputs::Kafka).to receive(:new).and_return(mock_kafka_plugin)
         | 
| 85 | 
            -
                  expect(subject).to receive(:create_consumer_group) do |options|
         | 
| 86 | 
            -
                    TestInfiniteKafkaGroup.new(options)
         | 
| 87 | 
            -
                  end
         | 
| 88 | 
            -
                end
         | 
| 89 | 
            -
              end
         | 
| 90 | 
            -
             | 
| 91 | 
            -
              it 'should populate kafka config with default values' do
         | 
| 92 | 
            -
                kafka = LogStash::Inputs::TestKafka.new(kafka_config)
         | 
| 93 | 
            -
                insist {kafka.zk_connect} == 'localhost:2181'
         | 
| 94 | 
            -
                insist {kafka.topic_id} == 'test'
         | 
| 95 | 
            -
                insist {kafka.group_id} == 'logstash'
         | 
| 96 | 
            -
                !insist { kafka.reset_beginning }
         | 
| 97 | 
            -
              end
         | 
| 98 | 
            -
             | 
| 99 | 
            -
              it 'should retrieve event from kafka' do
         | 
| 100 | 
            -
                kafka = LogStash::Inputs::TestKafka.new(kafka_config)
         | 
| 101 | 
            -
                expect(kafka).to receive(:create_consumer_group) do |options|
         | 
| 102 | 
            -
                  TestKafkaGroup.new(options)
         | 
| 103 | 
            -
                end
         | 
| 104 | 
            -
                kafka.register
         | 
| 105 | 
            -
             | 
| 106 | 
            -
                logstash_queue = Queue.new
         | 
| 107 | 
            -
                kafka.run logstash_queue
         | 
| 108 | 
            -
                e = logstash_queue.pop
         | 
| 109 | 
            -
                insist { e['message'] } == 'Kafka message'
         | 
| 110 | 
            -
                # no metadata by default
         | 
| 111 | 
            -
                insist { e['kafka'] } == nil
         | 
| 112 | 
            -
              end
         | 
| 113 | 
            -
             | 
| 114 | 
            -
              it 'should retrieve a decorated event from kafka' do
         | 
| 115 | 
            -
                kafka = LogStash::Inputs::TestKafka.new(decorated_kafka_config)
         | 
| 116 | 
            -
                expect(kafka).to receive(:create_consumer_group) do |options|
         | 
| 117 | 
            -
                  TestKafkaGroup.new(options)
         | 
| 118 | 
            -
                end
         | 
| 119 | 
            -
                kafka.register
         | 
| 120 | 
            -
             | 
| 121 | 
            -
                logstash_queue = Queue.new
         | 
| 122 | 
            -
                kafka.run logstash_queue
         | 
| 123 | 
            -
                e = logstash_queue.pop
         | 
| 124 | 
            -
                insist { e['message'] } == 'Kafka message'
         | 
| 125 | 
            -
                # no metadata by default
         | 
| 126 | 
            -
                insist { e['kafka']['topic'] } == 'test'
         | 
| 127 | 
            -
                insist { e['kafka']['consumer_group'] } == 'logstash'
         | 
| 128 | 
            -
                insist { e['kafka']['msg_size'] } == 13
         | 
| 129 | 
            -
                insist { e['kafka']['partition'] } == 0
         | 
| 130 | 
            -
                insist { e['kafka']['key'] } == nil
         | 
| 131 | 
            -
                insist { e['kafka']['offset'] } == 1
         | 
| 132 | 
            -
              end
         | 
| 133 | 
            -
            end
         |