logstash-integration-jdbc 5.4.1 → 5.4.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: 71bdfca5d1e5e86b7d86b5c49caf237cfc882e31dab78d63e169241e1c96814d
4
- data.tar.gz: 5c07e44042c4a6e6e29b8ecc7fb7631147100a27777c6fdd2a22015ac7fd3b4e
3
+ metadata.gz: 0427bfc9149fd1b4751f91bda69dcbc67fe50bbb59ba331142c52b0ac79b92df
4
+ data.tar.gz: 9b89e07e05f01b5f4226cbbb452a36e0edb116ca116d843d8f578508206086b8
5
5
  SHA512:
6
- metadata.gz: 53e45e47383b15f559e58969e96c0217c43ceb5ba3528db5d6ce3bad10628da6e4c14442aeb5a8795e17b667ac558e5b1377134bb0ecc5e60a375e6ebe106b2c
7
- data.tar.gz: d33a2cdea75e56fbe338e175276679e2910b4023c956bc8df7d0795f58140b39da1b9167d668c7665e27b2577c086409b3e390b2a3f8d86c4f9a3e3cdef343e3
6
+ metadata.gz: 7bcc88da6e2d4de082a5547f0f273063913f2fe8e87578d7177eb4929604a66ec8be48818ba7b32a88a7bf978aad42f07c14f69f60349d82531f531c0cd77480
7
+ data.tar.gz: 76bc8bb2c010a6f6087e91be3280c1b83ae165449889cc425cb91b4e6fe0f9092b229f7ed37df5fb6ae7be3acbaa8c69541c610bbfff07c374a32be014ccdcbf
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 5.4.3
2
+ - Fix crash when metadata file can't be deleted after moving under path.data [#136](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/136)
3
+
4
+ ## 5.4.2
5
+ - Doc: described default_hash and tag_on_default_use interaction filter plugin [#122](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/122)
6
+ - Added new settings `statement_retry_attempts` and `statement_retry_attempts_wait_time` for retry of failed sql statement execution [#123](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/123)
7
+
1
8
  ## 5.4.1
2
9
  - Bugfix leak which happened in creating a new Database pool for every query. The pool is now crated on registration and closed on plugin's `stop` [#119](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/119)
3
10
 
@@ -111,10 +111,14 @@ filter {
111
111
  query => "SELECT firstname, lastname FROM users WHERE userid = ? AND country = ?"
112
112
  prepared_parameters => ["[loggedin_userid]", "[user_nation]"] <4>
113
113
  target => "user" <5>
114
+ default_hash => { <6>
115
+ firstname => nil
116
+ lastname => nil
117
+ }
114
118
  }
115
119
  ]
116
120
  # using add_field here to add & rename values to the event root
117
- add_field => { server_name => "%{[server][0][description]}" } <6>
121
+ add_field => { server_name => "%{[server][0][description]}" } <7>
118
122
  add_field => { user_firstname => "%{[user][0][firstname]}" }
119
123
  add_field => { user_lastname => "%{[user][0][lastname]}" }
120
124
  remove_field => ["server", "user"]
@@ -127,6 +131,13 @@ filter {
127
131
  jdbc_connection_string => "jdbc:postgresql://remotedb:5432/ls_test_2"
128
132
  }
129
133
  }
134
+
135
+ output {
136
+ if "_jdbcstaticdefaultsused" in [tags] {
137
+ # Print all the not found users
138
+ stdout { }
139
+ }
140
+ }
130
141
  -----
131
142
  <1> Queries an external database to fetch the dataset that will be cached
132
143
  locally.
@@ -139,7 +150,8 @@ See <<plugins-{type}s-{plugin}-object_order>>.
139
150
  follow the positional ordering.
140
151
  <5> Specifies the event field that will store the looked-up data. If the lookup
141
152
  returns multiple columns, the data is stored as a JSON object within the field.
142
- <6> Takes data from the JSON object and stores it in top-level event fields for
153
+ <6> When the user is not found in the database, an event is created using data from the <<plugins-{type}s-{plugin}-local_lookups>> `default hash` setting, and the event is tagged with the list set in <<plugins-{type}s-{plugin}-tag_on_default_use>>.
154
+ <7> Takes data from the JSON object and stores it in top-level event fields for
143
155
  easier analysis in Kibana.
