logstash-filter-elasticsearch 3.18.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -8
- data/docs/index.asciidoc +18 -109
- data/lib/logstash/filters/elasticsearch/client.rb +2 -19
- data/lib/logstash/filters/elasticsearch.rb +16 -92
- data/logstash-filter-elasticsearch.gemspec +3 -6
- data/spec/filters/elasticsearch_spec.rb +6 -94
- data/spec/filters/elasticsearch_ssl_spec.rb +17 -0
- data/spec/filters/integration/elasticsearch_spec.rb +2 -9
- metadata +3 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 015a98dbd36122dd3fc4c74da5744a31f6182f67023f802189cc73e837d5ba7a
|
4
|
+
data.tar.gz: 8f1c3a79c0af3fc4154501d16bf775e01b6aa7575627852cb18954a0dd952d91
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc3971541568e34c0ef644c250243fefcb48c778b2471f81f5e87a1b59535a6f5ccc2a2c13d57f5123e0577efb80962b85f8096d3d6f70e0721df4f716d705e1
|
7
|
+
data.tar.gz: 5fe74aa6d8179e6dd3d9c69a6d0c81f284035bd82343543132f129be7bfb3355e01678eddbd051d9d4c360e9704f8a234737096e757f710b395b5d366f57936f
|
data/CHANGELOG.md
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
##
|
2
|
-
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
## 4.0.0
|
2
|
+
- SSL settings that were marked deprecated in version `3.15.0` are now marked obsolete, and will prevent the plugin from starting.
|
3
|
+
- These settings are:
|
4
|
+
- `ca_file`, which should be replaced by `ssl_certificate_authorities`
|
5
|
+
- `keystore`, which should be replaced by `ssl_keystore_path`
|
6
|
+
- `keystore_password`, which should be replaced by `ssl_keystore_password`
|
7
|
+
- `keystore_type`, which should be replaced by `ssl_keystore_password`
|
8
|
+
- `ssl`, which should be replaced by `ssl_enabled`
|
9
|
+
- [#183](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/183)
|
9
10
|
|
10
11
|
## 3.16.2
|
11
12
|
- Add `x-elastic-product-origin` header to Elasticsearch requests [#185](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/185)
|
data/docs/index.asciidoc
CHANGED
@@ -110,7 +110,7 @@ Authentication to a secure Elasticsearch cluster is possible using _one_ of the
|
|
110
110
|
* <<plugins-{type}s-{plugin}-user>> AND <<plugins-{type}s-{plugin}-password>>
|
111
111
|
* <<plugins-{type}s-{plugin}-cloud_auth>>
|
112
112
|
* <<plugins-{type}s-{plugin}-api_key>>
|
113
|
-
* <<plugins-{type}s-{plugin}-
|
113
|
+
* <<plugins-{type}s-{plugin}-ssl_keystore_path>> and/or <<plugins-{type}s-{plugin}-ssl_keystore_password>>
|
114
114
|
|
115
115
|
[id="plugins-{type}s-{plugin}-autz"]
|
116
116
|
==== Authorization
|
@@ -121,7 +121,10 @@ The `monitoring` permission at cluster level is necessary to perform periodic co
|
|
121
121
|
[id="plugins-{type}s-{plugin}-options"]
|
122
122
|
==== Elasticsearch Filter Configuration Options
|
123
123
|
|
124
|
-
This plugin supports the following configuration options plus the <<plugins-{type}s-{plugin}-common-options>>
|
124
|
+
This plugin supports the following configuration options plus the <<plugins-{type}s-{plugin}-common-options>> described later.
|
125
|
+
|
126
|
+
NOTE: As of version `4.0.0` of this plugin, a number of previously deprecated settings related to SSL have been removed. Please see the
|
127
|
+
<<plugins-{type}s-{plugin}-obsolete-options>> for more details.
|
125
128
|
|
126
129
|
[cols="<,<,<",options="header",]
|
127
130
|
|=======================================================================
|
@@ -131,7 +134,6 @@ This plugin supports the following configuration options plus the <<plugins-{typ
|
|
131
134
|
| <<plugins-{type}s-{plugin}-ca_trusted_fingerprint>> |<<string,string>>|No
|
132
135
|
| <<plugins-{type}s-{plugin}-cloud_auth>> |<<password,password>>|No
|
133
136
|
| <<plugins-{type}s-{plugin}-cloud_id>> |<<string,string>>|No
|
134
|
-
| <<plugins-{type}s-{plugin}-custom_headers>> |<<hash,hash>>|No
|
135
137
|
| <<plugins-{type}s-{plugin}-docinfo_fields>> |<<hash,hash>>|No
|
136
138
|
| <<plugins-{type}s-{plugin}-enable_sort>> |<<boolean,boolean>>|No
|
137
139
|
| <<plugins-{type}s-{plugin}-fields>> |<<array,array>>|No
|
@@ -145,7 +147,6 @@ This plugin supports the following configuration options plus the <<plugins-{typ
|
|
145
147
|
| <<plugins-{type}s-{plugin}-retry_on_failure>> |<<number,number>>|No
|
146
148
|
| <<plugins-{type}s-{plugin}-retry_on_status>> |<<array,array>>|No
|
147
149
|
| <<plugins-{type}s-{plugin}-sort>> |<<string,string>>|No
|
148
|
-
| <<plugins-{type}s-{plugin}-ssl>> |<<boolean,boolean>>|__Deprecated__
|
149
150
|
| <<plugins-{type}s-{plugin}-ssl_certificate>> |<<path,path>>|No
|
150
151
|
| <<plugins-{type}s-{plugin}-ssl_certificate_authorities>> |list of <<path,path>>|No
|
151
152
|
| <<plugins-{type}s-{plugin}-ssl_cipher_suites>> |list of <<string,string>>|No
|
@@ -160,7 +161,6 @@ This plugin supports the following configuration options plus the <<plugins-{typ
|
|
160
161
|
| <<plugins-{type}s-{plugin}-ssl_truststore_type>> |<<string,string>>|No
|
161
162
|
| <<plugins-{type}s-{plugin}-ssl_verification_mode>> |<<string,string>>, one of `["full", "none"]`|No
|
162
163
|
| <<plugins-{type}s-{plugin}-tag_on_failure>> |<<array,array>>|No
|
163
|
-
| <<plugins-{type}s-{plugin}-target>> |<<string,string>>|No
|
164
164
|
| <<plugins-{type}s-{plugin}-user>> |<<string,string>>|No
|
165
165
|
|=======================================================================
|
166
166
|
|
@@ -174,11 +174,8 @@ filter plugins.
|
|
174
174
|
|
175
175
|
* Value type is <<hash,hash>>
|
176
176
|
* Default value is `{}`
|
177
|
-
* Format: `"aggregation_name" => "[path][on][event]"`:
|
178
|
-
** `aggregation_name`: aggregation name in result from {es}
|
179
|
-
** `[path][on][event]`: path for where to place the value on the current event, using field-reference notation
|
180
177
|
|
181
|
-
|
178
|
+
Hash of aggregation names to copy from elasticsearch response into Logstash event fields
|
182
179
|
|
183
180
|
Example:
|
184
181
|
[source,ruby]
|
@@ -233,26 +230,13 @@ Cloud ID, from the Elastic Cloud web console. If set `hosts` should not be used.
|
|
233
230
|
For more info, check out the
|
234
231
|
{logstash-ref}/connecting-to-cloud.html[Logstash-to-Cloud documentation].
|
235
232
|
|
236
|
-
|
237
|
-
[id="plugins-{type}s-{plugin}-custom_headers"]
|
238
|
-
===== `custom_headers`
|
239
|
-
|
240
|
-
* Value type is <<hash,hash>>
|
241
|
-
* Default value is empty
|
242
|
-
|
243
|
-
Pass a set of key value pairs as the headers sent in each request to Elasticsearch.
|
244
|
-
These custom headers will override any headers previously set by the plugin such as the User Agent or Authorization headers.
|
245
|
-
|
246
233
|
[id="plugins-{type}s-{plugin}-docinfo_fields"]
|
247
234
|
===== `docinfo_fields`
|
248
235
|
|
249
236
|
* Value type is <<hash,hash>>
|
250
237
|
* Default value is `{}`
|
251
|
-
* Format: `"path.in.source" => "[path][on][event]"`:
|
252
|
-
** `path.in.source`: field path in document source of result from {es}, using dot-notation
|
253
|
-
** `[path][on][event]`: path for where to place the value on the current event, using field-reference notation
|
254
238
|
|
255
|
-
|
239
|
+
Hash of docinfo fields to copy from old event (found via elasticsearch) into new event
|
256
240
|
|
257
241
|
Example:
|
258
242
|
[source,ruby]
|
@@ -278,11 +262,9 @@ Whether results should be sorted or not
|
|
278
262
|
|
279
263
|
* Value type is <<array,array>>
|
280
264
|
* Default value is `{}`
|
281
|
-
* Format: `"path.in.result" => "[path][on][event]"`:
|
282
|
-
** `path.in.result`: field path in indexed result from {es}, using dot-notation
|
283
|
-
** `[path][on][event]`: path for where to place the value on the current event, using field-reference notation
|
284
265
|
|
285
|
-
|
266
|
+
An array of fields to copy from the old event (found via elasticsearch) into the
|
267
|
+
new event, currently being processed.
|
286
268
|
|
287
269
|
In the following example, the values of `@timestamp` and `event_id` on the event
|
288
270
|
found via elasticsearch are copied to the current event's
|
@@ -530,43 +512,6 @@ WARNING: Setting certificate verification to `none` disables many security benef
|
|
530
512
|
|
531
513
|
Tags the event on failure to look up previous log event information. This can be used in later analysis.
|
532
514
|
|
533
|
-
[id="plugins-{type}s-{plugin}-target"]
|
534
|
-
===== `target`
|
535
|
-
|
536
|
-
* Value type is <<string,string>>
|
537
|
-
* There is no default value for this setting.
|
538
|
-
|
539
|
-
Define the target field for placing the result data.
|
540
|
-
If this setting is omitted, the target will be the root (top level) of the event.
|
541
|
-
|
542
|
-
The destination fields specified in <<plugins-{type}s-{plugin}-fields>>, <<plugins-{type}s-{plugin}-aggregation_fields>>, and <<plugins-{type}s-{plugin}-docinfo_fields>> are relative to this target.
|
543
|
-
|
544
|
-
For example, if you want the data to be put in the `operation` field:
|
545
|
-
[source,ruby]
|
546
|
-
if [type] == "end" {
|
547
|
-
filter {
|
548
|
-
query => "type:start AND transaction:%{[transactionId]}"
|
549
|
-
elasticsearch {
|
550
|
-
target => "transaction"
|
551
|
-
fields => {
|
552
|
-
"@timestamp" => "started"
|
553
|
-
"transaction_id" => "id"
|
554
|
-
}
|
555
|
-
}
|
556
|
-
}
|
557
|
-
}
|
558
|
-
|
559
|
-
`fields` fields will be expanded into a data structure in the `target` field, overall shape looks like this:
|
560
|
-
[source,ruby]
|
561
|
-
{
|
562
|
-
"transaction" => {
|
563
|
-
"started" => "2025-04-29T12:01:46.263Z"
|
564
|
-
"id" => "1234567890"
|
565
|
-
}
|
566
|
-
}
|
567
|
-
|
568
|
-
NOTE: when writing to a field that already exists on the event, the previous value will be overwritten.
|
569
|
-
|
570
515
|
[id="plugins-{type}s-{plugin}-user"]
|
571
516
|
===== `user`
|
572
517
|
|
@@ -576,57 +521,21 @@ NOTE: when writing to a field that already exists on the event, the previous val
|
|
576
521
|
Basic Auth - username
|
577
522
|
|
578
523
|
|
579
|
-
[id="plugins-{type}s-{plugin}-
|
580
|
-
==== Elasticsearch Filter
|
581
|
-
|
582
|
-
This plugin supports the following deprecated configurations.
|
524
|
+
[id="plugins-{type}s-{plugin}-obsolete-options"]
|
525
|
+
==== Elasticsearch Filter Obsolete Configuration Options
|
583
526
|
|
584
|
-
WARNING:
|
527
|
+
WARNING: As of version `4.0.0` of this plugin, some configuration options have been replaced.
|
528
|
+
The plugin will fail to start if it contains any of these obsolete options.
|
585
529
|
|
586
530
|
[cols="<,<,<",options="header",]
|
587
531
|
|=======================================================================
|
588
|
-
|Setting|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
532
|
+
|Setting|Replaced by
|
533
|
+
| ca_file |<<plugins-{type}s-{plugin}-ssl_certificate_authorities>>
|
534
|
+
| keystore |<<plugins-{type}s-{plugin}-ssl_keystore_path>>
|
535
|
+
| keystore_password |<<plugins-{type}s-{plugin}-ssl_keystore_password>>
|
536
|
+
| ssl |<<plugins-{type}s-{plugin}-ssl_enabled>>
|
592
537
|
|=======================================================================
|
593
538
|
|
594
|
-
[id="plugins-{type}s-{plugin}-ca_file"]
|
595
|
-
===== `ca_file`
|
596
|
-
deprecated[3.15.0, Replaced by <<plugins-{type}s-{plugin}-ssl_certificate_authorities>>]
|
597
|
-
|
598
|
-
* Value type is <<path,path>>
|
599
|
-
* There is no default value for this setting.
|
600
|
-
|
601
|
-
SSL Certificate Authority file
|
602
|
-
|
603
|
-
[id="plugins-{type}s-{plugin}-ssl"]
|
604
|
-
===== `ssl`
|
605
|
-
deprecated[3.15.0, Replaced by <<plugins-{type}s-{plugin}-ssl_enabled>>]
|
606
|
-
|
607
|
-
* Value type is <<boolean,boolean>>
|
608
|
-
* Default value is `false`
|
609
|
-
|
610
|
-
SSL
|
611
|
-
|
612
|
-
[id="plugins-{type}s-{plugin}-keystore"]
|
613
|
-
===== `keystore`
|
614
|
-
deprecated[3.15.0, Replaced by <<plugins-{type}s-{plugin}-ssl_keystore_path>>]
|
615
|
-
|
616
|
-
* Value type is <<path,path>>
|
617
|
-
* There is no default value for this setting.
|
618
|
-
|
619
|
-
The keystore used to present a certificate to the server. It can be either .jks or .p12
|
620
|
-
|
621
|
-
[id="plugins-{type}s-{plugin}-keystore_password"]
|
622
|
-
===== `keystore_password`
|
623
|
-
deprecated[3.15.0, Replaced by <<plugins-{type}s-{plugin}-ssl_keystore_password>>]
|
624
|
-
|
625
|
-
* Value type is <<password,password>>
|
626
|
-
* There is no default value for this setting.
|
627
|
-
|
628
|
-
Set the keystore password
|
629
|
-
|
630
539
|
|
631
540
|
[id="plugins-{type}s-{plugin}-common-options"]
|
632
541
|
include::{include_path}/{type}.asciidoc[]
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "elasticsearch"
|
3
3
|
require "base64"
|
4
|
+
require "elasticsearch/transport/transport/http/manticore"
|
4
5
|
|
5
6
|
|
6
7
|
module LogStash
|
@@ -8,7 +9,6 @@ module LogStash
|
|
8
9
|
class ElasticsearchClient
|
9
10
|
|
10
11
|
attr_reader :client
|
11
|
-
attr_reader :es_transport_client_type
|
12
12
|
|
13
13
|
BUILD_FLAVOR_SERVERLESS = 'serverless'.freeze
|
14
14
|
DEFAULT_EAV_HEADER = { "Elastic-Api-Version" => "2023-10-31" }.freeze
|
@@ -20,8 +20,6 @@ module LogStash
|
|
20
20
|
api_key = options.fetch(:api_key, nil)
|
21
21
|
proxy = options.fetch(:proxy, nil)
|
22
22
|
user_agent = options[:user_agent]
|
23
|
-
custom_headers = options[:custom_headers]
|
24
|
-
|
25
23
|
|
26
24
|
transport_options = { }
|
27
25
|
transport_options[:headers] = options.fetch(:serverless, false) ? DEFAULT_EAV_HEADER.dup : {}
|
@@ -29,7 +27,6 @@ module LogStash
|
|
29
27
|
transport_options[:headers].merge!(setup_api_key(api_key))
|
30
28
|
transport_options[:headers].merge!({ 'user-agent' => "#{user_agent}" })
|
31
29
|
transport_options[:headers].merge!(INTERNAL_ORIGIN_HEADER)
|
32
|
-
transport_options[:headers].merge!(custom_headers) unless custom_headers.empty?
|
33
30
|
|
34
31
|
transport_options[:pool_max] = 1000
|
35
32
|
transport_options[:pool_max_per_route] = 100
|
@@ -44,7 +41,7 @@ module LogStash
|
|
44
41
|
|
45
42
|
client_options = {
|
46
43
|
hosts: hosts,
|
47
|
-
transport_class:
|
44
|
+
transport_class: ::Elasticsearch::Transport::Transport::HTTP::Manticore,
|
48
45
|
transport_options: transport_options,
|
49
46
|
ssl: ssl_options,
|
50
47
|
retry_on_failure: options[:retry_on_failure],
|
@@ -98,20 +95,6 @@ module LogStash
|
|
98
95
|
token = ::Base64.strict_encode64(api_key.value)
|
99
96
|
{ 'Authorization' => "ApiKey #{token}" }
|
100
97
|
end
|
101
|
-
|
102
|
-
def get_transport_client_class
|
103
|
-
# LS-core includes `elasticsearch` gem. The gem is composed of two separate gems: `elasticsearch-api` and `elasticsearch-transport`
|
104
|
-
# And now `elasticsearch-transport` is old, instead we have `elastic-transport`.
|
105
|
-
# LS-core updated `elasticsearch` > 8: https://github.com/elastic/logstash/pull/17161
|
106
|
-
# Following source bits are for the compatibility to support both `elasticsearch-transport` and `elastic-transport` gems
|
107
|
-
require "elasticsearch/transport/transport/http/manticore"
|
108
|
-
es_transport_client_type = "elasticsearch_transport"
|
109
|
-
::Elasticsearch::Transport::Transport::HTTP::Manticore
|
110
|
-
rescue ::LoadError
|
111
|
-
require "elastic/transport/transport/http/manticore"
|
112
|
-
es_transport_client_type = "elastic_transport"
|
113
|
-
::Elastic::Transport::Transport::HTTP::Manticore
|
114
|
-
end
|
115
98
|
end
|
116
99
|
end
|
117
100
|
end
|
@@ -2,20 +2,13 @@
|
|
2
2
|
require "logstash/filters/base"
|
3
3
|
require "logstash/namespace"
|
4
4
|
require "logstash/json"
|
5
|
-
require 'logstash/plugin_mixins/ecs_compatibility_support'
|
6
|
-
require 'logstash/plugin_mixins/ecs_compatibility_support/target_check'
|
7
5
|
require 'logstash/plugin_mixins/ca_trusted_fingerprint_support'
|
8
|
-
require "logstash/plugin_mixins/normalize_config_support"
|
9
|
-
require 'logstash/plugin_mixins/validator_support/field_reference_validation_adapter'
|
10
6
|
require "monitor"
|
11
7
|
|
12
8
|
require_relative "elasticsearch/client"
|
9
|
+
require_relative "elasticsearch/patches/_elasticsearch_transport_http_manticore"
|
13
10
|
|
14
11
|
class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
|
15
|
-
|
16
|
-
include LogStash::PluginMixins::ECSCompatibilitySupport
|
17
|
-
include LogStash::PluginMixins::ECSCompatibilitySupport::TargetCheck
|
18
|
-
|
19
12
|
config_name "elasticsearch"
|
20
13
|
|
21
14
|
# List of elasticsearch hosts to use for querying.
|
@@ -39,9 +32,6 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
|
|
39
32
|
# Array of fields to copy from old event (found via elasticsearch) into new event
|
40
33
|
config :fields, :validate => :array, :default => {}
|
41
34
|
|
42
|
-
# Custom headers for Elasticsearch requests
|
43
|
-
config :custom_headers, :validate => :hash, :default => {}
|
44
|
-
|
45
35
|
# Hash of docinfo fields to copy from old event (found via elasticsearch) into new event
|
46
36
|
config :docinfo_fields, :validate => :hash, :default => {}
|
47
37
|
|
@@ -71,18 +61,6 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
|
|
71
61
|
# Set the address of a forward HTTP proxy.
|
72
62
|
config :proxy, :validate => :uri_or_empty
|
73
63
|
|
74
|
-
# SSL
|
75
|
-
config :ssl, :validate => :boolean, :default => false, :deprecated => "Set 'ssl_enabled' instead."
|
76
|
-
|
77
|
-
# SSL Certificate Authority file
|
78
|
-
config :ca_file, :validate => :path, :deprecated => "Set 'ssl_certificate_authorities' instead."
|
79
|
-
|
80
|
-
# The keystore used to present a certificate to the server.
|
81
|
-
# It can be either .jks or .p12
|
82
|
-
config :keystore, :validate => :path, :deprecated => "Use 'ssl_keystore_path' instead."
|
83
|
-
|
84
|
-
# Set the keystore password
|
85
|
-
config :keystore_password, :validate => :password, :deprecated => "Use 'ssl_keystore_password' instead."
|
86
64
|
|
87
65
|
# OpenSSL-style X.509 certificate certificate to authenticate the client
|
88
66
|
config :ssl_certificate, :validate => :path
|
@@ -138,20 +116,21 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
|
|
138
116
|
# Tags the event on failure to look up geo information. This can be used in later analysis.
|
139
117
|
config :tag_on_failure, :validate => :array, :default => ["_elasticsearch_lookup_failure"]
|
140
118
|
|
141
|
-
# If set, the the result set will be nested under the target field
|
142
|
-
config :target, :validate => :field_reference
|
143
|
-
|
144
119
|
# How many times to retry on failure?
|
145
120
|
config :retry_on_failure, :validate => :number, :default => 0
|
146
121
|
|
147
122
|
# What status codes to retry on?
|
148
123
|
config :retry_on_status, :validate => :number, :list => true, :default => [500, 502, 503, 504]
|
149
124
|
|
125
|
+
|
126
|
+
config :ssl, :obsolete => "Set 'ssl_enabled' instead."
|
127
|
+
config :ca_file, :obsolete => "Set 'ssl_certificate_authorities' instead."
|
128
|
+
config :keystore, :obsolete => "Set 'ssl_keystore_path' instead."
|
129
|
+
config :keystore_password, :validate => :password, :obsolete => "Set 'ssl_keystore_password' instead."
|
130
|
+
|
150
131
|
# config :ca_trusted_fingerprint, :validate => :sha_256_hex
|
151
132
|
include LogStash::PluginMixins::CATrustedFingerprintSupport
|
152
133
|
|
153
|
-
include LogStash::PluginMixins::NormalizeConfigSupport
|
154
|
-
|
155
134
|
include MonitorMixin
|
156
135
|
attr_reader :shared_client
|
157
136
|
|
@@ -192,9 +171,6 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
|
|
192
171
|
|
193
172
|
test_connection!
|
194
173
|
setup_serverless
|
195
|
-
if get_client.es_transport_client_type == "elasticsearch_transport"
|
196
|
-
require_relative "elasticsearch/patches/_elasticsearch_transport_http_manticore"
|
197
|
-
end
|
198
174
|
end # def register
|
199
175
|
|
200
176
|
def filter(event)
|
@@ -224,19 +200,17 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
|
|
224
200
|
matched = true
|
225
201
|
@fields.each do |old_key, new_key|
|
226
202
|
old_key_path = extract_path(old_key)
|
227
|
-
|
203
|
+
set = resultsHits.map do |doc|
|
228
204
|
extract_value(doc["_source"], old_key_path)
|
229
205
|
end
|
230
|
-
|
231
|
-
set_to_event_target(event, new_key, value_to_set)
|
206
|
+
event.set(new_key, set.count > 1 ? set : set.first)
|
232
207
|
end
|
233
208
|
@docinfo_fields.each do |old_key, new_key|
|
234
209
|
old_key_path = extract_path(old_key)
|
235
|
-
|
210
|
+
set = resultsHits.map do |doc|
|
236
211
|
extract_value(doc, old_key_path)
|
237
212
|
end
|
238
|
-
|
239
|
-
set_to_event_target(event, new_key, value_to_set)
|
213
|
+
event.set(new_key, set.count > 1 ? set : set.first)
|
240
214
|
end
|
241
215
|
end
|
242
216
|
|
@@ -244,7 +218,7 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
|
|
244
218
|
if !resultsAggs.nil? && !resultsAggs.empty?
|
245
219
|
matched = true
|
246
220
|
@aggregation_fields.each do |agg_name, ls_field|
|
247
|
-
|
221
|
+
event.set(ls_field, resultsAggs[agg_name])
|
248
222
|
end
|
249
223
|
end
|
250
224
|
|
@@ -277,18 +251,6 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
|
|
277
251
|
|
278
252
|
private
|
279
253
|
|
280
|
-
# if @target is defined, creates a nested structure to inject result into target field
|
281
|
-
# if not defined, directly sets to the top-level event field
|
282
|
-
# @param event [LogStash::Event]
|
283
|
-
# @param new_key [String] name of the field to set
|
284
|
-
# @param value_to_set [Array] values to set
|
285
|
-
# @return [void]
|
286
|
-
def set_to_event_target(event, new_key, value_to_set)
|
287
|
-
key_to_set = target ? "[#{target}][#{new_key}]" : new_key
|
288
|
-
|
289
|
-
event.set(key_to_set, value_to_set)
|
290
|
-
end
|
291
|
-
|
292
254
|
def client_options
|
293
255
|
@client_options ||= {
|
294
256
|
:user => @user,
|
@@ -298,8 +260,7 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
|
|
298
260
|
:ssl => client_ssl_options,
|
299
261
|
:retry_on_failure => @retry_on_failure,
|
300
262
|
:retry_on_status => @retry_on_status,
|
301
|
-
:user_agent => prepare_user_agent
|
302
|
-
:custom_headers => @custom_headers
|
263
|
+
:user_agent => prepare_user_agent
|
303
264
|
}
|
304
265
|
end
|
305
266
|
|
@@ -518,46 +479,9 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
|
|
518
479
|
end
|
519
480
|
|
520
481
|
def setup_ssl_params!
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
# Infer the value if neither the deprecate `ssl` and `ssl_enabled` were set
|
526
|
-
infer_ssl_enabled_from_hosts
|
527
|
-
|
528
|
-
@ssl_keystore_path = normalize_config(:ssl_keystore_path) do |normalize|
|
529
|
-
normalize.with_deprecated_alias(:keystore)
|
530
|
-
end
|
531
|
-
|
532
|
-
@ssl_keystore_password = normalize_config(:ssl_keystore_password) do |normalize|
|
533
|
-
normalize.with_deprecated_alias(:keystore_password)
|
534
|
-
end
|
535
|
-
|
536
|
-
@ssl_certificate_authorities = normalize_config(:ssl_certificate_authorities) do |normalize|
|
537
|
-
normalize.with_deprecated_mapping(:ca_file) do |ca_file|
|
538
|
-
[ca_file]
|
539
|
-
end
|
540
|
-
end
|
541
|
-
|
542
|
-
params['ssl_enabled'] = @ssl_enabled
|
543
|
-
params['ssl_keystore_path'] = @ssl_keystore_path unless @ssl_keystore_path.nil?
|
544
|
-
params['ssl_keystore_password'] = @ssl_keystore_password unless @ssl_keystore_password.nil?
|
545
|
-
params['ssl_certificate_authorities'] = @ssl_certificate_authorities unless @ssl_certificate_authorities.nil?
|
546
|
-
end
|
547
|
-
|
548
|
-
def infer_ssl_enabled_from_hosts
|
549
|
-
return if original_params.include?('ssl') || original_params.include?('ssl_enabled')
|
550
|
-
|
551
|
-
@ssl_enabled = params['ssl_enabled'] = effectively_ssl?
|
552
|
-
end
|
553
|
-
|
554
|
-
def effectively_ssl?
|
555
|
-
return true if @ssl_enabled
|
556
|
-
|
557
|
-
hosts = Array(@hosts)
|
558
|
-
return false if hosts.nil? || hosts.empty?
|
559
|
-
|
560
|
-
hosts.all? { |host| host && host.to_s.start_with?("https") }
|
482
|
+
# Infer the value if neither `ssl_enabled` was not set
|
483
|
+
return if original_params.include?('ssl_enabled')
|
484
|
+
params['ssl_enabled'] = @ssl_enabled ||= Array(@hosts).all? { |host| host && host.to_s.start_with?("https") }
|
561
485
|
end
|
562
486
|
|
563
487
|
end #class LogStash::Filters::Elasticsearch
|
@@ -1,13 +1,13 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-filter-elasticsearch'
|
4
|
-
s.version = '
|
4
|
+
s.version = '4.0.0'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "Copies fields from previous log events in Elasticsearch to current events "
|
7
7
|
s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
|
8
8
|
s.authors = ["Elastic"]
|
9
9
|
s.email = 'info@elastic.co'
|
10
|
-
s.homepage = "
|
10
|
+
s.homepage = "http://www.elastic.co/guide/en/logstash/current/index.html"
|
11
11
|
s.require_paths = ["lib"]
|
12
12
|
|
13
13
|
# Files
|
@@ -21,12 +21,9 @@ Gem::Specification.new do |s|
|
|
21
21
|
|
22
22
|
# Gem dependencies
|
23
23
|
s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
|
24
|
-
s.add_runtime_dependency 'elasticsearch', ">= 7.14.9"
|
24
|
+
s.add_runtime_dependency 'elasticsearch', ">= 7.14.9" # LS >= 6.7 and < 7.14 all used version 5.0.5
|
25
25
|
s.add_runtime_dependency 'manticore', ">= 0.7.1"
|
26
|
-
s.add_runtime_dependency 'logstash-mixin-ecs_compatibility_support', '~> 1.3'
|
27
26
|
s.add_runtime_dependency 'logstash-mixin-ca_trusted_fingerprint_support', '~> 1.0'
|
28
|
-
s.add_runtime_dependency 'logstash-mixin-normalize_config_support', '~>1.0'
|
29
|
-
s.add_runtime_dependency 'logstash-mixin-validator_support', '~> 1.0'
|
30
27
|
s.add_development_dependency 'cabin', ['~> 0.6']
|
31
28
|
s.add_development_dependency 'webrick'
|
32
29
|
s.add_development_dependency 'logstash-devutils'
|
@@ -60,18 +60,9 @@ describe LogStash::Filters::Elasticsearch do
|
|
60
60
|
allow(plugin).to receive(:get_client).and_return(filter_client)
|
61
61
|
allow(filter_client).to receive(:serverless?).and_return(true)
|
62
62
|
allow(filter_client).to receive(:client).and_return(es_client)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
.with(a_hash_including(
|
67
|
-
:headers => LogStash::Filters::ElasticsearchClient::DEFAULT_EAV_HEADER))
|
68
|
-
.and_raise(Elastic::Transport::Transport::Errors::BadRequest.new)
|
69
|
-
else
|
70
|
-
allow(es_client).to receive(:info)
|
71
|
-
.with(a_hash_including(
|
72
|
-
:headers => LogStash::Filters::ElasticsearchClient::DEFAULT_EAV_HEADER))
|
73
|
-
.and_raise(Elasticsearch::Transport::Transport::Errors::BadRequest.new)
|
74
|
-
end
|
63
|
+
allow(es_client).to receive(:info).with(a_hash_including(:headers => LogStash::Filters::ElasticsearchClient::DEFAULT_EAV_HEADER)).and_raise(
|
64
|
+
Elasticsearch::Transport::Transport::Errors::BadRequest.new
|
65
|
+
)
|
75
66
|
end
|
76
67
|
|
77
68
|
it "raises an exception when Elastic Api Version is not supported" do
|
@@ -112,11 +103,6 @@ describe LogStash::Filters::Elasticsearch do
|
|
112
103
|
|
113
104
|
before(:each) do
|
114
105
|
allow(LogStash::Filters::ElasticsearchClient).to receive(:new).and_return(client)
|
115
|
-
if elastic_ruby_v8_client_available?
|
116
|
-
allow(client).to receive(:es_transport_client_type).and_return('elastic_transport')
|
117
|
-
else
|
118
|
-
allow(client).to receive(:es_transport_client_type).and_return('elasticsearch_transport')
|
119
|
-
end
|
120
106
|
allow(client).to receive(:search).and_return(response)
|
121
107
|
allow(plugin).to receive(:test_connection!)
|
122
108
|
allow(plugin).to receive(:setup_serverless)
|
@@ -347,35 +333,6 @@ describe LogStash::Filters::Elasticsearch do
|
|
347
333
|
end
|
348
334
|
end
|
349
335
|
|
350
|
-
context "with custom headers" do
|
351
|
-
let(:config) do
|
352
|
-
{
|
353
|
-
"query" => "*",
|
354
|
-
"custom_headers" => { "Custom-Header-1" => "Custom Value 1", "Custom-Header-2" => "Custom Value 2" }
|
355
|
-
}
|
356
|
-
end
|
357
|
-
|
358
|
-
let(:plugin) { LogStash::Filters::Elasticsearch.new(config) }
|
359
|
-
let(:client_double) { double("client") }
|
360
|
-
let(:transport_double) { double("transport", options: { transport_options: { headers: config["custom_headers"] } }) }
|
361
|
-
|
362
|
-
before do
|
363
|
-
allow(plugin).to receive(:get_client).and_return(client_double)
|
364
|
-
if elastic_ruby_v8_client_available?
|
365
|
-
allow(client_double).to receive(:es_transport_client_type).and_return('elastic_transport')
|
366
|
-
else
|
367
|
-
allow(client_double).to receive(:es_transport_client_type).and_return('elasticsearch_transport')
|
368
|
-
end
|
369
|
-
allow(client_double).to receive(:client).and_return(transport_double)
|
370
|
-
end
|
371
|
-
|
372
|
-
it "sets custom headers" do
|
373
|
-
plugin.register
|
374
|
-
client = plugin.send(:get_client).client
|
375
|
-
expect(client.options[:transport_options][:headers]).to match(hash_including(config["custom_headers"]))
|
376
|
-
end
|
377
|
-
end
|
378
|
-
|
379
336
|
context "if query is on nested field" do
|
380
337
|
let(:config) do
|
381
338
|
{
|
@@ -525,12 +482,7 @@ describe LogStash::Filters::Elasticsearch do
|
|
525
482
|
# this spec is a safeguard to trigger an assessment of thread-safety should
|
526
483
|
# we choose a different transport adapter in the future.
|
527
484
|
transport_class = extract_transport(client).options.fetch(:transport_class)
|
528
|
-
|
529
|
-
allow(client).to receive(:es_transport_client_type).and_return("elastic_transport")
|
530
|
-
expect(transport_class).to equal ::Elastic::Transport::Transport::HTTP::Manticore
|
531
|
-
else
|
532
|
-
expect(transport_class).to equal ::Elasticsearch::Transport::Transport::HTTP::Manticore
|
533
|
-
end
|
485
|
+
expect(transport_class).to equal ::Elasticsearch::Transport::Transport::HTTP::Manticore
|
534
486
|
end
|
535
487
|
|
536
488
|
it 'uses a client with sufficient connection pool size' do
|
@@ -845,11 +797,6 @@ describe LogStash::Filters::Elasticsearch do
|
|
845
797
|
|
846
798
|
before(:each) do
|
847
799
|
allow(LogStash::Filters::ElasticsearchClient).to receive(:new).and_return(client)
|
848
|
-
if elastic_ruby_v8_client_available?
|
849
|
-
allow(client).to receive(:es_transport_client_type).and_return('elastic_transport')
|
850
|
-
else
|
851
|
-
allow(client).to receive(:es_transport_client_type).and_return('elasticsearch_transport')
|
852
|
-
end
|
853
800
|
allow(plugin).to receive(:test_connection!)
|
854
801
|
allow(plugin).to receive(:setup_serverless)
|
855
802
|
plugin.register
|
@@ -864,46 +811,11 @@ describe LogStash::Filters::Elasticsearch do
|
|
864
811
|
end
|
865
812
|
end
|
866
813
|
|
867
|
-
|
868
|
-
|
869
|
-
context "when `@target` is nil, default behavior" do
|
870
|
-
let(:config) {{ }}
|
871
|
-
|
872
|
-
it "sets the value directly to the top-level event field" do
|
873
|
-
plugin.send(:set_to_event_target, event, "new_field", %w[value1 value2])
|
874
|
-
expect(event.get("new_field")).to eq(%w[value1 value2])
|
875
|
-
end
|
876
|
-
end
|
877
|
-
|
878
|
-
context "when @target is defined" do
|
879
|
-
let(:config) {{ "target" => "nested" }}
|
880
|
-
|
881
|
-
it "creates a nested structure under the target field" do
|
882
|
-
plugin.send(:set_to_event_target, event, "new_field", %w[value1 value2])
|
883
|
-
expect(event.get("nested")).to eq({ "new_field" => %w[value1 value2] })
|
884
|
-
end
|
885
|
-
|
886
|
-
it "overwrites existing target field with new data" do
|
887
|
-
event.set("nested", { "existing_field" => "existing_value", "new_field" => "value0" })
|
888
|
-
plugin.send(:set_to_event_target, event, "new_field", ["value1"])
|
889
|
-
expect(event.get("nested")).to eq({ "existing_field" => "existing_value", "new_field" => ["value1"] })
|
890
|
-
end
|
891
|
-
end
|
892
|
-
end
|
893
|
-
|
894
|
-
def extract_transport(client)
|
895
|
-
# on 7x: client.transport.transport
|
896
|
-
# on >=8.x: client.transport
|
814
|
+
# @note can be removed once gem depends on elasticsearch >= 6.x
|
815
|
+
def extract_transport(client) # on 7.x client.transport is a ES::Transport::Client
|
897
816
|
client.transport.respond_to?(:transport) ? client.transport.transport : client.transport
|
898
817
|
end
|
899
818
|
|
900
|
-
def elastic_ruby_v8_client_available?
|
901
|
-
Elasticsearch::Transport
|
902
|
-
false
|
903
|
-
rescue NameError # NameError: uninitialized constant Elasticsearch::Transport if Elastic Ruby client is not available
|
904
|
-
true
|
905
|
-
end
|
906
|
-
|
907
819
|
class MockResponse
|
908
820
|
attr_reader :code, :headers
|
909
821
|
|
@@ -24,6 +24,23 @@ describe "SSL options" do
|
|
24
24
|
subject.close
|
25
25
|
end
|
26
26
|
|
27
|
+
describe "obsolete settings" do
|
28
|
+
[{:name => 'ca_file', :canonical_name => 'ssl_certificate_authorities'},
|
29
|
+
{:name => "keystore", :canonical_name => 'ssl_keystore_path'},
|
30
|
+
{:name => "keystore_password", :canonical_name => "ssl_keystore_password"},
|
31
|
+
{:name => "ssl", :canonical_name => "ssl_enabled"}
|
32
|
+
].each do |config_settings|
|
33
|
+
context "with option #{config_settings[:name]}" do
|
34
|
+
let(:obsolete_config) { settings.merge(config_settings[:name] => 'test_value') }
|
35
|
+
it "emits an error about the setting `#{config_settings[:name]}` now being obsolete and provides guidance to use `#{config_settings[:canonical_name]}`" do
|
36
|
+
error_text = /The setting `#{config_settings[:name]}` in plugin `elasticsearch` is obsolete and is no longer available. Set '#{config_settings[:canonical_name]}' instead/i
|
37
|
+
expect { LogStash::Filters::Elasticsearch.new(obsolete_config) }.to raise_error LogStash::ConfigurationError, error_text
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
27
44
|
context "when ssl_enabled is" do
|
28
45
|
context "true and there is no https hosts" do
|
29
46
|
let(:hosts) { %w[http://es01 http://es01] }
|
@@ -84,9 +84,7 @@ describe LogStash::Filters::Elasticsearch, :integration => true do
|
|
84
84
|
end
|
85
85
|
|
86
86
|
it "fails to register plugin" do
|
87
|
-
expect { plugin.register }.to raise_error
|
88
|
-
Elastic::Transport::Transport::Errors::Unauthorized :
|
89
|
-
Elasticsearch::Transport::Transport::Errors::Unauthorized
|
87
|
+
expect { plugin.register }.to raise_error Elasticsearch::Transport::Transport::Errors::Unauthorized
|
90
88
|
end
|
91
89
|
|
92
90
|
end if ELASTIC_SECURITY_ENABLED
|
@@ -152,10 +150,5 @@ describe LogStash::Filters::Elasticsearch, :integration => true do
|
|
152
150
|
end
|
153
151
|
end
|
154
152
|
end
|
155
|
-
|
156
|
-
Elasticsearch::Transport
|
157
|
-
false
|
158
|
-
rescue NameError # NameError: uninitialized constant Elasticsearch::Transport if Elastic Ruby client is not available
|
159
|
-
true
|
160
|
-
end
|
153
|
+
|
161
154
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-filter-elasticsearch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-01-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -36,9 +36,6 @@ dependencies:
|
|
36
36
|
- - ">="
|
37
37
|
- !ruby/object:Gem::Version
|
38
38
|
version: 7.14.9
|
39
|
-
- - "<"
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
version: '9'
|
42
39
|
name: elasticsearch
|
43
40
|
type: :runtime
|
44
41
|
prerelease: false
|
@@ -47,9 +44,6 @@ dependencies:
|
|
47
44
|
- - ">="
|
48
45
|
- !ruby/object:Gem::Version
|
49
46
|
version: 7.14.9
|
50
|
-
- - "<"
|
51
|
-
- !ruby/object:Gem::Version
|
52
|
-
version: '9'
|
53
47
|
- !ruby/object:Gem::Dependency
|
54
48
|
requirement: !ruby/object:Gem::Requirement
|
55
49
|
requirements:
|
@@ -64,20 +58,6 @@ dependencies:
|
|
64
58
|
- - ">="
|
65
59
|
- !ruby/object:Gem::Version
|
66
60
|
version: 0.7.1
|
67
|
-
- !ruby/object:Gem::Dependency
|
68
|
-
requirement: !ruby/object:Gem::Requirement
|
69
|
-
requirements:
|
70
|
-
- - "~>"
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
version: '1.3'
|
73
|
-
name: logstash-mixin-ecs_compatibility_support
|
74
|
-
type: :runtime
|
75
|
-
prerelease: false
|
76
|
-
version_requirements: !ruby/object:Gem::Requirement
|
77
|
-
requirements:
|
78
|
-
- - "~>"
|
79
|
-
- !ruby/object:Gem::Version
|
80
|
-
version: '1.3'
|
81
61
|
- !ruby/object:Gem::Dependency
|
82
62
|
requirement: !ruby/object:Gem::Requirement
|
83
63
|
requirements:
|
@@ -92,34 +72,6 @@ dependencies:
|
|
92
72
|
- - "~>"
|
93
73
|
- !ruby/object:Gem::Version
|
94
74
|
version: '1.0'
|
95
|
-
- !ruby/object:Gem::Dependency
|
96
|
-
requirement: !ruby/object:Gem::Requirement
|
97
|
-
requirements:
|
98
|
-
- - "~>"
|
99
|
-
- !ruby/object:Gem::Version
|
100
|
-
version: '1.0'
|
101
|
-
name: logstash-mixin-normalize_config_support
|
102
|
-
type: :runtime
|
103
|
-
prerelease: false
|
104
|
-
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
requirements:
|
106
|
-
- - "~>"
|
107
|
-
- !ruby/object:Gem::Version
|
108
|
-
version: '1.0'
|
109
|
-
- !ruby/object:Gem::Dependency
|
110
|
-
requirement: !ruby/object:Gem::Requirement
|
111
|
-
requirements:
|
112
|
-
- - "~>"
|
113
|
-
- !ruby/object:Gem::Version
|
114
|
-
version: '1.0'
|
115
|
-
name: logstash-mixin-validator_support
|
116
|
-
type: :runtime
|
117
|
-
prerelease: false
|
118
|
-
version_requirements: !ruby/object:Gem::Requirement
|
119
|
-
requirements:
|
120
|
-
- - "~>"
|
121
|
-
- !ruby/object:Gem::Version
|
122
|
-
version: '1.0'
|
123
75
|
- !ruby/object:Gem::Dependency
|
124
76
|
requirement: !ruby/object:Gem::Requirement
|
125
77
|
requirements:
|
@@ -208,7 +160,7 @@ files:
|
|
208
160
|
- spec/filters/fixtures/test_certs/ls.der.sha256
|
209
161
|
- spec/filters/fixtures/test_certs/ls.key
|
210
162
|
- spec/filters/integration/elasticsearch_spec.rb
|
211
|
-
homepage:
|
163
|
+
homepage: http://www.elastic.co/guide/en/logstash/current/index.html
|
212
164
|
licenses:
|
213
165
|
- Apache License (2.0)
|
214
166
|
metadata:
|