fluent-plugin-kafka 0.16.3 → 0.17.3

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: 1cc628766df718a6fff17debcf2cffdcc041419cb96c1c9b6ce1fee532807b58
4
- data.tar.gz: 543ccbd91345f45ee75c3e5e84ef5b3414420a0e2557c76a40afc8e308d70735
3
+ metadata.gz: 380a588c3128af581568815d5fdec9edea856c702832de8be87a9e83a012a8b7
4
+ data.tar.gz: afd5d2e7ba2b89a6948637cbb325b3b0683e0c23ac37a591f717902a78a5ba1b
5
5
  SHA512:
6
- metadata.gz: 7cb27a4fe28ccc0f31e36449046faf8d4d3389be7820f7cfce8f612aad84b3239234663a71b50523cb08a13e145f78fdc86e93cf9cec28d35d82765b96c9dddc
7
- data.tar.gz: 98f52a5d84fb348178f9df6ede6592412ddccd43891c95e9d6937622bff8b02bb4cbb3231c7ca7d709a3ae6cdbfb90d3f00074eefe4cc0703379315098424809
6
+ metadata.gz: fe4f49213a66d2e58bb4177f888ab3c0f3cf0fefe3ca2fa5972bc6394ee46c34c7f054088efd035c10e3beb4d277a5368f0f17ff9aa81954d0340e0962e31902
7
+ data.tar.gz: 1c59d58e36828d61eb8d42b9c60578850dd8a439b21faadc0261d7f6b873a7d3874797923b341b9fc6fc6ffce59e1bff4ac90433e8b329580df2031b41d4005a
@@ -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:
@@ -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,21 @@
1
+ Release 0.17.3 - 2021/11/26
2
+ * output: Suppress large warning logs for events skipped by `max_send_limit_bytes`
3
+
4
+ Release 0.17.2 - 2021/10/14
5
+ * out_rdkafka2: Add `max_enqueue_bytes_per_second` parameter
6
+ * out_rdkafka2: Support `use_event_time` parameter
7
+ * out_rdkafka2: Fix a potential bug that the plugin might exit without receiving responses from Kafka.
8
+
9
+ Release 0.17.1 - 2021/09/24
10
+ * out_rdkafka/out_rdkafka2: Support rdkafka 0.9.0 or later
11
+ * out_rdkafka/out_rdkafka2: Add `exclude_fields` parameter
12
+ * out_kafka2.rb: Fix one more Ruby 3.0 keyword arguments issue
13
+
14
+ Release 0.17.0 - 2021/08/30
15
+ * out_kafka/out_kafka_buffered/out_kafka2: Provide murmur2 partitioner hash function choice
16
+ * 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
17
+ * out_kafka/out_kafka2: fix description for `exclude_message_key` option
18
+
1
19
  Release 0.16.3 - 2021/05/17
2
20
  * in_kafka_group: Fix one more Ruby 3.0 keyword arguments issue
3
21
 
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
@@ -40,14 +40,14 @@ If you want to use zookeeper related parameters, you also need to install zookee
40
40
 
41
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.
42
42
 
43
- #### SASL authentication
43
+ #### SASL authentication
44
44
 
45
45
  ##### with GSSAPI
46
46
 
47
47
  - principal
48
48
  - keytab
49
49
 
