fluent-plugin-sql 0.6.1 → 1.0.0.rc1

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
  SHA1:
3
- metadata.gz: 8bdf7e835bed062213f63778607f5f4e3a6f9a02
4
- data.tar.gz: d9b7d721ef9ad035193fbf0eb5a5460e88caa9aa
3
+ metadata.gz: 3e683b76d37276e4bbe276dc6148216c113e5267
4
+ data.tar.gz: 374e957bfaf1f9eea818a6d3bc9c9b370c58604f
5
5
  SHA512:
6
- metadata.gz: ab807cd58fa29576d9164e4ab1e307a3b8cde72dd129e608acc78da01c15499e9ba9def596b044604bd2890c877fc3d66be79ca31d441e24f0d6f5cba8a741f6
7
- data.tar.gz: 23a7698d628cd9dad85b9d1ab8f50ade3d925531cb230cbc9a93ace20e03ab157bd0ed09c1a3f97a9380931135acda9837402249e6b360e1881f694b157eff3e
6
+ metadata.gz: 1a71af14e2817621d22c85ac31a49d54d6b7f224b605ce2febaf09fbe369b435b33df779b23196e37ac6fb5d3c5a26d2039cb5aadf24dc90ec5d105ba4b283c6
7
+ data.tar.gz: 593be077cfbc429c9502ad7b56c404cac24afbae65268d095c723339bb77a4645a5c4297d03a6cbf73dd269cdda69824d3e2e5d4d4b498406e8871c5e0fb775e
@@ -14,7 +14,6 @@ rvm:
14
14
 
15
15
  gemfile:
16
16
  - Gemfile
17
- - Gemfile.v0.12
18
17
 
19
18
  before_install:
20
19
  - gem install bundler
data/README.md CHANGED
@@ -7,6 +7,15 @@ This SQL plugin has two parts:
7
7
  1. SQL **input** plugin reads records from RDBMSes periodically. An example use case would be getting "diffs" of a table (based on the "updated_at" field).
8
8
  2. SQL **output** plugin that writes records into RDBMes. An example use case would be aggregating server/app/sensor logs into RDBMS systems.
9
9
 
10
+ ## Requirements
11
+
12
+ | fluent-plugin-sql | fluentd | ruby |
13
+ |-------------------|------------|--------|
14
+ | >= 1.0.0 | >= v0.14.4 | >= 2.1 |
15
+ | < 1.0.0 | < v0.14.0 | >= 1.9 |
16
+
17
+ NOTE: fluent-plugin-sql v1.0.0 is now RC. We will release stable v1.0.0 soon.
18
+
10
19
  ## Installation
11
20
 
12
21
  $ fluent-gem install fluent-plugin-sql --no-document
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.1
1
+ 1.0.0.rc1
@@ -16,59 +16,47 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- require "fluent/input"
19
+ require "fluent/plugin/input"
20
20
 
21
- module Fluent
21
+ module Fluent::Plugin
22
22
 
23
23
  require 'active_record'
24
24
 
25
25
  class SQLInput < Input
26
- Plugin.register_input('sql', self)
27
-
28
- # For fluentd v0.12.16 or earlier
29
- class << self
30
- unless method_defined?(:desc)
31
- def desc(description)
32
- end
33
- end
34
- end
26
+ Fluent::Plugin.register_input('sql', self)
35
27
 
36
28
  desc 'RDBMS host'
37
29
  config_param :host, :string
38
30
  desc 'RDBMS port'
39
- config_param :port, :integer, :default => nil
31
+ config_param :port, :integer, default: nil
40
32
  desc 'RDBMS driver name.'
41
33
  config_param :adapter, :string
42
34
  desc 'RDBMS database name'
43
35
  config_param :database, :string
44
36
  desc 'RDBMS login user name'
45
- config_param :username, :string, :default => nil
37
+ config_param :username, :string, default: nil
46
38
  desc 'RDBMS login password'
47
- config_param :password, :string, :default => nil, :secret => true
39
+ config_param :password, :string, default: nil, secret: true
48
40
  desc 'RDBMS socket path'
49
- config_param :socket, :string, :default => nil
41
+ config_param :socket, :string, default: nil
50
42
 
