fluent-plugin-mysql-bulk 0.0.4 → 0.0.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 +4 -4
- data/fluent-plugin-mysql-bulk.gemspec +1 -1
- data/lib/fluent/plugin/out_mysql_bulk.rb +58 -30
- data/test/helper.rb +4 -4
- data/test/plugin/test_out_mysql_bulk.rb +15 -17
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7bb1a0fcf1728e6d85a9592f8790d8faf14018ef
|
4
|
+
data.tar.gz: 47053866831072f969671259227a663f032009d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6398f672df551f4d2d894e8806aff7be9792a36b505c1089a42049042ae48ae8abeced526b321a64a0889d8f0c96e2d59bda817cf7300993ed9e63f8230f626e
|
7
|
+
data.tar.gz: f7b746d6a8c3a3924b15a0f4945216dc827331a8add729c1dc167c3565c6876f013da61fef03e6f92a0aaf73bb8828c1a0bfccadf3ef64dbe077100a3fcf4c26
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
Gem::Specification.new do |gem|
|
3
3
|
gem.name = "fluent-plugin-mysql-bulk"
|
4
|
-
gem.version = "0.0.
|
4
|
+
gem.version = "0.0.5"
|
5
5
|
gem.authors = ["Hiroshi Toyama"]
|
6
6
|
gem.email = ["toyama0919@gmail.com"]
|
7
7
|
gem.description = %q{fluent plugin mysql bulk insert is high performance and on duplicate key update respond.}
|
@@ -3,18 +3,18 @@ module Fluent
|
|
3
3
|
class Fluent::MysqlBulkOutput < Fluent::BufferedOutput
|
4
4
|
Fluent::Plugin.register_output('mysql_bulk', self)
|
5
5
|
|
6
|
-
config_param :host, :string, :
|
7
|
-
config_param :port, :integer, :
|
6
|
+
config_param :host, :string, default: '127.0.0.1'
|
7
|
+
config_param :port, :integer, default: 3306
|
8
8
|
config_param :database, :string
|
9
9
|
config_param :username, :string
|
10
|
-
config_param :password, :string, :
|
10
|
+
config_param :password, :string, default: ''
|
11
11
|
|
12
12
|
config_param :column_names, :string
|
13
|
-
config_param :key_names, :string, :
|
13
|
+
config_param :key_names, :string, default: nil
|
14
14
|
config_param :table, :string
|
15
15
|
|
16
|
-
config_param :on_duplicate_key_update, :bool, :
|
17
|
-
config_param :on_duplicate_update_keys, :string, :
|
16
|
+
config_param :on_duplicate_key_update, :bool, default: false
|
17
|
+
config_param :on_duplicate_update_keys, :string, default: nil
|
18
18
|
|
19
19
|
attr_accessor :handler
|
20
20
|
|
@@ -27,31 +27,41 @@ module Fluent
|
|
27
27
|
super
|
28
28
|
|
29
29
|
if @column_names.nil?
|
30
|
-
|
30
|
+
fail Fluent::ConfigError, 'column_names MUST specified, but missing'
|
31
31
|
end
|
32
32
|
|
33
33
|
if @on_duplicate_key_update
|
34
34
|
if @on_duplicate_update_keys.nil?
|
35
|
-
|
35
|
+
fail Fluent::ConfigError, 'on_duplicate_key_update = true , on_duplicate_update_keys nil!'
|
36
36
|
end
|
37
37
|
@on_duplicate_update_keys = @on_duplicate_update_keys.split(',')
|
38
38
|
|
39
|
-
@on_duplicate_key_update_sql =
|
39
|
+
@on_duplicate_key_update_sql = ' ON DUPLICATE KEY UPDATE '
|
40
40
|
updates = []
|
41
|
-
@on_duplicate_update_keys.each
|
41
|
+
@on_duplicate_update_keys.each do |update_column|
|
42
42
|
updates.push(" #{update_column} = VALUES(#{update_column})")
|
43
|
-
|
43
|
+
end
|
44
44
|
@on_duplicate_key_update_sql += updates.join(',')
|
45
45
|
end
|
46
46
|
|
47
47
|
@column_names = @column_names.split(',')
|
48
48
|
@key_names = @key_names.nil? ? @column_names : @key_names.split(',')
|
49
|
-
@format_proc = Proc.new{|tag, time, record| @key_names.map{|k| k == '${time}' ? Time.at(time).strftime("%Y-%m-%d %H:%M:%S") : record[k]}}
|
50
|
-
|
51
49
|
end
|
52
50
|
|
53
51
|
def start
|
54
52
|
super
|
53
|
+
result = client.xquery("SHOW COLUMNS FROM #{@table}")
|
54
|
+
@max_lengths = []
|
55
|
+
@column_names.each do |column|
|
56
|
+
info = result.select { |x| x['Field'] == column }.first
|
57
|
+
r = /(char|varchar)\(([\d]+)\)/
|
58
|
+
begin
|
59
|
+
max_length = info['Type'].scan(r)[0][1].to_i
|
60
|
+
rescue
|
61
|
+
max_length = nil
|
62
|
+
end
|
63
|
+
@max_lengths << max_length
|
64
|
+
end
|
55
65
|
end
|
56
66
|
|
57
67
|
def shutdown
|
@@ -59,36 +69,54 @@ module Fluent
|
|
59
69
|
end
|
60
70
|
|
61
71
|
def format(tag, time, record)
|
62
|
-
[tag, time,
|
72
|
+
[tag, time, format_proc.call(tag, time, record)].to_msgpack
|
63
73
|
end
|
64
74
|
|
65
75
|
def client
|
66
|
-
Mysql2::Client.new(
|
67
|
-
:
|
68
|
-
:
|
69
|
-
:
|
70
|
-
:
|
71
|
-
:
|
72
|
-
:
|
73
|
-
|
76
|
+
Mysql2::Client.new(
|
77
|
+
host: @host,
|
78
|
+
port: @port,
|
79
|
+
username: @username,
|
80
|
+
password: @password,
|
81
|
+
database: @database,
|
82
|
+
flags: Mysql2::Client::MULTI_STATEMENTS
|
83
|
+
)
|
74
84
|
end
|
75
85
|
|
76
86
|
def write(chunk)
|
77
87
|
@handler = client
|
78
88
|
values_templates = []
|
79
|
-
values =
|
80
|
-
chunk.msgpack_each
|
81
|
-
values_templates
|
89
|
+
values = []
|
90
|
+
chunk.msgpack_each do |tag, time, data|
|
91
|
+
values_templates << "(#{ @column_names.map { |key| '?' }.join(',') })"
|
82
92
|
values.concat(data)
|
83
|
-
}
|
84
|
-
sql = "INSERT INTO #{@table} (#{@column_names.join(',')}) VALUES #{values_templates.join(',')}"
|
85
|
-
if @on_duplicate_key_update
|
86
|
-
sql += @on_duplicate_key_update_sql
|
87
93
|
end
|
94
|
+
sql = "INSERT INTO #{@table} (#{@column_names.join(',')}) VALUES #{values_templates.join(',')}"
|
95
|
+
sql += @on_duplicate_key_update_sql if @on_duplicate_key_update
|
88
96
|
|
89
|
-
$log.info "bulk insert
|
97
|
+
$log.info "bulk insert values size => #{values_templates.size}"
|
90
98
|
@handler.xquery(sql, values)
|
91
99
|
end
|
92
100
|
|
101
|
+
private
|
102
|
+
|
103
|
+
def format_proc
|
104
|
+
proc do |tag, time, record|
|
105
|
+
values = []
|
106
|
+
@key_names.each_with_index do |key, i|
|
107
|
+
if key == '${time}'
|
108
|
+
value = Time.at(time).strftime('%Y-%m-%d %H:%M:%S')
|
109
|
+
else
|
110
|
+
if @max_lengths[i].nil? || record[key].nil?
|
111
|
+
value = record[key]
|
112
|
+
else
|
113
|
+
value = record[key].slice(0, @max_lengths[i])
|
114
|
+
end
|
115
|
+
end
|
116
|
+
values << value
|
117
|
+
end
|
118
|
+
values
|
119
|
+
end
|
120
|
+
end
|
93
121
|
end
|
94
122
|
end
|
data/test/helper.rb
CHANGED
@@ -4,7 +4,7 @@ begin
|
|
4
4
|
Bundler.setup(:default, :development)
|
5
5
|
rescue Bundler::BundlerError => e
|
6
6
|
$stderr.puts e.message
|
7
|
-
$stderr.puts
|
7
|
+
$stderr.puts 'Run `bundle install` to install missing gems'
|
8
8
|
exit e.status_code
|
9
9
|
end
|
10
10
|
require 'test/unit'
|
@@ -12,12 +12,12 @@ require 'test/unit'
|
|
12
12
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
13
13
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
14
14
|
require 'fluent/test'
|
15
|
-
unless ENV.
|
15
|
+
unless ENV.key?('VERBOSE')
|
16
16
|
nulllogger = Object.new
|
17
|
-
nulllogger.instance_eval
|
17
|
+
nulllogger.instance_eval do|obj|
|
18
18
|
def method_missing(method, *args)
|
19
19
|
end
|
20
|
-
|
20
|
+
end
|
21
21
|
$log = nulllogger
|
22
22
|
end
|
23
23
|
|
@@ -6,13 +6,12 @@ class MysqlBulkOutputTest < Test::Unit::TestCase
|
|
6
6
|
Fluent::Test.setup
|
7
7
|
end
|
8
8
|
|
9
|
-
def create_driver(conf = CONFIG, tag='test')
|
9
|
+
def create_driver(conf = CONFIG, tag = 'test')
|
10
10
|
Fluent::Test::BufferedOutputTestDriver.new(Fluent::MysqlBulkOutput, tag).configure(conf)
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_configure_error
|
14
|
-
|
15
|
-
assert_raise(Fluent::ConfigError) {
|
14
|
+
assert_raise(Fluent::ConfigError) do
|
16
15
|
d = create_driver %[
|
17
16
|
host localhost
|
18
17
|
database test_app_development
|
@@ -23,9 +22,9 @@ class MysqlBulkOutputTest < Test::Unit::TestCase
|
|
23
22
|
on_duplicate_update_keys user_name,updated_at
|
24
23
|
flush_interval 10s
|
25
24
|
]
|
26
|
-
|
25
|
+
end
|
27
26
|
|
28
|
-
assert_raise(Fluent::ConfigError)
|
27
|
+
assert_raise(Fluent::ConfigError) do
|
29
28
|
d = create_driver %[
|
30
29
|
host localhost
|
31
30
|
database test_app_development
|
@@ -36,9 +35,9 @@ class MysqlBulkOutputTest < Test::Unit::TestCase
|
|
36
35
|
on_duplicate_key_update true
|
37
36
|
flush_interval 10s
|
38
37
|
]
|
39
|
-
|
38
|
+
end
|
40
39
|
|
41
|
-
assert_raise(Fluent::ConfigError)
|
40
|
+
assert_raise(Fluent::ConfigError) do
|
42
41
|
d = create_driver %[
|
43
42
|
host localhost
|
44
43
|
username root
|
@@ -49,12 +48,12 @@ class MysqlBulkOutputTest < Test::Unit::TestCase
|
|
49
48
|
on_duplicate_update_keys user_name,updated_at
|
50
49
|
flush_interval 10s
|
51
50
|
]
|
52
|
-
|
51
|
+
end
|
53
52
|
end
|
54
53
|
|
55
54
|
def test_configure
|
56
55
|
# not define format(default csv)
|
57
|
-
assert_nothing_raised(Fluent::ConfigError)
|
56
|
+
assert_nothing_raised(Fluent::ConfigError) do
|
58
57
|
d = create_driver %[
|
59
58
|
host localhost
|
60
59
|
database test_app_development
|
@@ -66,9 +65,9 @@ class MysqlBulkOutputTest < Test::Unit::TestCase
|
|
66
65
|
on_duplicate_update_keys user_name,updated_at
|
67
66
|
flush_interval 10s
|
68
67
|
]
|
69
|
-
|
68
|
+
end
|
70
69
|
|
71
|
-
assert_nothing_raised(Fluent::ConfigError)
|
70
|
+
assert_nothing_raised(Fluent::ConfigError) do
|
72
71
|
d = create_driver %[
|
73
72
|
database test_app_development
|
74
73
|
username root
|
@@ -76,9 +75,9 @@ class MysqlBulkOutputTest < Test::Unit::TestCase
|
|
76
75
|
column_names id,user_name,created_at,updated_at
|
77
76
|
table users
|
78
77
|
]
|
79
|
-
|
78
|
+
end
|
80
79
|
|
81
|
-
assert_nothing_raised(Fluent::ConfigError)
|
80
|
+
assert_nothing_raised(Fluent::ConfigError) do
|
82
81
|
d = create_driver %[
|
83
82
|
database test_app_development
|
84
83
|
username root
|
@@ -88,9 +87,9 @@ class MysqlBulkOutputTest < Test::Unit::TestCase
|
|
88
87
|
on_duplicate_key_update true
|
89
88
|
on_duplicate_update_keys user_name,updated_at
|
90
89
|
]
|
91
|
-
|
90
|
+
end
|
92
91
|
|
93
|
-
assert_nothing_raised(Fluent::ConfigError)
|
92
|
+
assert_nothing_raised(Fluent::ConfigError) do
|
94
93
|
d = create_driver %[
|
95
94
|
database test_app_development
|
96
95
|
username root
|
@@ -101,7 +100,6 @@ class MysqlBulkOutputTest < Test::Unit::TestCase
|
|
101
100
|
on_duplicate_key_update true
|
102
101
|
on_duplicate_update_keys user_name,updated_at
|
103
102
|
]
|
104
|
-
|
103
|
+
end
|
105
104
|
end
|
106
|
-
|
107
105
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-mysql-bulk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hiroshi Toyama
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|
@@ -146,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
146
|
version: '0'
|
147
147
|
requirements: []
|
148
148
|
rubyforge_project:
|
149
|
-
rubygems_version: 2.2.
|
149
|
+
rubygems_version: 2.2.2
|
150
150
|
signing_key:
|
151
151
|
specification_version: 4
|
152
152
|
summary: fluent plugin mysql bulk insert is high performance and on duplicate key
|