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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f03efe1dee8bff74ba9e0588956bc919244ac6ddf24ff40821d072602dab916
4
- data.tar.gz: b081913e347f5dd28d1339a1eca3f063661217fa4f1738787161cb825c3485fc
3
+ metadata.gz: 230266adf4ba3d77b8b2fd743863377c4dd2532297f45e4489df62bfcbee1db5
4
+ data.tar.gz: 4b82d2f33bbbb3294f547a7af154783c432c6316f1155a0e3a822361232743e4
5
5
  SHA512:
6
- metadata.gz: 03e89037f5982ca8aa121c1c1672160e95fb488ee7e9ca6bd8038e8d9b0cc9d99348ab91a2e1896e174fed4fa2b4c25fb9e65ee72b9a4ba74062c631953ca345
7
- data.tar.gz: 5ca6f6093a1f46ab89b4b268416c16d9758102b76fcdb2bba8d2f235daa7b88e9914e48a0e4d0397df13ea9159a21ba1bbe525186670fd7b7622cfdd3d2cac2f
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,5 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Ask a Question
4
+ url: https://discuss.fluentd.org/
5
+ about: I have questions about fluent-plugin-kafka. Please ask and answer questions at https://discuss.fluentd.org/.
@@ -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
+
@@ -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
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in fluent-plugin-kafka.gemspec
4
4
  gemspec
5
+
6
+ gem 'rdkafka', '>= 0.6.0' if ENV["USE_RDKAFKA"]
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # fluent-plugin-kafka, a plugin for [Fluentd](http://fluentd.org)
2
2
 
3
- [![Build Status](https://travis-ci.org/fluent/fluent-plugin-kafka.svg?branch=master)](https://travis-ci.org/fluent/fluent-plugin-kafka)
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
@@ -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.1'
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.2.0', '< 2'
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, ssl_ca_cert: read_ssl_file(@ssl_ca_cert),
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, ssl_ca_cert: read_ssl_file(@ssl_ca_cert),
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, ssl_ca_cert: read_ssl_file(@ssl_ca_cert),
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(@fetch_args)
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, ssl_ca_cert: read_ssl_file(@ssl_ca_cert),
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, ssl_ca_cert: read_ssl_file(@ssl_ca_cert),
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, ssl_ca_cert: read_ssl_file(@ssl_ca_cert),
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(@consumer_opts)
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(@fetch_opts) { |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, ssl_ca_cert: read_ssl_file(@ssl_ca_cert),
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, ssl_ca_cert: read_ssl_file(@ssl_ca_cert),
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, ssl_ca_cert: read_ssl_file(@ssl_ca_cert),
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 partition key from data'
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, ssl_ca_cert: read_ssl_file(@ssl_ca_cert),
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, ssl_ca_cert: read_ssl_file(@ssl_ca_cert),
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, ssl_ca_cert: read_ssl_file(@ssl_ca_cert),
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, @producer_opts)
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, ssl_ca_cert: read_ssl_file(@ssl_ca_cert),
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, ssl_ca_cert: read_ssl_file(@ssl_ca_cert),
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, ssl_ca_cert: read_ssl_file(@ssl_ca_cert),
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