watchmonkey_cli 1.4

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.
Files changed (34) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +45 -0
  6. data/Rakefile +1 -0
  7. data/VERSION +1 -0
  8. data/bin/watchmonkey +8 -0
  9. data/bin/watchmonkey.sh +14 -0
  10. data/lib/watchmonkey_cli/application/colorize.rb +22 -0
  11. data/lib/watchmonkey_cli/application/configuration.rb +55 -0
  12. data/lib/watchmonkey_cli/application/configuration.tpl +142 -0
  13. data/lib/watchmonkey_cli/application/dispatch.rb +86 -0
  14. data/lib/watchmonkey_cli/application.rb +255 -0
  15. data/lib/watchmonkey_cli/checker.rb +228 -0
  16. data/lib/watchmonkey_cli/checkers/ftp_availability.rb +22 -0
  17. data/lib/watchmonkey_cli/checkers/mysql_replication.rb +57 -0
  18. data/lib/watchmonkey_cli/checkers/ssl_expiration.rb +83 -0
  19. data/lib/watchmonkey_cli/checkers/unix_defaults.rb +40 -0
  20. data/lib/watchmonkey_cli/checkers/unix_df.rb +41 -0
  21. data/lib/watchmonkey_cli/checkers/unix_file_exists.rb +25 -0
  22. data/lib/watchmonkey_cli/checkers/unix_load.rb +30 -0
  23. data/lib/watchmonkey_cli/checkers/unix_mdadm.rb +60 -0
  24. data/lib/watchmonkey_cli/checkers/unix_memory.rb +37 -0
  25. data/lib/watchmonkey_cli/checkers/www_availability.rb +54 -0
  26. data/lib/watchmonkey_cli/helpers.rb +19 -0
  27. data/lib/watchmonkey_cli/hooks/platypus.rb +38 -0
  28. data/lib/watchmonkey_cli/hooks/requeue.rb +106 -0
  29. data/lib/watchmonkey_cli/loopback_connection.rb +36 -0
  30. data/lib/watchmonkey_cli/ssh_connection.rb +50 -0
  31. data/lib/watchmonkey_cli/version.rb +4 -0
  32. data/lib/watchmonkey_cli.rb +41 -0
  33. data/watchmonkey_cli.gemspec +27 -0
  34. metadata +163 -0
