fluent-plugin-elasticsearch 5.0.0 → 5.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +6 -0
  3. data/.github/workflows/linux.yml +5 -2
  4. data/.github/workflows/macos.yml +5 -2
  5. data/.github/workflows/windows.yml +5 -2
  6. data/Gemfile +1 -1
  7. data/History.md +65 -1
  8. data/README.Troubleshooting.md +91 -0
  9. data/README.md +129 -4
  10. data/fluent-plugin-elasticsearch.gemspec +2 -1
  11. data/lib/fluent/plugin/elasticsearch_compat.rb +30 -0
  12. data/lib/fluent/plugin/elasticsearch_error_handler.rb +19 -4
  13. data/lib/fluent/plugin/elasticsearch_fallback_selector.rb +2 -2
  14. data/lib/fluent/plugin/elasticsearch_index_lifecycle_management.rb +18 -4
  15. data/lib/fluent/plugin/elasticsearch_index_template.rb +20 -4
  16. data/lib/fluent/plugin/elasticsearch_simple_sniffer.rb +2 -1
  17. data/lib/fluent/plugin/filter_elasticsearch_genid.rb +1 -1
  18. data/lib/fluent/plugin/in_elasticsearch.rb +2 -1
  19. data/lib/fluent/plugin/oj_serializer.rb +2 -1
  20. data/lib/fluent/plugin/out_elasticsearch.rb +80 -19
  21. data/lib/fluent/plugin/out_elasticsearch_data_stream.rb +132 -62
  22. data/lib/fluent/plugin/out_elasticsearch_dynamic.rb +3 -1
  23. data/test/plugin/mock_chunk.dat +0 -0
  24. data/test/plugin/test_elasticsearch_error_handler.rb +130 -23
  25. data/test/plugin/test_elasticsearch_fallback_selector.rb +16 -8
  26. data/test/plugin/test_elasticsearch_index_lifecycle_management.rb +55 -15
  27. data/test/plugin/test_filter_elasticsearch_genid.rb +16 -16
  28. data/test/plugin/test_in_elasticsearch.rb +20 -0
  29. data/test/plugin/test_out_elasticsearch.rb +795 -134
  30. data/test/plugin/test_out_elasticsearch_data_stream.rb +717 -117
  31. data/test/plugin/test_out_elasticsearch_dynamic.rb +150 -18
  32. metadata +21 -5
  33. data/.travis.yml +0 -40
  34. data/appveyor.yml +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f2f8268d9a8a5acf6d941a915044bd3781a5722cea8bc7ac205d6b7fd6fe580
4
- data.tar.gz: 7d9373fb963040efac0ea42f11bf1841f2e0b2a39b5566f5e2794507e77e5f5c
3
+ metadata.gz: 7e2737dc1ced4c50a3db85d71c83351e77a606d581fbd768261ca6613b1700f8
4
+ data.tar.gz: 49a84ff1ea184c4afd43e69fb6cbb89559926bbd6ac063196bd777281be17d2b
5
5
  SHA512:
6
- metadata.gz: 0e432748181717cedfa55239d2da7b0141c3280da7240f6f9643db411f1f3168f00f88c6933d65a5d1b944620dab0d87ce088f4dba76fdf17cec336ca55e83bf
7
- data.tar.gz: f44b2a14c5a13e1a59bd7d6926af13a9a9ba7b990594bca45de20071756d9ca88f7ee53d6ec00e09f0ad2ed054510a7803ac11c7b695275d37dbacb1e5d51457
6
+ metadata.gz: 157dbe3ab067ec279f2051a8b6c6ac25538821903b48e96a09687b547270796d7f6972d0707225c99cd36694e8a8668d32dc9ebba3599d24f08c814712c0849a
7
+ data.tar.gz: 73c611531aa95d5d03d8bd5146ab5f6812c30b3be634f5d1ca139b2ffc6206ccebb8915c4fa1e78d2d53706f6c14b7203342d235bd217a89ac9bf0135e3fec21
@@ -0,0 +1,6 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "github-actions"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
@@ -2,18 +2,21 @@ name: Testing on Ubuntu
2
2
  on:
3
3
  - push
4
4
  - pull_request
5
+ permissions:
6
+ contents: read
7
+
5
8
  jobs:
6
9
  build:
7
10
  runs-on: ${{ matrix.os }}
8
11
  strategy:
9
12
  fail-fast: false
10
13
  matrix:
11
- ruby: [ '2.4', '2.5', '2.6', '2.7' ]
14
+ ruby: [ '2.6', '2.7', '3.0' ]
12
15
  os:
