pimon 0.1.11 → 0.2.0
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/bin/pimon +26 -19
- data/config/config.ru +11 -3
- data/config/default.yml +7 -13
- data/config/test.yml +6 -12
- data/config/test_broken.yml +0 -1
- data/lib/pimon.rb +2 -69
- data/lib/pimon/app.rb +81 -0
- data/lib/pimon/config.rb +34 -0
- data/lib/pimon/probe.rb +15 -0
- data/lib/pimon/probe/cpu_freq.rb +14 -0
- data/lib/pimon/probe/cpu_usage.rb +11 -8
- data/lib/pimon/probe/disk_usage.rb +11 -8
- data/lib/pimon/probe/memory_usage.rb +15 -10
- data/lib/pimon/probe/swap_usage.rb +16 -10
- data/lib/pimon/probe/system_memory.rb +16 -16
- data/lib/pimon/probe/temperature.rb +11 -13
- data/lib/pimon/probe/uptime.rb +37 -9
- data/lib/pimon/public/index.js +60 -120
- data/lib/pimon/public/normalize.css +427 -0
- data/lib/pimon/public/piecon.js +194 -0
- data/lib/pimon/public/style.css +13 -0
- data/lib/pimon/stats_collector.rb +66 -66
- data/lib/pimon/version.rb +1 -1
- data/lib/pimon/views/index.haml +17 -7
- data/pimon.gemspec +26 -25
- data/spec/{pimon_spec.rb → pimon/app_spec.rb} +9 -6
- data/spec/pimon/config_spec.rb +33 -0
- data/spec/pimon/stats_collector_spec.rb +13 -0
- data/spec/spec_helper.rb +9 -2
- metadata +195 -219
- data/.gitignore +0 -10
- data/.travis.yml +0 -6
- data/Gemfile +0 -20
- data/Gemfile.lock +0 -87
- data/README.md +0 -68
- data/Rakefile +0 -13
- data/WTFPL-LICENSE +0 -13
- data/bin/free.c +0 -12
- data/bin/makefile +0 -2
- data/bin/random.c +0 -21
- data/bin/random.h +0 -1
- data/bin/vmstat.c +0 -12
- data/lib/pimon/hash_extensions.rb +0 -12
- data/lib/pimon/pimon_config.rb +0 -32
- data/lib/pimon/probe/probe.rb +0 -13
- data/lib/pimon/probe/time_check.rb +0 -11
- data/lib/pimon/public/piecon.min.js +0 -5
- data/lib/pimon/stats.rb +0 -25
- data/spec/pimon_config_spec.rb +0 -17
- data/spec/stats_collector_spec.rb +0 -67
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a8ca73f2a9b9b25e474fb1104f343eeba425dbba
|
4
|
+
data.tar.gz: 4fdee4b13a77a452c4023aed9e3701c23764d3f7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b489ca2b46048bd2e5f1b7d8d43ef02807c62212e43622cc84933499bfa83537c59c86f69c7e8cd90fe8672d7f6da4c9ff9f50594509e4ee0b3eb112a1ababce
|
7
|
+
data.tar.gz: 40dd2febfa8e037079beb66839abaaf61d0fe9aba177acb2ec9c41d9cc0d22a851761e66b5fc97658f66894b04c59565727d5c8f90f175024e2415f189eed515
|
data/bin/pimon
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
$: << "#{File.dirname(__FILE__)}/../lib"
|
3
2
|
require 'optparse'
|
4
3
|
|
5
4
|
options = {}
|
@@ -13,20 +12,20 @@ Options:
|
|
13
12
|
'YAML configuration file for pimon') do |config|
|
14
13
|
options[:pimon_config] = config
|
15
14
|
end
|
16
|
-
|
15
|
+
|
17
16
|
opts.on('-d',
|
18
17
|
'--daemonize',
|
19
18
|
'Run Pimon daemonized in the background') do
|
20
19
|
options[:daemonize] = true
|
21
20
|
end
|
22
|
-
|
21
|
+
|
23
22
|
opts.on('-e ENVIRONMENT',
|
24
23
|
'--environment ENVIRONMENT',
|
25
24
|
'Application environment (default: "development", options: "development", "production")',
|
26
25
|
/^development|production$/) do |environment|
|
27
26
|
options[:environment] = environment
|
28
27
|
end
|
29
|
-
|
28
|
+
|
30
29
|
opts.on('-i INTERFACE',
|
31
30
|
'--interface INTERFACE',
|
32
31
|
'Hostname or IP address of the interface to listen on (default: "localhost")') do |interface|
|
@@ -38,16 +37,16 @@ Options:
|
|
38
37
|
'Port to use (default: 3000)') do |port|
|
39
38
|
options[:port] = port
|
40
39
|
end
|
41
|
-
|
40
|
+
|
42
41
|
opts.on('-P PIDFILE',
|
43
42
|
'--pid PIDFILE',
|
44
43
|
'File to store PID (default: /tmp/pimon.pid)') do |pid_file|
|
45
44
|
options[:pid_file] = pid_file
|
46
45
|
end
|
47
|
-
|
46
|
+
|
48
47
|
opts.on('-v',
|
49
48
|
'--version',
|
50
|
-
'Display Pimon version') do |
|
49
|
+
'Display Pimon version') do |_|
|
51
50
|
ARGV[0] = 'version'
|
52
51
|
end
|
53
52
|
end
|
@@ -55,13 +54,13 @@ end
|
|
55
54
|
begin
|
56
55
|
option_parser.parse!
|
57
56
|
if ARGV.empty?
|
58
|
-
puts
|
57
|
+
puts 'error: you must supply an action'
|
59
58
|
puts option_parser.help
|
60
59
|
exit 1
|
61
60
|
end
|
62
|
-
|
61
|
+
|
63
62
|
pid_file = options[:pid_file] || '/tmp/pimon.pid'
|
64
|
-
|
63
|
+
|
65
64
|
case ARGV[0]
|
66
65
|
when 'start'
|
67
66
|
require 'thin'
|
@@ -72,27 +71,35 @@ begin
|
|
72
71
|
ENV['PIMON_CONFIG'] = options[:pimon_config] if options[:pimon_config]
|
73
72
|
puts "Pimon is starting at http://#{interface}:#{port}"
|
74
73
|
puts "Running in #{ENV['RACK_ENV']} mode."
|
75
|
-
|
74
|
+
|
76
75
|
if ENV['PIMON_CONFIG']
|
77
76
|
puts "Using configuration file #{ENV['PIMON_CONFIG']}"
|
78
77
|
else
|
79
|
-
puts
|
78
|
+
puts 'Using default configuration'
|
80
79
|
end
|
81
|
-
|
82
|
-
|
80
|
+
|
81
|
+
server_options = {
|
82
|
+
config: config,
|
83
|
+
daemonize: options[:daemonize],
|
84
|
+
pid: pid_file,
|
85
|
+
Port: port,
|
86
|
+
server: 'thin',
|
87
|
+
Host: interface
|
88
|
+
}
|
89
|
+
|
90
|
+
server = Rack::Server.new(server_options)
|
83
91
|
server.start
|
84
92
|
when 'stop'
|
85
93
|
if File.file?(pid_file)
|
86
|
-
pid =
|
87
|
-
Process.kill(
|
88
|
-
File.delete(pid_file) if File.
|
94
|
+
pid = File.read(pid_file).to_i
|
95
|
+
Process.kill('KILL', pid)
|
96
|
+
File.delete(pid_file) if File.exist?(pid_file)
|
89
97
|
puts 'Pimon stopped...'
|
90
98
|
else
|
91
99
|
puts "Pid file not found at #{pid_file}, please supply a valid pid_file using -p or --pid"
|
92
100
|
end
|
93
101
|
when 'version'
|
94
|
-
|
95
|
-
puts "Pimon version is #{Pimon::VERSION}"
|
102
|
+
puts "Pimon version is #{Gem::Specification.load("#{File.dirname(__FILE__)}/../pimon.gemspec").version}"
|
96
103
|
else
|
97
104
|
STDERR.puts option_parser
|
98
105
|
end
|
data/config/config.ru
CHANGED
@@ -1,4 +1,12 @@
|
|
1
|
-
|
2
|
-
require '
|
1
|
+
if ENV['RACK_ENV'] == 'development'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler'
|
3
4
|
|
4
|
-
|
5
|
+
Bundler.require
|
6
|
+
end
|
7
|
+
|
8
|
+
require_relative '../lib/pimon'
|
9
|
+
|
10
|
+
$PROGRAM_NAME = 'pimon'
|
11
|
+
|
12
|
+
run Pimon::App
|
data/config/default.yml
CHANGED
@@ -1,14 +1,8 @@
|
|
1
|
-
|
2
|
-
cpu:
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
color: '#87CEFA'
|
8
|
-
temp:
|
9
|
-
color: '#FF9B04'
|
10
|
-
swap:
|
11
|
-
color: '#3CB371'
|
1
|
+
colors:
|
2
|
+
cpu: '#D2691E'
|
3
|
+
disk: '#CDC673'
|
4
|
+
mem: '#87CEFA'
|
5
|
+
temp: '#FF9B04'
|
6
|
+
swap: '#3CB371'
|
12
7
|
stats_collector:
|
13
|
-
|
14
|
-
time_period_in_secs: 30
|
8
|
+
time_period_in_secs: 10
|
data/config/test.yml
CHANGED
@@ -1,15 +1,9 @@
|
|
1
|
-
|
2
|
-
cpu:
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
color: '#87CEFA'
|
8
|
-
temp:
|
9
|
-
color: '#FF9B04'
|
10
|
-
swap:
|
11
|
-
color: '#3CB371'
|
1
|
+
colors:
|
2
|
+
cpu: '#D2691E'
|
3
|
+
disk: '#CDC673'
|
4
|
+
mem: '#87CEFA'
|
5
|
+
temp: '#FF9B04'
|
6
|
+
swap: '#3CB371'
|
12
7
|
hostname: 'test_hostname'
|
13
8
|
stats_collector:
|
14
|
-
number_of_stats: 6
|
15
9
|
time_period_in_min: 10
|
data/config/test_broken.yml
CHANGED
data/lib/pimon.rb
CHANGED
@@ -1,71 +1,4 @@
|
|
1
|
-
|
1
|
+
require 'pimon/app'
|
2
2
|
|
3
|
-
|
4
|
-
require 'bundler/setup'
|
5
|
-
Bundler.require(:default, ENV['RACK_ENV'])
|
6
|
-
end
|
7
|
-
require 'eventmachine'
|
8
|
-
require 'json'
|
9
|
-
require 'haml'
|
10
|
-
require 'pimon/pimon_config'
|
11
|
-
require 'pimon/stats_collector'
|
12
|
-
require 'sinatra'
|
13
|
-
require 'sinatra-websocket'
|
14
|
-
|
15
|
-
class Pimon < Sinatra::Base
|
16
|
-
set :public_folder, "#{File.dirname(__FILE__)}/pimon/public"
|
17
|
-
set :views, "#{File.dirname(__FILE__)}/pimon/views"
|
18
|
-
set :sockets, []
|
19
|
-
|
20
|
-
configure :development, :production do
|
21
|
-
filename = "#{File.dirname(__FILE__)}/../config/default.yml"
|
22
|
-
config = PimonConfig.create_new(ENV['PIMON_CONFIG'] || filename)
|
23
|
-
|
24
|
-
EventMachine::next_tick do
|
25
|
-
settings.timer = EventMachine::add_periodic_timer(config.stats[:time_period_in_secs]) do
|
26
|
-
settings.stats_checker.collect_stats
|
27
|
-
@stats = settings.stats_checker.show_stats
|
28
|
-
|
29
|
-
settings.sockets.each{ |s| s.send(@stats) }
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
set :config, config
|
34
|
-
set :stats_checker, StatsCollector.new(config)
|
35
|
-
set :timer, nil
|
36
|
-
|
37
|
-
settings.stats_checker.collect_stats
|
38
|
-
@stats = settings.stats_checker.show_stats
|
39
|
-
end
|
40
|
-
|
41
|
-
configure :test do
|
42
|
-
config = PimonConfig.create_new("#{File.dirname(__FILE__)}/../config/test.yml")
|
43
|
-
|
44
|
-
set :config, config
|
45
|
-
set :stats_checker, StatsCollector.new(config)
|
46
|
-
set :timer, nil
|
47
|
-
end
|
48
|
-
|
49
|
-
get '/' do
|
50
|
-
if !request.websocket?
|
51
|
-
last_update = settings.stats_checker.last_update
|
52
|
-
last_modified(last_update) if ENV['RACK_ENV'] != 'development' && last_update
|
53
|
-
|
54
|
-
haml :index
|
55
|
-
else
|
56
|
-
request.websocket do |ws|
|
57
|
-
ws.onopen do
|
58
|
-
settings.sockets << ws
|
59
|
-
@stats ||= settings.stats_checker.show_stats
|
60
|
-
ws.send(@stats)
|
61
|
-
end
|
62
|
-
ws.onmessage do |msg|
|
63
|
-
puts "message received!! -> #{msg}"
|
64
|
-
end
|
65
|
-
ws.onclose do
|
66
|
-
settings.sockets.delete(ws)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
3
|
+
module Pimon
|
71
4
|
end
|
data/lib/pimon/app.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'json'
|
3
|
+
require 'haml'
|
4
|
+
require 'sinatra'
|
5
|
+
require 'faye/websocket'
|
6
|
+
|
7
|
+
require 'pimon/config'
|
8
|
+
require 'pimon/stats_collector'
|
9
|
+
|
10
|
+
Faye::WebSocket.load_adapter('thin')
|
11
|
+
|
12
|
+
module Pimon
|
13
|
+
class App < Sinatra::Base
|
14
|
+
set :public_folder, "#{File.dirname(__FILE__)}/public"
|
15
|
+
set :views, "#{File.dirname(__FILE__)}/views"
|
16
|
+
set :connected_websockets, []
|
17
|
+
|
18
|
+
configure :development, :production do
|
19
|
+
filename = "#{File.dirname(__FILE__)}/../../config/default.yml"
|
20
|
+
config = Pimon::Config.load(ENV['PIMON_CONFIG'] || filename)
|
21
|
+
|
22
|
+
set :config, config
|
23
|
+
set :stats_collector, Pimon::StatsCollector.new(config)
|
24
|
+
set :timer, nil
|
25
|
+
end
|
26
|
+
|
27
|
+
configure :test do
|
28
|
+
config = Pimon::Config.load("#{File.dirname(__FILE__)}/../../config/test.yml")
|
29
|
+
|
30
|
+
set :config, config
|
31
|
+
set :stats_collector, Pimon::StatsCollector.new(config)
|
32
|
+
set :timer, nil
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(*args, &bk)
|
36
|
+
super
|
37
|
+
start_collecting_stats
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
get '/' do
|
42
|
+
locals = {
|
43
|
+
charts: settings.stats_collector.charts,
|
44
|
+
single_stats: settings.stats_collector.single_stats,
|
45
|
+
hostname: settings.config.hostname
|
46
|
+
}
|
47
|
+
|
48
|
+
haml :index, locals: locals
|
49
|
+
end
|
50
|
+
|
51
|
+
get '/stats' do
|
52
|
+
if Faye::WebSocket.websocket?(request.env)
|
53
|
+
websocket = Faye::WebSocket.new(request.env)
|
54
|
+
|
55
|
+
websocket.on(:open) do
|
56
|
+
settings.connected_websockets << websocket
|
57
|
+
websocket.send(settings.stats_collector.show_stats.to_json)
|
58
|
+
end
|
59
|
+
|
60
|
+
websocket.on(:close) do
|
61
|
+
settings.connected_websockets.delete(websocket)
|
62
|
+
end
|
63
|
+
|
64
|
+
websocket.rack_response
|
65
|
+
else
|
66
|
+
halt 404
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def start_collecting_stats
|
71
|
+
return if settings.test?
|
72
|
+
settings.stats_collector.collect_stats
|
73
|
+
EventMachine.next_tick do
|
74
|
+
settings.timer = EventMachine.add_periodic_timer(settings.config.stats['time_period_in_secs']) do
|
75
|
+
settings.stats_collector.collect_stats
|
76
|
+
settings.connected_websockets.each { |s| s.send(settings.stats_collector.show_stats.to_json) }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/pimon/config.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Pimon
|
4
|
+
class Config
|
5
|
+
attr_reader :config
|
6
|
+
attr_reader :hostname
|
7
|
+
|
8
|
+
def self.load(filename)
|
9
|
+
new(filename)
|
10
|
+
end
|
11
|
+
|
12
|
+
def colors
|
13
|
+
config['colors']
|
14
|
+
end
|
15
|
+
|
16
|
+
def stats
|
17
|
+
config['stats_collector']
|
18
|
+
end
|
19
|
+
|
20
|
+
def hostname
|
21
|
+
@hostname ||= config['hostname'].nil? ? `hostname` : config['hostname']
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def initialize(filename)
|
27
|
+
@config = YAML.load_file(filename)
|
28
|
+
@config.freeze
|
29
|
+
rescue StandardError => e
|
30
|
+
puts "Error while loading config file: #{filename}"
|
31
|
+
raise e
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/pimon/probe.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'pimon/probe/cpu_freq'
|
2
|
+
require 'pimon/probe/cpu_usage'
|
3
|
+
require 'pimon/probe/disk_usage'
|
4
|
+
require 'pimon/probe/memory_usage'
|
5
|
+
require 'pimon/probe/swap_usage'
|
6
|
+
require 'pimon/probe/system_memory'
|
7
|
+
require 'pimon/probe/temperature'
|
8
|
+
require 'pimon/probe/uptime'
|
9
|
+
|
10
|
+
# Monkeypatching OpenStruct to render correct json in a probe sample
|
11
|
+
class OpenStruct
|
12
|
+
def to_json(options)
|
13
|
+
table.to_json(options)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Pimon
|
2
|
+
module Probe
|
3
|
+
class CpuFreq
|
4
|
+
def self.check(date = Time.now)
|
5
|
+
value = `cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq`.to_i / 1000
|
6
|
+
OpenStruct.new(date: date.strftime('%Y-%m-%d %H:%M:%S'), probe_name: 'cpu_freq', value: value, unit: unit)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.unit
|
10
|
+
'Mhz'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -1,11 +1,14 @@
|
|
1
|
-
|
1
|
+
module Pimon
|
2
|
+
module Probe
|
3
|
+
class CpuUsage
|
4
|
+
def self.check(date = Time.now)
|
5
|
+
value = 100 - `vmstat 1 2`.split(/\n/)[3].split(' ')[14].to_i
|
6
|
+
OpenStruct.new(date: date.strftime('%Y-%m-%d %H:%M:%S'), probe_name: 'cpu', value: value, unit: unit)
|
7
|
+
end
|
2
8
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
def self.symbol
|
9
|
-
:cpu
|
9
|
+
def self.unit
|
10
|
+
'%'
|
11
|
+
end
|
12
|
+
end
|
10
13
|
end
|
11
14
|
end
|
@@ -1,11 +1,14 @@
|
|
1
|
-
|
1
|
+
module Pimon
|
2
|
+
module Probe
|
3
|
+
class DiskUsage
|
4
|
+
def self.check(date = Time.now)
|
5
|
+
value = `df`.split(/\n/)[1].split(' ')[4].to_i
|
6
|
+
OpenStruct.new(date: date.strftime('%Y-%m-%d %H:%M:%S'), probe_name: 'disk', value: value, unit: unit)
|
7
|
+
end
|
2
8
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
def self.symbol
|
9
|
-
:disk
|
9
|
+
def self.unit
|
10
|
+
'%'
|
11
|
+
end
|
12
|
+
end
|
10
13
|
end
|
11
14
|
end
|