ziltoid 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 77f322004f95c4414b3364d2f5197ffda8b7dfd4
4
- data.tar.gz: b47765f8f8d5484e7a70e6dd9a94e6b59242aa14
3
+ metadata.gz: dcb27a64e424602045c22c62ffa2d1f272d0113f
4
+ data.tar.gz: c3cd9add836c7460ef1c91feded47f5300b47bff
5
5
  SHA512:
6
- metadata.gz: 3c21b057c2abbe9c46c2b1227bd84ab2e8eea66d8852220e5421b163e98eb97c485ce20e7f9fe812c670e3e98dac881707debb35494062206917164ef6aeedf4
7
- data.tar.gz: 22f3f11346e327a60d813098d71e6ca254117f126390ffecb791df8c0125f8808f9f6a218b6b97aecf6a330b400efd46e22e0baa999c5a5453e4f2217167e4dd
6
+ metadata.gz: 8acc9991ab54b8b22af355f32089e1097ce2e1101c0670b4f9979176560abd155ff56ff61bfd53f8974a01576677af83f668fd23e8def0513048bfb52f9b0958
7
+ data.tar.gz: cd56cf1a67d3b8199df6baeed68cad43c86ddd4c0beb53037b4c9ba7a78f547239e830f15f16eeb968be9daddc039e6bdacdab103a9a43300e3b003c558160a4
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ziltoid
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stéphane Akkaoui
@@ -9,57 +9,50 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-12-22 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: pony
16
- requirement: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - '>='
19
- - !ruby/object:Gem::Version
20
- version: '0'
21
- type: :runtime
22
- prerelease: false
23
- version_requirements: !ruby/object:Gem::Requirement
24
- requirements:
25
- - - '>='
26
- - !ruby/object:Gem::Version
27
- version: '0'
28
- description: Ziltoid, crontab based monitoring system
29
- email: developers@sociabliz.com
12
+ date: 2018-08-06 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: |2
15
+ There are many software applications that aim to watch processes, and keep them alive and clean. Some of them are well known: god, monit, bluepill.
16
+ All have good and bad sides. One of the bad sides is that each alternative is based on a deamon that computes data and then sleeps for a while. Who is monitoring this particular deamon ? What if this process suddenly stops ? Also, you often need root rights to run those tools. On some hosting environments (mainly in shared hosting), this is an issue.
17
+
18
+ Ziltoid is an attempt to solve those issues using the crontab system, which comes with many good sides :
19
+ - it's on every system
20
+ - it launches a task periodically then waits for an amount of time
21
+ - it doesn't need monitoring
22
+ - it can send emails to warn of an error
23
+ - and it can run any script.
24
+ email:
25
+ - sakkaoui@gmail.com
26
+ - vincent.gabou@gmail.com>
30
27
  executables: []
31
28
  extensions: []
32
29
  extra_rdoc_files: []
33
30
  files:
34
- - README.md
35
31
  - lib/ziltoid.rb
36
- - lib/ziltoid/command_parser.rb
37
- - lib/ziltoid/email_notifier.rb
38
- - lib/ziltoid/process.rb
39
- - lib/ziltoid/system.rb
40
- - lib/ziltoid/watcher.rb
41
- - ziltoid.gemspec
42
- homepage: http://github.com/meuble/ziltoid
32
+ homepage: https://github.com/meuble/ziltoid
43
33
  licenses:
44
34
  - WTFPL
45
- metadata: {}
35
+ metadata:
36
+ bug_tracker_uri: https://github.com/meuble/ziltoid/issues
37
+ homepage_uri: https://github.com/meuble/ziltoid
38
+ source_code_uri: https://github.com/meuble/ziltoid
46
39
  post_install_message:
47
40
  rdoc_options: []
48
41
  require_paths:
49
42
  - lib
50
43
  required_ruby_version: !ruby/object:Gem::Requirement
51
44
  requirements:
52
- - - '>='
45
+ - - ">="
53
46
  - !ruby/object:Gem::Version
54
47
  version: '0'
55
48
  required_rubygems_version: !ruby/object:Gem::Requirement
56
49
  requirements:
57
- - - '>='
50
+ - - ">="
58
51
  - !ruby/object:Gem::Version