13
16
  - ubuntu-latest
14
17
  name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
15
18
  steps:
16
- - uses: actions/checkout@v2
19
+ - uses: actions/checkout@v3
17
20
  - uses: ruby/setup-ruby@v1
18
21
  with:
19
22
  ruby-version: ${{ matrix.ruby }}
@@ -2,18 +2,21 @@ name: Testing on macOS
2
2
  on:
3
3
  - push
4
4
  - pull_request
5
+ permissions:
6
+ contents: read
7
+
5
8
  jobs:
6
9
  build:
7
10
  runs-on: ${{ matrix.os }}
8
11
  strategy:
9
12
  fail-fast: false
10
13
  matrix:
11
- ruby: [ '2.4', '2.5', '2.6', '2.7' ]
14
+ ruby: [ '2.6', '2.7', '3.0' ]
12
15
  os:
13
16
  - macOS-latest
14
17
  name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
15
18
  steps:
16
- - uses: actions/checkout@v2
19
+ - uses: actions/checkout@v3
17
20
  - uses: ruby/setup-ruby@v1
18
21
  with:
19
22
  ruby-version: ${{ matrix.ruby }}
@@ -2,18 +2,21 @@ name: Testing on Windows
2
2
  on:
3
3
  - push
4
4
  - pull_request
5
+ permissions:
6
+ contents: read
7
+
5
8
  jobs:
6
9
  build:
7
10
  runs-on: ${{ matrix.os }}
8
11
  strategy:
9
12
  fail-fast: false
10
13
  matrix:
11
- ruby: [ '2.4', '2.5', '2.6', '2.7' ]
14
+ ruby: [ '2.6', '2.7', '3.0' ]
12
15
  os:
13
16
  - windows-latest
14
17
  name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
15
18
  steps:
16
- - uses: actions/checkout@v2
19
+ - uses: actions/checkout@v3
17
20
  - uses: ruby/setup-ruby@v1
18
21
  with:
19
22
  ruby-version: ${{ matrix.ruby }}
data/Gemfile CHANGED
@@ -7,5 +7,5 @@ gem 'simplecov', require: false
7
7
  gem 'coveralls', ">= 0.8.0", require: false
8
8
  gem 'strptime', require: false if RUBY_ENGINE == "ruby" && RUBY_VERSION =~ /^2/
9
9
  gem "irb" if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.6"
10
- gem "elasticsearch-xpack"
10
+ gem "elasticsearch-xpack" if ENV["USE_XPACK"]
11
11
  gem "oj"
data/History.md CHANGED
@@ -2,8 +2,72 @@
2
2
 
3
3
  ### [Unreleased]
4
4
 