@@ -0,0 +1,19 @@
1
+ module WatchmonkeyCli
2
+ module Helpers
3
+ BYTE_UNITS = %W(TiB GiB MiB KiB B).freeze
4
+
5
+ def human_filesize(s)
6
+ s = s.to_f
7
+ i = BYTE_UNITS.length - 1
8
+ while s > 512 && i > 0
9
+ i -= 1
10
+ s /= 1024
11
+ end
12
+ ((s > 9 || s.modulo(1) < 0.1 ? '%d' : '%.1f') % s) + ' ' + BYTE_UNITS[i]
13
+ end
14
+
15
+ def human_number(n)
16
+ n.to_s.reverse.gsub(/...(?=.)/,'\&,').reverse
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,38 @@
1
+ module WatchmonkeyCli
2
+ class Platypus
3
+ def self.hook!(app, opts = {})
4
+ opts = opts.reverse_merge(notifications: true)
5
+ app.instance_eval do
6
+ # send errors via notification center
7
+ hook :result_dump do |robj, args, checker|
8
+ if robj.error?
9
+ robj.messages.each do |m|
10
+ msg = "#{robj.args[0].try(:name) || robj.args[0].presence || "?"}: #{m}"
11
+
12
+ case opts[:notifications]
13
+ when 1
14
+ # makes no sound
15
+ fmsg = msg.gsub('"', '\"').gsub("'", %{'"'"'})
16
+ `osascript -e 'display notification "#{fmsg}" with title "WatchMonkey"'`
17
+ when 2
18
+ # makes a sound
19
+ sync { puts "NOTIFICATION:#{msg}" }
20
+ end
21
+ end
22
+ end
23
+ end if opts[:notifications]
24
+
25
+ hook :wm_work_start, :wm_work_end do
26
+ # mastermind calculation I swear :D (<-- no idea what I did here)
27
+ # sync { puts "PROGRESS:#{((@threads.length-@threads.select{|t| t[:working] }.length.to_d) / @threads.length * 100).to_i}" }
28
+ sync do
29
+ active = @threads.select{|t| t[:working] }.length
30
+ total = @threads.select{|t| t[:working] }.length + @queue.length
31
+ perc = total.zero? ? 100 : (active.to_d / total * 100).to_i
32
+ puts "PROGRESS:#{perc}"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,106 @@
1
+ module WatchmonkeyCli
2
+ class Requeue
3
+ def self.hook!(app)
4
+ app.instance_eval do
5
+ # app options
6
+ @opts[:loop_forever] = true
7
+ @opts[:logfile] = logger_filename # enable logging
8
+
9
+ # module options
10
+ @opts[:default_requeue] = 60
11
+ # @opts[:default_requeue_ftp_availability] = 60
12
+ @opts[:default_requeue_mysql_replication] = 30
13
+ @opts[:default_requeue_ssl_expiration] = 1.hour
14
+ @opts[:default_requeue_unix_defaults] = false
15
+ # @opts[:default_requeue_unix_df] = 60
16
+ # @opts[:default_requeue_unix_file_exists] = 60
17
+ # @opts[:default_requeue_unix_load] = 60
18
+ @opts[:default_requeue_unix_mdadm] = 5.minutes
19
+ # @opts[:default_requeue_unix_memory] = 60
20
+ @opts[:default_requeue_www_availability] = 30
21
+
22
+ # Requeue threads
23
+ @requeue = []
24
+
25
+
26
+ # =================
27
+ # = Status thread =
28
+ # =================
29
+ @platypus_status_thread = Thread.new do
30
+ Thread.current.abort_on_exception = true
31
+ while STDIN.gets
32
+ sync do
33
+ puts "========== STATUS =========="
34
+ puts " Queue: #{@queue.length}"
35
+ puts " Requeue: #{@requeue.length}"
36
+ puts " Workers: #{@threads.select{|t| t[:working] }.length}/#{@threads.length} working (#{@threads.select(&:alive?).length} alive)"
37
+ puts " Threads: #{Thread.list.length}"
38
+ # puts " #{@threads.select(&:alive?).length} alive"
39
+ # puts " #{@threads.select{|t| t.status == "run" }.length} running"
40
+ # puts " #{@threads.select{|t| t.status == "sleep" }.length} sleeping"
41
+ puts " Processed: #{@processed}"
42
+ puts "========== //STATUS =========="
43
+ end
44
+ end
45
+ end
46
+
47
+
48
+ # =========
49
+ # = Hooks =
50
+ # =========
51
+ hook :dequeue do |checker, args|
52
+ opts = args.extract_options!
53
+ retry_in = opts[:every] if opts[:every].is_a?(Fixnum)
54
+ retry_in = @opts[:"default_requeue_#{checker.class.checker_name}"] if retry_in.nil?
55
+ retry_in = @opts[:default_requeue] if retry_in.nil?
56
+ if retry_in
57
+ debug "Requeuing #{checker} in #{retry_in} seconds"
58
+ requeue checker, args + [opts], retry_in
59
+ end
60
+ end
61
+
62
+ hook :wm_shutdown do
63
+ sync do
64
+ debug "[ReQ] #{@requeue.length} items in requeue..."
65
+ unless @requeue.empty?
66
+ @requeue.each(&:kill).each(&:join).select!(&:alive?)
67
+ debug "[ReQ] #{@requeue.length} items in requeue..."
68
+ end
69
+ @requeue_status_thread.try(:kill).try(:join)
70
+ end
71
+ end
72
+
73
+
74
+ # ===========
75
+ # = Methods =
76
+ # ===========
77
+ def requeue checker, args, delay = 10
78
+ return if $wm_runtime_exiting
79
+ sync do
80
+ @requeue << Thread.new {
81
+ Thread.current.abort_on_exception = true
82
+ sleep(delay)
83
+ checker.enqueue(*args)
84
+ sync { @requeue.delete Thread.current }
85
+ }
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+
94
+ __END__
95
+
96
+
97
+ log "checking...", false
98
+ log "PROGRESS:100", false
99
+ $threads.select!(&:alive?)
100
+ GC.start
101
+ sleep 3
102
+ log "sleeping...", false
103
+ 20.times do |i|
104
+ log "PROGRESS:#{(100-(i*3/60.0*100)).round(0)}", false
105
+ sleep 3
106
+ end
@@ -0,0 +1,36 @@
1
+ module WatchmonkeyCli
2
+ class LoopbackConnection
3
+ def initialize(id, opts = {}, &initializer)
4
+ @id = id
5
+ @opts = {}.merge(opts)
6
+ # @mutex = Monitor.new
7
+ initializer.try(:call, @opts)
8
+ end
9
+
10
+ def to_s
11
+ "#<WatchmonkeyCli::LoopbackConnection:#{@id}>"
12
+ end
13
+
14
+ def name
15
+ "lo:#{@id}"
16
+ end
17
+
18
+ def sync &block
19
+ # @mutex.synchronize(&block)
20
+ block.try(:call)
21
+ end
22
+
23
+ def exec cmd, chomp = true
24
+ _stdin, _stdouterr, _thread = Open3.popen2e(cmd)
25
+ _thread.join
26
+ res = _stdouterr.read
27
+ chomp ? res.chomp : res
28
+ ensure
29
+ _stdin.close rescue false
30
+ _stdouterr.close rescue false
31
+ end
32
+
33
+ def close!
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,50 @@
1
+ module WatchmonkeyCli
2
+ class SshConnection
3
+ def initialize(id, opts = {}, &initializer)
4
+ @id = id
5
+
6
+ if opts.is_a?(String)
7
+ u, h = opts.split("@", 2)
8
+ opts = { user: u, host_name: h }
9
+ elsif opts[:host].is_a?(String)
10
+ u, h = opts[:host].split("@", 2)
11
+ opts = opts.merge(user: u, host_name: h)
12
+ opts.delete(:host)
13
+ end
14
+
15
+ # net/ssh options
16
+ @opts = {
17
+ config: false,
18
+ }.merge(opts)
19
+ @mutex = Monitor.new
20
+ initializer.try(:call, @opts)
21
+ end
22
+
23
+ def to_s
24
+ "#<WatchmonkeyCli::SshConnection:#{@id}>"
25
+ end
26
+
27
+ def name
28
+ "ssh:#{@id}"
29
+ end
30
+
31
+ def sync &block
32
+ @mutex.synchronize(&block)
33
+ end
34
+
35
+ def exec cmd, chomp = true
36
+ sync do
37
+ res = connection.exec!(cmd)
38
+ chomp ? res.chomp : res
39
+ end
40
+ end
41
+
42
+ def connection
43
+ sync { @ssh ||= Net::SSH.start(nil, nil, @opts) }
44
+ end
45
+
46
+ def close!
47
+ @ssh.try(:close) rescue false
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,4 @@
1
+ module WatchmonkeyCli
2
+ VERSION = "1.4"
3
+ UPDATE_URL = "https://raw.githubusercontent.com/2called-chaos/watchmonkey_cli/master/VERSION"
4
+ end
@@ -0,0 +1,41 @@
1
+ STDOUT.sync = true
2
+
3
+ # stdlib
4
+ require "benchmark"
5
+ require "fileutils"
6
+ require "thread"
7
+ require "monitor"
8
+ require "optparse"
9
+ require "open3"
10
+ require "net/ftp"
11
+ require 'net/https'
12
+
13
+ # 3rd party
14
+ require "active_support"
15
+ require "active_support/core_ext"
16
+ begin ; require "pry" ; rescue LoadError ; end
17
+ require "httparty"
18
+ require 'net/ssh'
19
+
20
+ # lib
21
+ require "watchmonkey_cli/version"
22
+ require "watchmonkey_cli/loopback_connection"
23
+ require "watchmonkey_cli/ssh_connection"
24
+ require "watchmonkey_cli/helpers"
25
+ require "watchmonkey_cli/checker"
26
+ require "watchmonkey_cli/application/colorize"
27
+ require "watchmonkey_cli/application/configuration"
28
+ require "watchmonkey_cli/application/dispatch"
29
+ require "watchmonkey_cli/application"
30
+
31
+ # require buildin checkers
32
+ require "watchmonkey_cli/checkers/ftp_availability"
33
+ require "watchmonkey_cli/checkers/mysql_replication"
34
+ require "watchmonkey_cli/checkers/ssl_expiration"
35
+ require "watchmonkey_cli/checkers/unix_defaults"
36
+ require "watchmonkey_cli/checkers/unix_df"
37
+ require "watchmonkey_cli/checkers/unix_file_exists"
38
+ require "watchmonkey_cli/checkers/unix_load"
39
+ require "watchmonkey_cli/checkers/unix_mdadm"
40
+ require "watchmonkey_cli/checkers/unix_memory"
41
+ require "watchmonkey_cli/checkers/www_availability"
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'watchmonkey_cli/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "watchmonkey_cli"
8
+ spec.version = WatchmonkeyCli::VERSION
9
+ spec.authors = ["Sven Pachnit"]
10
+ spec.email = ["sven@bmonkeys.net"]
11
+ spec.summary = %q{Watchmonkey CLI - dead simple agentless monitoring via SSH, HTTP, FTP, etc.}
12
+ spec.description = %q{If you want an easy way to monitor services without the need of installing agents let a monkey do the job by polling status information via transport protocols.}
13
+ spec.homepage = "https://github.com/2called-chaos/watchmonkey_cli"
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_dependency "activesupport"
22
+ spec.add_dependency "httparty"
23
+ spec.add_dependency "net-ssh"
24
+ spec.add_development_dependency "pry"
25
+ spec.add_development_dependency "bundler"
26
+ spec.add_development_dependency "rake"
27
+ end
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: watchmonkey_cli
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.4'
5
+ platform: ruby
6
+ authors:
7
+ - Sven Pachnit
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-10-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: httparty
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: net-ssh
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: pry
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: bundler
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: rake
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: If you want an easy way to monitor services without the need of installing
98
+ agents let a monkey do the job by polling status information via transport protocols.
99
+ email:
100
+ - sven@bmonkeys.net
101
+ executables:
102
+ - watchmonkey
103
+ - watchmonkey.sh
104
+ extensions: []
105
+ extra_rdoc_files: []
106
+ files:
107
+ - ".gitignore"
108
+ - Gemfile
109
+ - LICENSE.txt
110
+ - README.md
111
+ - Rakefile
112
+ - VERSION
113
+ - bin/watchmonkey
114
+ - bin/watchmonkey.sh
115
+ - lib/watchmonkey_cli.rb
116
+ - lib/watchmonkey_cli/application.rb
117
+ - lib/watchmonkey_cli/application/colorize.rb
118
+ - lib/watchmonkey_cli/application/configuration.rb
119
+ - lib/watchmonkey_cli/application/configuration.tpl
120
+ - lib/watchmonkey_cli/application/dispatch.rb
121
+ - lib/watchmonkey_cli/checker.rb
122
+ - lib/watchmonkey_cli/checkers/ftp_availability.rb
123
+ - lib/watchmonkey_cli/checkers/mysql_replication.rb
124
+ - lib/watchmonkey_cli/checkers/ssl_expiration.rb
125
+ - lib/watchmonkey_cli/checkers/unix_defaults.rb
126
+ - lib/watchmonkey_cli/checkers/unix_df.rb
127
+ - lib/watchmonkey_cli/checkers/unix_file_exists.rb
128
+ - lib/watchmonkey_cli/checkers/unix_load.rb
129
+ - lib/watchmonkey_cli/checkers/unix_mdadm.rb
130
+ - lib/watchmonkey_cli/checkers/unix_memory.rb
131
+ - lib/watchmonkey_cli/checkers/www_availability.rb
132
+ - lib/watchmonkey_cli/helpers.rb
133
+ - lib/watchmonkey_cli/hooks/platypus.rb
134
+ - lib/watchmonkey_cli/hooks/requeue.rb
135
+ - lib/watchmonkey_cli/loopback_connection.rb
136
+ - lib/watchmonkey_cli/ssh_connection.rb
137
+ - lib/watchmonkey_cli/version.rb
138
+ - watchmonkey_cli.gemspec
139
+ homepage: https://github.com/2called-chaos/watchmonkey_cli
140
+ licenses:
141
+ - MIT
142
+ metadata: {}
143
+ post_install_message:
144
+ rdoc_options: []
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ requirements: []
158
+ rubyforge_project:
159
+ rubygems_version: 2.6.6
160
+ signing_key:
161
+ specification_version: 4
162
+ summary: Watchmonkey CLI - dead simple agentless monitoring via SSH, HTTP, FTP, etc.
163
+ test_files: []