51
43
  desc 'path to a file to store last rows'
52
- config_param :state_file, :string, :default => nil
44
+ config_param :state_file, :string, default: nil
53
45
  desc 'prefix of tags of events. actual tag will be this_tag_prefix.tables_tag (optional)'
54
- config_param :tag_prefix, :string, :default => nil
46
+ config_param :tag_prefix, :string, default: nil
55
47
  desc 'interval to run SQLs (optional)'
56
- config_param :select_interval, :time, :default => 60
48
+ config_param :select_interval, :time, default: 60
57
49
  desc 'limit of number of rows for each SQL(optional)'
58
- config_param :select_limit, :time, :default => 500
59
-
60
- unless method_defined?(:log)
61
- define_method(:log) { $log }
62
- end
50
+ config_param :select_limit, :time, default: 500
63
51
 
64
52
  class TableElement
65
- include Configurable
53
+ include Fluent::Configurable
66
54
 
67
55
  config_param :table, :string
68
- config_param :tag, :string, :default => nil
69
- config_param :update_column, :string, :default => nil
70
- config_param :time_column, :string, :default => nil
71
- config_param :primary_key, :string, :default => nil
56
+ config_param :tag, :string, default: nil
57
+ config_param :update_column, :string, default: nil
58
+ config_param :time_column, :string, default: nil
59
+ config_param :primary_key, :string, default: nil
72
60
 
73
61
  def configure(conf)
74
62
  super
@@ -127,9 +115,9 @@ module Fluent
127
115
  relation = relation.order("#{@update_column} ASC")
128
116
  relation = relation.limit(limit) if limit > 0
129
117
 
130
- now = Engine.now
118
+ now = Fluent::Engine.now
131
119
 
132
- me = MultiEventStream.new
120
+ me = Fluent::MultiEventStream.new
133
121
  relation.each do |obj|
134
122
  record = obj.serializable_hash rescue nil
135
123
  if record
@@ -181,13 +169,13 @@ module Fluent
181
169
  @state_store = @state_file.nil? ? MemoryStateStore.new : StateStore.new(@state_file)
182
170
 
183
171
  config = {
184
- :adapter => @adapter,
185
- :host => @host,
186
- :port => @port,
187
- :database => @database,
188
- :username => @username,
189
- :password => @password,
190
- :socket => @socket,
172
+ adapter: @adapter,
173
+ host: @host,
174
+ port: @port,
175
+ database: @database,
176
+ username: @username,
177
+ password: @password,
178
+ socket: @socket,
191
179
  }
192
180
 
193
181
  # creates subclass of ActiveRecord::Base so that it can have different
@@ -230,7 +218,7 @@ module Fluent
230
218
  log.info "Selecting '#{te.table}' table"
231
219
  false
232
220
  rescue => e
233
- log.warn "Can't handle '#{te.table}' table. Ignoring.", :error => e.message, :error_class => e.class
221
+ log.warn "Can't handle '#{te.table}' table. Ignoring.", error: e
234
222
  log.warn_backtrace e.backtrace
235
223
  true
236
224
  end
@@ -264,7 +252,7 @@ module Fluent
264
252
  @state_store.last_records[t.table] = t.emit_next_records(last_record, @select_limit)
265
253
  @state_store.update!
266
254
  rescue => e
267
- log.error "unexpected error", :error => e.message, :error_class => e.class
255
+ log.error "unexpected error", error: e
268
256
  log.error_backtrace e.backtrace
269
257
  end
270
258
  end
@@ -1,59 +1,52 @@
1
- require "fluent/output"
1
+ require "fluent/plugin/output"
2
2
 
3
- module Fluent
4
- class SQLOutput < BufferedOutput
5
- Plugin.register_output('sql', self)
3
+ module Fluent::Plugin
4
+ class SQLOutput < Output
5
+ Fluent::Plugin.register_output('sql', self)
6
6
 
7
- include SetTimeKeyMixin
8
- include SetTagKeyMixin
7
+ DEFAULT_BUFFER_TYPE = "memory"
9
8
 
10
- # For fluentd v0.12.16 or earlier
11
- class << self
12
- unless method_defined?(:desc)
13
- def desc(description)
14
- end
15
- end
16
- end
9
+ helpers :inject, :compat_parameters, :event_emitter
17
10
 