5
+ ### 5.2.3
6
+ - Bump actions/checkout from 2 to 3 (#978)
7
+ - chore: Included githubactions in the dependabot config (#977)
8
+ - chore: Set permissions for GitHub actions (#972)
9
+ - Remove nested msgpack\_each in handle\_error (#970)
10
+ - do not overwrite @timestamp in data stream if it already exists in the record (#968)
11
+
12
+ ### 5.2.2
13
+ - Add missing top level class markers (#961)
14
+ - Ensure use_record_as_seed for same records (#960)
15
+
16
+ ### 5.2.1
17
+ - respect include\_tag\_key and tag\_key setting when using data streams (#936)
18
+ - Handle unsupported version error (#956)
19
+ - Display deprecated warning on ES dynamic plugin (#955)
20
+
21
+ ### 5.2.0
22
+ - Migrate to handle Elasticsearch 8 (#949)
23
+
24
+ ### 5.1.5
25
+ - Make retryable DataStreams creation at configure phase (#943)
26
+ - Handle @hosts parameter on data_stream plugin (#942)
27
+ - allow specifying custom ILM policies for data streams (#933)
28
+
29
+ ### 5.1.4
30
+ - Handle ES8 or above more strictly (#931)
31
+ - fixing double "\_policy" in index lifecycle management policy for elasticsearch\_data\_stream output (#930)
32
+
33
+ ### 5.1.3
34
+ - fixing execution order for dynamic data stream creation (#928)
35
+
36
+ ### 5.1.2
37
+ - Fix default values of datastream parameters (#926)
38
+
39
+ ### 5.1.1
40
+ - Report appropriate error for data_stream parameters (#922)
41
+ - Add ILM and template parameters for data streams (#920)
42
+ - Support Buffer in Data Stream Output (#917)
43
+
44
+ ### 5.1.0
45
+ - Correct default target bytes value (#914)
46
+ - Handle elasticsearch-ruby 7.14 properly (#913)
47
+
48
+ ### 5.0.5
49
+ - Drop json_parse_exception messages for bulk failures (#900)
50
+ - GitHub Actions: Drop Ruby 2.5 due to EOL (#894)
51
+
52
+ ### 5.0.4
53
+ - test: out_elasticsearch: Remove a needless headers from affinity stub (#888)
54
+ - Target Index Affinity (#883)
55
+
56
+ ### 5.0.3
57
+ - Fix use_legacy_template documentation (#880)
58
+ - Add FAQ for dynamic index/template (#878)
59
+ - Handle IPv6 address string on host and hosts parameters (#877)
60
+
61
+ ### 5.0.2
62
+ - GitHub Actions: Tweak Ruby versions on test (#875)
63
+ - test: datastreams: Set nonexistent datastream as default (#874)
64
+ - Fix overwriting of index template and index lifecycle policy on existing data streams (#872)
65
+
66
+ ### 5.0.1
67
+ - Use elasticsearch/api instead of elasticsearch/xpack (#870)
68
+
5
69
  ### 5.0.0
6
- - Support #retry_operate on data stream (#863)
70
+ - Support #retry_operate on data stream (#863)
7
71
  - Support placeholder in @data\_stream\_name for @type elasticsearch\_data\_stream (#862)
8
72
  - Extract troubleshooting section (#861)
9
73
  - Fix unmatched `<source>` close tag (#860)
@@ -10,6 +10,7 @@
10
10
  + [Random 400 - Rejected by Elasticsearch is occured, why?](#random-400---rejected-by-elasticsearch-is-occured-why)
11
11
  + [Fluentd seems to hang if it unable to connect Elasticsearch, why?](#fluentd-seems-to-hang-if-it-unable-to-connect-elasticsearch-why)
12
12
  + [Enable Index Lifecycle Management](#enable-index-lifecycle-management)
13
+ + [Configuring for dynamic index or template](#configuring-for-dynamic-index-or-template)
13
14
  + [How to specify index codec](#how-to-specify-index-codec)
14
15
  + [Cannot push logs to Elasticsearch with connect_write timeout reached, why?](#cannot-push-logs-to-elasticsearch-with-connect_write-timeout-reached-why)
15
16
 
@@ -524,6 +525,96 @@ template_name your-fluentd-template
524
525
  template_file /path/to/fluentd-template.json
525
526
  ```
526
527
 
528
+ #### Configuring for dynamic index or template
529
+
530
+ Some users want to setup ILM for dynamic index/template.
531
+ `index_petterns` and `template.settings.index.lifecycle.name` in Elasticsearch template will be overwritten by Elasticsearch plugin:
532
+
533
+ ```json
534
+ {
535
+ "index_patterns": ["mock"],
536
+ "template": {
537
+ "settings": {
538
+ "index": {
539
+ "lifecycle": {
540
+ "name": "mock",
541
+ "rollover_alias": "mock"
542
+ },
543
+ "number_of_shards": "<<shard>>",
544
+ "number_of_replicas": "<<replica>>"
545
+ }
546
+ }
547
+ }
548
+ }
549
+ ```
550
+
551
+ This template will be handled with:
552
+
553
+ ```aconf
554
+ <source>
555
+ @type http
556
+ port 5004
557
+ bind 0.0.0.0
558
+ body_size_limit 32m
559
+ keepalive_timeout 10s
560
+ <parse>
561
+ @type json
562
+ </parse>
563
+ </source>
564
+
565
+ <match kubernetes.var.log.containers.**etl-webserver**.log>
566
+ @type elasticsearch
567
+ @id out_es_etl_webserver
568
+ @log_level info
569
+ include_tag_key true
570
+ host $HOST
571
+ port $PORT
572
+ path "#{ENV['FLUENT_ELASTICSEARCH_PATH']}"
573
+ request_timeout "#{ENV['FLUENT_ELASTICSEARCH_REQUEST_TIMEOUT'] || '30s'}"
574
+ scheme "#{ENV['FLUENT_ELASTICSEARCH_SCHEME'] || 'http'}"
575
+ ssl_verify "#{ENV['FLUENT_ELASTICSEARCH_SSL_VERIFY'] || 'true'}"
576
+ ssl_version "#{ENV['FLUENT_ELASTICSEARCH_SSL_VERSION'] || 'TLSv1'}"
577
+ reload_connections "#{ENV['FLUENT_ELASTICSEARCH_RELOAD_CONNECTIONS'] || 'false'}"
578
+ reconnect_on_error "#{ENV['FLUENT_ELASTICSEARCH_RECONNECT_ON_ERROR'] || 'true'}"
579
+ reload_on_failure "#{ENV['FLUENT_ELASTICSEARCH_RELOAD_ON_FAILURE'] || 'true'}"
580
+ log_es_400_reason "#{ENV['FLUENT_ELASTICSEARCH_LOG_ES_400_REASON'] || 'false'}"
581
+ logstash_prefix "#{ENV['FLUENT_ELASTICSEARCH_LOGSTASH_PREFIX'] || 'etl-webserver'}"
582
+ logstash_format "#{ENV['FLUENT_ELASTICSEARCH_LOGSTASH_FORMAT'] || 'false'}"
583
+ index_name "#{ENV['FLUENT_ELASTICSEARCH_LOGSTASH_INDEX_NAME'] || 'etl-webserver'}"
584
+ type_name "#{ENV['FLUENT_ELASTICSEARCH_LOGSTASH_TYPE_NAME'] || 'fluentd'}"
585
+ time_key "#{ENV['FLUENT_ELASTICSEARCH_TIME_KEY'] || '@timestamp'}"
586
+ include_timestamp "#{ENV['FLUENT_ELASTICSEARCH_INCLUDE_TIMESTAMP'] || 'true'}"
587
+
588
+ # ILM Settings - WITH ROLLOVER support
589
+ # https://github.com/uken/fluent-plugin-elasticsearch#enable-index-lifecycle-management
590
+ application_name "etl-webserver"
591
+ index_date_pattern ""
592
+ # Policy configurations
593
+ enable_ilm true
594
+ ilm_policy_id etl-webserver
595
+ ilm_policy_overwrite true
596
+ ilm_policy {"policy": {"phases": {"hot": {"min_age": "0ms","actions": {"rollover": {"max_age": "5m","max_size": "3gb"},"set_priority": {"priority": 100}}},"delete": {"min_age": "30d","actions": {"delete": {"delete_searchable_snapshot": true}}}}}}
597
+ use_legacy_template false
598
+ template_name etl-webserver
599
+ template_file /configs/index-template.json
600
+ template_overwrite true
601
+ customize_template {"<<shard>>": "3","<<replica>>": "0"}
602
+
603
+ <buffer>
604
+ flush_thread_count "#{ENV['FLUENT_ELASTICSEARCH_BUFFER_FLUSH_THREAD_COUNT'] || '8'}"
605
+ flush_interval "#{ENV['FLUENT_ELASTICSEARCH_BUFFER_FLUSH_INTERVAL'] || '5s'}"
606
+ chunk_limit_size "#{ENV['FLUENT_ELASTICSEARCH_BUFFER_CHUNK_LIMIT_SIZE'] || '8MB'}"
607
+ total_limit_size "#{ENV['FLUENT_ELASTICSEARCH_TOTAL_LIMIT_SIZE'] || '450MB'}"
608
+ queue_limit_length "#{ENV['FLUENT_ELASTICSEARCH_BUFFER_QUEUE_LIMIT_LENGTH'] || '32'}"
609
+ retry_max_interval "#{ENV['FLUENT_ELASTICSEARCH_BUFFER_RETRY_MAX_INTERVAL'] || '60s'}"
610
+ retry_forever false
611
+ </buffer>
612
+ </match>
613
+ ```
614
+
615
+ For more details, please refer the discussion:
616
+ https://github.com/uken/fluent-plugin-elasticsearch/issues/867
617
+
527
618
  ### How to specify index codec
528
619
 
529
620
  Elasticsearch can handle compression methods for stored data such as LZ4 and best_compression.
data/README.md CHANGED
@@ -11,7 +11,7 @@ Send your logs to Elasticsearch (and search them with Kibana maybe?)
11
11
 
12
12
  Note: For Amazon Elasticsearch Service please consider using [fluent-plugin-aws-elasticsearch-service](https://github.com/atomita/fluent-plugin-aws-elasticsearch-service)
13
13
 
14
- Current maintainers: @cosmo0920
14
+ Current maintainers: [Hiroshi Hatake | @cosmo0920](https://github.com/cosmo0920), [Kentaro Hayashi | @kenhys](https://github.com/kenhys)
15
15
 
16
16
  * [Installation](#installation)
17
17
  * [Usage](#usage)
@@ -38,6 +38,7 @@ Current maintainers: @cosmo0920
38
38
  + [suppress_type_name](#suppress_type_name)
39
39
  + [target_index_key](#target_index_key)
40
40
  + [target_type_key](#target_type_key)
41
+ + [target_index_affinity](#target_index_affinity)
41
42
  + [template_name](#template_name)
42
43
  + [template_file](#template_file)
43
44
  + [template_overwrite](#template_overwrite)
@@ -171,6 +172,24 @@ You can specify Elasticsearch host by this parameter.
171
172
 
172
173
  **Note:** Since v3.3.2, `host` parameter supports builtin placeholders. If you want to send events dynamically into different hosts at runtime with `elasticsearch_dynamic` output plugin, please consider to switch to use plain `elasticsearch` output plugin. In more detail for builtin placeholders, please refer to [Placeholders](#placeholders) section.
173
174
 
175
+ To use IPv6 address on `host` parameter, you can use the following styles:
176
+
177
+ #### string style
178
+
179
+ To use string style, you must quote IPv6 address due to prevent to be interpreted as JSON:
180
+
181
+ ```
182
+ host "[2404:7a80:d440:3000:192a:a292:bd7f:ca10]"
183
+ ```
184
+
185
+ #### raw style
186
+
187
+ You can also specify raw IPv6 address. This will be handled as `[specified IPv6 address]`:
188
+
189
+ ```
190
+ host 2404:7a80:d440:3000:192a:a292:bd7f:ca10
191
+ ```
192
+
174
193
  ### port
175
194
 
176
195
  ```
@@ -237,6 +256,16 @@ hosts host1:port1,host2:port2,host3 # port3 is 9200
237
256
 
238
257
  **Note:** Up until v2.8.5, it was allowed to embed the username/password in the URL. However, this syntax is deprecated as of v2.8.6 because it was found to cause serious connection problems (See #394). Please migrate your settings to use the `user` and `password` field (described below) instead.
239
258
 
259
+ #### IPv6 addresses
260
+
261
+ When you want to specify IPv6 addresses, you must specify schema together:
262
+
263
+ ```
264
+ hosts http://[2404:7a80:d440:3000:de:7311:6329:2e6c]:port1,http://[2404:7a80:d440:3000:de:7311:6329:1e6c]:port2,http://[2404:7a80:d440:3000:de:6311:6329:2e6c]:port3
265
+ ```
266
+
267
+ If you don't specify hosts with schema together, Elasticsearch plugin complains Invalid URI for them.
268
+
240
269
  ### user, password, path, scheme, ssl_verify
241
270
 
242
271
  ```
@@ -426,6 +455,75 @@ and this record will be written to the specified index (`logstash-2014.12.19`) r
426
455
 
427
456
  Similar to `target_index_key` config, find the type name to write to in the record under this key (or nested record). If key not found in record - fallback to `type_name` (default "fluentd").
428
457
 
458
+ ### target_index_affinity
459
+
460
+ Enable plugin to dynamically select logstash time based target index in update/upsert operations based on already indexed data rather than current time of indexing.
461
+
462
+ ```
463
+ target_index_affinity true # defaults to false
464
+ ```
465
+
466
+ By default plugin writes data of logstash format index based on current time. For example daily based index after mignight data is written to newly created index. This is normally ok when data is coming from single source and not updated after indexing.
467
+
468
+ But if you have a use case where data is also updated after indexing and `id_key` is used to identify the document uniquely for updating. Logstash format is wanted to be used for easy data managing and retention. Updates are done right after indexing to complete the data (all data not available from single source) and no updates are done anymore later point on time. In this case problem happends at index rotation time where write to 2 indexes with same id_key value may happen.
469
+
470
+ This setting will search existing data by using elastic search's [id query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-ids-query.html) using `id_key` value (with logstash_prefix and logstash_prefix_separator index pattarn e.g. `logstash-*`). The index of found data is used for update/upsert. When no data is found, data is written to current logstash index as normally.
471
+
472
+ This setting requires following other settings:
473
+ ```
474
+ logstash_format true
475
+ id_key myId # Some field on your data to identify the data uniquely
476
+ write_operation upsert # upsert or update
477
+ ```
478
+
479
+ Suppose you have the following situation where you have 2 different match to consume data from 2 different Kafka topics independently but close in time with each other (order not known).
480
+
481
+ ```
482
+ <match data1>
483
+ @type elasticsearch
484
+ ...
485
+ id_key myId
486
+ write_operation upsert
487
+ logstash_format true
488
+ logstash_dateformat %Y.%m.%d
489
+ logstash_prefix myindexprefix
490
+ target_index_affinity true
491
+ ...
492
+
493
+ <match data2>
494
+ @type elasticsearch
495
+ ...
496
+ id_key myId
497
+ write_operation upsert
498
+ logstash_format true
499
+ logstash_dateformat %Y.%m.%d
500
+ logstash_prefix myindexprefix
501
+ target_index_affinity true
502
+ ...
503
+ ```
504
+
505
+ If your first (data1) input is:
506
+ ```
507
+ {
508
+ "myId": "myuniqueId1",
509
+ "datafield1": "some value",
510
+ }
511
+ ```
512
+
513
+ and your second (data2) input is:
514
+ ```
515
+ {
516
+ "myId": "myuniqueId1",
517
+ "datafield99": "some important data from other source tightly related to id myuniqueId1 and wanted to be in same document.",
518
+ }
519
+ ```
520
+
521
+ Date today is 10.05.2021 so data is written to index `myindexprefix-2021.05.10` when both data1 and data2 is consumed during today.
522
+ But when we are close to index rotation and data1 is consumed and indexed at `2021-05-10T23:59:55.59707672Z` and data2
523
+ is consumed a bit later at `2021-05-11T00:00:58.222079Z` i.e. logstash index has been rotated and normally data2 would have been written
524
+ to index `myindexprefix-2021.05.11`. But with target_index_affinity setting as value true, data2 is now written to index `myindexprefix-2021.05.10`
525
+ into same document with data1 as wanted and duplicated document is avoided.
526
+
429
527
  ### template_name
430
528
 
431
529
  The name of the template to define. If a template by the name given is already present, it will be left unchanged, unless [template_overwrite](#template_overwrite) is set, in which case the template will be updated.
@@ -1325,9 +1423,9 @@ Default value is `nil`.
1325
1423
 
1326
1424
  Use legacy template or not.
1327
1425
 
1328
- Elasticsearch 7.8 or later supports the brand new composable templates.
1426
+ For Elasticsearch 7.8 or later, users can specify this parameter as `false` if their [template_file](#template_file) contains a composable index template.
1329
1427
 
1330
- For Elasticsearch 7.7 or older, users should specify this parameter as `false`.
1428
+ For Elasticsearch 7.7 or older, users should specify this parameter as `true`.
1331
1429
 
1332
1430
  Composable template documentation is [Put Index Template API | Elasticsearch Reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/index-templates.html) and legacy template documentation is [Index Templates | Elasticsearch Reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-templates-v1.html).
1333
1431
 
@@ -1423,7 +1521,7 @@ You can enable this feature by specifying `@type elasticsearch_data_stream`.
1423
1521
  data_stream_name test
1424
1522
  ```
1425
1523
 
1426
- When `@type elasticsearch_data_stream` is used, ILM default policy is set to the specified data stream.
1524
+ When `@type elasticsearch_data_stream` is used, unless specified with `data_stream_ilm_name` and `data_stream_template_name` or `data_stream_ilm_policy`, ILM default policy is set to the specified data stream.
1427
1525
  Then, the matching index template is also created automatically.
1428
1526
 
1429
1527
  ### data_stream_name
@@ -1431,10 +1529,37 @@ Then, the matching index template is also created automatically.
1431
1529
  You can specify Elasticsearch data stream name by this parameter.
1432
1530
  This parameter is mandatory for `elasticsearch_data_stream`.
1433
1531
 
1532
+ ### data_stream_template_name
1533
+
1534
+ You can specify an existing matching index template for the data stream. If not present, it creates a new matching index template.
1535
+
1536
+ Default value is `data_stream_name`.
1537
+
1538
+ ### data_stream_ilm_name
1539
+
1540
+ You can specify the name of an existing ILM policy, which will be applied to the data stream. If not present, it creates a new ILM default policy (unless `data_stream_template_name` is defined, in that case the ILM will be set to the one specified in the matching index template).
1541
+
1542
+ Default value is `data_stream_name`.
1543
+
1434
1544
  There are some limitations about naming rule.
1435
1545
 
1436
1546
  In more detail, please refer to the [Path parameters](https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-create-data-stream.html#indices-create-data-stream-api-path-params).
1437
1547
 
1548
+
1549
+ ### data_stream_ilm_policy
1550
+
1551
+ You can specify the ILM policy contents as hash. If not present, it will apply the ILM default policy.
1552
+
1553
+ **NOTE:** This parameter requests to install elasticsearch-xpack gem.
1554
+
1555
+ ### data_stream_ilm_policy_overwrite
1556
+
1557
+ Specify whether the data stream ILM policy should be overwritten.
1558
+
1559
+ Default value is `false`.
1560
+
1561
+ **NOTE:** This parameter requests to install elasticsearch-xpack gem.
1562
+
1438
1563
  ## Troubleshooting
1439
1564
 
1440
1565
  See [Troubleshooting document](README.Troubleshooting.md)
@@ -3,7 +3,7 @@ $:.push File.expand_path('../lib', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = 'fluent-plugin-elasticsearch'
6
- s.version = '5.0.0'
6
+ s.version = '5.2.3'
7
7
  s.authors = ['diogo', 'pitr', 'Hiroshi Hatake']
8
8
  s.email = ['pitr.vern@gmail.com', 'me@diogoterror.com', 'cosmo0920.wp@gmail.com']
9
9
  s.description = %q{Elasticsearch output plugin for Fluent event collector}
@@ -28,6 +28,7 @@ Gem::Specification.new do |s|
28
28
 
29
29
 
30
30
  s.add_development_dependency 'rake', '>= 0'
31
+ s.add_development_dependency 'webrick', '~> 1.7.0'
31
32
  s.add_development_dependency 'webmock', '~> 3'
32
33
  s.add_development_dependency 'test-unit', '~> 3.3.0'
33
34
  s.add_development_dependency 'minitest', '~> 5.8'
@@ -0,0 +1,30 @@
1
+ begin
2
+ require 'elastic/transport'
3
+ ::TRANSPORT_CLASS = Elastic::Transport
4
+ rescue LoadError
5
+ end
6
+ begin
7
+ require 'elasticsearch/transport'
8
+ ::TRANSPORT_CLASS = Elasticsearch::Transport
9
+ rescue LoadError
10
+ end
11
+ if Gem::Version.new(Elasticsearch::VERSION) < Gem::Version.new("8.0.0")
12
+ begin
13
+ require 'elasticsearch/xpack'
14
+ rescue LoadError
15
+ end
16
+ end
17
+
18
+ begin
19
+ require 'elastic/transport/transport/connections/selector'
20
+ ::SELECTOR_CLASS = Elastic::Transport::Transport::Connections::Selector
21
+ rescue LoadError
22
+ end
23
+ begin
24
+ require 'elasticsearch/transport/transport/connections/selector'
25
+ ::SELECTOR_CLASS = Elasticsearch::Transport::Transport::Connections::Selector
26
+ rescue LoadError
27
+ end
28
+ unless defined?(::Elasticsearch::UnsupportedProductError)
29
+ class ::Elasticsearch::UnsupportedProductError < StandardError; end
30
+ end
@@ -23,6 +23,10 @@ class Fluent::Plugin::ElasticsearchErrorHandler
23
23
  unrecoverable_error_types.include?(type)
24
24
  end
25
25
 
26
+ def unrecoverable_record_error?(type)
27
+ ['json_parse_exception'].include?(type)
28
+ end
29
+
26
30
  def log_es_400_reason(&block)
27
31
  if @plugin.log_es_400_reason
28
32
  block.call
@@ -31,7 +35,7 @@ class Fluent::Plugin::ElasticsearchErrorHandler
31
35
  end
32
36
  end
33
37
 
34
- def handle_error(response, tag, chunk, bulk_message_count, extracted_values)
38
+ def handle_error(response, tag, chunk, bulk_message_count, extracted_values, unpacked_msg_arr)
35
39
  items = response['items']
36
40
  if items.nil? || !items.is_a?(Array)
37
41
  raise ElasticsearchVersionMismatch, "The response format was unrecognized: #{response}"
@@ -43,15 +47,21 @@ class Fluent::Plugin::ElasticsearchErrorHandler
43
47
  stats = Hash.new(0)
44
48
  meta = {}
45
49
  header = {}
46
- chunk.msgpack_each do |time, rawrecord|
50
+ affinity_target_indices = @plugin.get_affinity_target_indices(chunk)
51
+
52
+ unpacked_msg_arr.each do |msg|
53
+ time = msg[:time]
54
+ rawrecord = msg[:record]
55
+
47
56
  bulk_message = ''
48
57
  next unless rawrecord.is_a? Hash
49
58
  begin
50
59
  # we need a deep copy for process_message to alter
51
60
  processrecord = Marshal.load(Marshal.dump(rawrecord))
52
- meta, header, record = @plugin.process_message(tag, meta, header, time, processrecord, extracted_values)
61
+ meta, header, record = @plugin.process_message(tag, meta, header, time, processrecord, affinity_target_indices, extracted_values)
53
62
  next unless @plugin.append_record_to_messages(@plugin.write_operation, meta, header, record, bulk_message)
54
63
  rescue => e
64
+ @plugin.log.debug("Exception in error handler during deep copy: #{e}")
55
65
  stats[:bad_chunk_record] += 1
56
66
  next
57
67
  end
@@ -105,10 +115,15 @@ class Fluent::Plugin::ElasticsearchErrorHandler
105
115
  elsif item[write_operation].has_key?('error') && item[write_operation]['error'].has_key?('type')
106
116
  type = item[write_operation]['error']['type']
107
117
  stats[type] += 1
108
- retry_stream.add(time, rawrecord)
109
118
  if unrecoverable_error?(type)
110
119
  raise ElasticsearchRequestAbortError, "Rejected Elasticsearch due to #{type}"
111
120
  end
121
+ if unrecoverable_record_error?(type)
122
+ @plugin.router.emit_error_event(tag, time, rawrecord, ElasticsearchError.new("#{status} - #{type}: #{reason}"))
123
+ next
124
+ else
125
+ retry_stream.add(time, rawrecord) unless unrecoverable_record_error?(type)
126
+ end
112
127
  else
113
128
  # When we don't have a type field, something changed in the API
114
129
  # expected return values (ES 2.x)
@@ -1,7 +1,7 @@
1
- require 'elasticsearch/transport/transport/connections/selector'
1
+ require_relative 'elasticsearch_compat'
2
2
 
3
3
  class Fluent::Plugin::ElasticseatchFallbackSelector
4
- include Elasticsearch::Transport::Transport::Connections::Selector::Base
4
+ include SELECTOR_CLASS::Base
5
5
 
6
6
  def select(options={})
7
7
  connections.first
@@ -1,3 +1,5 @@
1
+ require_relative 'elasticsearch_compat'
2
+
1
3
  module Fluent::Plugin::ElasticsearchIndexLifecycleManagement
2
4
  ILM_DEFAULT_POLICY_PATH = "default-ilm-policy.json"
3
5
 
@@ -21,7 +23,7 @@ module Fluent::Plugin::ElasticsearchIndexLifecycleManagement
21
23
  raise Fluent::ConfigError, "Index Lifecycle management is enabled in Fluentd, but not available in your Elasticsearch" unless ilm['available']
22
24
  raise Fluent::ConfigError, "Index Lifecycle management is enabled in Fluentd, but not enabled in your Elasticsearch" unless ilm['enabled']
23
25
 
24
- rescue Elasticsearch::Transport::Transport::Error => e
26
+ rescue ::TRANSPORT_CLASS::Transport::Error => e
25
27
  raise Fluent::ConfigError, "Index Lifecycle management is enabled in Fluentd, but not installed on your Elasticsearch", error: e
26
28
  end
27
29
  end
@@ -43,12 +45,20 @@ module Fluent::Plugin::ElasticsearchIndexLifecycleManagement
43
45
  end
44
46
 
45
47
  def get_ilm_policy
46
- client.ilm.get_policy
48
+ if Gem::Version.new(TRANSPORT_CLASS::VERSION) < Gem::Version.new("8.0.0")
49
+ client.ilm.get_policy
50
+ else
51
+ client.enrich.get_policy
52
+ end
47
53
  end
48
54
 
49
55
  def ilm_policy_exists?(policy_id)
50
56
  begin
51
- client.ilm.get_policy(policy_id: policy_id)
57
+ if Gem::Version.new(TRANSPORT_CLASS::VERSION) < Gem::Version.new("8.0.0")
58
+ client.ilm.get_policy(policy_id: policy_id)
59
+ else
60
+ client.enrich.get_policy(name: policy_id)
61
+ end
52
62
  true
53
63
  rescue
54
64
  false
@@ -57,7 +67,11 @@ module Fluent::Plugin::ElasticsearchIndexLifecycleManagement
57
67
 
58
68
  def ilm_policy_put(policy_id, policy)
59
69
  log.info("Installing ILM policy: #{policy}")
60
- client.ilm.put_policy(policy_id: policy_id, body: policy)
70
+ if Gem::Version.new(TRANSPORT_CLASS::VERSION) < Gem::Version.new("8.0.0")
71
+ client.ilm.put_policy(policy_id: policy_id, body: policy)
72
+ else
73
+ client.enrich.put_policy(name: policy_id, body: policy)
74
+ end
61
75
  end
62
76
 
63
77
  def default_policy_payload