eznemo 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +112 -0
- data/bin/eznemo +13 -0
- data/eznemo.gemspec +23 -0
- data/lib/eznemo/config.rb +18 -0
- data/lib/eznemo/datastore.rb +15 -0
- data/lib/eznemo/monitor/ping.rb +115 -0
- data/lib/eznemo/monitor.rb +50 -0
- data/lib/eznemo/mysql.rb +85 -0
- data/lib/eznemo/version.rb +5 -0
- data/lib/eznemo.rb +53 -0
- metadata +84 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 14365e43e3184d7e2a7d8978b8a8c4fe76d57596
|
4
|
+
data.tar.gz: 2d7ca0b5a7fe4f8acdc9b2fa0a87020497b85317
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a75aa47b2879c4e018d1613f07db5f604831985d5e3b9b0d2f629ad0e78ad7049305af989f8c9aceb3dda1a5f7b3c31619bfe76eb40e822c9373abef741fe149
|
7
|
+
data.tar.gz: 452ce77dbd521523f4c7ecd417a6554f1c7d55026b4dcd53cfdc5d0ce855e4a6d9292c27c9767a826546d83b769d7c5d10356064dbeb937f72d9a12904dfa231
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Ken J.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
# eznemo
|
2
|
+
|
3
|
+
A Ruby gem. It's a simple monitoring engine and stores results in a database. Runs on EventMachine.
|
4
|
+
|
5
|
+
For reports and alerts, analyze the results in the database.
|
6
|
+
|
7
|
+
## Requirements
|
8
|
+
|
9
|
+
- Ruby 2.0.0 <=
|
10
|
+
- eventmachine 1.0 <=
|
11
|
+
|
12
|
+
### Data Storage Options
|
13
|
+
|
14
|
+
Currently, only support MySQL, so you'll also need the following gem:
|
15
|
+
|
16
|
+
- mysql2 0.4 <=
|
17
|
+
|
18
|
+
## Getting Started
|
19
|
+
|
20
|
+
### Install
|
21
|
+
|
22
|
+
```
|
23
|
+
$ gem install eznemo
|
24
|
+
```
|
25
|
+
|
26
|
+
### Use
|
27
|
+
|
28
|
+
```
|
29
|
+
$ eznemo start -c config.yml
|
30
|
+
```
|
31
|
+
|
32
|
+
### Examples
|
33
|
+
|
34
|
+
Config file.
|
35
|
+
|
36
|
+
```yaml
|
37
|
+
---
|
38
|
+
:datastore:
|
39
|
+
:type: :mysql
|
40
|
+
:options:
|
41
|
+
:host: '127.0.0.1'
|
42
|
+
:username: 'user'
|
43
|
+
:password: 'paSsw0rd'
|
44
|
+
:database: 'eznemo'
|
45
|
+
:checks:
|
46
|
+
:tags:
|
47
|
+
- tag1
|
48
|
+
- tag2
|
49
|
+
:monitor:
|
50
|
+
:path: '/bin/ping'
|
51
|
+
:min_interval: 10
|
52
|
+
:timeout: 5
|
53
|
+
:cmd_opts: '-s 102'
|
54
|
+
```
|
55
|
+
|
56
|
+
## Data Structure
|
57
|
+
|
58
|
+
### Checks
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
{
|
62
|
+
id: 123, # auto_increment
|
63
|
+
name: 'Check name',
|
64
|
+
hostname: '192.168.0.111',
|
65
|
+
interval: 60, # frequecy this check is run in seconds
|
66
|
+
type: 'ping', # or other monitor plugin name
|
67
|
+
state: true, # true means active
|
68
|
+
tags: '["tag1", "tag2"]',
|
69
|
+
options: '-S 192.168.0.11'
|
70
|
+
}
|
71
|
+
```
|
72
|
+
|
73
|
+
### Results
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
{
|
77
|
+
check_id: 123, # from checks
|
78
|
+
timestamp: '2016-04-01 10:00:00 -07:00',
|
79
|
+
status: true, # true means OK
|
80
|
+
response_ms: 0.012, # in milliseconds
|
81
|
+
status_desc: 'OK' # short description of the result
|
82
|
+
}
|
83
|
+
```
|
84
|
+
|
85
|
+
### MySQL
|
86
|
+
|
87
|
+
```sql
|
88
|
+
CREATE TABLE `checks` (
|
89
|
+
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
90
|
+
`name` varchar(255) NOT NULL DEFAULT '',
|
91
|
+
`hostname` varchar(255) NOT NULL DEFAULT '',
|
92
|
+
`interval` int(11) NOT NULL,
|
93
|
+
`type` varchar(255) NOT NULL DEFAULT '',
|
94
|
+
`state` tinyint(1) NOT NULL,
|
95
|
+
`tags` text,
|
96
|
+
`options` text,
|
97
|
+
PRIMARY KEY (`id`)
|
98
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
99
|
+
|
100
|
+
CREATE TABLE `results` (
|
101
|
+
`id` int(11) NOT NULL AUTO_INCREMENT,
|
102
|
+
`check_id` int(11) NOT NULL,
|
103
|
+
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
104
|
+
`status` tinyint(1) NOT NULL,
|
105
|
+
`response_ms` float NOT NULL DEFAULT '0',
|
106
|
+
`status_desc` varchar(255) NOT NULL DEFAULT '',
|
107
|
+
PRIMARY KEY (`id`),
|
108
|
+
KEY `check_id` (`check_id`),
|
109
|
+
KEY `timestamp` (`timestamp`),
|
110
|
+
KEY `status` (`status`)
|
111
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
112
|
+
```
|
data/bin/eznemo
ADDED
data/eznemo.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
|
2
|
+
require 'eznemo/version'
|
3
|
+
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'eznemo'
|
7
|
+
s.version = EzNemo::Version
|
8
|
+
s.authors = ['Ken J.']
|
9
|
+
s.email = ['kenjij@gmail.com']
|
10
|
+
s.description = %q{Simple network monitoring}
|
11
|
+
s.summary = %q{Simple network monitoring implemented with Ruby.}
|
12
|
+
s.homepage = 'https://github.com/kenjij/eznemo'
|
13
|
+
s.license = 'MIT'
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split($/)
|
16
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
s.require_paths = ['lib']
|
18
|
+
|
19
|
+
s.required_ruby_version = '>= 2.0.0'
|
20
|
+
|
21
|
+
s.add_runtime_dependency 'kajiki', '~> 1.1'
|
22
|
+
s.add_runtime_dependency 'eventmachine', '~> 1.0'
|
23
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module EzNemo
|
4
|
+
|
5
|
+
# Load YAML config file
|
6
|
+
# @param path [String] config file
|
7
|
+
# @return [Object] config; a shared instance
|
8
|
+
def self.load_config(path)
|
9
|
+
raise 'config file missing' unless path
|
10
|
+
@config ||= YAML.load_file(path)
|
11
|
+
end
|
12
|
+
|
13
|
+
# see #self.load_config
|
14
|
+
def self.config
|
15
|
+
@config
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module EzNemo
|
2
|
+
|
3
|
+
# ICMP ping plugin
|
4
|
+
class Ping
|
5
|
+
|
6
|
+
DEFAULT_MIN_INTERVAL = 10
|
7
|
+
DEFAULT_TIMEOUT = 5
|
8
|
+
|
9
|
+
attr_reader :monitor
|
10
|
+
attr_reader :config
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
os = RbConfig::CONFIG['host_os']
|
14
|
+
case
|
15
|
+
when os.include?('darwin')
|
16
|
+
@os = 'bsd'
|
17
|
+
when os.include?('linux')
|
18
|
+
@os = 'linux'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Gets called by Monitor at regisration
|
23
|
+
# @return [Symbol]
|
24
|
+
def name
|
25
|
+
return :ping
|
26
|
+
end
|
27
|
+
|
28
|
+
# Gets called by Monitor after regisration
|
29
|
+
# @param mon [Object] parent Monitor object
|
30
|
+
def registered(mon)
|
31
|
+
@monitor = mon
|
32
|
+
@config = EzNemo.config[:monitor][:ping] if EzNemo.config[:monitor]
|
33
|
+
@config ||= {}
|
34
|
+
@config[:path] ||= 'ping'
|
35
|
+
@config[:min_interval] ||= DEFAULT_MIN_INTERVAL
|
36
|
+
@config[:timeout] ||= DEFAULT_TIMEOUT
|
37
|
+
end
|
38
|
+
|
39
|
+
# Add a check using this plugin
|
40
|
+
# @param check [Hash]
|
41
|
+
def add_check(check)
|
42
|
+
min = config[:min_interval]
|
43
|
+
check[:interval] = min if check[:interval] < min
|
44
|
+
EM.add_periodic_timer(check[:interval]) do
|
45
|
+
self.send("#{@os}_ping", check)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def linux_ping(check)
|
50
|
+
result = {
|
51
|
+
timestamp: Time.now,
|
52
|
+
check_id: check[:id]
|
53
|
+
}
|
54
|
+
path = config[:path]
|
55
|
+
timeout = config[:timeout]
|
56
|
+
options = "#{config[:cmd_opts]} #{check[:options]}"
|
57
|
+
hostname = check[:hostname]
|
58
|
+
cmd = "#{path} -c 1 -nqW #{timeout} #{options} #{hostname}"
|
59
|
+
EM.system(cmd) do |output, status|
|
60
|
+
case status.exitstatus
|
61
|
+
when 0
|
62
|
+
expr = /=\s*([0-9\.]+)/
|
63
|
+
expr =~ output
|
64
|
+
result[:status] = 1
|
65
|
+
result[:response_ms] = $1.to_f
|
66
|
+
result[:status_desc] = 'OK'
|
67
|
+
when 1
|
68
|
+
result[:status] = 0
|
69
|
+
result[:response_ms] = 0
|
70
|
+
result[:status_desc] = 'NG'
|
71
|
+
else
|
72
|
+
output = 'see log' if output.nil? || output.size == 0
|
73
|
+
result[:status] = 0
|
74
|
+
result[:response_ms] = 0
|
75
|
+
result[:status_desc] = "ERROR: #{output}".chomp
|
76
|
+
end
|
77
|
+
monitor.report(result)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def bsd_ping(check)
|
82
|
+
result = {
|
83
|
+
timestamp: Time.now,
|
84
|
+
check_id: check[:id]
|
85
|
+
}
|
86
|
+
timeout = config[:timeout] * 1000
|
87
|
+
options = "#{config[:cmd_opts]} #{check[:option]}"
|
88
|
+
hostname = check[:hostname]
|
89
|
+
cmd = "#{path} -c 1 -nqW #{timeout} #{options} #{hostname}"
|
90
|
+
EM.system(cmd) do |output, status|
|
91
|
+
case status.exitstatus
|
92
|
+
when 0
|
93
|
+
expr = /=\s*([0-9\.]+)/
|
94
|
+
expr =~ output
|
95
|
+
result[:status] = 1
|
96
|
+
result[:response_ms] = $1.to_f
|
97
|
+
result[:status_desc] = 'OK'
|
98
|
+
when 2
|
99
|
+
result[:status] = 0
|
100
|
+
result[:response_ms] = 0
|
101
|
+
result[:status_desc] = 'NG'
|
102
|
+
else
|
103
|
+
result[:status] = 0
|
104
|
+
result[:response_ms] = 0
|
105
|
+
result[:status_desc] = "ERROR: #{output}".chomp
|
106
|
+
end
|
107
|
+
monitor.report(result)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
monitor.register(Ping.new)
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module EzNemo
|
4
|
+
|
5
|
+
# The shared Monitor instance
|
6
|
+
# @return [EzNemo::Monitor]
|
7
|
+
def self.monitor
|
8
|
+
@monitor ||= Monitor.new
|
9
|
+
end
|
10
|
+
|
11
|
+
# Maintains an array of all the monitor plugins
|
12
|
+
class Monitor
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@plugins = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
# Registers a plugin; usually called by the plugin itself
|
19
|
+
# @param plugin [Object]
|
20
|
+
def register(plugin)
|
21
|
+
@plugins[plugin.name] = plugin
|
22
|
+
plugin.registered(self)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Starts check loops in the reactor
|
26
|
+
# @param checks [Array<Hash, ...>]
|
27
|
+
def start_checks(checks)
|
28
|
+
cfg_tags = EzNemo.config[:checks][:tags]
|
29
|
+
i = 0
|
30
|
+
checks.each do |c|
|
31
|
+
if cfg_tags
|
32
|
+
c[:tags] ? tags = JSON.parse(c[:tags]) : tags = []
|
33
|
+
next if (cfg_tags & tags).empty?
|
34
|
+
end
|
35
|
+
p = @plugins[c[:type].to_sym]
|
36
|
+
p.add_check(c)
|
37
|
+
i += 1
|
38
|
+
end
|
39
|
+
puts "#{i} checks activated."
|
40
|
+
end
|
41
|
+
|
42
|
+
# Report result; usually called by the plugin
|
43
|
+
# @param result [Hash] :check_id, :timestamp, :status, :response_ms, :status_desc
|
44
|
+
def report(result)
|
45
|
+
EzNemo.datastore.store_result(result)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
data/lib/eznemo/mysql.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'mysql2/em'
|
2
|
+
|
3
|
+
|
4
|
+
module EzNemo
|
5
|
+
|
6
|
+
# Defines DataStorage class for MySQL
|
7
|
+
module StorageAdapter
|
8
|
+
|
9
|
+
# Number of records it queues up before writing
|
10
|
+
QUEUE_SIZE = 20
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@results = []
|
14
|
+
@opts = EzNemo.config[:datastore][:options]
|
15
|
+
@opts[:flags] = Mysql2::Client::MULTI_STATEMENTS
|
16
|
+
end
|
17
|
+
|
18
|
+
# Creates and returns new instance of {Mysql2::Client}
|
19
|
+
# @return [Mysql2::Client]
|
20
|
+
def database
|
21
|
+
Mysql2::Client.new(@opts)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Creates and returns new instance of {Mysql2::EM::Client}
|
25
|
+
# @return [Mysql2::EM::Client]
|
26
|
+
def emdatabase
|
27
|
+
Mysql2::EM::Client.new(@opts)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns all active checks
|
31
|
+
# @return [Array<Hash, ...>]
|
32
|
+
def checks
|
33
|
+
q = 'SELECT * FROM checks WHERE state = true'
|
34
|
+
database.query(q, {symbolize_keys: true, cast_booleans: true})
|
35
|
+
end
|
36
|
+
|
37
|
+
# Stores a result; into queue first
|
38
|
+
# @param result [Hash] (see {EzNemo::Monitor#report})
|
39
|
+
def store_result(result)
|
40
|
+
@results << result
|
41
|
+
if @results.count >= QUEUE_SIZE
|
42
|
+
write_results
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Write the results to storage from queue
|
47
|
+
# @param sync [Boolean] use EM (async) if false
|
48
|
+
# @return [Object] Mysql2 client instance
|
49
|
+
def write_results(sync = false)
|
50
|
+
return nil if @results.empty?
|
51
|
+
sync ? db = database : db = emdatabase
|
52
|
+
stmt = ''
|
53
|
+
@results.each do |r|
|
54
|
+
r[:status_desc] = db.escape(r[:status_desc])
|
55
|
+
cols = r.keys.join(',')
|
56
|
+
vals = r.values.join("','")
|
57
|
+
stmt << "INSERT INTO results (#{cols}) VALUES ('#{vals}');"
|
58
|
+
end
|
59
|
+
@results.clear
|
60
|
+
if sync
|
61
|
+
db.query(stmt)
|
62
|
+
else
|
63
|
+
defer = db.query(stmt)
|
64
|
+
defer.callback do
|
65
|
+
end
|
66
|
+
defer.errback do |r|
|
67
|
+
puts r.message
|
68
|
+
db.close if db.ping
|
69
|
+
end
|
70
|
+
end
|
71
|
+
db
|
72
|
+
end
|
73
|
+
|
74
|
+
# Flush queue to storage
|
75
|
+
def flush
|
76
|
+
if write_results(true)
|
77
|
+
puts "Flushed."
|
78
|
+
else
|
79
|
+
puts "Nothing to flush."
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
data/lib/eznemo.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'eznemo/config'
|
2
|
+
require 'eznemo/version'
|
3
|
+
require 'eventmachine'
|
4
|
+
|
5
|
+
module EzNemo
|
6
|
+
|
7
|
+
# EventMachine reactor
|
8
|
+
class Reactor
|
9
|
+
|
10
|
+
# Start reactor
|
11
|
+
# @param opts [Hash] from command line
|
12
|
+
# @return [Object]
|
13
|
+
def self.run!(opts)
|
14
|
+
r = Reactor.new(opts)
|
15
|
+
r.run
|
16
|
+
r
|
17
|
+
end
|
18
|
+
|
19
|
+
# Usually called by #self.run!
|
20
|
+
def initialize(opts)
|
21
|
+
c = EzNemo.load_config(opts[:config])
|
22
|
+
|
23
|
+
require "eznemo/#{c[:datastore][:type].to_s}"
|
24
|
+
require 'eznemo/datastore'
|
25
|
+
|
26
|
+
require 'eznemo/monitor'
|
27
|
+
require 'eznemo/monitor/ping'
|
28
|
+
end
|
29
|
+
|
30
|
+
# Usually called by #self.run!
|
31
|
+
def run
|
32
|
+
ds = EzNemo.datastore
|
33
|
+
|
34
|
+
Signal.trap('INT') do
|
35
|
+
puts 'Interrupted. Flushing...'
|
36
|
+
ds.flush
|
37
|
+
exit
|
38
|
+
end
|
39
|
+
|
40
|
+
Signal.trap('SIGTERM') do
|
41
|
+
puts 'Stopping...'
|
42
|
+
ds.flush
|
43
|
+
exit
|
44
|
+
end
|
45
|
+
|
46
|
+
EM.run do
|
47
|
+
EzNemo.monitor.start_checks(ds.checks)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: eznemo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ken J.
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-04-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: kajiki
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: eventmachine
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.0'
|
41
|
+
description: Simple network monitoring
|
42
|
+
email:
|
43
|
+
- kenjij@gmail.com
|
44
|
+
executables:
|
45
|
+
- eznemo
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- LICENSE
|
50
|
+
- README.md
|
51
|
+
- bin/eznemo
|
52
|
+
- eznemo.gemspec
|
53
|
+
- lib/eznemo.rb
|
54
|
+
- lib/eznemo/config.rb
|
55
|
+
- lib/eznemo/datastore.rb
|
56
|
+
- lib/eznemo/monitor.rb
|
57
|
+
- lib/eznemo/monitor/ping.rb
|
58
|
+
- lib/eznemo/mysql.rb
|
59
|
+
- lib/eznemo/version.rb
|
60
|
+
homepage: https://github.com/kenjij/eznemo
|
61
|
+
licenses:
|
62
|
+
- MIT
|
63
|
+
metadata: {}
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options: []
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 2.0.0
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 2.4.3
|
81
|
+
signing_key:
|
82
|
+
specification_version: 4
|
83
|
+
summary: Simple network monitoring implemented with Ruby.
|
84
|
+
test_files: []
|