144
156
 
145
157
  Here's a full example:
@@ -491,10 +491,12 @@ How often to validate a connection (in seconds)
491
491
  ===== `last_run_metadata_path`
492
492
 
493
493
  * Value type is <<string,string>>
494
- * Default value is `"$HOME/.logstash_jdbc_last_run"`
494
+ * Default value is `"<path.data>/plugins/inputs/jdbc/logstash_jdbc_last_run"`
495
495
 
496
496
  Path to file with last run time
497
497
 
498
+ In versions prior to 5.2.6 the metadata file was written to `$HOME/.logstash_jdbc_last_run`. If during a Logstash upgrade the file is found in "$HOME" it will be moved to the default location under "path.data". If the path is defined by the user then no automatic move is performed.
499
+
498
500
  [id="plugins-{type}s-{plugin}-lowercase_column_names"]
499
501
  ===== `lowercase_column_names`
500
502
 
@@ -406,7 +406,7 @@ module LogStash module Inputs class Jdbc < LogStash::Inputs::Base
406
406
  # the correct access rights
407
407
  ::File.delete(old_default_path.to_path)
408
408
  @logger.info("Successfully moved the #{old_default_path.to_path} into #{metadata_new_path.to_path}")
409
- rescue e
409
+ rescue => e
410
410
  @logger.warn("Using new metadata file at #{metadata_new_path.to_path} but #{old_default_path} can't be removed.")
411
411
  end
412
412
  end
@@ -104,6 +104,11 @@ module LogStash module PluginMixins module Jdbc
104
104
  # Number of seconds to sleep between connection attempts
105
105
  config :connection_retry_attempts_wait_time, :validate => :number, :default => 0.5
106
106
 
107
+ # Maximum number of times to try running statement
108
+ config :statement_retry_attempts, :validate => :number, :default => 1
109
+ # Number of seconds to sleep between statement execution
110
+ config :statement_retry_attempts_wait_time, :validate => :number, :default => 0.5
111
+
107
112
  # give users the ability to force Sequel application side into using local timezone
108
113
  config :plugin_timezone, :validate => ["local", "utc"], :default => "utc"
109
114
  end
@@ -202,7 +207,10 @@ module LogStash module PluginMixins module Jdbc
202
207
  public
203
208
  def execute_statement
204
209
  success = false
210
+ retry_attempts = @statement_retry_attempts
211
+
205
212
  begin
213
+ retry_attempts -= 1
206
214
  sql_last_value = @use_column_value ? @value_tracker.value : Time.now.utc
207
215
  @tracking_column_warning_sent = false
208
216
  @statement_handler.perform_query(@database, @value_tracker.value) do |row|
@@ -210,17 +218,23 @@ module LogStash module PluginMixins module Jdbc
210
218
  yield extract_values_from(row)
211
219
  end
212
220
  success = true
213
- rescue Sequel::DatabaseConnectionError,
214
- Sequel::DatabaseError,
215
- Sequel::InvalidValue,
216
- Java::JavaSql::SQLException => e
221
+ rescue Sequel::Error, Java::JavaSql::SQLException => e
217
222
  details = { exception: e.class, message: e.message }
218
223
  details[:cause] = e.cause.inspect if e.cause
219
224
  details[:backtrace] = e.backtrace if @logger.debug?
220
225
  @logger.warn("Exception when executing JDBC query", details)
226
+
227
+ if retry_attempts == 0
228
+ @logger.error("Unable to execute statement. Tried #{@statement_retry_attempts} times.")
229
+ else
230
+ @logger.error("Unable to execute statement. Trying again.")
231
+ sleep(@statement_retry_attempts_wait_time)
232
+ retry
233
+ end
221
234
  else
222
235
  @value_tracker.set_value(sql_last_value)
223
236
  end
237
+
224
238
  return success
225
239
  end
226
240
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-integration-jdbc'
3
- s.version = '5.4.1'
3
+ s.version = '5.4.3'
4
4
  s.licenses = ['Apache License (2.0)']
5
5
  s.summary = "Integration with JDBC - input and filter plugins"
6
6
  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"
@@ -1169,19 +1169,31 @@ describe LogStash::Inputs::Jdbc do
1169
1169
  context "when a file exists" do
