logstash-integration-jdbc 5.2.4 → 5.2.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ad77fc92ab07e1da7e4c6285075b6583f9f293c073199b614e3852cd22bbc6a9
4
- data.tar.gz: 9e7b2c0f0c16930903bdee1f22b2651db7cf9f80d01a12f212b7a40155d4ebea
3
+ metadata.gz: b74796568bc1df12ae5015cfcf38aeb43971b3bd3eda2dcc668104decc69b6a2
4
+ data.tar.gz: ae3a1f82f7354798692933a2426977ea2e17f7335a74d02eb09a376e4421af6b
5
5
  SHA512:
6
- metadata.gz: 2928a01bbe1ef418f36d6ddc7847416fc6d43278b20242926037bef02e8a429ba1d4587f1bd88f8d52de2ec1fef26e749aeb358de82a8bf69c36e5c3c9d42f8e
7
- data.tar.gz: 8aae596826ec1d9155e0f8bdfad9a882e92fa2be610f89d7c67a7b3f44f0e6937bcbafd78900457d92b20a5a28188163f7b4f25040d8deb229f505ab6faf2c22
6
+ metadata.gz: d198c08e74dc4702dae5de1ca4661d68d10298ff497e44739e7cc775d575bfc9fe825154a9de6f2497e60fb3c694f06d36d8971ecf9935e13592c959d6c13c53
7
+ data.tar.gz: ccd725393201ec5282644f003880fa0449a027942442698fe6e1758f25335ff585efb73d0f52716c9698eb19990ef67a15b21fef90255473b39683339520796a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 5.2.5
2
+ - Fix: do not execute more queries with debug logging [#109](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/109)
3
+
1
4
  ## 5.2.4
2
5
  - Fix: compatibility with all (>= 3.0) rufus-scheduler versions [#97](https://github.com/logstash-plugins/logstash-integration-jdbc/pull/97)
3
6
 
@@ -259,8 +259,8 @@ module LogStash module Inputs class Jdbc < LogStash::Inputs::Base
259
259
  end
260
260
  end
261
261
 
262
- set_value_tracker(LogStash::PluginMixins::Jdbc::ValueTracking.build_last_value_tracker(self))
263
- set_statement_logger(LogStash::PluginMixins::Jdbc::CheckedCountLogger.new(@logger))
262
+ set_value_tracker LogStash::PluginMixins::Jdbc::ValueTracking.build_last_value_tracker(self)
263
+ set_statement_handler LogStash::PluginMixins::Jdbc::StatementHandler.build_statement_handler(self)
264
264
 
265
265
  @enable_encoding = !@charset.nil? || !@columns_charset.empty?
266
266
 
@@ -283,8 +283,8 @@ module LogStash module Inputs class Jdbc < LogStash::Inputs::Base
283
283
  end # def register
284
284
 
285
285
  # test injection points
286
- def set_statement_logger(instance)
287
- @statement_handler = LogStash::PluginMixins::Jdbc::StatementHandler.build_statement_handler(self, instance)
286
+ def set_statement_handler(handler)
287
+ @statement_handler = handler
288
288
  end
289
289
 
290
290
  def set_value_tracker(instance)
@@ -4,7 +4,6 @@ require "logstash/config/mixin"
4
4
  require "time"
5
5
  require "date"
6
6
  require_relative "value_tracking"
7
- require_relative "checked_count_logger"
8
7
  require_relative "statement_handler"
9
8
 
10
9
  java_import java.util.concurrent.locks.ReentrantLock
@@ -2,7 +2,7 @@
2
2
 
3
3
  module LogStash module PluginMixins module Jdbc
4
4
  class StatementHandler
5
- def self.build_statement_handler(plugin, logger)
5
+ def self.build_statement_handler(plugin)
6
6
  if plugin.use_prepared_statements
7
7
  klass = PreparedStatementHandler
8
8
  else
@@ -16,27 +16,39 @@ module LogStash module PluginMixins module Jdbc
16
16
  klass = NormalStatementHandler
17
17
  end
18
18
  end
19
- klass.new(plugin, logger)
19
+ klass.new(plugin)
20
20
  end
21
21
 
22
- attr_reader :statement, :parameters, :statement_logger
22
+ attr_reader :statement, :parameters
23
23
 
24
- def initialize(plugin, statement_logger)
24
+ def initialize(plugin)
25
25
  @statement = plugin.statement
26
- @statement_logger = statement_logger
27
- post_init(plugin)
28
26
  end
29
27
 
30
28
  def build_query(db, sql_last_value)
31
- # override in subclass
29
+ fail NotImplementedError # override in subclass
32
30
  end
33
31
 
34
- def post_init(plugin)
35
- # override in subclass, if needed
36
- end
37
32
  end
38
33
 
39
34
  class NormalStatementHandler < StatementHandler
35
+
36
+ attr_reader :parameters
37
+
38
+ def initialize(plugin)
39
+ super(plugin)
40
+ @parameter_keys = ["sql_last_value"] + plugin.parameters.keys
41
+ @parameters = plugin.parameters.inject({}) do |hash,(k,v)|
42
+ case v
43
+ when LogStash::Timestamp
44
+ hash[k.to_sym] = v.time
45
+ else
46
+ hash[k.to_sym] = v
47
+ end
48
+ hash
49
+ end
50
+ end
51
+
40
52
  # Performs the query, yielding once per row of data
41
53
  # @param db [Sequel::Database]
42
54
  # @param sql_last_value [Integer|DateTime|Time]
@@ -52,27 +64,18 @@ module LogStash module PluginMixins module Jdbc
52
64
 
53
65
  def build_query(db, sql_last_value)
54
66
  parameters[:sql_last_value] = sql_last_value
55
- query = db[statement, parameters]
56
- statement_logger.log_statement_parameters(statement, parameters, query)
57
- query
67
+ db[statement, parameters]
58
68
  end
59
69
 
60
- def post_init(plugin)
61
- @parameter_keys = ["sql_last_value"] + plugin.parameters.keys
62
- @parameters = plugin.parameters.inject({}) do |hash,(k,v)|
63
- case v
64
- when LogStash::Timestamp
65
- hash[k.to_sym] = v.time
66
- else
67
- hash[k.to_sym] = v
68
- end
69
- hash
70
- end
71
- end
72
70
  end
73
71
 
74
72
  class PagedNormalStatementHandler < NormalStatementHandler
75
- attr_reader :jdbc_page_size
73
+
74
+ def initialize(plugin)
75
+ super(plugin)
76
+ @jdbc_page_size = plugin.jdbc_page_size
77
+ @logger = plugin.logger
78
+ end
76
79
 
77
80
  # Performs the query, respecting our pagination settings, yielding once per row of data
78
81
  # @param db [Sequel::Database]
@@ -81,16 +84,22 @@ module LogStash module PluginMixins module Jdbc
81
84
  def perform_query(db, sql_last_value)
82
85
  query = build_query(db, sql_last_value)
83
86
  query.each_page(@jdbc_page_size) do |paged_dataset|
87
+ log_dataset_page(paged_dataset) if @logger.debug?
84
88
  paged_dataset.each do |row|
85
89
  yield row
86
90
  end
87
91
  end
88
92
  end
89
93
 
90
- def post_init(plugin)
91
- super(plugin)
92
- @jdbc_page_size = plugin.jdbc_page_size
94
+ private
95
+
96
+ # @param paged_dataset [Sequel::Dataset::Pagination] like object
97
+ def log_dataset_page(paged_dataset)
98
+ @logger.debug "fetching paged dataset", current_page: paged_dataset.current_page,
99
+ record_count: paged_dataset.current_page_record_count,
100
+ total_record_count: paged_dataset.pagination_record_count
93
101
  end
102
+
94
103
  end
95
104
 
96
105
  class ExplicitPagingModeStatementHandler < PagedNormalStatementHandler
@@ -101,20 +110,29 @@ module LogStash module PluginMixins module Jdbc
101
110
  def perform_query(db, sql_last_value)
102
111
  query = build_query(db, sql_last_value)
103
112
  offset = 0
113
+ page_size = @jdbc_page_size
104
114
  loop do
105
115
  rows_in_page = 0
106
- query.with_sql(query.sql, offset: offset, size: jdbc_page_size).each do |row|
116
+ query.with_sql(query.sql, offset: offset, size: page_size).each do |row|
107
117
  yield row
108
118
  rows_in_page += 1
109
119
  end
110
- break unless rows_in_page == jdbc_page_size
111
- offset += jdbc_page_size
120
+ break unless rows_in_page == page_size
121
+ offset += page_size
112
122
  end
113
123
  end
114
124
  end
115
125
 
116
126
  class PreparedStatementHandler < StatementHandler
117
- attr_reader :name, :bind_values_array, :statement_prepared, :prepared
127
+ attr_reader :name, :bind_values_array, :statement_prepared, :prepared, :parameters
128
+
129
+ def initialize(plugin)
130
+ super(plugin)
131
+ @name = plugin.prepared_statement_name.to_sym
132
+ @bind_values_array = plugin.prepared_statement_bind_values
133
+ @parameters = plugin.parameters
134
+ @statement_prepared = Concurrent::AtomicBoolean.new(false)
135
+ end
118
136
 
119
137
  # Performs the query, ignoring our pagination settings, yielding once per row of data
120
138
  # @param db [Sequel::Database]
@@ -142,7 +160,6 @@ module LogStash module PluginMixins module Jdbc
142
160
  db.set_prepared_statement(name, prepared)
143
161
  end
144
162
  bind_value_sql_last_value(sql_last_value)
145
- statement_logger.log_statement_parameters(statement, parameters, nil)
146
163
  begin
147
164
  db.call(name, parameters)
148
165
  rescue => e
@@ -153,17 +170,6 @@ module LogStash module PluginMixins module Jdbc
153
170
  end
154
171
  end
155
172
 
156
- def post_init(plugin)
157
- # don't log statement count when using prepared statements for now...
158
- # needs enhancement to allow user to supply a bindable count prepared statement in settings.
159
- @statement_logger.disable_count
160
-
161
- @name = plugin.prepared_statement_name.to_sym
162
- @bind_values_array = plugin.prepared_statement_bind_values
163
- @parameters = plugin.parameters
164
- @statement_prepared = Concurrent::AtomicBoolean.new(false)
165
- end
166
-
167
173
  def create_bind_values_hash
168
174
  hash = {}
169
175
  bind_values_array.each_with_index {|v,i| hash[:"p#{i}"] = v}
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-integration-jdbc'
3
- s.version = '5.2.4'
3
+ s.version = '5.2.5'
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"
@@ -41,6 +41,31 @@ describe LogStash::Inputs::Jdbc, :integration => true do
41
41
  expect(event.get('first_name')).to eq("Mark")
42
42
  expect(event.get('last_name')).to eq("Guckenheimer")
43
43
  end
44
+
45
+ context 'with paging' do
46
+ let(:settings) do
47
+ super().merge 'jdbc_paging_enabled' => true, 'jdbc_page_size' => 1,
48
+ "statement" => 'SELECT * FROM "employee" WHERE EMP_NO >= :p1 ORDER BY EMP_NO',
49
+ 'parameters' => { 'p1' => 0 }
50
+ end
51
+
52
+ before do # change plugin logger level to debug - to exercise logging
53
+ logger = plugin.class.name.gsub('::', '.').downcase
54
+ logger = org.apache.logging.log4j.LogManager.getLogger(logger)
55
+ @prev_logger_level = [ logger.getName, logger.getLevel ]
56
+ org.apache.logging.log4j.core.config.Configurator.setLevel logger.getName, org.apache.logging.log4j.Level::DEBUG
57
+ end
58
+
59
+ after do
60
+ org.apache.logging.log4j.core.config.Configurator.setLevel *@prev_logger_level
61
+ end
62
+
63
+ it "should populate the event with database entries" do
64
+ plugin.run(queue)
65
+ event = queue.pop
66
+ expect(event.get('first_name')).to eq('David')
67
+ end
68
+ end
44
69
  end
45
70
 
46
71
  context "when supplying a non-existent library" do
@@ -1432,54 +1432,6 @@ describe LogStash::Inputs::Jdbc do
1432
1432
  end
1433
1433
  end
1434
1434
 
1435
- context "when debug logging and a count query raises a count related error" do
1436
- let(:settings) do
1437
- { "statement" => "SELECT * from types_table" }
1438
- end
1439
- let(:logger) { double("logger", :debug? => true) }
1440
- let(:statement_logger) { LogStash::PluginMixins::Jdbc::CheckedCountLogger.new(logger) }
1441
- let(:value_tracker) { double("value tracker", :set_value => nil, :write => nil) }
1442
- let(:msg) { 'Java::JavaSql::SQLSyntaxErrorException: Dynamic SQL Error; SQL error code = -104; Token unknown - line 1, column 105; LIMIT [SQLState:42000, ISC error code:335544634]' }
1443
- let(:error_args) do
1444
- {"exception" => msg}
1445
- end
1446
-
1447
- before do
1448
- db << "INSERT INTO types_table (num, string, started_at, custom_time, ranking) VALUES (1, 'A test', '1999-12-31', '1999-12-31 23:59:59', 95.67)"
1449
- plugin.register
1450
- plugin.set_statement_logger(statement_logger)
1451
- plugin.set_value_tracker(value_tracker)
1452
- allow(value_tracker).to receive(:value).and_return("bar")
1453
- allow(statement_logger).to receive(:execute_count).once.and_raise(StandardError.new(msg))
1454
- end
1455
-
1456
- after do
1457
- plugin.stop
1458
- end
1459
-
1460
- context "if the count query raises an error" do
1461
- it "should log a debug line without a count key as its unknown whether a count works at this stage" do
1462
- expect(logger).to receive(:warn).once.with("Attempting a count query raised an error, the generated count statement is most likely incorrect but check networking, authentication or your statement syntax", error_args)
1463
- expect(logger).to receive(:warn).once.with("Ongoing count statement generation is being prevented")
1464
- expect(logger).to receive(:debug).once.with("Executing JDBC query", :statement => settings["statement"], :parameters => {:sql_last_value=>"bar"})
1465
- plugin.run(queue)
1466
- queue.pop
1467
- end
1468
-
1469
- it "should create an event normally" do
1470
- allow(logger).to receive(:warn)
1471
- allow(logger).to receive(:debug)
1472
- plugin.run(queue)
1473
- event = queue.pop
1474
- expect(event.get("num")).to eq(1)
1475
- expect(event.get("string")).to eq("A test")
1476
- expect(event.get("started_at")).to be_a_logstash_timestamp_equivalent_to("1999-12-31T00:00:00.000Z")
1477
- expect(event.get("custom_time")).to be_a_logstash_timestamp_equivalent_to("1999-12-31T23:59:59.000Z")
1478
- expect(event.get("ranking").to_f).to eq(95.67)
1479
- end
1480
- end
1481
- end
1482
-
1483
1435
  context "when an unreadable jdbc_driver_path entry is present" do
1484
1436
  let(:driver_jar_path) do
1485
1437
  jar_file = $CLASSPATH.find { |name| name.index(Jdbc::Derby.driver_jar) }
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.2.4
4
+ version: 5.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-14 00:00:00.000000000 Z
11
+ date: 2022-05-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -275,7 +275,6 @@ files:
275
275
  - lib/logstash/filters/jdbc_streaming.rb
276
276
  - lib/logstash/inputs/jdbc.rb
277
277
  - lib/logstash/inputs/tzinfo_jruby_patch.rb
278
- - lib/logstash/plugin_mixins/jdbc/checked_count_logger.rb
279
278
  - lib/logstash/plugin_mixins/jdbc/common.rb
280
279
  - lib/logstash/plugin_mixins/jdbc/jdbc.rb
281
280
  - lib/logstash/plugin_mixins/jdbc/scheduler.rb
@@ -1,43 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module LogStash module PluginMixins module Jdbc
4
- class CheckedCountLogger
5
- def initialize(logger)
6
- @logger = logger
7
- @needs_check = true
8
- @count_is_supported = false
9
- @in_debug = @logger.debug?
10
- end
11
-
12
- def disable_count
13
- @needs_check = false
14
- @count_is_supported = false
15
- end
16
-
17
- def log_statement_parameters(statement, parameters, query)
18
- return unless @in_debug
19
- check_count_query(query) if @needs_check && query
20
- if @count_is_supported
21
- @logger.debug("Executing JDBC query", :statement => statement, :parameters => parameters, :count => execute_count(query))
22
- else
23
- @logger.debug("Executing JDBC query", :statement => statement, :parameters => parameters)
24
- end
25
- end
26
-
27
- def check_count_query(query)
28
- @needs_check = false
29
- begin
30
- execute_count(query)
31
- @count_is_supported = true
32
- rescue Exception => e
33
- @logger.warn("Attempting a count query raised an error, the generated count statement is most likely incorrect but check networking, authentication or your statement syntax", "exception" => e.message)
34
- @logger.warn("Ongoing count statement generation is being prevented")
35
- @count_is_supported = false
36
- end
37
- end
38
-
39
- def execute_count(query)
40
- query.count
41
- end
42
- end
43
- end end end