logstash-input-kafka 4.1.1 → 4.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/logstash/inputs/kafka.rb +27 -3
- data/logstash-input-kafka.gemspec +1 -1
- data/spec/integration/inputs/kafka_spec.rb +84 -44
- data/spec/unit/inputs/kafka_spec.rb +2 -2
- 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: 392af7e1646f486c6f81b5ed7dd2206335be8287
|
4
|
+
data.tar.gz: 75f322acc9c088a79a6e87c51349237d6bff91ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2541883711e5a2fdb1acf216fdf1f25a2af1ed266c84293a869805f3e7e418c2d6a162e5f57cece82dbadf63256d8edf8271be4b6e489e93381f7f8ca8ad3a93
|
7
|
+
data.tar.gz: 6b2fc56fbafe56be7c8a891f44b1c83dea8759e49856b8fc94da6e1378edcf69a7bd7e1b1fddbfaf2e8a333674d97a165fe9b151efd08b1168081cc35aef1be0
|
data/CHANGELOG.md
CHANGED
@@ -114,8 +114,11 @@ class LogStash::Inputs::Kafka < LogStash::Inputs::Base
|
|
114
114
|
config :session_timeout_ms, :validate => :string, :default => "30000"
|
115
115
|
# Java Class used to deserialize the record's value
|
116
116
|
config :value_deserializer_class, :validate => :string, :default => "org.apache.kafka.common.serialization.StringDeserializer"
|
117
|
-
# A list of topics to subscribe to.
|
118
|
-
config :topics, :validate => :array, :
|
117
|
+
# A list of topics to subscribe to, defaults to ["logstash"].
|
118
|
+
config :topics, :validate => :array, :default => ["logstash"]
|
119
|
+
# A topic regex pattern to subscribe to.
|
120
|
+
# The topics configuration will be ignored when using this configuration.
|
121
|
+
config :topics_pattern, :validate => :string
|
119
122
|
# Time kafka consumer will wait to receive new messages from topics
|
120
123
|
config :poll_timeout_ms, :validate => :number, :default => 100
|
121
124
|
# Enable SSL/TLS secured communication to Kafka broker. Note that secure communication
|
@@ -129,6 +132,14 @@ class LogStash::Inputs::Kafka < LogStash::Inputs::Base
|
|
129
132
|
config :ssl_keystore_location, :validate => :path
|
130
133
|
# If client authentication is required, this setting stores the keystore password
|
131
134
|
config :ssl_keystore_password, :validate => :password
|
135
|
+
# Option to add Kafka metadata like topic, message size to the event.
|
136
|
+
# This will add a field named `kafka` to the logstash event containing the following attributes:
|
137
|
+
# `topic`: The topic this message is associated with
|
138
|
+
# `consumer_group`: The consumer group used to read in this event
|
139
|
+
# `partition`: The partition this message is associated with
|
140
|
+
# `offset`: The offset from the partition this message is associated with
|
141
|
+
# `key`: A ByteBuffer containing the message key
|
142
|
+
config :decorate_events, :validate => :boolean, :default => false
|
132
143
|
|
133
144
|
|
134
145
|
public
|
@@ -156,12 +167,25 @@ class LogStash::Inputs::Kafka < LogStash::Inputs::Base
|
|
156
167
|
def thread_runner(logstash_queue, consumer)
|
157
168
|
Thread.new do
|
158
169
|
begin
|
159
|
-
|
170
|
+
unless @topics_pattern.nil?
|
171
|
+
nooplistener = org.apache.kafka.clients.consumer.internals.NoOpConsumerRebalanceListener.new
|
172
|
+
pattern = java.util.regex.Pattern.compile(@topics_pattern)
|
173
|
+
consumer.subscribe(pattern, nooplistener)
|
174
|
+
else
|
175
|
+
consumer.subscribe(topics);
|
176
|
+
end
|
160
177
|
while !stop?
|
161
178
|
records = consumer.poll(poll_timeout_ms);
|
162
179
|
for record in records do
|
163
180
|
@codec.decode(record.value.to_s) do |event|
|
164
181
|
decorate(event)
|
182
|
+
if @decorate_events
|
183
|
+
event.set("[kafka][topic]", record.topic)
|
184
|
+
event.set("[kafka][consumer_group]", @group_id)
|
185
|
+
event.set("[kafka][partition]", record.partition)
|
186
|
+
event.set("[kafka][offset]", record.offset)
|
187
|
+
event.set("[kafka][key]", record.key)
|
188
|
+
end
|
165
189
|
logstash_queue << event
|
166
190
|
end
|
167
191
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-input-kafka'
|
4
|
-
s.version = '4.
|
4
|
+
s.version = '4.2.0'
|
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
7
|
s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
|
@@ -2,59 +2,99 @@
|
|
2
2
|
require "logstash/devutils/rspec/spec_helper"
|
3
3
|
require "logstash/inputs/kafka"
|
4
4
|
require "digest"
|
5
|
+
require "rspec/wait"
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
let(:
|
10
|
-
|
11
|
-
let(:
|
7
|
+
# Please run kafka_test_setup.sh prior to executing this integration test.
|
8
|
+
describe "inputs/kafka", :integration => true do
|
9
|
+
# Group ids to make sure that the consumers get all the logs.
|
10
|
+
let(:group_id_1) {rand(36**8).to_s(36)}
|
11
|
+
let(:group_id_2) {rand(36**8).to_s(36)}
|
12
|
+
let(:group_id_3) {rand(36**8).to_s(36)}
|
13
|
+
let(:plain_config) { { 'topics' => ['logstash_topic_plain'], 'codec' => 'plain', 'group_id' => group_id_1, 'auto_offset_reset' => 'earliest'} }
|
14
|
+
let(:snappy_config) { { 'topics' => ['logstash_topic_snappy'], 'codec' => 'plain', 'group_id' => group_id_1, 'auto_offset_reset' => 'earliest'} }
|
15
|
+
let(:lz4_config) { { 'topics' => ['logstash_topic_lz4'], 'codec' => 'plain', 'group_id' => group_id_1, 'auto_offset_reset' => 'earliest'} }
|
16
|
+
let(:pattern_config) { { 'topics_pattern' => 'logstash_topic_.*', 'group_id' => group_id_2, 'codec' => 'plain', 'auto_offset_reset' => 'earliest'} }
|
17
|
+
let(:decorate_config) { { 'topics' => ['logstash_topic_plain'], 'codec' => 'plain', 'group_id' => group_id_3, 'auto_offset_reset' => 'earliest', 'decorate_events' => true} }
|
18
|
+
let(:timeout_seconds) { 120 }
|
12
19
|
let(:num_events) { 103 }
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
20
|
+
|
21
|
+
describe "#kafka-topics" do
|
22
|
+
def thread_it(kafka_input, queue)
|
23
|
+
Thread.new do
|
24
|
+
begin
|
25
|
+
kafka_input.run(queue)
|
26
|
+
end
|
18
27
|
end
|
19
28
|
end
|
29
|
+
|
30
|
+
it "should consume all messages from plain 3-partition topic" do
|
31
|
+
kafka_input = LogStash::Inputs::Kafka.new(plain_config)
|
32
|
+
queue = Array.new
|
33
|
+
t = thread_it(kafka_input, queue)
|
34
|
+
t.run
|
35
|
+
wait(timeout_seconds).for { queue.length }.to eq(num_events)
|
36
|
+
expect(queue.length).to eq(num_events)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should consume all messages from snappy 3-partition topic" do
|
40
|
+
kafka_input = LogStash::Inputs::Kafka.new(snappy_config)
|
41
|
+
queue = Array.new
|
42
|
+
t = thread_it(kafka_input, queue)
|
43
|
+
t.run
|
44
|
+
wait(timeout_seconds).for { queue.length }.to eq(num_events)
|
45
|
+
expect(queue.length).to eq(num_events)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should consume all messages from lz4 3-partition topic" do
|
49
|
+
kafka_input = LogStash::Inputs::Kafka.new(lz4_config)
|
50
|
+
queue = Array.new
|
51
|
+
t = thread_it(kafka_input, queue)
|
52
|
+
t.run
|
53
|
+
wait(timeout_seconds).for { queue.length }.to eq(num_events)
|
54
|
+
expect(queue.length).to eq(num_events)
|
55
|
+
end
|
56
|
+
|
20
57
|
end
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
58
|
+
|
59
|
+
describe "#kafka-topics-pattern" do
|
60
|
+
|
61
|
+
def thread_it(kafka_input, queue)
|
62
|
+
Thread.new do
|
63
|
+
begin
|
64
|
+
kafka_input.run(queue)
|
28
65
|
end
|
29
66
|
end
|
30
67
|
end
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
it "should consume all messages from snappy 3-partition topic" do
|
43
|
-
kafka_input = LogStash::Inputs::Kafka.new(snappy_config)
|
44
|
-
queue = Array.new
|
45
|
-
t = thread_it(kafka_input, queue)
|
46
|
-
t.run
|
47
|
-
wait_for_events(queue, num_events)
|
48
|
-
expect(queue.size).to eq(num_events)
|
68
|
+
|
69
|
+
it "should consume all messages from all 3 topics" do
|
70
|
+
kafka_input = LogStash::Inputs::Kafka.new(pattern_config)
|
71
|
+
queue = Array.new
|
72
|
+
t = thread_it(kafka_input, queue)
|
73
|
+
t.run
|
74
|
+
wait(timeout_seconds).for { queue.length }.to eq(3*num_events)
|
75
|
+
expect(queue.length).to eq(3*num_events)
|
76
|
+
end
|
49
77
|
end
|
50
78
|
|
51
|
-
|
52
|
-
kafka_input
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
79
|
+
describe "#kafka-decorate" do
|
80
|
+
def thread_it(kafka_input, queue)
|
81
|
+
Thread.new do
|
82
|
+
begin
|
83
|
+
kafka_input.run(queue)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should show the right topic and group name in decorated kafka section" do
|
89
|
+
kafka_input = LogStash::Inputs::Kafka.new(decorate_config)
|
90
|
+
queue = Queue.new
|
91
|
+
t = thread_it(kafka_input, queue)
|
92
|
+
t.run
|
93
|
+
wait(timeout_seconds).for { queue.length }.to eq(num_events)
|
94
|
+
expect(queue.length).to eq(num_events)
|
95
|
+
event = queue.shift
|
96
|
+
expect(event.get("kafka")["topic"]).to eq("logstash_topic_plain")
|
97
|
+
expect(event.get("kafka")["consumer_group"]).to eq(group_id_3)
|
98
|
+
end
|
58
99
|
end
|
59
|
-
|
60
100
|
end
|
@@ -16,7 +16,7 @@ class MockConsumer
|
|
16
16
|
raise org.apache.kafka.common.errors.WakeupException.new
|
17
17
|
else
|
18
18
|
10.times.map do
|
19
|
-
org.apache.kafka.clients.consumer.ConsumerRecord.new("
|
19
|
+
org.apache.kafka.clients.consumer.ConsumerRecord.new("logstash", 0, 0, "key", "value")
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -30,7 +30,7 @@ class MockConsumer
|
|
30
30
|
end
|
31
31
|
|
32
32
|
describe LogStash::Inputs::Kafka do
|
33
|
-
let(:config) { { 'topics' => ['
|
33
|
+
let(:config) { { 'topics' => ['logstash'], 'consumer_threads' => 4 } }
|
34
34
|
subject { LogStash::Inputs::Kafka.new(config) }
|
35
35
|
|
36
36
|
it "should register" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-input-kafka
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elasticsearch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-02-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|