eznemo 0.0.2
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 +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: []
|