fluent-plugin-mysql-bulk 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|