db_mon 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c7aec1564fd1a3250a73ff614f6faa8e72110576
4
+ data.tar.gz: c88966ae796c48ca953285e009978e7189e01edf
5
+ SHA512:
6
+ metadata.gz: cfa0df816c9bef767c7a6286fc8a623a34da83bc20de9793cab9de90f2be78b92ba3fc38e57c19a7e09082a59cb798480003724bd489a6ca62b481e514a6a2e5
7
+ data.tar.gz: c2218b2e5b11825bcc15e226a30d7c86a823a8fd8e9bfee870f28c495abdea0d830252f0b6a2e1facb0776b571023b1c0d2f4f865dc0e8664cf640b8a7efdff4
data/.gitignore ADDED
@@ -0,0 +1,22 @@
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
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in db_mon.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Steve Lewis
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.
data/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # DBMon
2
+
3
+ DBMon is a simple database monitoring daemon that watches a given table for writes. If it doesn't detect a certain amount of writes within a specific period of time, it triggers an alert.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'dbmon'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install dbmon
18
+
19
+ ## Usage
20
+
21
+ The gem comes with a command-line utility, <code>dbmon</code>, that starts and stops the monitor in addition to other daemon tasks. To start the monitor, simply invoke the <code>dbmon start</code> command and point to your configuration file:
22
+
23
+ ```
24
+ dbmon start -- -C /path/to_your/config.yml
25
+ ```
26
+
27
+ This will invoke the script as a daemon, putting it in the background.
28
+
29
+ You can stop the monitor at any time by invoking <code>dbmon stop</code>
30
+
31
+
32
+ ## Configuration
33
+
34
+ The configuration file for DBMon is a YAML file that allows you to specify many of the aspects of DBmon's behavior. An example config is below:
35
+
36
+ ```
37
+ interval: 10
38
+ threshold: 1
39
+ adapter: 'pg'
40
+ database: 'is_development'
41
+ table: 'users'
42
+ username: 'stlewis'
43
+ password: 'dbpass'
44
+ notify: 'steve.lewis@moduspowered.com'
45
+ delivery_method: 'smtp'
46
+
47
+ ```
48
+
49
+ The purpose of these options is described below:
50
+
51
+ **interval**
52
+
53
+ How often (in seconds) to check the table for new writes. DBMon will query the table in question for writes that occurred between NOW() and <code>interval</code> ago.
54
+
55
+ **threshold**
56
+
57
+ This is the minimum number of records that must have been added to the database within the interval specified to avoid triggering an alert.
58
+
59
+ **adapter**
60
+
61
+ The database adapter to use for making connections. Currently supported options are mysql2 and pg. Note that you must have either the mysql2 gem or the pg gem in order to use it as an adapter.
62
+
63
+ **database**
64
+
65
+ The name of the database to connect to.
66
+
67
+ **table**
68
+
69
+ The name of the table you want to monitor.
70
+
71
+ **username**
72
+
73
+ The database username
74
+
75
+ **password**
76
+
77
+ The database password
78
+
79
+ **notify**
80
+
81
+ The email address you would like to receive a notification when an alert is triggered.
82
+
83
+ **delivery_method**
84
+
85
+ This option is passed directly to the Mail gem, and determines how you would like messages delivered. The default is 'smtp', but if you would like to test email delivery, you can use 'test' as a value.
86
+
87
+
88
+ ## TODO
89
+
90
+ * Make more options available for Mail configuration
91
+ * Monitoring for multiple tables
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/dbmon ADDED
@@ -0,0 +1,9 @@
1
+ #! /usr/bin/env ruby
2
+ require 'optparse'
3
+ require 'yaml'
4
+ require 'daemons'
5
+
6
+
7
+ path_to_file = File.expand_path('../../lib/db_mon.rb', __FILE__)
8
+ puts path_to_file
9
+ Daemons.run(path_to_file, dir_mode: :normal, dir: '/tmp')
data/db_mon.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'db_mon/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "db_mon"
8
+ spec.version = DbMon::VERSION
9
+ spec.authors = ["Steve Lewis"]
10
+ spec.email = ["steve.lewis@moduspowered.com"]
11
+ spec.summary = %q{DBMon is a simple daemon that monitors writes to a database table.}
12
+ spec.description = %q{In many cases, one of the primary indicators of system and application health is whether or not a certain table is receiving a consistent number of writes over time. DBMon helps to monitor database tables, and sends alerts if it doesn't see enough writes over time.}
13
+ spec.homepage = "https://www.github.com/JJCOINCWEBDEV/db_mon"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+ end
@@ -0,0 +1,77 @@
1
+ require 'mail'
2
+
3
+
4
+ module DbMon
5
+
6
+ class Monitor
7
+
8
+ def initialize(options = {})
9
+ @interval = options['interval']
10
+ @threshold = options['threshold']
11
+ @database = options['database']
12
+ @username = options['username']
13
+ @password = options['password']
14
+ @table = options['table']
15
+ @notify = options['notify']
16
+ @time_column = options['time_column'] || 'created_at'
17
+
18
+
19
+ Mail.defaults do
20
+ delivery_method options['delivery_method'].to_sym
21
+ end
22
+ end
23
+
24
+
25
+ def monitor_table
26
+ while true
27
+ sleep @interval.to_i
28
+ result = query_table
29
+
30
+ unless result.count >= @threshold
31
+ send_alert_email
32
+ end
33
+ end
34
+ end
35
+
36
+ def query_table
37
+ raise "Must be implemented on child classes"
38
+ end
39
+
40
+ def send_alert_email
41
+ table = @table
42
+ database = @database
43
+ threshold = @threshold
44
+ interval = @interval
45
+ notify = @notify
46
+
47
+ mail = Mail.deliver do
48
+ from 'database_monitor@modustools.com'
49
+ to notify
50
+ subject 'Database Monitor Alert'
51
+
52
+ html_part do
53
+ content_type 'text/html; charset=UTF-8'
54
+ body <<-EOM
55
+ <h2>Database Alert</h2>
56
+
57
+ <p>
58
+ The #{table} table on #{database} has had less than #{threshold} record(s)
59
+ added to it in the last #{interval} seconds. This may be an indication that
60
+ there is a problem with the service(s) responsible for creating these records.
61
+ </p>
62
+ <p>
63
+ #{interval} seconds is:
64
+ </p>
65
+ #{interval/60.0} minutes<br />
66
+ #{(interval/60.0)/60.0} hours<br />
67
+ #{((interval/60.0)/60.0)/24.0} days<br />
68
+ EOM
69
+ end
70
+ end
71
+
72
+ p
73
+
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,15 @@
1
+ require 'mysql2'
2
+ module DbMon
3
+
4
+ class MysqlMonitor < Monitor
5
+ def initialize(options)
6
+ super(options)
7
+ @connection = Mysql2::Client.new(host: 'localhost', username: @username, password: @password)
8
+ end
9
+
10
+ def query_table
11
+ return @connection.query("SELECT #{@time_column} FROM #{@table} WHERE #{@time_column} BETWEEN '#{@interval.seconds.ago}' AND '#{Time.now}' ORDER BY #{@time_column}")
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,18 @@
1
+ require 'pg'
2
+ module DbMon
3
+
4
+ class PgMonitor < Monitor
5
+
6
+ def initialize(options)
7
+ super(options)
8
+ @connection = PG.connect(dbname: @database, user: @username, password: @password)
9
+ end
10
+
11
+ def query_table
12
+ @connection.exec("SELECT #{@time_column} FROM #{@table} WHERE #{@time_column} BETWEEN '#{Time.now - @interval}' AND '#{Time.now}' ORDER BY #{@time_column}").values
13
+ end
14
+
15
+
16
+
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ require_relative 'monitor'
2
+
3
+ module DbMon
4
+
5
+ class Runner
6
+ attr_reader :monitor
7
+
8
+
9
+ def initialize(options = {})
10
+ @monitor = nil
11
+ case options['adapter']
12
+ when 'mysql2'
13
+ require_relative 'mysql_monitor'
14
+ @monitor = MysqlMonitor.new(options)
15
+ when 'pg'
16
+ require_relative 'pg_monitor'
17
+ @monitor = PgMonitor.new(options)
18
+ when 'sqlite'
19
+ raise "SQLite Monitor not implemented"
20
+ @monitor = SqliteMonitor.new(options)
21
+ else
22
+ raise 'Unsupported Adapter'
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,3 @@
1
+ module DbMon
2
+ VERSION = "0.0.1"
3
+ end
data/lib/db_mon.rb ADDED
@@ -0,0 +1,21 @@
1
+ require_relative "db_mon/version"
2
+ require_relative 'db_mon/runner'
3
+
4
+ module DbMon
5
+ end
6
+
7
+
8
+ options = {}
9
+
10
+ optparse = OptionParser.new do |opts|
11
+ opts.banner = "Usage: dbmon -C <path to config file>"
12
+ opts.on('-C', '--config FILE', 'Full path to configuration file') do |file|
13
+ options[:config_file] = file
14
+ end
15
+ end
16
+ optparse.parse!
17
+
18
+ raise "No config file provided" unless options[:config_file]
19
+ config = YAML::load(File.read(options[:config_file]))
20
+ monitor = DbMon::Runner.new(config).monitor
21
+ monitor.monitor_table
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: db_mon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Steve Lewis
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: In many cases, one of the primary indicators of system and application
42
+ health is whether or not a certain table is receiving a consistent number of writes
43
+ over time. DBMon helps to monitor database tables, and sends alerts if it doesn't
44
+ see enough writes over time.
45
+ email:
46
+ - steve.lewis@moduspowered.com
47
+ executables:
48
+ - dbmon
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - .gitignore
53
+ - Gemfile
54
+ - LICENSE.txt
55
+ - README.md
56
+ - Rakefile
57
+ - bin/dbmon
58
+ - db_mon.gemspec
59
+ - lib/db_mon.rb
60
+ - lib/db_mon/monitor.rb
61
+ - lib/db_mon/mysql_monitor.rb
62
+ - lib/db_mon/pg_monitor.rb
63
+ - lib/db_mon/runner.rb
64
+ - lib/db_mon/version.rb
65
+ homepage: https://www.github.com/JJCOINCWEBDEV/db_mon
66
+ licenses:
67
+ - MIT
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 2.0.3
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: DBMon is a simple daemon that monitors writes to a database table.
89
+ test_files: []