fluent-plugin-mysql-bulk 0.0.1 → 0.0.2

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
  SHA1:
3
- metadata.gz: e1f4635f23f11af148bbb46bffb0191992a1dd44
4
- data.tar.gz: cce2ab34d60e853b727c53f51d5bb1c48b2d56ff
3
+ metadata.gz: 86de300a43868df18918561c887617eecf22354c
4
+ data.tar.gz: 2fef1cc8fe51e087a5f6a71a561fda00dc8b438f
5
5
  SHA512:
6
- metadata.gz: 3666e01d6c87578447e656dec0cd9937cb7e50de564e63e20e2046a940b761d37a4ca14a7d481715a9e6ec5d555e4b4ec7ad0c2decb3519fa4787ad8194cd4d9
7
- data.tar.gz: 96cafee91c3690fd8a86db4d64e4a0ea6b819a27b582354f27abdbf5c6e1bd4ed44f193a0905c79b1d345ddb1ff6d990ababc6de9390937b2b920aaa9c4c3af7
6
+ metadata.gz: d37c300044121019994ce5fb752fad6f12c5a6f14268faf60f5b4d1994e1bd7aabb79b913d5841c0bfe7c84623cb617a23dc52016e39ed294b7695d972198c49
7
+ data.tar.gz: cf4c3176eb6420c7b324927bd971cc44fa1c79038664bc60a7c6239d6540ed4f138b08a4eeadd3c63710ef5021efd415342720f408f7c9b3101a88cb62fc62bb
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ test.conf
@@ -0,0 +1,7 @@
1
+ rvm:
2
+ - 1.9.2
3
+ - 1.9.3
4
+ - 2.0.0
5
+ gemfile:
6
+ - Gemfile
7
+ script: "rake test"
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Hiroshi Toyama
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,179 @@
1
+
2
+ # fluent-plugin-mysql-bulk [![Build Status](https://secure.travis-ci.org/toyama0919/fluent-plugin-mysql-bulk.png?branch=master)](http://travis-ci.org/toyama0919/fluent-plugin-mysql-bulk)
3
+
4
+ fluent plugin mysql bulk insert is high performance and on duplicate key update respond.
5
+
6
+ ## Installation
7
+
8
+ ### td-agent(Linux)
9
+
10
+ /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-mysql-bulk
11
+
12
+ ### td-agent(Mac)
13
+
14
+ sudo /usr/local/Cellar/td-agent/1.1.XX/bin/fluent-gem install fluent-plugin-mysql-bulk
15
+
16
+ ### fluentd only
17
+
18
+ gem install fluent-plugin-mysql-bulk
19
+
20
+
21
+ ## Parameters
22
+
23
+ param|value
24
+ --------|------
25
+ host|database host(default: 127.0.0.1)
26
+ database|database name(require)
27
+ username|user(require)
28
+ password|password(default: blank)
29
+ column_names|bulk insert column (require)
30
+ key_names|value key names (default : column_names)
31
+ table|bulk insert table (require)
32
+ on_duplicate_key_update|on duplicate key update enable (true:false)
33
+ on_duplicate_update_keys|on duplicate key update column, comma separator
34
+
35
+ ## Configuration Example(bulk insert)
36
+
37
+ ```
38
+ <match mysql.input>
39
+ type mysql_bulk
40
+ host localhost
41
+ database test_app_development
42
+ username root
43
+ password hogehoge
44
+ column_names id,user_name,created_at,updated_at
45
+ table users
46
+ flush_interval 10s
47
+ </match>
48
+ ```
49
+
50
+ Assume following input is coming:
51
+
52
+ ```js
53
+ mysql.input: {"user_name":"toyama","created_at":"2014/01/03 21:35:15","updated_at":"2014/01/03 21:35:15","dummy":"hogehoge"}
54
+ mysql.input: {"user_name":"toyama2","created_at":"2014/01/03 21:35:21","updated_at":"2014/01/03 21:35:21","dummy":"hogehoge"}
55
+ mysql.input: {"user_name":"toyama3","created_at":"2014/01/03 21:35:27","updated_at":"2014/01/03 21:35:27","dummy":"hogehoge"}
56
+ ```
57
+
58
+ then result becomes as below (indented):
59
+
60
+ ```sql
61
+ +-----+-----------+---------------------+---------------------+
62
+ | id | user_name | created_at | updated_at |
63
+ +-----+-----------+---------------------+---------------------+
64
+ | 1 | toyama | 2014-01-03 21:35:15 | 2014-01-03 21:35:15 |
65
+ | 2 | toyama2 | 2014-01-03 21:35:21 | 2014-01-03 21:35:21 |
66
+ | 3 | toyama3 | 2014-01-03 21:35:27 | 2014-01-03 21:35:27 |
67
+ +-----+-----------+---------------------+---------------------+
68
+ ```
69
+
70
+ running query
71
+
72
+ ```sql
73
+ INSERT INTO users (id,user_name,created_at,updated_at) VALUES (NULL,'toyama','2014/01/03 21:35:15','2014/01/03 21:35:15'),(NULL,'toyama2','2014/01/03 21:35:21','2014/01/03 21:35:21')
74
+ ```
75
+
76
+ ## Configuration Example(bulk insert , if duplicate error record update)
77
+
78
+ ```
79
+ <match mysql.input>
80
+ type mysql_bulk
81
+ host localhost
82
+ database test_app_development
83
+ username root
84
+ password hogehoge
85
+ column_names id,user_name,created_at,updated_at
86
+ table users
87
+ on_duplicate_key_update true
88
+ on_duplicate_update_keys user_name,updated_at
89
+ flush_interval 60s
90
+ </match>
91
+ ```
92
+
93
+ Assume following input is coming:
94
+
95
+ ```js
96
+ mysql.input: {"id":"1" ,"user_name":"toyama7","created_at":"2014/01/03 21:58:03","updated_at":"2014/01/03 21:58:03"}
97
+ mysql.input: {"id":"2" ,"user_name":"toyama7","created_at":"2014/01/03 21:58:06","updated_at":"2014/01/03 21:58:06"}
98
+ mysql.input: {"id":"3" ,"user_name":"toyama7","created_at":"2014/01/03 21:58:08","updated_at":"2014/01/03 21:58:08"}
99
+ mysql.input: {"id":"10","user_name":"toyama7","created_at":"2014/01/03 21:58:18","updated_at":"2014/01/03 21:58:18"}
100
+ ```
101
+
102
+ then result becomes as below (indented):
103
+
104
+ ```sql
105
+ +-----+-----------+---------------------+---------------------+
106
+ | id | user_name | created_at | updated_at |
107
+ +-----+-----------+---------------------+---------------------+
108
+ | 1 | toyama7 | 2014-01-03 21:35:15 | 2014-01-03 21:58:03 |
109
+ | 2 | toyama7 | 2014-01-03 21:35:21 | 2014-01-03 21:58:06 |
110
+ | 3 | toyama7 | 2014-01-03 21:35:27 | 2014-01-03 21:58:08 |
111
+ | 10 | toyama7 | 2014-01-03 21:58:18 | 2014-01-03 21:58:18 |
112
+ +-----+-----------+---------------------+---------------------+
113
+ ```
114
+
115
+ if duplicate id , update username and updated_at
116
+
117
+
118
+ ## Configuration Example(bulk insert,fluentd key different column name)
119
+
120
+ ```
121
+ <match mysql.input>
122
+ type mysql_bulk
123
+ host localhost
124
+ database test_app_development
125
+ username root
126
+ password hogehoge
127
+ column_names id,user_name,created_at,updated_at
128
+ key_names id,user,created_date,updated_date
129
+ table users
130
+ flush_interval 10s
131
+ </match>
132
+ ```
133
+
134
+ Assume following input is coming:
135
+
136
+ ```js
137
+ mysql.input: {"user":"toyama","created_date":"2014/01/03 21:35:15","updated_date":"2014/01/03 21:35:15","dummy":"hogehoge"}
138
+ mysql.input: {"user":"toyama2","created_date":"2014/01/03 21:35:21","updated_date":"2014/01/03 21:35:21","dummy":"hogehoge"}
139
+ mysql.input: {"user":"toyama3","created_date":"2014/01/03 21:35:27","updated_date":"2014/01/03 21:35:27","dummy":"hogehoge"}
140
+ ```
141
+
142
+ then result becomes as below (indented):
143
+
144
+ ```sql
145
+ +-----+-----------+---------------------+---------------------+
146
+ | id | user_name | created_at | updated_at |
147
+ +-----+-----------+---------------------+---------------------+
148
+ | 1 | toyama | 2014-01-03 21:35:15 | 2014-01-03 21:35:15 |
149
+ | 2 | toyama2 | 2014-01-03 21:35:21 | 2014-01-03 21:35:21 |
150
+ | 3 | toyama3 | 2014-01-03 21:35:27 | 2014-01-03 21:35:27 |
151
+ +-----+-----------+---------------------+---------------------+
152
+ ```
153
+
154
+
155
+
156
+
157
+ ## spec
158
+
159
+ ```
160
+ bundle install
161
+ rake test
162
+ ```
163
+
164
+ ## todo
165
+
166
+ divide bulk insert(exsample 1000 per)
167
+
168
+
169
+ ## Contributing
170
+
171
+ 1. Fork it
172
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
173
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
174
+ 4. Push to the branch (`git push origin my-new-feature`)
175
+ 5. Create new [Pull Request](../../pull/new/master)
176
+
177
+ ## Copyright
178
+
179
+ Copyright (c) 2013 Hiroshi Toyama. See [LICENSE](LICENSE) for details.
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rake/testtask'
5
+ Rake::TestTask.new(:test) do |test|
6
+ test.libs << 'lib' << 'test'
7
+ test.pattern = 'test/**/test_*.rb'
8
+ test.verbose = true
9
+ end
10
+
11
+ task :default => :test
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ Gem::Specification.new do |gem|
3
+ gem.name = "fluent-plugin-mysql-bulk"
4
+ gem.version = "0.0.2"
5
+ gem.authors = ["Toyama Hiroshi"]
6
+ gem.email = ["toyama0919@gmail.com"]
7
+ gem.description = %q{fluent plugin mysql bulk insert is high performance and on duplicate key update respond.}
8
+ gem.summary = %q{fluent plugin mysql bulk insert is high performance and on duplicate key update respond.}
9
+ gem.homepage = "https://github.com/toyama0919/fluent-plugin-mysql-bulk"
10
+ gem.licenses = ["MIT"]
11
+ gem.has_rdoc = false
12
+
13
+ gem.files = `git ls-files`.split($\)
14
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
+ gem.require_paths = ["lib"]
17
+
18
+ gem.add_runtime_dependency "fluentd"
19
+ gem.add_runtime_dependency "mysql2-cs-bind"
20
+ gem.add_development_dependency "bundler", "~> 1.3"
21
+ gem.add_development_dependency "rake"
22
+ gem.add_development_dependency "rspec"
23
+ gem.add_development_dependency "spork"
24
+ gem.add_development_dependency "pry"
25
+
26
+ end
@@ -0,0 +1,94 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module Fluent
3
+ class Fluent::MysqlBulkOutput < Fluent::BufferedOutput
4
+ Fluent::Plugin.register_output('mysql_bulk', self)
5
+
6
+ config_param :host, :string, :default => "127.0.0.1"
7
+ config_param :port, :integer, :default => 3306
8
+ config_param :database, :string
9
+ config_param :username, :string
10
+ config_param :password, :string, :default => ''
11
+
12
+ config_param :column_names, :string
13
+ config_param :key_names, :string, :default => nil
14
+ config_param :table, :string
15
+
16
+ config_param :on_duplicate_key_update, :bool, :default => false
17
+ config_param :on_duplicate_update_keys, :string, :default => nil
18
+
19
+ attr_accessor :handler
20
+
21
+ def initialize
22
+ super
23
+ require 'mysql2-cs-bind'
24
+ end
25
+
26
+ def configure(conf)
27
+ super
28
+
29
+ if @column_names.nil?
30
+ raise Fluent::ConfigError, "column_names MUST be specified, but missing"
31
+ end
32
+
33
+ if @on_duplicate_key_update
34
+ if @on_duplicate_update_keys.nil?
35
+ raise Fluent::ConfigError, "on_duplicate_key_update = true , on_duplicate_update_keys nil!"
36
+ end
37
+ @on_duplicate_update_keys = @on_duplicate_update_keys.split(',')
38
+
39
+ @on_duplicate_key_update_sql = " ON DUPLICATE KEY UPDATE "
40
+ updates = []
41
+ @on_duplicate_update_keys.each{|update_column|
42
+ updates.push(" #{update_column} = VALUES(#{update_column})")
43
+ }
44
+ @on_duplicate_key_update_sql += updates.join(',')
45
+ end
46
+
47
+ @column_names = @column_names.split(',')
48
+ @key_names = @key_names.nil? ? @column_names : @key_names.split(',')
49
+ @format_proc = Proc.new{|tag, time, record| @key_names.map{|k| record[k]}}
50
+
51
+ end
52
+
53
+ def start
54
+ @handler = client
55
+ super
56
+ end
57
+
58
+ def shutdown
59
+ super
60
+ end
61
+
62
+ def format(tag, time, record)
63
+ [tag, time, @format_proc.call(tag, time, record)].to_msgpack
64
+ end
65
+
66
+ def client
67
+ Mysql2::Client.new({
68
+ :host => @host,
69
+ :port => @port,
70
+ :username => @username,
71
+ :password => @password,
72
+ :database => @database,
73
+ :flags => Mysql2::Client::MULTI_STATEMENTS
74
+ })
75
+ end
76
+
77
+ def write(chunk)
78
+ values_templates = []
79
+ values = Array.new
80
+ chunk.msgpack_each { |tag, time, data|
81
+ values_templates.push "(#{@column_names.map{|key| '?'}.join(',')})"
82
+ 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
+ end
88
+
89
+ $log.info "bulk insert sql => [#{Mysql2::Client.pseudo_bind(sql, values)}]"
90
+ @handler.xquery(sql, values)
91
+ end
92
+
93
+ end
94
+ end
@@ -0,0 +1,27 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+
12
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
14
+ require 'fluent/test'
15
+ unless ENV.has_key?('VERBOSE')
16
+ nulllogger = Object.new
17
+ nulllogger.instance_eval {|obj|
18
+ def method_missing(method, *args)
19
+ end
20
+ }
21
+ $log = nulllogger
22
+ end
23
+
24
+ require 'fluent/plugin/out_mysql_bulk'
25
+
26
+ class Test::Unit::TestCase
27
+ end
@@ -0,0 +1,107 @@
1
+ require 'helper'
2
+ require 'mysql2-cs-bind'
3
+
4
+ class MysqlBulkOutputTest < Test::Unit::TestCase
5
+ def setup
6
+ Fluent::Test.setup
7
+ end
8
+
9
+ def create_driver(conf = CONFIG, tag='test')
10
+ Fluent::Test::BufferedOutputTestDriver.new(Fluent::MysqlBulkOutput, tag).configure(conf)
11
+ end
12
+
13
+ def test_configure_error
14
+
15
+ assert_raise(Fluent::ConfigError) {
16
+ d = create_driver %[
17
+ host localhost
18
+ database test_app_development
19
+ username root
20
+ password hogehoge
21
+ table users
22
+ on_duplicate_key_update true
23
+ on_duplicate_update_keys user_name,updated_at
24
+ flush_interval 10s
25
+ ]
26
+ }
27
+
28
+ assert_raise(Fluent::ConfigError) {
29
+ d = create_driver %[
30
+ host localhost
31
+ database test_app_development
32
+ username root
33
+ password hogehoge
34
+ column_names id,user_name,created_at,updated_at
35
+ table users
36
+ on_duplicate_key_update true
37
+ flush_interval 10s
38
+ ]
39
+ }
40
+
41
+ assert_raise(Fluent::ConfigError) {
42
+ d = create_driver %[
43
+ host localhost
44
+ username root
45
+ password hogehoge
46
+ column_names id,user_name,created_at,updated_at
47
+ table users
48
+ on_duplicate_key_update true
49
+ on_duplicate_update_keys user_name,updated_at
50
+ flush_interval 10s
51
+ ]
52
+ }
53
+ end
54
+
55
+ def test_configure
56
+ # not define format(default csv)
57
+ assert_nothing_raised(Fluent::ConfigError) {
58
+ d = create_driver %[
59
+ host localhost
60
+ database test_app_development
61
+ username root
62
+ password hogehoge
63
+ column_names id,user_name,created_at,updated_at
64
+ table users
65
+ on_duplicate_key_update true
66
+ on_duplicate_update_keys user_name,updated_at
67
+ flush_interval 10s
68
+ ]
69
+ }
70
+
71
+ assert_nothing_raised(Fluent::ConfigError) {
72
+ d = create_driver %[
73
+ database test_app_development
74
+ username root
75
+ password hogehoge
76
+ column_names id,user_name,created_at,updated_at
77
+ table users
78
+ ]
79
+ }
80
+
81
+ assert_nothing_raised(Fluent::ConfigError) {
82
+ d = create_driver %[
83
+ database test_app_development
84
+ username root
85
+ password hogehoge
86
+ column_names id,user_name,created_at,updated_at
87
+ table users
88
+ on_duplicate_key_update true
89
+ on_duplicate_update_keys user_name,updated_at
90
+ ]
91
+ }
92
+
93
+ assert_nothing_raised(Fluent::ConfigError) {
94
+ d = create_driver %[
95
+ database test_app_development
96
+ username root
97
+ password hogehoge
98
+ column_names id,user_name,created_at,updated_at
99
+ key_names id,user,created_date,updated_date
100
+ table users
101
+ on_duplicate_key_update true
102
+ on_duplicate_update_keys user_name,updated_at
103
+ ]
104
+ }
105
+ end
106
+
107
+ 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.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Toyama Hiroshi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-03 00:00:00.000000000 Z
11
+ date: 2014-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -115,7 +115,17 @@ email:
115
115
  executables: []
116
116
  extensions: []
117
117
  extra_rdoc_files: []
118
- files: []
118
+ files:
119
+ - ".gitignore"
120
+ - ".travis.yml"
121
+ - Gemfile
122
+ - LICENSE
123
+ - README.md
124
+ - Rakefile
125
+ - fluent-plugin-mysql-bulk.gemspec
126
+ - lib/fluent/plugin/out_mysql_bulk.rb
127
+ - test/helper.rb
128
+ - test/plugin/test_out_mysql_bulk.rb
119
129
  homepage: https://github.com/toyama0919/fluent-plugin-mysql-bulk
120
130
  licenses:
121
131
  - MIT
@@ -141,4 +151,6 @@ signing_key:
141
151
  specification_version: 4
142
152
  summary: fluent plugin mysql bulk insert is high performance and on duplicate key
143
153
  update respond.
144
- test_files: []
154
+ test_files:
155
+ - test/helper.rb
156
+ - test/plugin/test_out_mysql_bulk.rb