18
11
  desc 'RDBMS host'
19
12
  config_param :host, :string
20
13
  desc 'RDBMS port'
21
- config_param :port, :integer, :default => nil
14
+ config_param :port, :integer, default: nil
22
15
  desc 'RDBMS driver name.'
23
16
  config_param :adapter, :string
24
17
  desc 'RDBMS login user name'
25
- config_param :username, :string, :default => nil
18
+ config_param :username, :string, default: nil
26
19
  desc 'RDBMS login password'
27
- config_param :password, :string, :default => nil, :secret => true
20
+ config_param :password, :string, default: nil, secret: true
28
21
  desc 'RDBMS database name'
29
22
  config_param :database, :string
30
23
  desc 'RDBMS socket path'
31
- config_param :socket, :string, :default => nil
24
+ config_param :socket, :string, default: nil
32
25
  desc 'remove the given prefix from the events'
33
- config_param :remove_tag_prefix, :string, :default => nil
26
+ config_param :remove_tag_prefix, :string, default: nil
34
27
  desc 'enable fallback'
35
- config_param :enable_fallback, :bool, :default => true
36
-
37
- attr_accessor :tables
28
+ config_param :enable_fallback, :bool, default: true
38
29
 
39
- unless method_defined?(:log)
40
- define_method(:log) { $log }
30
+ config_section :buffer do
31
+ config_set_default :@type, DEFAULT_BUFFER_TYPE
41
32
  end
42
33
 
34
+ attr_accessor :tables
35
+
43
36
  # TODO: Merge SQLInput's TableElement
44
37
  class TableElement
45
- include Configurable
38
+ include Fluent::Configurable
46
39
 
47
40
  config_param :table, :string
48
41
  config_param :column_mapping, :string
49
- config_param :num_retries, :integer, :default => 5
42
+ config_param :num_retries, :integer, default: 5
50
43
 
51
44
  attr_reader :model
52
45
  attr_reader :pattern
53
46
 
54
47
  def initialize(pattern, log, enable_fallback)
55
48
  super()
56
- @pattern = MatchPattern.create(pattern)
49
+ @pattern = Fluent::MatchPattern.create(pattern)
57
50
  @log = log
58
51
  @enable_fallback = enable_fallback
59
52
  end
@@ -95,7 +88,7 @@ module Fluent
95
88
  # format process should be moved to emit / format after supports error stream.
96
89
  records << @model.new(@format_proc.call(data))
97
90
  rescue => e
98
- args = {:error => e.message, :error_class => e.class, :table => @table, :record => Yajl.dump(data)}
91
+ args = {error: e, table: @table, record: Yajl.dump(data)}
99
92
  @log.warn "Failed to create the model. Ignore a record:", args
100
93
  end
101
94
  }
@@ -104,10 +97,10 @@ module Fluent
104
97
  rescue ActiveRecord::StatementInvalid, ActiveRecord::Import::MissingColumnError => e
105
98
  if @enable_fallback
106
99
  # ignore other exceptions to use Fluentd retry mechanizm
107
- @log.warn "Got deterministic error. Fallback to one-by-one import", :error => e.message, :error_class => e.class
100
+ @log.warn "Got deterministic error. Fallback to one-by-one import", error: e
108
101
  one_by_one_import(records)
109
102
  else
110
- $log.warn "Got deterministic error. Fallback is disabled", :error => e.message, :error_class => e.class
103
+ $log.warn "Got deterministic error. Fallback is disabled", error: e
111
104
  raise e
112
105
  end
113
106
  end
@@ -119,15 +112,15 @@ module Fluent
119
112
  begin
120
113
  @model.import([record])
121
114
  rescue ActiveRecord::StatementInvalid, ActiveRecord::Import::MissingColumnError => e
122
- @log.error "Got deterministic error again. Dump a record", :error => e.message, :error_class => e.class, :record => record
115
+ @log.error "Got deterministic error again. Dump a record", error: e, record: record
123
116
  rescue => e
124
117
  retries += 1
125
118
  if retries > @num_retries