59
52
  version: '0'
60
53
  requirements: []
61
54
  rubyforge_project:
62
- rubygems_version: 2.4.2
55
+ rubygems_version: 2.5.1
63
56
  signing_key:
64
57
  specification_version: 4
65
58
  summary: Ziltoid, crontab based monitoring system
data/README.md DELETED
@@ -1,107 +0,0 @@
1
- # ziltoid
2
-
3
- Cron based monitoring system.
4
-
5
- There are many softwares that aim to watch processes, keeping them alive and clean. Some of them are well known :
6
- - god (http://godrb.com)
7
- - monit (http://mmonit.com/monit/)
8
- - bluepill (https://github.com/bluepill-rb/bluepill)
9
- - ... (https://www.ruby-toolbox.com/categories/server_monitoring)
10
-
11
- All have good and bad sides.
12
- One of the bad side is that each alternative is based on a deamon that compute data and then sleeps for a while. Who is monitoring this particular deamon ? What if this process suddenly stop ?
13
- Also, you often need root right to run those tools. On some hosting environments (mainly in shared hosting), this is an issue.
14
-
15
- Ziltoid is an attempt to solve those issues using the crontab system. It's on every system, it launches a task periodically then waits for an amount of time, it doesn't need monitoring, it can send emails to warn of a an error, and can run any script.
16
-
17
- ## Usage
18
-
19
- The principle of Ziltoid is to use the crontab system. You need to create a script that monitor your processes and then configure it in your crontab to run as frequently as possible (every minutes) :
20
-
21
- * * * * * /bin/bash -l -c 'ruby /path_to_ziltoid.rb'
22
-
23
- Ziltoid is here to help you build this script.
24
-
25
- ### Process
26
-
27
- It encapsulates a process and everything Ziltoid might need to monitor it :
28
- - start, stop en restart commands
29
- - pid file path
30
- - RAM and CPU limits
31
-
32
- You define one like so :
33
-
34
- ```ruby
35
- Ziltoid::Process.new("Lighty", {
36
- :pid_file => "/home/ror/http/tmp/lighttpd.pid",
37
- :commands => {
38
- :start => "/home/ror/bin/lighty start",
39
- :stop => "/home/ror/bin/lighty stop"
40
- },
41
- :limit => {
42
- :ram => 256,
43
- :cpu => 10
44
- }
45
- })
46
- ```
47
-
48
- Processes are seen as `watchables` by Ziltoid. You can build your own watchable objects and passe them to Ziltoid, as long you can call the following methods on them :
49
- - `start`
50
- - `stop`
51
- - `restart`
52
- - `watch`
53
-
54
- ### Email Notifier
55
-
56
- This is a wrapper to email notifications. Every log message of a level higher than Logger::INFO will be sent by email.
57
-
58
- You can configure a mail like so :
59
-
60
- ```ruby
61
- Ziltoid::EmailNotifier.new(
62
- :via_options => {
63
- :address => 'smtp.ziltoid.com',
64
- :port => '25',
65
- :domain => "ziltoid.com"
66
- },
67
- :subject => "[Balloonz] Ziltoid message",
68
- :to => ['developers@sociabliz.com'],
69
- :from => 'ziltoidd@ziltoid.com'
70
- )
71
- ```
72
-
73
- The `via_options` accept every options supported by the [pony](https://github.com/benprew/pony) library.
74
-
75
- You can build your own notifiers (for IRC, XMPP, BaseCamp, Redmine, ....) as long as it respond to the `send` method. This method receives a `message` parameter which is the message to be sent.
76
-
77
- ### Watcher
78
-
79
- This is the main object of Ziltoid. You can think of it as a container. With this container, you plug in a Logger, a Notifier and as many watchables as you want. Then, you run the commande of your choice.
80
-
81
- Commands are :
82
- - `start`: to start watchable items
83
- - `stop`: to stop watchable items
84
- - `restart`: to restart watchable items
85
- - `watch`: to watch watchable items. IE start them if dead, restart them if of limits
86
-
87
- You can see a sample Ziltoid script in the `exemple` folder.
88
-
89
- ## Drawbacks
90
-
91
- Ziltoid is not yet complet. We are working on other watchables, like disk usage and RAM usage.
92
- We also want to work on a grace system, where we don't count the RAM and CPU at start of process, and where we wait for a certain number of off-limit mesures to restart a process (and allow burst).
93
-
94
- One of the bad point of the crontab system is that it doesn't run under the minute. But we think that if our system can't handle a dead process for a minute, there is an issue somewhere (in replication, sizing, ...).
95
-
96
- ## About Ziltoid
97
-
98
- It comes from Devin Townsen famous album "Ziltoid the omniscient".
99
- Ziltoid is omniscient, watches everything and control everything. Even processes.
100
-
101
- Ziltoid is given to you by [The Social Client](http://www.thesocialclient.com), a digital and CRM consultant agency.
102
-
103
- ## Licencing
104
-
105
- Ziltoid is a [Beerware](http://en.wikipedia.org/wiki/Beerware) and is licensed under the terms of the [WTFPL](http://www.wtfpl.net), see the included WTFPL-LICENSE file.
106
-
107
- If we meet some day, and you think this stuff is worth it, you can buy us a beer in return.
@@ -1,53 +0,0 @@
1
- require 'ostruct'
2
- require 'optparse'
3
-
4
- module Ziltoid
5
- class CommandParser
6
-
7
- ALLOWED_COMMANDS = ["watch", "start", "stop", "restart"]
8
-
9
- # Returns a structure describing the options.
10
- def self.parse(args)
11
- runnable = OpenStruct.new
12
-
13
- helptext = <<-HELP
14
- Available commands are :
15
- watch : watches all processes
16
- start : starts all processes
17
- stop : stops all processes
18
- restart : restarts all processes
19
- HELP
20
-
21
- opt_parser = OptionParser.new do |opts|
22
- # Printing generic help at the top of commands summary
23
- opts.banner = "Usage: ziltoid.rb [options]"
24
- opts.separator ""
25
- opts.separator helptext
26
- opts.separator ""
27
- opts.separator "Common options :"
28
-
29
- # No argument, shows at tail. This will print a commands summary.
30
- opts.on_tail("-h", "--help", "Show this message") do
31
- puts opts
32
- exit
33
- end
34
- end
35
-
36
- # Retrieves all arguments except option-like ones (e.g. '-h' or '-v')
37
- opt_parser.parse!(args)
38
- # Fetches the first argument as the intended command
39
- command = args.shift
40
-
41
- # Making sure the command is valid, otherwise print commands summary
42
- if command && ALLOWED_COMMANDS.include?(command)
43
- runnable.command = command
44
- else
45
- puts opt_parser.help
46
- exit
47
- end
48
-
49
- runnable
50
- end # parse()
51
-
52
- end
53
- end
@@ -1,24 +0,0 @@
1
- require 'pony'
2
-
3
- module Ziltoid
4
- class EmailNotifier
5
- attr_accessor :via_options, :from, :to, :subject
6
-
7
- def initialize(options)
8
- self.via_options = options[:via_options]
9
- self.to = options[:to]
10
- self.from = options[:from]
11
- self.subject = options[:subject]
12
- end
13
-
14
- def send(message)
15
- Pony.mail(
16
- :to => self.to,
17
- :via => :smtp,
18
- :via_options => self.via_options,
19
- :from => self.from,
20
- :subject => self.subject, :body => message
21
- )
22
- end
23
- end
24
- end
@@ -1,106 +0,0 @@
1
- module Ziltoid
2
- class Process
3
- attr_accessor :name, :ram_limit, :cpu_limit, :start_command, :stop_command, :restart_command, :pid_file
4
-
5
- WAIT_TIME_BEFORE_CHECK = 1.0
6
-
7
- def initialize(name, options = {})
8
- self.name = name
9
- self.ram_limit = options[:limit] ? options[:limit][:ram] : nil
10
- self.cpu_limit = options[:limit] ? options[:limit][:cpu] : nil
11
- self.pid_file = options[:pid_file] || "~/.ziltoid/#{name}.pid"
12
-
13
- if options[:commands]
14
- self.start_command = options[:commands][:start] || nil
15
- self.stop_command = options[:commands][:stop] || nil
16
- self.restart_command = options[:commands][:restart] || nil
17
- end
18
- end
19
-
20
- def pid
21
- if self.pid_file && File.exist?(self.pid_file)
22
- str = File.read(pid_file)
23
- str.to_i if str.size > 0
24
- end
25
- end
26
-
27
- def alive?
28
- Ziltoid::System.pid_alive?(self.pid)
29
- end
30
-
31
- def dead?
32
- !alive?
33
- end
34
-
35
- def remove_pid_file
36
- if self.pid_file && File.exist?(self.pid_file)
37
- File.delete(self.pid_file)
38
- end
39
- end
40
-
41
- def above_cpu_limit?(include_children = true)
42
- Ziltoid::System.cpu_usage(self.pid, include_children) > self.cpu_limit.to_f
43
- end
44
-
45
- def above_ram_limit?(include_children = true)
46
- Ziltoid::System.ram_usage(self.pid, include_children) > self.ram_limit.to_i * 1024
47
- end
48
-
49
- def watch!
50
- Watcher.log("Ziltoid is watching process #{self.name}")
51
- if !alive?
52
- Watcher.log("Process #{self.name} is dead", Logger::WARN)
53
- return start!
54
- end
55
- if above_cpu_limit?
56
- Watcher.log("Process #{self.name} is above CPU limit (#{self.cpu_limit.to_f})", Logger::WARN)
57
- return restart!
58
- end
59
- if above_ram_limit?
60
- Watcher.log("Process #{self.name} is above RAM limit (#{self.ram_limit.to_f})", Logger::WARN)
61
- return restart!
62
- end
63
- end
64
-
65
- def start!
66
- return if Ziltoid::System.pid_alive?(self.pid)
67
- Watcher.log("Ziltoid is starting process #{self.name}", Logger::WARN)
68
- remove_pid_file
69
- %x(#{self.start_command})
70
- end
71
-
72
- def stop!
73
- Watcher.log("Ziltoid is stoping process #{self.name}", Logger::WARN)
74
- memoized_pid = self.pid
75
-
76
- if dead?
77
- remove_pid_file
78
- else
79
-
80
- thread = Thread.new do
81
- %x(#{self.stop_command})
82
- sleep(WAIT_TIME_BEFORE_CHECK)
83
- if alive?
84
- %x(kill #{memoized_pid})
85
- sleep(WAIT_TIME_BEFORE_CHECK)
86
- if alive?
87
- %x(kill -9 #{memoized_pid})
88
- sleep(WAIT_TIME_BEFORE_CHECK)
89
- end
90
- end
91
- remove_pid_file if dead?
92
- end.join
93
-
94
- end
95
- end
96
-
97
- def restart!
98
- Watcher.log("Ziltoid is restarting process #{self.name}", Logger::WARN)
99
- alive = self.alive?
100
- return %x(#{self.restart_command}) if alive && self.restart_command
101
- stop! if alive
102
- return start!
103
- end
104
-
105
- end
106
- end
@@ -1,77 +0,0 @@
1
- module Ziltoid
2
-
3
- module System
4
-
5
- # The position of each field in ps output
6
- PS_FIELDS = [:pid, :ppid, :cpu, :ram]
7
-
8
- module_function
9
-
10
- def pid_alive?(pid)
11
- return false if pid.nil?
12
- begin
13
- ::Process.kill(0, pid)
14
- true
15
- rescue Errno::EPERM # no permission, but it is definitely alive
16
- true
17
- rescue Errno::ESRCH
18
- false
19
- end
20
- end
21
-
22
- def ps_aux
23
- # BSD style ps invocation
24
- processes = `ps axo pid,ppid,pcpu,rss`.split("\n")
25
-
26
- processes.inject({}) do |result, process|
27
- info = process.split(/\s+/)
28
- info.delete_if { |p_info| p_info.strip.empty? }
29
- info.map! { |p_info| p_info.gsub(",", ".") }
30
-
31
- info = PS_FIELDS.each_with_index.inject({}) do |info_hash, (field, field_index)|
32
- info_hash[field] = info[field_index]
33
- info_hash
34
- end
35
-
36
- pid = info[:pid].strip.to_i
37
- result[pid] = info
38
- result
39
- end
40
- end
41
-
42
- def cpu_usage(pid, include_children = true)
43
- ps = ps_aux
44
- return unless ps[pid]
45
- cpu_used = ps[pid][:cpu].to_f
46
-
47
- get_children(pid).each do |child_pid|
48
- cpu_used += ps[child_pid][:cpu].to_f if ps[child_pid]
49
- end if include_children
50
-
51
- cpu_used
52
- end
53
-
54
- def ram_usage(pid, include_children = true)
55
- ps = ps_aux
56
- return unless ps[pid]
57
- mem_used = ps[pid][:ram].to_i
58
-
59
- get_children(pid).each do |child_pid|
60
- mem_used += ps[child_pid][:ram].to_i if ps[child_pid]
61
- end if include_children
62
-
63
- mem_used
64
- end
65
-
66
- def get_children(parent_pid)
67
- child_pids = []
68
- ps_aux.each_pair do |_pid, info|
69
- child_pids << info[:pid].to_i if info[:ppid].to_i == parent_pid.to_i
70
- end
71
- grand_children = child_pids.map { |pid| get_children(pid) }.flatten
72
- child_pids.concat grand_children
73
- end
74
-
75
- end
76
-
77
- end
@@ -1,86 +0,0 @@
1
- require "logger"
2
-
3
- module Ziltoid
4
- class Watcher
5
- attr_accessor :watchlist
6
-
7
- def logger
8
- Ziltoid::Watcher.logger
9
- end
10
-
11
- def self.logger
12
- @@logger
13
- end
14
-
15
- def notifiers
16
- Ziltoid::Watcher.notifiers
17
- end
18
-
19
- def self.notifiers
20
- @@notifiers ||= []
21
- return @@notifiers
22
- end
23
-
24
- def self.log(message, level = Logger::INFO)
25
- @@logger ||= Logger.new($stdout)
26
- @@logger.add(level, message)
27
- if level > Logger::INFO
28
- self.notifiers.each do |n|
29
- n.send(message)
30
- end
31
- end
32
- end
33
-
34
- def initialize(options = {})
35
- self.watchlist ||= {}
36
- @@logger = options[:logger] || Logger.new($stdout)
37
- @@logger.progname = options[:progname] || "Ziltoid"
38
- @@logger.level = options[:log_level] || Logger::INFO
39
- @@notifiers = options[:notifiers] if options[:notifiers]
40
- end
41
-
42
- def add(watchable)
43
- self.watchlist[watchable.name] = watchable
44
- end
45
-
46
- def run!(command = :watch)
47
- watchlist.values.each do |watchable|
48
- watchable.send("#{command}!".to_sym)
49
- end
50
- end
51
-
52
- def watch!
53
- Watcher.log("Ziltoid is now on duty : watching all watchables !")
54
- run!(:watch)
55
- end
56
-
57
- def start!
58
- Watcher.log("Ziltoid is now on duty : all watchables starting !")
59
- run!(:start)
60
- end
61
-
62
- def stop!
63
- Watcher.log("Ziltoid is now on duty : all watchables stoping !")
64
- run!(:stop)
65
- end
66
-
67
- def restart!
68
- Watcher.log("Ziltoid is now on duty : all watchables restarting !")
69
- run!(:restart)
70
- end
71
-
72
- def run(command = :watch)
73
- case command
74
- when :watch
75
- watch!
76
- when :start
77
- start!
78
- when :stop
79
- stop!
80
- when :restart
81
- restart!
82
- end
83
- end
84
-
85
- end
86
- end
data/ziltoid.gemspec DELETED
@@ -1,15 +0,0 @@
1
- Gem::Specification.new do |s|
2
- s.name = 'ziltoid'
3
- s.version = '1.0.0'
4
- s.date = '2014-12-22'
5
- s.summary = "Ziltoid, crontab based monitoring system"
6
- s.description = "Ziltoid, crontab based monitoring system"
7
- s.authors = ["Stéphane Akkaoui", "Vincent Gabou"]
8
- s.email = 'developers@sociabliz.com'
9
- s.files = %w(README.md ziltoid.gemspec) + Dir['lib/**/*.rb']
10
- s.add_dependency 'pony'
11
-
12
- s.homepage =
13
- 'http://github.com/meuble/ziltoid'
14
- s.license = 'WTFPL'
15
- end