1170
1170
  before do
1171
1171
  # in a faked HOME folder save a valid previous last_run metadata file
1172
+ allow(ENV).to receive(:[]).and_call_original
1172
1173
  allow(ENV).to receive(:[]).with('HOME').and_return(fake_home)
1173
- File.open("#{ENV['HOME']}/.logstash_jdbc_last_run", 'w') do |file|
1174
+
1175
+ File.open("#{fake_home}/.logstash_jdbc_last_run", 'w') do |file|
1174
1176
  file.write("--- !ruby/object:DateTime '2022-03-08 08:10:00.486889000 Z'")
1175
1177
  end
1176
1178
  end
1179
+ let(:old_path) { "#{fake_home}/.logstash_jdbc_last_run" }
1180
+ let(:path_data) { LogStash::SETTINGS.get_value("path.data") }
1181
+ let(:new_path) { "#{path_data}/plugins/inputs/jdbc/logstash_jdbc_last_run" }
1177
1182
 
1178
1183
  it "should be moved" do
1179
1184
  plugin.register
1180
-
1181
- expect(::File.exist?("#{ENV['HOME']}/.logstash_jdbc_last_run")).to be false
1182
- path = LogStash::SETTINGS.get_value("path.data")
1183
- full_path = "#{path}/plugins/inputs/jdbc/logstash_jdbc_last_run"
1184
- expect(::File.exist?(full_path)).to be true
1185
+ expect(::File).to_not exist(old_path)
1186
+ expect(::File).to exist(new_path)
1187
+ end
1188
+ context "if the delete fails" do
1189
+ before(:each) do
1190
+ allow(File).to receive(:delete).and_raise ArgumentError
1191
+ end
1192
+ it "should be still be moved" do
1193
+ plugin.register
1194
+ expect(::File).to exist(old_path) # old still exists
1195
+ expect(::File).to exist(new_path)
1196
+ end
1185
1197
  end
1186
1198
  end
1187
1199
  end
@@ -1352,6 +1364,34 @@ describe LogStash::Inputs::Jdbc do
1352
1364
  expect { plugin.register }.to_not raise_error
1353
1365
  plugin.stop
1354
1366
  end
1367
+
1368
+ it "does retry when query execution fails" do
1369
+ mixin_settings['statement_retry_attempts'] = 2
1370
+ mixin_settings['statement_retry_attempts_wait_time'] = 0.5
1371
+ queue = Queue.new
1372
+ plugin.register
1373
+
1374
+ handler = plugin.instance_variable_get(:@statement_handler)
1375
+ allow(handler).to receive(:perform_query).with(instance_of(Sequel::JDBC::Database), instance_of(Time)).and_raise(Sequel::PoolTimeout)
1376
+ expect(plugin.logger).to receive(:error).with("Unable to execute statement. Trying again.")
1377
+ expect(plugin.logger).to receive(:error).with("Unable to execute statement. Tried 2 times.")
1378
+
1379
+ plugin.run(queue)
1380
+ plugin.stop
1381
+ end
1382
+
1383
+ it "does not retry when query execution succeeds" do
1384
+ mixin_settings['connection_retry_attempts'] = 2
1385
+ queue = Queue.new
1386
+ plugin.register
1387
+
1388
+ handler = plugin.instance_variable_get(:@statement_handler)
1389
+ allow(handler).to receive(:perform_query).with(instance_of(Sequel::JDBC::Database), instance_of(Time)).and_call_original
1390
+ expect(plugin.logger).not_to receive(:error)
1391
+
1392
+ plugin.run(queue)
1393
+ plugin.stop
1394
+ end
1355
1395
  end
1356
1396
 
1357
1397
  context "when encoding of some columns need to be changed" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-integration-jdbc
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.4.1
4
+ version: 5.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-04 00:00:00.000000000 Z
11
+ date: 2023-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -333,7 +333,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
333
333
  - !ruby/object:Gem::Version
334
334
  version: '0'
335
335
  requirements: []
336
- rubygems_version: 3.1.6
336
+ rubygems_version: 3.2.33
337
337
  signing_key:
338
338
  specification_version: 4
339
339
  summary: Integration with JDBC - input and filter plugins