50
- Set principal and path to keytab for SASL/GSSAPI authentication.
50
+ Set principal and path to keytab for SASL/GSSAPI authentication.
51
51
  See [Authentication using SASL](https://github.com/zendesk/ruby-kafka#authentication-using-sasl) for more details.
52
52
 
53
53
  ##### with Plain/SCRAM
@@ -57,7 +57,7 @@ See [Authentication using SASL](https://github.com/zendesk/ruby-kafka#authentica
57
57
  - scram_mechanism
58
58
  - sasl_over_ssl
59
59
 
60
- 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.
61
61
  See [Authentication using SASL](https://github.com/zendesk/ruby-kafka#authentication-using-sasl) for more details.
62
62
 
63
63
  ### Input plugin (@type 'kafka')
@@ -119,7 +119,7 @@ Consume events by kafka consumer group features..
119
119
  topics <listening topics(separate with comma',')>
120
120
  format <input text type (text|json|ltsv|msgpack)> :default => json
121
121
  message_key <key (Optional, for text format only, default is message)>
122
- kafka_mesasge_key <key (Optional, If specified, set kafka's message key to this key)>
122
+ kafka_message_key <key (Optional, If specified, set kafka's message key to this key)>
123
123
  add_headers <If true, add kafka's message headers to record>
124
124
  add_prefix <tag prefix (Optional)>
125
125
  add_suffix <tag suffix (Optional)>
@@ -155,7 +155,7 @@ With the introduction of the rdkafka-ruby based input plugin we hope to support
155
155
  topics <listening topics(separate with comma',')>
156
156
  format <input text type (text|json|ltsv|msgpack)> :default => json
157
157
  message_key <key (Optional, for text format only, default is message)>
158
- kafka_mesasge_key <key (Optional, If specified, set kafka's message key to this key)>
158
+ kafka_message_key <key (Optional, If specified, set kafka's message key to this key)>
159
159
  add_headers <If true, add kafka's message headers to record>
160
160
  add_prefix <tag prefix (Optional)>
161
161
  add_suffix <tag suffix (Optional)>
@@ -200,8 +200,10 @@ If `ruby-kafka` doesn't fit your kafka environment, check `rdkafka2` plugin inst
200
200
  get_kafka_client_log (bool) :default => false
201
201
  headers (hash) :default => {}
202
202
  headers_from_record (hash) :default => {}
203
+ use_event_time (bool) :default => false
203
204
  use_default_for_unknown_topic (bool) :default => false
204
205
  discard_kafka_delivery_failed (bool) :default => false (No discard)
206
+ partitioner_hash_function (enum) (crc32|murmur2) :default => 'crc32'
205
207
 
206
208
  <format>
207
209
  @type (json|ltsv|msgpack|attr:<record name>|<formatter name>) :default => json
@@ -230,6 +232,8 @@ If `ruby-kafka` doesn't fit your kafka environment, check `rdkafka2` plugin inst
230
232
 
231
233
  The `<formatter name>` in `<format>` uses fluentd's formatter plugins. See [formatter article](https://docs.fluentd.org/v/1.0/formatter).
232
234
 
235
+ **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.
236
+
233
237
  ruby-kafka sometimes returns `Kafka::DeliveryFailed` error without good information.
234
238
  In this case, `get_kafka_client_log` is useful for identifying the error cause.
235
239
  ruby-kafka's log is routed to fluentd log so you can see ruby-kafka's log in fluentd logs.
@@ -313,6 +317,23 @@ The Kafka message will have a header of source_ip=12.7.0.0.1.
313
317
 
314
318
  The configuration format is jsonpath. It is descibed in https://docs.fluentd.org/plugin-helper-overview/api-plugin-helper-record_accessor
315
319
 
320
+ #### Excluding fields
321
+ Fields can be excluded from output data. Only works for kafka2 and rdkafka2 output plugin.
322
+
323
+ Fields must be specified using an array of dot notation `$.`, for example:
324
+
325
+ <match app.**>
326
+ @type kafka2
327
+ [...]
328
+ exclude_fields $.source.ip,$.HTTP_FOO
329
+ <match>
330
+
331
+ This config can be used to remove fields used on another configs.
332
+
333
+ For example, `$.source.ip` can be extracted with config `headers_from_record` and excluded from message payload.
334
+
335
+ > 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.
336
+
316
337
  ### Buffered output plugin
317
338
 
318
339
  This plugin uses ruby-kafka producer for writing data. This plugin is for v0.12. If you use v1, see `kafka2`.
@@ -343,6 +364,8 @@ Support of fluentd v0.12 has ended. `kafka_buffered` will be an alias of `kafka2
343
364
  exclude_topic_key (bool) :default => false
344
365
  exclude_partition_key (bool) :default => false
345
366
  get_kafka_client_log (bool) :default => false
367
+ use_event_time (bool) :default => false
368
+ partitioner_hash_function (enum) (crc32|murmur2) :default => 'crc32'
346
369
 
347
370
  # See fluentd document for buffer related parameters: https://docs.fluentd.org/v/0.12/buffer
348
371
 
@@ -365,6 +388,8 @@ Support of fluentd v0.12 has ended. `kafka_buffered` will be an alias of `kafka2
365
388
  - kafka_agg_max_bytes - default: 4096 - Maximum value of total message size to be included in one batch transmission.
366
389
  - kafka_agg_max_messages - default: nil - Maximum number of messages to include in one batch transmission.
367
390
 
391
+ **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.
392
+
368
393
  ### Non-buffered output plugin
369
394
 
370
395
  This plugin uses ruby-kafka producer for writing data. For performance and reliability concerns, use `kafka_bufferd` output instead. This is mainly for testing.
@@ -385,6 +410,7 @@ This plugin uses ruby-kafka producer for writing data. For performance and relia
385
410
  output_include_time (bool) :default => false
386
411
  exclude_topic_key (bool) :default => false
387
412
  exclude_partition_key (bool) :default => false
413
+ partitioner_hash_function (enum) (crc32|murmur2) :default => 'crc32'
388
414
 
389
415
  # ruby-kafka producer options
390
416
  max_send_retries (integer) :default => 1
@@ -397,6 +423,8 @@ This plugin uses ruby-kafka producer for writing data. For performance and relia
397
423
 
398
424
  This plugin also supports ruby-kafka related parameters. See Buffered output plugin section.
399
425
 
426
+ **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.
427
+
400
428
  ### rdkafka based output plugin
401
429
 
402
430
  This plugin uses `rdkafka` instead of `ruby-kafka` for kafka client.
@@ -426,6 +454,7 @@ You need to install rdkafka gem.
426
454
  exclude_topic_key (bool) :default => false
427
455
  exclude_partition_key (bool) :default => false
428
456
  discard_kafka_delivery_failed (bool) :default => false (No discard)
457
+ use_event_time (bool) :default => false
429
458
 
430
459
  # same with kafka2
431
460
  headers (hash) :default => {}
@@ -460,6 +489,10 @@ You need to install rdkafka gem.
460
489
  rdkafka_delivery_handle_poll_timeout (integer) :default => 30
461
490
  # If the record size is larger than this value, such records are ignored. Default is no limit
462
491
  max_send_limit_bytes (integer) :default => nil
492
+ # The maximum number of enqueueing bytes per second. It can reduce the
493
+ # load of both Fluentd and Kafka when excessive messages are attempted
494
+ # to send. Default is no limit.
495
+ max_enqueue_bytes_per_second (integer) :default => nil
463
496
  </match>
464
497
 
465
498
  If you use v0.12, use `rdkafka` instead.
@@ -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.3'
16
+ gem.version = '0.17.3'
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)
@@ -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)
@@ -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
@@ -234,7 +240,8 @@ DESC
234
240
  record_buf = @formatter_proc.call(tag, time, record)
235
241
  record_buf_bytes = record_buf.bytesize
236
242
  if @max_send_limit_bytes && record_buf_bytes > @max_send_limit_bytes
237
- log.warn "record size exceeds max_send_limit_bytes. Skip event:", :time => time, :record => record
243
+ log.warn "record size exceeds max_send_limit_bytes. Skip event:", :time => time, :record_size => record_buf_bytes
244
+ log.debug "Skipped event:", :record => record
238
245
  next
239
246
  end
240
247
  log.trace { "message will send to #{topic} with partition_key: #{partition_key}, partition: #{partition}, message_key: #{message_key} and value: #{record_buf}." }
@@ -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,10 +259,17 @@ 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
254
- log.warn "record size exceeds max_send_limit_bytes. Skip event:", :time => time, :record => record
271
+ log.warn "record size exceeds max_send_limit_bytes. Skip event:", :time => time, :record_size => record_buf_bytes
272
+ log.debug "Skipped event:", :record => record
255
273
  next
256
274
  end
257
275
  rescue StandardError => e
@@ -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
@@ -326,7 +332,8 @@ DESC
326
332
  record_buf = @formatter_proc.call(tag, time, record)
327
333
  record_buf_bytes = record_buf.bytesize
328
334
  if @max_send_limit_bytes && record_buf_bytes > @max_send_limit_bytes
329
- log.warn "record size exceeds max_send_limit_bytes. Skip event:", :time => time, :record => record
335
+ log.warn "record size exceeds max_send_limit_bytes. Skip event:", :time => time, :record_size => record_buf_bytes
336
+ log.debug "Skipped event:", :record => record
330
337
  next
331
338
  end
332
339
  rescue StandardError => e