126
- @log.error "Can't recover undeterministic error. Dump a record", :error => e.message, :error_class => e.class, :record => record
119
+ @log.error "Can't recover undeterministic error. Dump a record", error: e, record: record
127
120
  next
128
121
  end
129
122
 
130
- @log.warn "Failed to import a record: retry number = #{retries}", :error => e.message, :error_class => e.class
123
+ @log.warn "Failed to import a record: retry number = #{retries}", error: e
131
124
  sleep 0.5
132
125
  retry
133
126
  end
@@ -154,6 +147,8 @@ module Fluent
154
147
  end
155
148
 
156
149
  def configure(conf)
150
+ compat_parameters_convert(conf, :inject, :buffer)
151
+
157
152
  super
158
153
 
159
154
  if remove_tag_prefix = conf['remove_tag_prefix']
@@ -177,7 +172,7 @@ module Fluent
177
172
  @only_default = @tables.empty?
178
173
 
179
174
  if @default_table.nil?
180
- raise ConfigError, "There is no default table. <table> is required in sql output"
175
+ raise Fluent::ConfigError, "There is no default table. <table> is required in sql output"
181
176
  end
182
177
  end
183
178
 
@@ -185,13 +180,13 @@ module Fluent
185
180
  super
186
181
 
187
182
  config = {
188
- :adapter => @adapter,
189
- :host => @host,
190
- :port => @port,
191
- :database => @database,
192
- :username => @username,
193
- :password => @password,
194
- :socket => @socket,
183
+ adapter: @adapter,
184
+ host: @host,
185
+ port: @port,
186
+ database: @database,
187
+ username: @username,
188
+ password: @password,
189
+ socket: @socket,
195
190
  }
196
191
 
197
192
  @base_model = Class.new(ActiveRecord::Base) do
@@ -221,9 +216,14 @@ module Fluent
221
216
  end
222
217
 
223
218
  def format(tag, time, record)
219
+ record = inject_values_to_record(tag, time, record)
224
220
  [tag, time, record].to_msgpack
225
221
  end
226
222
 
223
+ def formatted_to_msgpack_binary
224
+ true
225
+ end
226
+
227
227
  def write(chunk)
228
228
  ActiveRecord::Base.connection_pool.with_connection do
229
229
 
@@ -244,7 +244,7 @@ module Fluent
244
244
  log.info "Selecting '#{te.table}' table"
245
245
  false
246
246
  rescue => e
247
- log.warn "Can't handle '#{te.table}' table. Ignoring.", :error => e.message, :error_class => e.class
247
+ log.warn "Can't handle '#{te.table}' table. Ignoring.", error: e
248
248
  log.warn_backtrace e.backtrace
249
249
  true
250
250
  end
@@ -1,4 +1,5 @@
1
1
  require "helper"
2
+ require "fluent/test/driver/input"
2
3
 
3
4
  class SqlInputTest < Test::Unit::TestCase
4
5
  def setup
@@ -28,7 +29,7 @@ class SqlInputTest < Test::Unit::TestCase
28
29
  ]
29
30
 
30
31
  def create_driver(conf = CONFIG)
31
- Fluent::Test::InputTestDriver.new(Fluent::SQLInput).configure(conf)
32
+ Fluent::Test::Driver::Input.new(Fluent::Plugin::SQLInput).configure(conf)
32
33
  end
33
34
 
34
35
  def test_configure
@@ -65,18 +66,21 @@ class SqlInputTest < Test::Unit::TestCase
65
66
  Message.create!(message: "message 2")
66
67
  Message.create!(message: "message 3")
67
68
 
69
+ d.end_if do
70
+ d.record_count >= 3
71
+ end
68
72
  d.run
69
73
 
70
- assert_equal("db.logs", d.emits[0][0])
74
+ assert_equal("db.logs", d.events[0][0])
71
75
  expected = [
72
- [d.emits[0][1], "message 1"],
73
- [d.emits[1][1], "message 2"],
74
- [d.emits[2][1], "message 3"],
76
+ [d.events[0][1], "message 1"],
77
+ [d.events[1][1], "message 2"],
78
+ [d.events[2][1], "message 3"],
75
79
  ]
