fluent-plugin-rds-mysql-slow-log 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 36fa45a004f050662ff15c1873fd7293f357eca0
4
+ data.tar.gz: 2f213f061c22154b832206bddfc202c08a1afd0c
5
+ SHA512:
6
+ metadata.gz: 16a03a50674bf7eed453d223af75257a4409c188ed65b9d7d1692892949823d0919559dc012c6f33c9984a106b868c1eba1dd22e3056da6e1a5cba2600eb6fb7
7
+ data.tar.gz: ecef8575d6ce05d0e7782199feb89e4b01eae80469775d8f633b88cc545d2ebeee3398f943e573cc84aa1d159e07fe85333a909da0f2785e040dd2033f75e482
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
@@ -0,0 +1,7 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ Style/GuardClause:
4
+ Enabled: false
5
+
6
+ Style/SpecialGlobalVars:
7
+ Enabled: false
@@ -0,0 +1,14 @@
1
+ Metrics/BlockLength:
2
+ Enabled: false
3
+
4
+ Metrics/ClassLength:
5
+ Enabled: false
6
+
7
+ Metrics/LineLength:
8
+ Enabled: false
9
+
10
+ Metrics/MethodLength:
11
+ Enabled: false
12
+
13
+ Style/Documentation:
14
+ Enabled: false
@@ -0,0 +1 @@
1
+ 2.1.10
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-rds-mysql-slow-log.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Satoshi Matsumoto
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,65 @@
1
+ # fluent-plugin-rds-mysql-slow-log
2
+
3
+ [![Gem](https://img.shields.io/gem/v/fluent-plugin-rds-mysql-slow-log.svg?style=flat-square)](https://rubygems.org/gems/fluent-plugin-rds-mysql-slow-log)
4
+ [![Gemnasium](https://img.shields.io/gemnasium/kaorimatz/fluent-plugin-rds-mysql-slow-log.svg?style=flat-square)](https://gemnasium.com/kaorimatz/fluent-plugin-rds-mysql-slow-log)
5
+
6
+ Fluentd input plugin for MySQL slow query log table on Amazon RDS.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'fluent-plugin-rds-mysql-slow-log'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install fluent-plugin-rds-mysql-slow-log
23
+
24
+ ## Usage
25
+
26
+ ```
27
+ <source>
28
+ @type rds_mysql_slow_log
29
+ database_timezone Asia/Tokyo
30
+ emit_interval 30
31
+ encoding utf-8
32
+ from_encoding shift_jis
33
+ keep_time_key
34
+ null_empty_string
35
+ tag_prefix slow_log
36
+ <server>
37
+ host db1.xxxxxxxxxxxx.us-east-1.rds.amazonaws.com
38
+ port 3306
39
+ username user
40
+ password xxxxxxxxxxxx
41
+ tag db1
42
+ </server>
43
+ <server>
44
+ host db2.xxxxxxxxxxxx.us-east-1.rds.amazonaws.com
45
+ port 3306
46
+ username user
47
+ password xxxxxxxxxxxx
48
+ tag db2
49
+ </server>
50
+ </source>
51
+ ```
52
+
53
+ ## Development
54
+
55
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
56
+
57
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in the gemspec, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
58
+
59
+ ## Contributing
60
+
61
+ Bug reports and pull requests are welcome on GitHub at https://github.com/kaorimatz/fluent-plugin-rds-mysql-slow-log.
62
+
63
+ ## License
64
+
65
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,2 @@
1
+ require 'bundler/gem_tasks'
2
+ task default: :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'fluent/plugin/in_rds_mysql_slow_log'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'fluent-plugin-rds-mysql-slow-log'
8
+ spec.version = '0.1.0'
9
+ spec.authors = ['Satoshi Matsumoto']
10
+ spec.email = ['kaorimatz@gmail.com']
11
+
12
+ spec.summary = 'Fluentd input plugin for MySQL slow query log table on Amazon RDS'
13
+ spec.description = 'Fluentd input plugin for MySQL slow query log table on Amazon RDS.'
14
+ spec.homepage = 'https://github.com/kaorimatz/fluent-plugin-rds-mysql-slow-log'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = 'exe'
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_dependency 'fluentd', '>= 0.10.58'
25
+ spec.add_dependency 'mysql2'
26
+ spec.add_dependency 'tzinfo'
27
+
28
+ spec.add_development_dependency 'bundler'
29
+ spec.add_development_dependency 'rake'
30
+ spec.add_development_dependency 'rubocop'
31
+ end
@@ -0,0 +1,223 @@
1
+ require 'cool.io'
2
+ require 'fluent/input'
3
+ require 'mysql2'
4
+ require 'scanf'
5
+ require 'time'
6
+
7
+ module Fluent
8
+ class RdsMysqlSlowLog < Input
9
+ Plugin.register_input('rds_mysql_slow_log', self)
10
+
11
+ config_param :database_timezone, :string, default: nil, desc: 'The timezone of the database.'
12
+ config_param :emit_interval, :time, default: 10, desc: 'The interval in seconds to emit records.'
13
+ config_param :encoding, :string, default: nil, desc: 'The encoding of strings in an emitted record.'
14
+ config_param :from_encoding, :string, default: nil, desc: 'The encoding of sql_text data.'
15
+ config_param :keep_time_key, :bool, default: false, desc: 'Keep the time key in an emitted record.'
16
+ config_param :null_empty_string, :bool, default: false, desc: 'Convert empty strings to null.'
17
+ config_param :tag_prefix, :string, default: nil, desc: 'The prefix of the tag.'
18
+ config_section :server, param_name: :servers, required: true do
19
+ config_param :host, :string, desc: 'The IP address or hostname of the server.'
20
+ config_param :password, :string, default: nil, secret: true, desc: 'The password to use when connecting to the server.'
21
+ config_param :port, :integer, default: 3306, desc: 'The port number of the server.'
22
+ config_param :tag, :string, desc: 'The tag of the event.'
23
+ config_param :username, :string, default: nil, desc: 'The username to use when connecting to the server.'
24
+ end
25
+
26
+ def configure(conf)
27
+ super
28
+
29
+ configure_servers
30
+ configure_timezone
31
+ configure_encoding
32
+ end
33
+
34
+ def configure_servers
35
+ @servers.map! do |s|
36
+ tag = @tag_prefix ? "#{@tag_prefix}.#{s.tag}" : s.tag
37
+ [tag, Server.new(s.host, s.port, s.username, s.password)]
38
+ end
39
+ end
40
+
41
+ def configure_timezone
42
+ @database_timezone = parse_timezone_param(@database_timezone) if @database_timezone
43
+ end
44
+
45
+ def parse_timezone_param(timezone)
46
+ TZInfo::Timezone.get(timezone)
47
+ rescue InvalidTimezoneIdentifier => e
48
+ raise ConfigError, e.message
49
+ end
50
+
51
+ def configure_encoding
52
+ if !@encoding && @from_encoding
53
+ raise ConfigError, "'from_encoding' parameter must be specified with 'encoding' parameter."
54
+ end
55
+
56
+ @encoding = parse_encoding_param(@encoding) if @encoding
57
+ @from_encoding = parse_encoding_param(@from_encoding) if @from_encoding
58
+ end
59
+
60
+ def parse_encoding_param(encoding)
61
+ Encoding.find(encoding)
62
+ rescue ArgumentError => e
63
+ raise ConfigError, e.message
64
+ end
65
+
66
+ def start
67
+ super
68
+
69
+ @loop = Coolio::Loop.new
70
+ @timer = TimerWatcher.new(@emit_interval, true, log, &method(:on_timer))
71
+ @loop.attach(@timer)
72
+ @thread = Thread.new(&method(:run))
73
+ end
74
+
75
+ def run
76
+ @loop.run
77
+ rescue
78
+ log.error $!.to_s
79
+ log.error_backtrace
80
+ end
81
+
82
+ def on_timer
83
+ @servers.each do |tag, server|
84
+ emit_slow_log(tag, server)
85
+ end
86
+ end
87
+
88
+ def emit_slow_log(tag, server)
89
+ server.connect do |client|
90
+ client.query('CALL mysql.rds_rotate_slow_log')
91
+
92
+ es = MultiEventStream.new
93
+ client.query('SELECT * FROM slow_log_backup').each do |row|
94
+ es.add(*process(row))
95
+ end
96
+
97
+ router.emit_stream(tag, es)
98
+ end
99
+ rescue
100
+ log.error $!.to_s
101
+ log.error_backtrace
102
+ end
103
+
104
+ def process(record)
105
+ process_timestamp(record)
106
+ process_string(record)
107
+ process_time(record)
108
+ process_integer(record)
109
+ [extract_time(record), record]
110
+ end
111
+
112
+ def process_timestamp(record)
113
+ record['start_time'] &&= timestamp_to_time(record['start_time'])
114
+ end
115
+
116
+ def timestamp_to_time(timestamp)
117
+ year, month, day, hour, min, sec, usec = timestamp.scanf('%4u-%2u-%2u %2u:%2u:%2u.%6u')
118
+ t = Time.utc(year, month, day, hour, min, sec, usec)
119
+ @database_timezone ? @database_timezone.local_to_utc(t) : t
120
+ end
121
+
122
+ def process_string(record)
123
+ if @null_empty_string
124
+ %w[user_host db sql_text].each do |field|
125
+ record[field] = nil if (record[field] || '').empty?
126
+ end
127
+ end
128
+
129
+ if @encoding
130
+ encode(record['user_host'], @encoding, Encoding::UTF_8)
131
+ encode(record['db'], @encoding, Encoding::UTF_8)
132
+ encode(record['sql_text'], @encoding, @from_encoding)
133
+ end
134
+ end
135
+
136
+ def encode(str, dst, src)
137
+ if str.nil?
138
+ nil
139
+ elsif src
140
+ str.encode!(dst, src)
141
+ else
142
+ str.force_encoding(dst)
143
+ end
144
+ end
145
+
146
+ def process_time(record)
147
+ %w[query_time lock_time].each do |field|
148
+ record[field] &&= time_to_microseconds(record[field])
149
+ end
150
+ end
151
+
152
+ def time_to_microseconds(time)
153
+ hour, min, sec, usec = time.scanf('%2u:%2u:%2u.%6u')
154
+ hour * 3_600_000_000 + min * 60_000_000 + sec * 1_000_000 + usec.to_i
155
+ end
156
+
157
+ def process_integer(record)
158
+ %w[
159
+ rows_sent
160
+ rows_examined
161
+ last_insert_id
162
+ insert_id
163
+ server_id
164
+ thread_id
165
+ rows_affected
166
+ ].each do |field|
167
+ record[field] &&= record[field].to_i
168
+ end
169
+ end
170
+
171
+ def extract_time(record)
172
+ time = @keep_time_key ? record['start_time'] : record.delete('start_time')
173
+ (time || Engine.now).to_i
174
+ end
175
+
176
+ def shutdown
177
+ super
178
+
179
+ @loop.watchers.each(&:detach)
180
+ @loop.stop
181
+ @thread.join
182
+ end
183
+
184
+ class Server
185
+ def initialize(host, port, username, password)
186
+ @host = host
187
+ @port = port
188
+ @username = username
189
+ @password = password
190
+ end
191
+
192
+ def connect
193
+ client = Mysql2::Client.new(
194
+ host: @host,
195
+ port: @port,
196
+ username: @username,
197
+ password: @password,
198
+ database: 'mysql',
199
+ cache_rows: false,
200
+ cast: false
201
+ )
202
+ yield client
203
+ ensure
204
+ client.close if client
205
+ end
206
+ end
207
+
208
+ class TimerWatcher < Coolio::TimerWatcher
209
+ def initialize(interval, repeat, log, &callback)
210
+ @callback = callback
211
+ @log = log
212
+ super(interval, repeat)
213
+ end
214
+
215
+ def on_timer
216
+ @callback.call
217
+ rescue
218
+ @log.error $!.to_s
219
+ @log.error_backtrace
220
+ end
221
+ end
222
+ end
223
+ end
metadata ADDED
@@ -0,0 +1,140 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-rds-mysql-slow-log
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Satoshi Matsumoto
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-08-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fluentd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.10.58
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.10.58
27
+ - !ruby/object:Gem::Dependency
28
+ name: mysql2
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: tzinfo
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Fluentd input plugin for MySQL slow query log table on Amazon RDS.
98
+ email:
99
+ - kaorimatz@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".rubocop.yml"
106
+ - ".rubocop_todo.yml"
107
+ - ".ruby-version"
108
+ - Gemfile
109
+ - LICENSE.txt
110
+ - README.md
111
+ - Rakefile
112
+ - bin/console
113
+ - bin/setup
114
+ - fluent-plugin-rds-mysql-slow-log.gemspec
115
+ - lib/fluent/plugin/in_rds_mysql_slow_log.rb
116
+ homepage: https://github.com/kaorimatz/fluent-plugin-rds-mysql-slow-log
117
+ licenses:
118
+ - MIT
119
+ metadata: {}
120
+ post_install_message:
121
+ rdoc_options: []
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ requirements: []
135
+ rubyforge_project:
136
+ rubygems_version: 2.2.5
137
+ signing_key:
138
+ specification_version: 4
139
+ summary: Fluentd input plugin for MySQL slow query log table on Amazon RDS
140
+ test_files: []