fluent-plugin-kafka 0.16.1 → 0.17.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.yaml +71 -0
- data/.github/ISSUE_TEMPLATE/config.yml +5 -0
- data/.github/ISSUE_TEMPLATE/feature_request.yaml +38 -0
- data/.github/workflows/linux.yml +12 -0
- data/.github/workflows/stale-actions.yml +22 -0
- data/ChangeLog +16 -0
- data/Gemfile +2 -0
- data/README.md +31 -4
- data/ci/prepare-kafka-server.sh +33 -0
- data/fluent-plugin-kafka.gemspec +4 -2
- data/lib/fluent/plugin/in_kafka.rb +5 -4
- data/lib/fluent/plugin/in_kafka_group.rb +5 -5
- data/lib/fluent/plugin/out_kafka.rb +12 -6
- data/lib/fluent/plugin/out_kafka2.rb +25 -8
- data/lib/fluent/plugin/out_kafka_buffered.rb +12 -6
- data/lib/fluent/plugin/out_rdkafka.rb +15 -9
- data/lib/fluent/plugin/out_rdkafka2.rb +26 -8
- data/test/helper.rb +7 -0
- data/test/plugin/test_in_kafka.rb +66 -0
- data/test/plugin/test_in_kafka_group.rb +67 -0
- data/test/plugin/test_kafka_plugin_util.rb +18 -12
- data/test/plugin/test_out_kafka.rb +10 -0
- data/test/plugin/test_out_kafka2.rb +116 -0
- data/test/plugin/test_out_kafka_buffered.rb +68 -0
- data/test/plugin/test_out_rdkafka2.rb +120 -0
- metadata +48 -6
- data/.travis.yml +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 230266adf4ba3d77b8b2fd743863377c4dd2532297f45e4489df62bfcbee1db5
|
4
|
+
data.tar.gz: 4b82d2f33bbbb3294f547a7af154783c432c6316f1155a0e3a822361232743e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9321cd8bd10dcd603b653c101e6695b7071d7b9dc61fb49bc79248b22cbe9f1db46416c40132243c9862e9c4a3888c818f7a8906906ccf0dda545032f2ac53fd
|
7
|
+
data.tar.gz: 832517ac39c4f775d95775454b07bc0f3ecc2f27b1c0bd4c3f8025e795dfbe869d3e349084f868bdb54cfa72188d4cbd96173192f728fae4281f7f84e5d973aa
|
@@ -0,0 +1,71 @@
|
|
1
|
+
name: Bug Report
|
2
|
+
description: Create a report with a procedure for reproducing the bug
|
3
|
+
body:
|
4
|
+
- type: markdown
|
5
|
+
attributes:
|
6
|
+
value: |
|
7
|
+
Check [README](https://github.com/fluent/fluent-plugin-kafka/#faq) first and here is the list to help us investigate the problem.
|
8
|
+
- type: textarea
|
9
|
+
id: description
|
10
|
+
attributes:
|
11
|
+
label: Describe the bug
|
12
|
+
description: A clear and concise description of what the bug is
|
13
|
+
validations:
|
14
|
+
required: true
|
15
|
+
- type: textarea
|
16
|
+
id: reproduce
|
17
|
+
attributes:
|
18
|
+
label: To Reproduce
|
19
|
+
description: Steps to reproduce the behavior
|
20
|
+
validations:
|
21
|
+
required: true
|
22
|
+
- type: textarea
|
23
|
+
id: expected
|
24
|
+
attributes:
|
25
|
+
label: Expected behavior
|
26
|
+
description: A clear and concise description of what you expected to happen
|
27
|
+
validations:
|
28
|
+
required: true
|
29
|
+
- type: textarea
|
30
|
+
id: environment
|
31
|
+
attributes:
|
32
|
+
label: Your Environment
|
33
|
+
description: |
|
34
|
+
- Fluentd or td-agent version: `fluentd --version` or `td-agent --version`
|
35
|
+
- Operating system: `cat /etc/os-release`
|
36
|
+
- Kernel version: `uname -r`
|
37
|
+
|
38
|
+
Tip: If you hit the problem with older fluentd version, try latest version first.
|
39
|
+
value: |
|
40
|
+
- Fluentd version:
|
41
|
+
- TD Agent version:
|
42
|
+
- fluent-plugin-kafka version:
|
43
|
+
- ruby-kafka version:
|
44
|
+
- Operating system:
|
45
|
+
- Kernel version:
|
46
|
+
render: markdown
|
47
|
+
validations:
|
48
|
+
required: true
|
49
|
+
- type: textarea
|
50
|
+
id: configuration
|
51
|
+
attributes:
|
52
|
+
label: Your Configuration
|
53
|
+
description: |
|
54
|
+
Write your configuration here. Minimum reproducible fluentd.conf is recommended.
|
55
|
+
validations:
|
56
|
+
required: true
|
57
|
+
- type: textarea
|
58
|
+
id: logs
|
59
|
+
attributes:
|
60
|
+
label: Your Error Log
|
61
|
+
description: Write your ALL error log here
|
62
|
+
render: shell
|
63
|
+
validations:
|
64
|
+
required: true
|
65
|
+
- type: textarea
|
66
|
+
id: addtional-context
|
67
|
+
attributes:
|
68
|
+
label: Additional context
|
69
|
+
description: Add any other context about the problem here.
|
70
|
+
validations:
|
71
|
+
required: false
|
@@ -0,0 +1,38 @@
|
|
1
|
+
name: Feature request
|
2
|
+
description: Suggest an idea for this project
|
3
|
+
body:
|
4
|
+
- type: markdown
|
5
|
+
attributes:
|
6
|
+
value: |
|
7
|
+
Check [README.md](https://github.com/fluent/fluent-plugin-kafka/blob/master/README.md) first and here is the list to help us investigate the problem.
|
8
|
+
- type: textarea
|
9
|
+
id: description
|
10
|
+
attributes:
|
11
|
+
label: Is your feature request related to a problem? Please describe.
|
12
|
+
description: |
|
13
|
+
A clear and concise description of what the problem is.
|
14
|
+
Ex. I'm always frustrated when [...]
|
15
|
+
validations:
|
16
|
+
required: true
|
17
|
+
- type: textarea
|
18
|
+
id: solution
|
19
|
+
attributes:
|
20
|
+
label: Describe the solution you'd like
|
21
|
+
description: A clear and concise description of what you want to happen.
|
22
|
+
validations:
|
23
|
+
required: true
|
24
|
+
- type: textarea
|
25
|
+
id: alternative
|
26
|
+
attributes:
|
27
|
+
label: Describe alternatives you've considered
|
28
|
+
description: A clear and concise description of any alternative solutions or features you've considered.
|
29
|
+
validations:
|
30
|
+
required: true
|
31
|
+
- type: textarea
|
32
|
+
id: addtional-context
|
33
|
+
attributes:
|
34
|
+
label: Additional context
|
35
|
+
description: Add any other context or screenshots about the feature request here.
|
36
|
+
validations:
|
37
|
+
required: false
|
38
|
+
|
data/.github/workflows/linux.yml
CHANGED
@@ -5,6 +5,8 @@ on:
|
|
5
5
|
jobs:
|
6
6
|
build:
|
7
7
|
runs-on: ${{ matrix.os }}
|
8
|
+
env:
|
9
|
+
USE_RDKAFKA: 1
|
8
10
|
strategy:
|
9
11
|
fail-fast: false
|
10
12
|
matrix:
|
@@ -17,10 +19,20 @@ jobs:
|
|
17
19
|
- uses: ruby/setup-ruby@v1
|
18
20
|
with:
|
19
21
|
ruby-version: ${{ matrix.ruby }}
|
22
|
+
- name: Install confluent-kafka
|
23
|
+
run: |
|
24
|
+
sudo apt install -V -y gnupg2 wget
|
25
|
+
wget https://packages.confluent.io/deb/6.0/archive.key
|
26
|
+
sudo gpg2 --homedir /tmp --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/confluent-archive-keyring.gpg --import archive.key
|
27
|
+
sudo chmod 644 /usr/share/keyrings/confluent-archive-keyring.gpg
|
28
|
+
sudo sh -c 'echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/confluent-archive-keyring.gpg] https://packages.confluent.io/deb/6.0 stable main" > /etc/apt/sources.list.d/confluent.list'
|
29
|
+
sudo apt update
|
30
|
+
sudo apt install -y confluent-community-2.13 openjdk-11-jre netcat-openbsd
|
20
31
|
- name: unit testing
|
21
32
|
env:
|
22
33
|
CI: true
|
23
34
|
run: |
|
35
|
+
sudo ./ci/prepare-kafka-server.sh
|
24
36
|
gem install bundler rake
|
25
37
|
bundle install --jobs 4 --retry 3
|
26
38
|
bundle exec rake test
|
@@ -0,0 +1,22 @@
|
|
1
|
+
name: "Mark or close stale issues and PRs"
|
2
|
+
on:
|
3
|
+
schedule:
|
4
|
+
- cron: "00 10 * * *"
|
5
|
+
|
6
|
+
jobs:
|
7
|
+
stale:
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
steps:
|
10
|
+
- uses: actions/stale@v3
|
11
|
+
with:
|
12
|
+
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
13
|
+
days-before-stale: 90
|
14
|
+
days-before-close: 30
|
15
|
+
stale-issue-message: "This issue has been automatically marked as stale because it has been open 90 days with no activity. Remove stale label or comment or this issue will be closed in 30 days"
|
16
|
+
stale-pr-message: "This PR has been automatically marked as stale because it has been open 90 days with no activity. Remove stale label or comment or this PR will be closed in 30 days"
|
17
|
+
close-issue-message: "This issue was automatically closed because of stale in 30 days"
|
18
|
+
close-pr-message: "This PR was automatically closed because of stale in 30 days"
|
19
|
+
stale-pr-label: "stale"
|
20
|
+
stale-issue-label: "stale"
|
21
|
+
exempt-issue-labels: "bug,enhancement,help wanted"
|
22
|
+
exempt-pr-labels: "bug,enhancement,help wanted"
|
data/ChangeLog
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
Release 0.17.1 - 2021/09/24
|
2
|
+
* out_rdkafka/out_rdkafka2: Support rdkafka 0.9.0 or later
|
3
|
+
* out_rdkafka/out_rdkafka2: Add `exclude_fields` parameter
|
4
|
+
* out_kafka2.rb: Fix one more Ruby 3.0 keyword arguments issue
|
5
|
+
|
6
|
+
Release 0.17.0 - 2021/08/30
|
7
|
+
* out_kafka/out_kafka_buffered/out_kafka2: Provide murmur2 partitioner hash function choice
|
8
|
+
* in_kafka/in_kafka_group/out_kafka/out_kafka_buffered/out_kafka2: Use Ruby Kafka's ssl_ca_cert_file_path parameter to feed the CA certs
|
9
|
+
* out_kafka/out_kafka2: fix description for `exclude_message_key` option
|
10
|
+
|
11
|
+
Release 0.16.3 - 2021/05/17
|
12
|
+
* in_kafka_group: Fix one more Ruby 3.0 keyword arguments issue
|
13
|
+
|
14
|
+
Release 0.16.2 - 2021/05/17
|
15
|
+
* in_kafka, in_kafka_group: Support Ruby 3.0 keyword arguments interop
|
16
|
+
|
1
17
|
Release 0.16.1 - 2021/04/14
|
2
18
|
* out_kafka/out_kafka_buffered: Support Ruby 3.0.0 keyword arguments interop
|
3
19
|
* kafka_plugin_util: Treat empty string in read_ssl_file as nil
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# fluent-plugin-kafka, a plugin for [Fluentd](http://fluentd.org)
|
2
2
|
|
3
|
-
[![
|
3
|
+
[![GitHub Actions Status](https://github.com/fluent/fluent-plugin-kafka/actions/workflows/linux.yml/badge.svg)](https://github.com/fluent/fluent-plugin-kafka/actions/workflows/linux.yml)
|
4
|
+
|
4
5
|
|
5
6
|
A fluentd plugin to both consume and produce data for Apache Kafka.
|
6
7
|
|
@@ -39,14 +40,14 @@ If you want to use zookeeper related parameters, you also need to install zookee
|
|
39
40
|
|
40
41
|
Set path to SSL related files. See [Encryption and Authentication using SSL](https://github.com/zendesk/ruby-kafka#encryption-and-authentication-using-ssl) for more detail.
|
41
42
|
|
42
|
-
#### SASL authentication
|
43
|
+
#### SASL authentication
|
43
44
|
|
44
45
|
##### with GSSAPI
|
45
46
|
|
46
47
|
- principal
|
47
48
|
- keytab
|
48
49
|
|
49
|
-
Set principal and path to keytab for SASL/GSSAPI authentication.
|
50
|
+
Set principal and path to keytab for SASL/GSSAPI authentication.
|
50
51
|
See [Authentication using SASL](https://github.com/zendesk/ruby-kafka#authentication-using-sasl) for more details.
|
51
52
|
|
52
53
|
##### with Plain/SCRAM
|
@@ -56,7 +57,7 @@ See [Authentication using SASL](https://github.com/zendesk/ruby-kafka#authentica
|
|
56
57
|
- scram_mechanism
|
57
58
|
- sasl_over_ssl
|
58
59
|
|
59
|
-
Set username, password, scram_mechanism and sasl_over_ssl for SASL/Plain or Scram authentication.
|
60
|
+
Set username, password, scram_mechanism and sasl_over_ssl for SASL/Plain or Scram authentication.
|
60
61
|
See [Authentication using SASL](https://github.com/zendesk/ruby-kafka#authentication-using-sasl) for more details.
|
61
62
|
|
62
63
|
### Input plugin (@type 'kafka')
|
@@ -201,6 +202,7 @@ If `ruby-kafka` doesn't fit your kafka environment, check `rdkafka2` plugin inst
|
|
201
202
|
headers_from_record (hash) :default => {}
|
202
203
|
use_default_for_unknown_topic (bool) :default => false
|
203
204
|
discard_kafka_delivery_failed (bool) :default => false (No discard)
|
205
|
+
partitioner_hash_function (enum) (crc32|murmur2) :default => 'crc32'
|
204
206
|
|
205
207
|
<format>
|
206
208
|
@type (json|ltsv|msgpack|attr:<record name>|<formatter name>) :default => json
|
@@ -229,6 +231,8 @@ If `ruby-kafka` doesn't fit your kafka environment, check `rdkafka2` plugin inst
|
|
229
231
|
|
230
232
|
The `<formatter name>` in `<format>` uses fluentd's formatter plugins. See [formatter article](https://docs.fluentd.org/v/1.0/formatter).
|
231
233
|
|
234
|
+
**Note:** Java based Kafka client uses `murmur2` as partitioner function by default. If you want to use same partitioning behavior with fluent-plugin-kafka, change it to `murmur2` instead of `crc32`. Note that for using `murmur2` hash partitioner function, you must install `digest-murmurhash` gem.
|
235
|
+
|
232
236
|
ruby-kafka sometimes returns `Kafka::DeliveryFailed` error without good information.
|
233
237
|
In this case, `get_kafka_client_log` is useful for identifying the error cause.
|
234
238
|
ruby-kafka's log is routed to fluentd log so you can see ruby-kafka's log in fluentd logs.
|
@@ -312,6 +316,23 @@ The Kafka message will have a header of source_ip=12.7.0.0.1.
|
|
312
316
|
|
313
317
|
The configuration format is jsonpath. It is descibed in https://docs.fluentd.org/plugin-helper-overview/api-plugin-helper-record_accessor
|
314
318
|
|
319
|
+
#### Excluding fields
|
320
|
+
Fields can be excluded from output data. Only works for kafka2 and rdkafka2 output plugin.
|
321
|
+
|
322
|
+
Fields must be specified using an array of dot notation `$.`, for example:
|
323
|
+
|
324
|
+
<match app.**>
|
325
|
+
@type kafka2
|
326
|
+
[...]
|
327
|
+
exclude_fields $.source.ip,$.HTTP_FOO
|
328
|
+
<match>
|
329
|
+
|
330
|
+
This config can be used to remove fields used on another configs.
|
331
|
+
|
332
|
+
For example, `$.source.ip` can be extracted with config `headers_from_record` and excluded from message payload.
|
333
|
+
|
334
|
+
> Using this config to remove unused fields is discouraged. A [filter plugin](https://docs.fluentd.org/v/0.12/filter) can be used for this purpose.
|
335
|
+
|
315
336
|
### Buffered output plugin
|
316
337
|
|
317
338
|
This plugin uses ruby-kafka producer for writing data. This plugin is for v0.12. If you use v1, see `kafka2`.
|
@@ -342,6 +363,7 @@ Support of fluentd v0.12 has ended. `kafka_buffered` will be an alias of `kafka2
|
|
342
363
|
exclude_topic_key (bool) :default => false
|
343
364
|
exclude_partition_key (bool) :default => false
|
344
365
|
get_kafka_client_log (bool) :default => false
|
366
|
+
partitioner_hash_function (enum) (crc32|murmur2) :default => 'crc32'
|
345
367
|
|
346
368
|
# See fluentd document for buffer related parameters: https://docs.fluentd.org/v/0.12/buffer
|
347
369
|
|
@@ -364,6 +386,8 @@ Support of fluentd v0.12 has ended. `kafka_buffered` will be an alias of `kafka2
|
|
364
386
|
- kafka_agg_max_bytes - default: 4096 - Maximum value of total message size to be included in one batch transmission.
|
365
387
|
- kafka_agg_max_messages - default: nil - Maximum number of messages to include in one batch transmission.
|
366
388
|
|
389
|
+
**Note:** Java based Kafka client uses `murmur2` as partitioner function by default. If you want to use same partitioning behavior with fluent-plugin-kafka, change it to `murmur2` instead of `crc32`. Note that for using `murmur2` hash partitioner function, you must install `digest-murmurhash` gem.
|
390
|
+
|
367
391
|
### Non-buffered output plugin
|
368
392
|
|
369
393
|
This plugin uses ruby-kafka producer for writing data. For performance and reliability concerns, use `kafka_bufferd` output instead. This is mainly for testing.
|
@@ -384,6 +408,7 @@ This plugin uses ruby-kafka producer for writing data. For performance and relia
|
|
384
408
|
output_include_time (bool) :default => false
|
385
409
|
exclude_topic_key (bool) :default => false
|
386
410
|
exclude_partition_key (bool) :default => false
|
411
|
+
partitioner_hash_function (enum) (crc32|murmur2) :default => 'crc32'
|
387
412
|
|
388
413
|
# ruby-kafka producer options
|
389
414
|
max_send_retries (integer) :default => 1
|
@@ -396,6 +421,8 @@ This plugin uses ruby-kafka producer for writing data. For performance and relia
|
|
396
421
|
|
397
422
|
This plugin also supports ruby-kafka related parameters. See Buffered output plugin section.
|
398
423
|
|
424
|
+
**Note:** Java based Kafka client uses `murmur2` as partitioner function by default. If you want to use same partitioning behavior with fluent-plugin-kafka, change it to `murmur2` instead of `crc32`. Note that for using `murmur2` hash partitioner function, you must install `digest-murmurhash` gem.
|
425
|
+
|
399
426
|
### rdkafka based output plugin
|
400
427
|
|
401
428
|
This plugin uses `rdkafka` instead of `ruby-kafka` for kafka client.
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
export KAFKA_OPTS=-Dzookeeper.4lw.commands.whitelist=ruok
|
4
|
+
/usr/bin/zookeeper-server-start /etc/kafka/zookeeper.properties &
|
5
|
+
N_POLLING=30
|
6
|
+
n=1
|
7
|
+
while true ; do
|
8
|
+
sleep 1
|
9
|
+
status=$(echo ruok | nc localhost 2181)
|
10
|
+
if [ "$status" = "imok" ]; then
|
11
|
+
break
|
12
|
+
fi
|
13
|
+
n=$((n + 1))
|
14
|
+
if [ $n -ge $N_POLLING ]; then
|
15
|
+
echo "failed to get response from zookeeper-server"
|
16
|
+
exit 1
|
17
|
+
fi
|
18
|
+
done
|
19
|
+
/usr/bin/kafka-server-start /etc/kafka/server.properties &
|
20
|
+
n=1
|
21
|
+
while true ; do
|
22
|
+
sleep 1
|
23
|
+
status=$(/usr/bin/zookeeper-shell localhost:2181 ls /brokers/ids | sed -n 6p)
|
24
|
+
if [ "$status" = "[0]" ]; then
|
25
|
+
break
|
26
|
+
fi
|
27
|
+
n=$((n + 1))
|
28
|
+
if [ $n -ge $N_POLLING ]; then
|
29
|
+
echo "failed to get response from kafka-server"
|
30
|
+
exit 1
|
31
|
+
fi
|
32
|
+
done
|
33
|
+
/usr/bin/kafka-topics --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
|
data/fluent-plugin-kafka.gemspec
CHANGED
@@ -13,13 +13,15 @@ Gem::Specification.new do |gem|
|
|
13
13
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
14
|
gem.name = "fluent-plugin-kafka"
|
15
15
|
gem.require_paths = ["lib"]
|
16
|
-
gem.version = '0.
|
16
|
+
gem.version = '0.17.1'
|
17
17
|
gem.required_ruby_version = ">= 2.1.0"
|
18
18
|
|
19
19
|
gem.add_dependency "fluentd", [">= 0.10.58", "< 2"]
|
20
20
|
gem.add_dependency 'ltsv'
|
21
|
-
gem.add_dependency 'ruby-kafka', '>= 1.
|
21
|
+
gem.add_dependency 'ruby-kafka', '>= 1.4.0', '< 2'
|
22
22
|
gem.add_development_dependency "rake", ">= 0.9.2"
|
23
23
|
gem.add_development_dependency "test-unit", ">= 3.0.8"
|
24
|
+
gem.add_development_dependency "test-unit-rr", "~> 1.0"
|
24
25
|
gem.add_development_dependency "webrick"
|
26
|
+
gem.add_development_dependency "digest-murmurhash"
|
25
27
|
end
|
@@ -71,6 +71,7 @@ class Fluent::KafkaInput < Fluent::Input
|
|
71
71
|
require 'kafka'
|
72
72
|
|
73
73
|
@time_parser = nil
|
74
|
+
@zookeeper = nil
|
74
75
|
end
|
75
76
|
|
76
77
|
def configure(conf)
|
@@ -197,17 +198,17 @@ class Fluent::KafkaInput < Fluent::Input
|
|
197
198
|
|
198
199
|
logger = @get_kafka_client_log ? log : nil
|
199
200
|
if @scram_mechanism != nil && @username != nil && @password != nil
|
200
|
-
@kafka = Kafka.new(seed_brokers: @brokers, client_id: @client_id, logger: logger,
|
201
|
+
@kafka = Kafka.new(seed_brokers: @brokers, client_id: @client_id, logger: logger, ssl_ca_cert_file_path: @ssl_ca_cert,
|
201
202
|
ssl_client_cert: read_ssl_file(@ssl_client_cert), ssl_client_cert_key: read_ssl_file(@ssl_client_cert_key),
|
202
203
|
ssl_ca_certs_from_system: @ssl_ca_certs_from_system, sasl_scram_username: @username, sasl_scram_password: @password,
|
203
204
|
sasl_scram_mechanism: @scram_mechanism, sasl_over_ssl: @sasl_over_ssl, ssl_verify_hostname: @ssl_verify_hostname)
|
204
205
|
elsif @username != nil && @password != nil
|
205
|
-
@kafka = Kafka.new(seed_brokers: @brokers, client_id: @client_id, logger: logger,
|
206
|
+
@kafka = Kafka.new(seed_brokers: @brokers, client_id: @client_id, logger: logger, ssl_ca_cert_file_path: @ssl_ca_cert,
|
206
207
|
ssl_client_cert: read_ssl_file(@ssl_client_cert), ssl_client_cert_key: read_ssl_file(@ssl_client_cert_key),
|
207
208
|
ssl_ca_certs_from_system: @ssl_ca_certs_from_system,sasl_plain_username: @username, sasl_plain_password: @password,
|
208
209
|
sasl_over_ssl: @sasl_over_ssl, ssl_verify_hostname: @ssl_verify_hostname)
|
209
210
|
else
|
210
|
-
@kafka = Kafka.new(seed_brokers: @brokers, client_id: @client_id, logger: logger,
|
211
|
+
@kafka = Kafka.new(seed_brokers: @brokers, client_id: @client_id, logger: logger, ssl_ca_cert_file_path: @ssl_ca_cert,
|
211
212
|
ssl_client_cert: read_ssl_file(@ssl_client_cert), ssl_client_cert_key: read_ssl_file(@ssl_client_cert_key),
|
212
213
|
ssl_ca_certs_from_system: @ssl_ca_certs_from_system, sasl_gssapi_principal: @principal, sasl_gssapi_keytab: @keytab,
|
213
214
|
ssl_verify_hostname: @ssl_verify_hostname)
|
@@ -294,7 +295,7 @@ class Fluent::KafkaInput < Fluent::Input
|
|
294
295
|
def consume
|
295
296
|
offset = @next_offset
|
296
297
|
@fetch_args[:offset] = offset
|
297
|
-
messages = @kafka.fetch_messages(
|
298
|
+
messages = @kafka.fetch_messages(**@fetch_args)
|
298
299
|
|
299
300
|
return if messages.size.zero?
|
300
301
|
|
@@ -183,17 +183,17 @@ class Fluent::KafkaGroupInput < Fluent::Input
|
|
183
183
|
|
184
184
|
logger = @get_kafka_client_log ? log : nil
|
185
185
|
if @scram_mechanism != nil && @username != nil && @password != nil
|
186
|
-
@kafka = Kafka.new(seed_brokers: @brokers, client_id: @client_id, logger: logger, connect_timeout: @connect_timeout, socket_timeout: @socket_timeout,
|
186
|
+
@kafka = Kafka.new(seed_brokers: @brokers, client_id: @client_id, logger: logger, connect_timeout: @connect_timeout, socket_timeout: @socket_timeout, ssl_ca_cert_file_path: @ssl_ca_cert,
|
187
187
|
ssl_client_cert: read_ssl_file(@ssl_client_cert), ssl_client_cert_key: read_ssl_file(@ssl_client_cert_key),
|
188
188
|
ssl_ca_certs_from_system: @ssl_ca_certs_from_system, sasl_scram_username: @username, sasl_scram_password: @password,
|
189
189
|
sasl_scram_mechanism: @scram_mechanism, sasl_over_ssl: @sasl_over_ssl, ssl_verify_hostname: @ssl_verify_hostname)
|
190
190
|
elsif @username != nil && @password != nil
|
191
|
-
@kafka = Kafka.new(seed_brokers: @brokers, client_id: @client_id, logger: logger, connect_timeout: @connect_timeout, socket_timeout: @socket_timeout,
|
191
|
+
@kafka = Kafka.new(seed_brokers: @brokers, client_id: @client_id, logger: logger, connect_timeout: @connect_timeout, socket_timeout: @socket_timeout, ssl_ca_cert_file_path: @ssl_ca_cert,
|
192
192
|
ssl_client_cert: read_ssl_file(@ssl_client_cert), ssl_client_cert_key: read_ssl_file(@ssl_client_cert_key),
|
193
193
|
ssl_ca_certs_from_system: @ssl_ca_certs_from_system, sasl_plain_username: @username, sasl_plain_password: @password,
|
194
194
|
sasl_over_ssl: @sasl_over_ssl, ssl_verify_hostname: @ssl_verify_hostname)
|
195
195
|
else
|
196
|
-
@kafka = Kafka.new(seed_brokers: @brokers, client_id: @client_id, logger: logger, connect_timeout: @connect_timeout, socket_timeout: @socket_timeout,
|
196
|
+
@kafka = Kafka.new(seed_brokers: @brokers, client_id: @client_id, logger: logger, connect_timeout: @connect_timeout, socket_timeout: @socket_timeout, ssl_ca_cert_file_path: @ssl_ca_cert,
|
197
197
|
ssl_client_cert: read_ssl_file(@ssl_client_cert), ssl_client_cert_key: read_ssl_file(@ssl_client_cert_key),
|
198
198
|
ssl_ca_certs_from_system: @ssl_ca_certs_from_system, sasl_gssapi_principal: @principal, sasl_gssapi_keytab: @keytab,
|
199
199
|
ssl_verify_hostname: @ssl_verify_hostname)
|
@@ -217,7 +217,7 @@ class Fluent::KafkaGroupInput < Fluent::Input
|
|
217
217
|
end
|
218
218
|
|
219
219
|
def setup_consumer
|
220
|
-
consumer = @kafka.consumer(
|
220
|
+
consumer = @kafka.consumer(**@consumer_opts)
|
221
221
|
@topics.each { |topic|
|
222
222
|
if m = /^\/(.+)\/$/.match(topic)
|
223
223
|
topic_or_regex = Regexp.new(m[1])
|
@@ -345,7 +345,7 @@ class Fluent::KafkaGroupInput < Fluent::Input
|
|
345
345
|
def run
|
346
346
|
while @consumer
|
347
347
|
begin
|
348
|
-
@consumer.each_batch(
|
348
|
+
@consumer.each_batch(**@fetch_opts) { |batch|
|
349
349
|
if @tag_source == :record
|
350
350
|
process_batch_with_record_tag(batch)
|
351
351
|
else
|
@@ -19,6 +19,8 @@ DESC
|
|
19
19
|
config_param :default_message_key, :string, :default => nil
|
20
20
|
config_param :default_partition_key, :string, :default => nil
|
21
21
|
config_param :default_partition, :integer, :default => nil
|
22
|
+
config_param :partitioner_hash_function, :enum, list: [:crc32, :murmur2], :default => :crc32,
|
23
|
+
:desc => "Specify kafka patrtitioner hash algorithm"
|
22
24
|
config_param :client_id, :string, :default => 'kafka'
|
23
25
|
config_param :sasl_over_ssl, :bool, :default => true,
|
24
26
|
:desc => <<-DESC
|
@@ -86,6 +88,7 @@ DESC
|
|
86
88
|
require 'kafka'
|
87
89
|
|
88
90
|
@kafka = nil
|
91
|
+
@field_separator = nil
|
89
92
|
end
|
90
93
|
|
91
94
|
def refresh_client
|
@@ -106,18 +109,21 @@ DESC
|
|
106
109
|
begin
|
107
110
|
if @seed_brokers.length > 0
|
108
111
|
if @scram_mechanism != nil && @username != nil && @password != nil
|
109
|
-
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id,
|
112
|
+
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id, ssl_ca_cert_file_path: @ssl_ca_cert,
|
110
113
|
ssl_client_cert: read_ssl_file(@ssl_client_cert), ssl_client_cert_key: read_ssl_file(@ssl_client_cert_key), ssl_ca_certs_from_system: @ssl_ca_certs_from_system,
|
111
114
|
sasl_scram_username: @username, sasl_scram_password: @password, sasl_scram_mechanism: @scram_mechanism, sasl_over_ssl: @sasl_over_ssl,
|
112
|
-
ssl_verify_hostname: @ssl_verify_hostname
|
115
|
+
ssl_verify_hostname: @ssl_verify_hostname,
|
116
|
+
partitioner: Kafka::Partitioner.new(hash_function: @partitioner_hash_function))
|
113
117
|
elsif @username != nil && @password != nil
|
114
|
-
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id,
|
118
|
+
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id, ssl_ca_cert_file_path: @ssl_ca_cert,
|
115
119
|
ssl_client_cert: read_ssl_file(@ssl_client_cert), ssl_client_cert_key: read_ssl_file(@ssl_client_cert_key), ssl_ca_certs_from_system: @ssl_ca_certs_from_system,
|
116
|
-
sasl_plain_username: @username, sasl_plain_password: @password, sasl_over_ssl: @sasl_over_ssl, ssl_verify_hostname: @ssl_verify_hostname
|
120
|
+
sasl_plain_username: @username, sasl_plain_password: @password, sasl_over_ssl: @sasl_over_ssl, ssl_verify_hostname: @ssl_verify_hostname,
|
121
|
+
partitioner: Kafka::Partitioner.new(hash_function: @partitioner_hash_function))
|
117
122
|
else
|
118
|
-
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id,
|
123
|
+
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id, ssl_ca_cert_file_path: @ssl_ca_cert,
|
119
124
|
ssl_client_cert: read_ssl_file(@ssl_client_cert), ssl_client_cert_key: read_ssl_file(@ssl_client_cert_key), ssl_ca_certs_from_system: @ssl_ca_certs_from_system,
|
120
|
-
sasl_gssapi_principal: @principal, sasl_gssapi_keytab: @keytab, sasl_over_ssl: @sasl_over_ssl, ssl_verify_hostname: @ssl_verify_hostname
|
125
|
+
sasl_gssapi_principal: @principal, sasl_gssapi_keytab: @keytab, sasl_over_ssl: @sasl_over_ssl, ssl_verify_hostname: @ssl_verify_hostname,
|
126
|
+
partitioner: Kafka::Partitioner.new(hash_function: @partitioner_hash_function))
|
121
127
|
end
|
122
128
|
log.info "initialized kafka producer: #{@client_id}"
|
123
129
|
else
|
@@ -24,6 +24,8 @@ DESC
|
|
24
24
|
config_param :partition_key_key, :string, :default => 'partition_key', :desc => "Field for kafka partition key"
|
25
25
|
config_param :default_partition_key, :string, :default => nil
|
26
26
|
config_param :partition_key, :string, :default => 'partition', :desc => "Field for kafka partition"
|
27
|
+
config_param :partitioner_hash_function, :enum, list: [:crc32, :murmur2], :default => :crc32,
|
28
|
+
:desc => "Specify kafka patrtitioner hash algorithm"
|
27
29
|
config_param :default_partition, :integer, :default => nil
|
28
30
|
config_param :use_default_for_unknown_topic, :bool, :default => false, :desc => "If true, default_topic is used when topic not found"
|
29
31
|
config_param :client_id, :string, :default => 'fluentd'
|
@@ -37,9 +39,11 @@ DESC
|
|
37
39
|
config_param :exclude_partition, :bool, :default => false,
|
38
40
|
:desc => 'Set true to remove partition from data'
|
39
41
|
config_param :exclude_message_key, :bool, :default => false,
|
40
|
-
:desc => 'Set true to remove
|
42
|
+
:desc => 'Set true to remove message key from data'
|
41
43
|
config_param :exclude_topic_key, :bool, :default => false,
|
42
44
|
:desc => 'Set true to remove topic name key from data'
|
45
|
+
config_param :exclude_fields, :array, :default => [], value_type: :string,
|
46
|
+
:desc => 'Fields to remove from data where the value is a jsonpath to a record value'
|
43
47
|
config_param :use_event_time, :bool, :default => false, :desc => 'Use fluentd event time for kafka create_time'
|
44
48
|
config_param :headers, :hash, default: {}, symbolize_keys: true, value_type: :string,
|
45
49
|
:desc => 'Kafka message headers'
|
@@ -96,20 +100,23 @@ DESC
|
|
96
100
|
begin
|
97
101
|
logger = @get_kafka_client_log ? log : nil
|
98
102
|
if @scram_mechanism != nil && @username != nil && @password != nil
|
99
|
-
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id, logger: logger, connect_timeout: @connect_timeout, socket_timeout: @socket_timeout,
|
103
|
+
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id, logger: logger, connect_timeout: @connect_timeout, socket_timeout: @socket_timeout, ssl_ca_cert_file_path: @ssl_ca_cert,
|
100
104
|
ssl_client_cert: read_ssl_file(@ssl_client_cert), ssl_client_cert_key: read_ssl_file(@ssl_client_cert_key), ssl_client_cert_chain: read_ssl_file(@ssl_client_cert_chain),
|
101
105
|
ssl_ca_certs_from_system: @ssl_ca_certs_from_system, sasl_scram_username: @username, sasl_scram_password: @password,
|
102
|
-
sasl_scram_mechanism: @scram_mechanism, sasl_over_ssl: @sasl_over_ssl, ssl_verify_hostname: @ssl_verify_hostname
|
106
|
+
sasl_scram_mechanism: @scram_mechanism, sasl_over_ssl: @sasl_over_ssl, ssl_verify_hostname: @ssl_verify_hostname,
|
107
|
+
partitioner: Kafka::Partitioner.new(hash_function: @partitioner_hash_function))
|
103
108
|
elsif @username != nil && @password != nil
|
104
|
-
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id, logger: logger, connect_timeout: @connect_timeout, socket_timeout: @socket_timeout,
|
109
|
+
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id, logger: logger, connect_timeout: @connect_timeout, socket_timeout: @socket_timeout, ssl_ca_cert_file_path: @ssl_ca_cert,
|
105
110
|
ssl_client_cert: read_ssl_file(@ssl_client_cert), ssl_client_cert_key: read_ssl_file(@ssl_client_cert_key), ssl_client_cert_chain: read_ssl_file(@ssl_client_cert_chain),
|
106
111
|
ssl_ca_certs_from_system: @ssl_ca_certs_from_system, sasl_plain_username: @username, sasl_plain_password: @password, sasl_over_ssl: @sasl_over_ssl,
|
107
|
-
ssl_verify_hostname: @ssl_verify_hostname
|
112
|
+
ssl_verify_hostname: @ssl_verify_hostname,
|
113
|
+
partitioner: Kafka::Partitioner.new(hash_function: @partitioner_hash_function))
|
108
114
|
else
|
109
|
-
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id, logger: logger, connect_timeout: @connect_timeout, socket_timeout: @socket_timeout,
|
115
|
+
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id, logger: logger, connect_timeout: @connect_timeout, socket_timeout: @socket_timeout, ssl_ca_cert_file_path: @ssl_ca_cert,
|
110
116
|
ssl_client_cert: read_ssl_file(@ssl_client_cert), ssl_client_cert_key: read_ssl_file(@ssl_client_cert_key), ssl_client_cert_chain: read_ssl_file(@ssl_client_cert_chain),
|
111
117
|
ssl_ca_certs_from_system: @ssl_ca_certs_from_system, sasl_gssapi_principal: @principal, sasl_gssapi_keytab: @keytab, sasl_over_ssl: @sasl_over_ssl,
|
112
|
-
ssl_verify_hostname: @ssl_verify_hostname
|
118
|
+
ssl_verify_hostname: @ssl_verify_hostname,
|
119
|
+
partitioner: Kafka::Partitioner.new(hash_function: @partitioner_hash_function))
|
113
120
|
end
|
114
121
|
log.info "initialized kafka producer: #{@client_id}"
|
115
122
|
rescue Exception => e
|
@@ -172,6 +179,10 @@ DESC
|
|
172
179
|
@headers_from_record.each do |key, value|
|
173
180
|
@headers_from_record_accessors[key] = record_accessor_create(value)
|
174
181
|
end
|
182
|
+
|
183
|
+
@exclude_field_accessors = @exclude_fields.map do |field|
|
184
|
+
record_accessor_create(field)
|
185
|
+
end
|
175
186
|
end
|
176
187
|
|
177
188
|
def multi_workers_ready?
|
@@ -230,7 +241,7 @@ DESC
|
|
230
241
|
mutate_headers = !@headers_from_record_accessors.empty?
|
231
242
|
|
232
243
|
begin
|
233
|
-
producer = @kafka.topic_producer(topic,
|
244
|
+
producer = @kafka.topic_producer(topic, **@producer_opts)
|
234
245
|
chunk.msgpack_each { |time, record|
|
235
246
|
begin
|
236
247
|
record = inject_values_to_record(tag, time, record)
|
@@ -248,6 +259,12 @@ DESC
|
|
248
259
|
headers = base_headers
|
249
260
|
end
|
250
261
|
|
262
|
+
unless @exclude_fields.empty?
|
263
|
+
@exclude_field_accessors.each do |exclude_field_accessor|
|
264
|
+
exclude_field_accessor.delete(record)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
251
268
|
record_buf = @formatter_proc.call(tag, time, record)
|
252
269
|
record_buf_bytes = record_buf.bytesize
|
253
270
|
if @max_send_limit_bytes && record_buf_bytes > @max_send_limit_bytes
|
@@ -26,6 +26,8 @@ DESC
|
|
26
26
|
config_param :default_partition_key, :string, :default => nil
|
27
27
|
config_param :partition_key, :string, :default => 'partition', :desc => "Field for kafka partition"
|
28
28
|
config_param :default_partition, :integer, :default => nil
|
29
|
+
config_param :partitioner_hash_function, :enum, list: [:crc32, :murmur2], :default => :crc32,
|
30
|
+
:desc => "Specify kafka patrtitioner hash algorithm"
|
29
31
|
config_param :client_id, :string, :default => 'kafka'
|
30
32
|
config_param :idempotent, :bool, :default => false, :desc => 'Enable idempotent producer'
|
31
33
|
config_param :sasl_over_ssl, :bool, :default => true,
|
@@ -105,6 +107,7 @@ DESC
|
|
105
107
|
@kafka = nil
|
106
108
|
@producers = {}
|
107
109
|
@producers_mutex = Mutex.new
|
110
|
+
@field_separator = nil
|
108
111
|
end
|
109
112
|
|
110
113
|
def multi_workers_ready?
|
@@ -130,18 +133,21 @@ DESC
|
|
130
133
|
if @seed_brokers.length > 0
|
131
134
|
logger = @get_kafka_client_log ? log : nil
|
132
135
|
if @scram_mechanism != nil && @username != nil && @password != nil
|
133
|
-
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id, logger: logger,
|
136
|
+
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id, logger: logger, ssl_ca_cert_file_path: @ssl_ca_cert,
|
134
137
|
ssl_client_cert: read_ssl_file(@ssl_client_cert), ssl_client_cert_key: read_ssl_file(@ssl_client_cert_key), ssl_ca_certs_from_system: @ssl_ca_certs_from_system,
|
135
138
|
sasl_scram_username: @username, sasl_scram_password: @password, sasl_scram_mechanism: @scram_mechanism, sasl_over_ssl: @sasl_over_ssl,
|
136
|
-
ssl_verify_hostname: @ssl_verify_hostname
|
139
|
+
ssl_verify_hostname: @ssl_verify_hostname,
|
140
|
+
partitioner: Kafka::Partitioner.new(hash_function: @partitioner_hash_function))
|
137
141
|
elsif @username != nil && @password != nil
|
138
|
-
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id, logger: logger,
|
142
|
+
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id, logger: logger, ssl_ca_cert_file_path: @ssl_ca_cert,
|
139
143
|
ssl_client_cert: read_ssl_file(@ssl_client_cert), ssl_client_cert_key: read_ssl_file(@ssl_client_cert_key), ssl_ca_certs_from_system: @ssl_ca_certs_from_system,
|
140
|
-
sasl_plain_username: @username, sasl_plain_password: @password, sasl_over_ssl: @sasl_over_ssl, ssl_verify_hostname: @ssl_verify_hostname
|
144
|
+
sasl_plain_username: @username, sasl_plain_password: @password, sasl_over_ssl: @sasl_over_ssl, ssl_verify_hostname: @ssl_verify_hostname,
|
145
|
+
partitioner: Kafka::Partitioner.new(hash_function: @partitioner_hash_function))
|
141
146
|
else
|
142
|
-
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id, logger: logger,
|
147
|
+
@kafka = Kafka.new(seed_brokers: @seed_brokers, client_id: @client_id, logger: logger, ssl_ca_cert_file_path: @ssl_ca_cert,
|
143
148
|
ssl_client_cert: read_ssl_file(@ssl_client_cert), ssl_client_cert_key: read_ssl_file(@ssl_client_cert_key), ssl_ca_certs_from_system: @ssl_ca_certs_from_system,
|
144
|
-
sasl_gssapi_principal: @principal, sasl_gssapi_keytab: @keytab, sasl_over_ssl: @sasl_over_ssl, ssl_verify_hostname: @ssl_verify_hostname
|
149
|
+
sasl_gssapi_principal: @principal, sasl_gssapi_keytab: @keytab, sasl_over_ssl: @sasl_over_ssl, ssl_verify_hostname: @ssl_verify_hostname,
|
150
|
+
partitioner: Kafka::Partitioner.new(hash_function: @partitioner_hash_function))
|
145
151
|
end
|
146
152
|
log.info "initialized kafka producer: #{@client_id}"
|
147
153
|
else
|