sys_watchdog 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: 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