sys_watchdog 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5ee1c0e291ad96ace550d5e8538db4e41cf5f9ff
4
+ data.tar.gz: dc135065fc06c720b8d3ee976abee42a00f941fa
5
+ SHA512:
6
+ metadata.gz: a138bc331c7063af2bac5c17f5db75cd7205872a389a945cca9ef4f5792e678504b19d025f50741b22df8e47fbc863b8ce2be26a5a828b612b0bbcfaf9a0be0e
7
+ data.tar.gz: 885df78c3268ba5c59e5997996e98ba9711646ff8744b525c26b29e90d6b39dab702524d392693a608ee2f7f749e749acc021f1dcae95f5142849730192fc655
data/.gitignore ADDED
@@ -0,0 +1,50 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ # Gemfile.lock
46
+ # .ruby-version
47
+ # .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
data/README.md ADDED
@@ -0,0 +1,89 @@
1
+
2
+ Sys Watchdog
3
+ =================
4
+
5
+ ** perform all steps as root
6
+
7
+ ## Installation
8
+
9
+ ```
10
+ gem install sys_watchdog
11
+ ```
12
+
13
+ If using Rbenv, run ```rbenv rehash``` to make sys_watchdog binary available.
14
+
15
+ ## Setup
16
+
17
+ If on Linux with systemd available (eg: Ubuntu 16+, RedHat 7+. Generally distro versions released from 2015):
18
+
19
+ ```
20
+ sys_watchdog setup_with_systemd
21
+ ```
22
+
23
+ Otherwise:
24
+
25
+ ```
26
+ sys_watchdog setup_with_cron
27
+ ```
28
+
29
+ ### Configuration
30
+
31
+ After install, edit ```/etc/sys_watchdog.yml```.
32
+ You can see some examples in this file and in [/test/sys_watchdog_test.yml](https://github.com/tomlobato/sys_watchdog/blob/master/test/sys_watchdog_test.yml).
33
+
34
+ Now you can test from the command line.
35
+
36
+ ```
37
+ sys_watchdog test
38
+ ```
39
+
40
+ ### Start
41
+
42
+ Finally, after installed and configured, enable periodic run...
43
+
44
+ for systemd:
45
+ ```systemctl start sys_watchdog```
46
+
47
+ or uncommenting the added cron line:
48
+ ```vim /etc/crontab```
49
+
50
+
51
+ ### Config Settings
52
+
53
+ setting | description
54
+ -------------|-------------------------------------------------------------------------------------------------
55
+ name | -
56
+ server_name | -
57
+ slack_token | -
58
+ slack_channel| -
59
+ smtp_server | -
60
+ smtp_domain | -
61
+ mail_from | -
62
+ mail_to | -
63
+
64
+ #### Sys Test Settings
65
+
66
+ setting | description
67
+ ------------------|-------------------------------------------------------------------------------------------
68
+ test_cmd | -
69
+ test_url | -
70
+ notify_on_change | -
71
+ restore_cmd | -
72
+ expected_regex | -
73
+ expected_string | -
74
+ expected_max | -
75
+ expected_min | -
76
+
77
+ ## Create a Slack Token
78
+
79
+ From https://github.com/slack-ruby/slack-ruby-client ...
80
+
81
+ This is something done in Slack, under [integrations](https://my.slack.com/services). Create a [new bot](https://my.slack.com/services/new/bot), and note its API token.
82
+
83
+ ![](screenshots/register-bot.png)
84
+
85
+ ## Copyright and License
86
+
87
+ Copyright (c) 2017-2016, [Tom Lobato](https://github.com/tomlobato).
88
+
89
+ This project is licensed under the MIT License.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << 'test'
5
+ end
6
+
7
+ desc "Run tests"
8
+ task :default => :test
data/bin/sys_watchdog ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'sys_watchdog'
4
+
5
+ case ARGV[0]
6
+
7
+ when 'setup_with_systemd'
8
+ Setup.new.setup_with_systemd
9
+
10
+ when 'setup_with_cron'
11
+ Setup.new.setup_with_cron
12
+
13
+ when 'test'
14
+ sw = SysWatchdog.new log_file: STDOUT
15
+ sw.run once: true
16
+
17
+ when 'once'
18
+ SysWatchdog.new.run once: true
19
+
20
+ when nil
21
+ SysWatchdog.new.run
22
+ end
23
+
@@ -0,0 +1,9 @@
1
+ class Exception
2
+ def desc
3
+ "#{self.message} #{self.backtrace.join "\n" if self.backtrace}"
4
+ end
5
+ end
6
+
7
+ def log_ex e
8
+ STDERR.puts e.desc
9
+ end
@@ -0,0 +1,83 @@
1
+ class SysWatchdog
2
+ DEFAULT_CONF_FILE = '/etc/sys_watchdog.yml'
3
+ DEFAULT_LOG_FILE = '/var/log/sys_watchdog.log'
4
+
5
+ def initialize conf_file: nil, log_file: nil
6
+ @logger = WdLogger.new (log_file || DEFAULT_LOG_FILE)
7
+ @trackers = {}
8
+ parse_conf (conf_file || DEFAULT_CONF_FILE)
9
+ setup
10
+ end
11
+
12
+ def run once: false
13
+ loop do
14
+ @tests.each{|test| run_test test}
15
+ return if once
16
+ sleep 60
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def setup
23
+ if @conf.slack_token
24
+ Slack.configure do |config|
25
+ config.token = @conf.slack_token
26
+ end
27
+ end
28
+ if @conf.smtp_server
29
+ Mail.defaults do
30
+ delivery_method :smtp, address: @conf.smtp_server, port: 587, :domain => @conf.smtp_domain,
31
+ :enable_starttls_auto => true, :openssl_verify_mode => 'none'
32
+ end
33
+ end
34
+ end
35
+
36
+ def parse_conf conf_file
37
+ raise "Conf file #{conf_file} not found." unless File.exist? conf_file
38
+
39
+ conf = YAML.load_file conf_file
40
+ conf.deep_symbolize_keys!
41
+
42
+ @conf = OpenStruct.new conf[:config]
43
+
44
+ @tests = conf[:tests].keys.map { |name|
45
+ WdTest.new(name, conf[:tests][name], @logger)
46
+ }
47
+ end
48
+
49
+ def run_test test, after_restore: false
50
+ success, exitstatus, output = test.run
51
+
52
+ if test.notify_on_change
53
+ if @trackers[test.name] != output
54
+ notify "#{test.name} changed", "old: #{@trackers[test.name]}\nnew: #{output}"
55
+ end
56
+ @trackers[test.name] = output
57
+ end
58
+
59
+ if success
60
+ if test.fail
61
+ test.fail = false
62
+ notify "#{test.name} ok"
63
+ end
64
+ else
65
+ unless test.fail
66
+ if test.restore_cmd and not after_restore
67
+ test.restore
68
+ run_test test, after_restore: true
69
+ else
70
+ fail test, exitstatus, output
71
+ end
72
+ end
73
+ end
74
+ rescue => e
75
+ @logger.error e.desc
76
+ end
77
+
78
+ def fail test, exitstatus, output
79
+ test.fail = true
80
+ body = "output: #{output}" if body and not body.empty?
81
+ notify "#{test.name} fail", body
82
+ end
83
+ end
@@ -0,0 +1,55 @@
1
+ class SysWatchdog
2
+ private
3
+
4
+ def notify sub, body = ""
5
+ begin
6
+ send_mail sub, body if @conf.smtp_server
7
+ rescue => e
8
+ @logger.error e.desc
9
+ end
10
+ begin
11
+ send_slack_msg "#{sub}\n#{body}" if @conf.slack_token
12
+ rescue => e
13
+ @logger.error e.desc
14
+ end
15
+ end
16
+
17
+ def send_slack_msg msg
18
+ slack_client = Slack::Web::Client.new
19
+ slack_client.chat_postMessage(channel: @conf[:slack_channel], text: "[#{server_name}] #{msg}", as_user: true)
20
+ end
21
+
22
+ def send_mail sub, _body
23
+ @logger.info "Sending email: #{ sub }"
24
+
25
+ body = _body || ""
26
+ body += append_sys_info
27
+
28
+ mail = Mail.new do
29
+ from @conf.mail_from
30
+ to @conf.mail_to
31
+ subject "Watchdog #{@conf.name} [#{server_name}]: #{ sub }"
32
+ body body
33
+ end
34
+
35
+ mail.deliver!
36
+ end
37
+
38
+ def server_name
39
+ @conf.server_name || `hostname`
40
+ end
41
+
42
+ def append_sys_info
43
+ ret = "\n\n--------------- sys info ---------------"
44
+ %Q(
45
+ ps aux
46
+ df -h
47
+ uptime
48
+
49
+ ).split("\n").map(&:strip).compact.reject(&:empty?).each do |cmd|
50
+ cmd_result = `#{ cmd }`
51
+ ret += "\n\n#{ cmd }:\n#{ cmd_result }"
52
+ end
53
+ ret
54
+ end
55
+ end
@@ -0,0 +1,69 @@
1
+
2
+ class Setup
3
+ def initialize
4
+ @thisdir = File.join File.dirname(__FILE__)
5
+ end
6
+
7
+ def with_systemd
8
+ copy_sample_conf
9
+ install_systemd_service
10
+
11
+ puts "Installed."
12
+
13
+ puts "\nEdit #{SysWatchdog::DEFAULT_CONF_FILE} and start:"
14
+ puts "systemctl start sys_watchdog"
15
+
16
+ puts "\nTo check daemon status:"
17
+ puts "systemctl status sys_watchdog"
18
+ end
19
+
20
+ def with_cron
21
+ copy_sample_conf
22
+ add_cron_line
23
+
24
+ puts "Installed."
25
+
26
+ puts "\nEdit #{SysWatchdog::DEFAULT_CONF_FILE} and uncomment the cron line added."
27
+ end
28
+
29
+ private
30
+
31
+ def add_cron_line
32
+ run "echo '#* * * * * root sys_watchdog' >> /etc/crontab"
33
+ end
34
+
35
+ def install_systemd_service
36
+ services_dir = "/lib/systemd/system/"
37
+
38
+ if `which systemctl`.empty?
39
+ STDERR.puts "SysWatchdog install requires systemctl. Aborting."
40
+ exit 1
41
+ end
42
+
43
+ unless File.exist? services_dir
44
+ STDERR.puts "SysWatchdog install requires dir #{services_dir}. Aborting."
45
+ exit 1
46
+ end
47
+
48
+ copy "#{@thisdir}/../../util/sys_watchdog.service",
49
+ services_dir
50
+
51
+ run 'systemctl enable sys_watchdog'
52
+ end
53
+
54
+ def copy_sample_conf
55
+ copy "#{@thisdir}/../../util/sys_watchdog_sample.yml",
56
+ SysWatchdog::DEFAULT_CONF_FILE
57
+ end
58
+
59
+ def copy from, to
60
+ puts "Copying #{from} to #{to}..."
61
+ FileUtils.cp from, to
62
+ end
63
+
64
+ def run cmd
65
+ puts "Running #{cmd}..."
66
+ system cmd
67
+ end
68
+
69
+ end
@@ -0,0 +1,34 @@
1
+
2
+ require 'syslog'
3
+ require 'syslog/logger'
4
+
5
+ class WdLogger < Logger
6
+ SYSLOG_NAME = 'sys_watchdog'
7
+
8
+ def initialize *args
9
+ @syslog = Syslog::Logger.new SYSLOG_NAME
10
+ super
11
+ end
12
+
13
+ def add(severity, message = nil, progname = nil, &block)
14
+ super
15
+
16
+ if message.nil?
17
+ if block_given?
18
+ message = yield
19
+ else
20
+ message = progname
21
+ end
22
+ end
23
+
24
+ added severity, message
25
+ end
26
+
27
+ def added severity, message
28
+ if severity >= Logger::WARN
29
+ @syslog.send Logger::Severity::constants[severity].downcase, message
30
+ end
31
+ end
32
+
33
+ end
34
+
@@ -0,0 +1,91 @@
1
+ class WdTest
2
+ attr_accessor :name,
3
+ :test_cmd, :test_url, :notify_on_change, :restore_cmd,
4
+ :expected_regex, :expected_string, :expected_max, :expected_min,
5
+ :fail
6
+
7
+ def initialize name, params, logger
8
+ @logger = logger
9
+
10
+ @name = name
11
+
12
+ @test_cmd = params[:test_cmd]
13
+ @test_url = params[:test_url]
14
+ @notify_on_change = params[:notify_on_change]
15
+ @restore_cmd = params[:restore_cmd]
16
+
17
+ @expected_regex = params[:expected_regex]
18
+ @expected_string = params[:expected_string]
19
+ @expected_max = params[:expected_max]
20
+ @expected_min = params[:expected_min]
21
+
22
+ @fail = false
23
+
24
+ setup
25
+ end
26
+
27
+ def restore
28
+ exitstatus, output = run_cmd @restore_cmd
29
+ unless exitstatus == 0
30
+ @logger.error "restore exited with non-zero: #{exitstatus} #{output}"
31
+ end
32
+ end
33
+
34
+ def run after_restore: false
35
+ @logger.info "========== testing #{@name}"
36
+
37
+ unless @test_cmd
38
+ @logger.error "test cmd or url required"
39
+ return
40
+ end
41
+
42
+ exitstatus, output = run_cmd @test_cmd
43
+
44
+ success = check_result exitstatus, output
45
+ @logger.info "success: #{success.to_s}"
46
+
47
+ [success, exitstatus, output]
48
+ end
49
+
50
+ private
51
+
52
+ def run_cmd cmd, allow_raise = false
53
+ @logger.info "run: #{ cmd }"
54
+
55
+ output = IO.popen(cmd, "r") {|pipe| pipe.read}
56
+ exitstatus = $?.exitstatus
57
+
58
+ if exitstatus != 0
59
+ @logger.error "#{cmd} -> #{output}"
60
+ end
61
+
62
+ [exitstatus, output]
63
+ end
64
+
65
+ def setup
66
+ if @test_url
67
+ @test_cmd = "wget -O - '#{ @test_url }' > /dev/null 2>&1"
68
+ end
69
+ if @expected_regex
70
+ @expected_regex = Regexp.new @expected_regex
71
+ end
72
+ if @notify_on_change
73
+ @test_cmd = @notify_on_change
74
+ end
75
+ end
76
+
77
+ def check_result exitstatus, output
78
+ success = if @expected_regex
79
+ output =~ @expected_regex
80
+ elsif @expected_string
81
+ output.index @expected_string
82
+ elsif @expected_max
83
+ output.to_f <= @expected_max
84
+ elsif @expected_min
85
+ output.to_f <= @expected_min
86
+ else
87
+ exitstatus == 0
88
+ end
89
+ !!success
90
+ end
91
+ end
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "net/https"
4
+ require 'net/smtp'
5
+ require "uri"
6
+ require 'fileutils'
7
+ require 'logger'
8
+ require 'ostruct'
9
+
10
+ require 'slack-ruby-client'
11
+ require 'mail'
12
+
13
+ require 'sys_watchdog/core_extensions'
14
+ require 'sys_watchdog/wd_logger'
15
+ require 'sys_watchdog/wd_test'
16
+ require 'sys_watchdog/install'
17
+
18
+ require 'sys_watchdog/main'
19
+ require 'sys_watchdog/notify'
Binary file
@@ -0,0 +1,21 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "sys_watchdog"
3
+ s.version = "0.0.1"
4
+ s.authors = ["Tom Lobato"]
5
+ s.email = "lobato@bettercall.io"
6
+ s.homepage = "http://rubygems.org/gems/sys_watchdog"
7
+ s.summary = "SysWatchdog keeps your UNIX servers green by performing periodic checks and opitionaly actions and notifications"
8
+ s.description = "SysWatchdog keeps your UNIX servers green by performing periodic checks and opitionaly actions and notifications."
9
+ s.licenses = ["MIT"]
10
+ s.platform = Gem::Platform::RUBY
11
+
12
+ s.files = `git ls-files`.split("\n")
13
+ s.test_files = `git ls-files -- test/*`.split("\n")
14
+ s.require_paths = ["lib"]
15
+ s.executables = %w(sys_watchdog)
16
+ s.required_ruby_version = '>= 2.1.0'
17
+
18
+ s.add_dependency("mail", "~> 2.5")
19
+ s.add_dependency("slack-ruby-client", "~> 0.8.1")
20
+ end
21
+
@@ -0,0 +1,26 @@
1
+
2
+ config:
3
+ name: My Website Server
4
+ server_name: main website
5
+
6
+ tests:
7
+ ls_success:
8
+ test_cmd: ls /
9
+
10
+ ls_fail:
11
+ test_cmd: ls /erfe/4ytwrg/qwewqf/34ter
12
+
13
+ site_status_success:
14
+ test_url: https://www.google.com
15
+
16
+ site_status_fail:
17
+ test_url: https://www.6wybwudybsuadbysiudkd.com
18
+
19
+ number_output_success:
20
+ test_cmd: echo 1
21
+ expected_max: 2
22
+
23
+ number_output_fail:
24
+ test_cmd: echo 3
25
+ expected_max: 2
26
+
@@ -0,0 +1,10 @@
1
+ require 'test/unit'
2
+ require 'sys_watchdog'
3
+
4
+ class SysWatchdogTest < Test::Unit::TestCase
5
+ def test_run
6
+ conf_file = File.join File.dirname(__FILE__), 'sys_watchdog_test.yml'
7
+ sw = SysWatchdog.new conf_file: conf_file, log_file: STDOUT
8
+ sw.run once: true
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+
2
+ [Unit]
3
+ Description=SysWatchdog supervisor
4
+
5
+ [Service]
6
+ User=root
7
+ Group=root
8
+ WorkingDirectory=/var/local/sys_watchdog
9
+ Restart=on-failure
10
+ ExecStart=/usr/local/sys_watchdog/sys_watchdog
11
+
@@ -0,0 +1,56 @@
1
+
2
+ config:
3
+ name: My Website Server
4
+ server_name: main website # if not present, `hostname` will be used
5
+
6
+ # Send alerts to Slack (create your slack token in https://github.com/slack-ruby/slack-ruby-client#usage)
7
+ # slack_token: xoxb-...
8
+ # slack_channel: '#alerts'
9
+
10
+ # Send email alerts (via any smtp server: https://sendgrid.com, https://postmarkapp.com/ or your own)
11
+ # smtp_server: smtp.mysite.com
12
+ # smtp_domain: mysite.com
13
+ # mail_from: system@mysite.com
14
+ # mail_to:
15
+ # - myself@mysite.com
16
+
17
+ tests:
18
+ ## General
19
+ boot_time:
20
+ notify_on_change: uptime -s
21
+
22
+ ## URLs
23
+ site_status:
24
+ test_url: https://www.mysite.com
25
+
26
+ # helpdesk_status:
27
+ # test_url: https://helpdesk_status.mysite.com
28
+
29
+ ## Disks
30
+ disk_root:
31
+ test_cmd: "df / | grep -v Filesystem | awk '{print $5}' | sed 's/%//'"
32
+ expected_max: 90
33
+
34
+ # disk_shared_storage:
35
+ # test_cmd: "df /var/www/site/shared | grep -v Filesystem | awk '{print $5}' | sed 's/%//'"
36
+ # expected_max: 90
37
+
38
+ ## Mounts
39
+ # shared_storage:
40
+ # test_cmd: mount | grep /var/www/site/shared
41
+
42
+ ## Services
43
+ # dns_server:
44
+ # test_cmd: host -t A www.mysite.com ns1.mydns.com | tail -1
45
+ # expected_regex: ^www.mysite.com has address
46
+ # restore_cmd: systemctl restart bind9
47
+
48
+ # redis_server:
49
+ # test_cmd: systemctl status redis-server
50
+ # expected_string: Active: active (running)
51
+ # restore_cmd: systemctl restart redis-server
52
+
53
+ ## Processes
54
+ # worker_status:
55
+ # test_cmd: ps aux | grep 'sidekiq 4.2.10 site'
56
+
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sys_watchdog
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tom Lobato
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-06-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mail
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: slack-ruby-client
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.8.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.8.1
41
+ description: SysWatchdog keeps your UNIX servers green by performing periodic checks
42
+ and opitionaly actions and notifications.
43
+ email: lobato@bettercall.io
44
+ executables:
45
+ - sys_watchdog
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - README.md
51
+ - Rakefile
52
+ - bin/sys_watchdog
53
+ - lib/sys_watchdog.rb
54
+ - lib/sys_watchdog/core_extensions.rb
55
+ - lib/sys_watchdog/main.rb
56
+ - lib/sys_watchdog/notify.rb
57
+ - lib/sys_watchdog/setup.rb
58
+ - lib/sys_watchdog/wd_logger.rb
59
+ - lib/sys_watchdog/wd_test.rb
60
+ - screenshots/register-bot.png
61
+ - sys_watchdog.gemspec
62
+ - test/sys_watchdog_test.yml
63
+ - test/test_sys_watchdog.rb
64
+ - util/sys_watchdog.service
65
+ - util/sys_watchdog_sample.yml
66
+ homepage: http://rubygems.org/gems/sys_watchdog
67
+ licenses:
68
+ - MIT
69
+ metadata: {}
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 2.1.0
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 2.5.1
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: SysWatchdog keeps your UNIX servers green by performing periodic checks and
90
+ opitionaly actions and notifications
91
+ test_files:
92
+ - test/sys_watchdog_test.yml
93
+ - test/test_sys_watchdog.rb