76
80
  actual = [
77
- [Time.parse(d.emits[0][2]["updated_at"]).to_i, d.emits[0][2]["message"]],
78
- [Time.parse(d.emits[1][2]["updated_at"]).to_i, d.emits[1][2]["message"]],
79
- [Time.parse(d.emits[2][2]["updated_at"]).to_i, d.emits[2][2]["message"]],
81
+ [Time.parse(d.events[0][2]["updated_at"]).to_i, d.events[0][2]["message"]],
82
+ [Time.parse(d.events[1][2]["updated_at"]).to_i, d.events[1][2]["message"]],
83
+ [Time.parse(d.events[2][2]["updated_at"]).to_i, d.events[2][2]["message"]],
80
84
  ]
81
85
  assert_equal(expected, actual)
82
86
  end
@@ -1,4 +1,5 @@
1
1
  require "helper"
2
+ require "fluent/test/driver/output"
2
3
 
3
4
  class SqlOutputTest < Test::Unit::TestCase
4
5
  def setup
@@ -26,7 +27,7 @@ class SqlOutputTest < Test::Unit::TestCase
26
27
  ]
27
28
 
28
29
  def create_driver(conf = CONFIG)
29
- Fluent::Test::BufferedOutputTestDriver.new(Fluent::SQLOutput).configure(conf)
30
+ Fluent::Test::Driver::Output.new(Fluent::Plugin::SQLOutput).configure(conf)
30
31
  end
31
32
 
32
33
  def test_configure
@@ -61,10 +62,10 @@ class SqlOutputTest < Test::Unit::TestCase
61
62
  d = create_driver
62
63
  time = Time.parse("2011-01-02 13:14:15 UTC").to_i
63
64
 
64
- d.emit({"message" => "message1"}, time)
65
- d.emit({"message" => "message2"}, time)
66
-
67
- d.run
65
+ d.run(default_tag: 'test') do
66
+ d.feed(time, {"message" => "message1"})
67
+ d.feed(time, {"message" => "message2"})
68
+ end
68
69
 
69
70
  default_table = d.instance.instance_variable_get(:@default_table)
70
71
  model = default_table.instance_variable_get(:@model)
@@ -78,10 +79,10 @@ class SqlOutputTest < Test::Unit::TestCase
78
79
  d = create_driver
79
80
  time = Time.parse("2011-01-02 13:14:15 UTC").to_i
80
81
 
81
- d.emit({"message" => "message1"}, time)
82
- d.emit({"message" => "message2"}, time)
82
+ d.run(default_tag: 'test') do
83
+ d.feed(time, {"message" => "message1"})
84
+ d.feed(time, {"message" => "message2"})
83
85
 
84
- d.run do
85
86
  default_table = d.instance.instance_variable_get(:@default_table)
86
87
  model = default_table.instance_variable_get(:@model)
87
88
  mock(model).import(anything).at_least(1) do
@@ -95,10 +96,10 @@ class SqlOutputTest < Test::Unit::TestCase
95
96
  d = create_driver
96
97
  time = Time.parse("2011-01-02 13:14:15 UTC").to_i
97
98
 
98
- d.emit({"message" => "message1"}, time)
99
- d.emit({"message" => "message2"}, time)
99
+ d.run(default_tag: 'test') do
100
+ d.feed(time, {"message" => "message1"})
101
+ d.feed(time, {"message" => "message2"})
100
102
 
101
- d.run do
102
103
  default_table = d.instance.instance_variable_get(:@default_table)
103
104
  model = default_table.instance_variable_get(:@model)
104
105
  mock(model).import([anything, anything]).once do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-sql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 1.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-27 00:00:00.000000000 Z
11
+ date: 2017-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -162,12 +162,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
162
162
  version: '0'
163
163
  required_rubygems_version: !ruby/object:Gem::Requirement
164
164
  requirements:
165
- - - ">="
165
+ - - ">"
166
166
  - !ruby/object:Gem::Version
167
- version: '0'
167
+ version: 1.3.1
168
168
  requirements: []
169
169
  rubyforge_project:
170
- rubygems_version: 2.6.11
170
+ rubygems_version: 2.6.13
171
171
  signing_key:
172
172
  specification_version: 4
173
173
  summary: SQL input/output plugin for Fluentd event collector