pimon 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ .idea
2
+ .rspec
3
+ bin/free
4
+ bin/vmstat
5
+ bin/*.o
6
+ config/thin/development_config.yml
7
+ coverage
8
+ log
9
+ pids
10
+ sandbox.sh
@@ -0,0 +1,6 @@
1
+ rvm:
2
+ - 1.9.3
3
+ script: "rake spec"
4
+ notifications:
5
+ email:
6
+ - pedro.carrico@gmail.com
data/Capfile ADDED
@@ -0,0 +1,2 @@
1
+ load 'deploy' if respond_to?(:namespace)
2
+ load 'config/deploy'
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source :rubygems
2
+
3
+ gem 'capistrano'
4
+ gem 'haml'
5
+ gem 'redis'
6
+ gem 'sinatra', :require => 'sinatra/base'
7
+ gem 'thin'
8
+
9
+ gem 'pry', :group => [:development, :test]
10
+
11
+ group :test do
12
+ gem 'mock_redis', '~> 0.5.0'
13
+ gem 'rack-test'
14
+ gem 'rspec', '~> 2.11.0'
15
+ gem 'simplecov', :require => false
16
+ gem 'simplecov-rcov'
17
+ gem 'timecop'
18
+ end
@@ -0,0 +1,77 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ capistrano (2.13.3)
5
+ highline
6
+ net-scp (>= 1.0.0)
7
+ net-sftp (>= 2.0.0)
8
+ net-ssh (>= 2.0.14)
9
+ net-ssh-gateway (>= 1.1.0)
10
+ coderay (1.0.7)
11
+ daemons (1.1.9)
12
+ diff-lcs (1.1.3)
13
+ eventmachine (0.12.10)
14
+ haml (3.1.7)
15
+ highline (1.6.13)
16
+ method_source (0.8)
17
+ mock_redis (0.5.0)
18
+ multi_json (1.0.4)
19
+ net-scp (1.0.4)
20
+ net-ssh (>= 1.99.1)
21
+ net-sftp (2.0.5)
22
+ net-ssh (>= 2.0.9)
23
+ net-ssh (2.5.2)
24
+ net-ssh-gateway (1.1.0)
25
+ net-ssh (>= 1.99.1)
26
+ pry (0.9.10)
27
+ coderay (~> 1.0.5)
28
+ method_source (~> 0.8)
29
+ slop (~> 3.3.1)
30
+ rack (1.4.1)
31
+ rack-protection (1.2.0)
32
+ rack
33
+ rack-test (0.6.1)
34
+ rack (>= 1.0)
35
+ redis (3.0.1)
36
+ rspec (2.11.0)
37
+ rspec-core (~> 2.11.0)
38
+ rspec-expectations (~> 2.11.0)
39
+ rspec-mocks (~> 2.11.0)
40
+ rspec-core (2.11.1)
41
+ rspec-expectations (2.11.2)
42
+ diff-lcs (~> 1.1.3)
43
+ rspec-mocks (2.11.2)
44
+ simplecov (0.6.1)
45
+ multi_json (~> 1.0)
46
+ simplecov-html (~> 0.5.3)
47
+ simplecov-html (0.5.3)
48
+ simplecov-rcov (0.2.3)
49
+ simplecov (>= 0.4.1)
50
+ sinatra (1.3.2)
51
+ rack (~> 1.3, >= 1.3.6)
52
+ rack-protection (~> 1.2)
53
+ tilt (~> 1.3, >= 1.3.3)
54
+ slop (3.3.2)
55
+ thin (1.4.1)
56
+ daemons (>= 1.0.9)
57
+ eventmachine (>= 0.12.6)
58
+ rack (>= 1.0.0)
59
+ tilt (1.3.3)
60
+ timecop (0.3.5)
61
+
62
+ PLATFORMS
63
+ ruby
64
+
65
+ DEPENDENCIES
66
+ capistrano
67
+ haml
68
+ mock_redis (~> 0.5.0)
69
+ pry
70
+ rack-test
71
+ redis
72
+ rspec (~> 2.11.0)
73
+ simplecov
74
+ simplecov-rcov
75
+ sinatra
76
+ thin
77
+ timecop
@@ -0,0 +1,77 @@
1
+ # Pimon
2
+
3
+ [![Build Status](https://secure.travis-ci.org/pedrocarrico/pimon.png)](http://travis-ci.org/pedrocarrico/pimon) [![Dependency Status](https://gemnasium.com/pedrocarrico/pimon.png?travis)](https://gemnasium.com/pedrocarrico/pimon) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/pedrocarrico/pimon)
4
+
5
+ ![Pimon](http://pedrocarrico.net/pimon.jpg "Pimon")
6
+
7
+ ## Description
8
+ Pimon is a simple server monitor designed for the Raspberry Pi.
9
+ It uses redis lists to keep the latest observed statistics and also uses
10
+ highcharts to display some nice charts on your web browser.
11
+
12
+ ## What do I need to get it to work?
13
+ 1. Install redis an configure it to run on a socket on /tmp/redis.sock
14
+ 2. bundle
15
+ 3. bin/pimon start # run the sinatra app
16
+ 4. go to http://localhost:3000 and PROFIT!
17
+ Optionally you may install it as a gem and run it, please check "Installing as a gem" further down.
18
+
19
+ ## Configuration
20
+ 1. basic_auth - enable or disable, configure username and password
21
+ 2. redis - location of the redis socket
22
+ 3. chart - colors for each chart
23
+ 4. queues - redis list names for the series in the charts
24
+ 5. stats - configure number of stats and time period between them
25
+
26
+ ## Deployment
27
+ To deploy on your raspberry pi you just have to have ssh enabled and your keys authorized.
28
+ Then you can deploy with capistrano using:
29
+ ```
30
+ cap deploy:setup
31
+ cap deploy:cold
32
+ ```
33
+
34
+ This will setup your raspberry pi and deploy the application.
35
+ The username and password for the basic_auth in the production environment will be asked in the
36
+ first deploy.
37
+ To start and stop the application you have the usual:
38
+ ```
39
+ cap deploy:start
40
+ cap deploy:stop
41
+ ```
42
+
43
+ ## Running tests
44
+ To run the coverage suite:
45
+ ```
46
+ rake coverage:spec
47
+ ```
48
+ Results will be in coverage/index.html directory.
49
+
50
+ ## Installing as a gem
51
+ ```
52
+ gem install pimon
53
+ ```
54
+ After installation just do _pimon start_ and go to http://localhost:3000 and check your stats
55
+ (This will only work on your Raspberry Pi and perhaps some other linux distros, check the quirks section for more info).
56
+
57
+ ## Quirks
58
+ Pimon uses _vmstat_ and _free_ to collect it's stats from the operating system and these are only
59
+ available on operating systems that have the /proc filesystem.
60
+ So if you want to develop on a Mac you may use the mock implementations that are in the bin directory.
61
+ The mock implementations are programmed in C and mimic the output of _vmstat_ and _free_.
62
+ They just change and generate some random values on the observed stats using /dev/urandom.
63
+ To use them you must first compile them using _make_ and then include the bin directory of this project
64
+ in your $PATH to have them available when you run the sinatra application.
65
+ The temperature stat is only available with the latest Raspbian distro (2012-09-18) on your Raspberry Pi and will (may)
66
+ not work if you're developing on other systems.
67
+
68
+ ## TODO
69
+ 1. Improve disk stats, have a way of having custom mount points
70
+ 2. Capistrano task to reset production basic_auth username and password
71
+ 3. Show uptime
72
+ 4. Change configuration in realtime
73
+ 5. Daemonize if running in production through bin/pimon (usefull for production environments without deploying through
74
+ capistrano)
75
+
76
+ ## Copyright
77
+ Licensed under the [WTFPL](http://en.wikipedia.org/wiki/WTFPL "Do What The Fuck You Want To Public License") license.
@@ -0,0 +1,13 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ desc 'run specs'
4
+ RSpec::Core::RakeTask.new
5
+
6
+ namespace :coverage do
7
+ desc 'run rspec code coverage'
8
+ task :spec do
9
+ ENV['COVERAGE'] = 'on'
10
+ FileUtils.rm_r 'coverage', :force => true
11
+ Rake::Task[:spec].execute
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+ Version 2, December 2004
3
+
4
+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
5
+
6
+ Everyone is permitted to copy and distribute verbatim or modified
7
+ copies of this license document, and changing it is allowed as long
8
+ as the name is changed.
9
+
10
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
+
13
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
@@ -0,0 +1 @@
1
+ /Users/pecarrico/opt/redis/src/redis-cli -s /tmp/redis.sock del pimon_mem del pimon_swap del pimon_cpu del pimon_time del pimon_disk pimon_temp
@@ -0,0 +1,12 @@
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+
4
+ int main (int argc, char *argv[])
5
+ {
6
+ int mem_used = generate_random();
7
+ int swap_used = generate_random();
8
+
9
+ printf(" total used free shared buffers cached\nMem: 215 %d %d 0 4 110\nSwap: 100 %d %d\n", mem_used, 215 - mem_used, swap_used, 100 - swap_used);
10
+
11
+ exit (0);
12
+ }
@@ -0,0 +1,2 @@
1
+ all:
2
+ gcc -c random.c vmstat.c free.c; gcc -o vmstat vmstat.o random.o ;gcc -o free free.o random.o
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ action = ARGV[0]
3
+ environment = ARGV[1]
4
+
5
+ case action
6
+ when "start"
7
+ require 'rack'
8
+
9
+ puts 'Pimon is starting at http://localhost:3000'
10
+ config = "#{File.dirname(__FILE__)}/../config/config.ru"
11
+
12
+ ARGV[1] ? ENV['RACK_ENV'] = environment : ENV['RACK_ENV'] = 'development'
13
+
14
+ puts "Running in #{ENV['RACK_ENV']} mode."
15
+ server = Rack::Server.new(:config => config, :Port => 3000, :server => 'thin')
16
+ server.start
17
+ else
18
+ puts "Usage: pimon start <environment>"
19
+ end
@@ -0,0 +1,21 @@
1
+ #include <stdio.h>
2
+ #include <unistd.h>
3
+ #include <stdlib.h>
4
+ #include <math.h>
5
+
6
+ int generate_random()
7
+ {
8
+ FILE *urandom;
9
+ unsigned int seed;
10
+ int cpu_idle;
11
+
12
+ urandom = fopen ("/dev/urandom", "r");
13
+ if (urandom == NULL) {
14
+ fprintf (stderr, "ERROR: Cannot open /dev/urandom!\n");
15
+ exit (1);
16
+ }
17
+ fread (&seed, sizeof (seed), 1, urandom);
18
+ srand (seed);
19
+
20
+ return ((int) floor (rand() * 100.0 / ((double) RAND_MAX + 1) ) + 1);
21
+ }
@@ -0,0 +1 @@
1
+ extern int generate_random();
@@ -0,0 +1,12 @@
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+ #include "random.h"
4
+
5
+ int main (int argc, char *argv[])
6
+ {
7
+ int cpu_idle = generate_random();
8
+
9
+ printf("procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----\n r b swpd free buff cache si so bi bo in cs us sy id wa\n 1 0 10976 50992 4900 113188 1 2 109 244 101 183 11 10 77 1\n 0 0 10976 50992 4900 113188 0 0 0 0 8366 315 10 5 %d 0\n", cpu_idle);
10
+
11
+ exit (0);
12
+ }
@@ -0,0 +1,4 @@
1
+ require 'sinatra'
2
+ require "#{File.dirname(__FILE__)}/../lib/pimon"
3
+
4
+ run Pimon
@@ -0,0 +1,11 @@
1
+ require 'sinatra'
2
+ require './pimon'
3
+
4
+ root_dir = File.dirname(__FILE__) + "/.."
5
+
6
+ set :environment, :development
7
+ set :root, root_dir
8
+ set :app_file, File.join(root_dir, 'pimon.rb')
9
+ disable :run
10
+
11
+ run Pimon
@@ -0,0 +1,65 @@
1
+ set :application, "pimon"
2
+ set :user, "pi"
3
+
4
+ set :scm, :git
5
+
6
+ set :repository, "git://github.com/pedrocarrico/pimon.git"
7
+
8
+ set :deploy_to, '/home/pi/app/pimon'
9
+ set :deploy_via, :remote_cache # quicker checkouts from github
10
+
11
+ set :domain, 'raspberrypi'
12
+ role :app, domain
13
+ role :web, domain
14
+
15
+ set :runner, user
16
+ set :use_sudo, false
17
+
18
+ after 'deploy:update_code', 'deploy:bundle_install'
19
+
20
+ namespace :deploy do
21
+ task :start, :roles => [:web, :app] do
22
+ run "cd #{deploy_to}/current && nohup thin -C config/thin/config.yml -R config/config.ru start"
23
+ end
24
+
25
+ task :stop, :roles => [:web, :app] do
26
+ run "cd #{deploy_to}/current && nohup thin -C config/thin/config.yml -R config/config.ru stop"
27
+ end
28
+
29
+ task :restart, :roles => [:web, :app] do
30
+ deploy.stop
31
+ deploy.check_basic_auth
32
+ deploy.start
33
+ end
34
+
35
+ task :cold do
36
+ deploy.update
37
+ deploy.check_basic_auth
38
+ deploy.start
39
+ end
40
+
41
+ desc "After deploying check if there's need for a new username/password for the basic_auth"
42
+ task :check_basic_auth, :roles => :app do
43
+ require "yaml"
44
+ set :username, proc { Capistrano::CLI.ui.ask("username : ") }
45
+ set :password, proc { Capistrano::CLI.password_prompt("password : ") }
46
+ set :shared_config, "#{deploy_to}/shared/production.yml"
47
+
48
+ if 'true' == capture("if [ -e #{shared_config} ]; then echo 'true'; fi").strip
49
+ run "cp #{shared_config} #{deploy_to}/current/config/production.yml"
50
+ else
51
+ production_config = YAML::load_file('config/production.yml')
52
+ production_config['basic_auth']['username'] = username
53
+ production_config['basic_auth']['password'] = password
54
+
55
+ put YAML::dump(production_config), shared_config, :mode => 0664
56
+ run "cp #{shared_config} #{deploy_to}/current/config/production.yml"
57
+ puts "DONE"
58
+ end
59
+ end
60
+
61
+ desc "run 'bundle install' to install Bundler's packaged gems for the current deploy"
62
+ task :bundle_install, :roles => :app do
63
+ run "cd #{deploy_to}/current && bundle install --without test development"
64
+ end
65
+ end
@@ -0,0 +1,25 @@
1
+ basic_auth:
2
+ enabled: false
3
+ redis:
4
+ socket: /tmp/redis.sock
5
+ chart:
6
+ cpu:
7
+ color: '#D2691E'
8
+ disk:
9
+ color: '#CDC673'
10
+ mem:
11
+ color: '#87CEFA'
12
+ temp:
13
+ color: '#FF9B04'
14
+ swap:
15
+ color: '#3CB371'
16
+ queues:
17
+ time: pimon_time
18
+ cpu: pimon_cpu
19
+ disk: pimon_disk
20
+ mem: pimon_mem
21
+ swap: pimon_swap
22
+ temp: pimon_temp
23
+ stats_collector:
24
+ number_of_stats: 6
25
+ time_period_in_min: 1
@@ -0,0 +1,27 @@
1
+ basic_auth:
2
+ enabled: true
3
+ username: changed_on_deploy
4
+ password: changed_on_deploy
5
+ redis:
6
+ socket: /tmp/redis.sock
7
+ chart:
8
+ cpu:
9
+ color: '#D2691E'
10
+ disk:
11
+ color: '#CDC673'
12
+ mem:
13
+ color: '#87CEFA'
14
+ temp:
15
+ color: '#FF9B04'
16
+ swap:
17
+ color: '#3CB371'
18
+ queues:
19
+ time: pimon_time
20
+ cpu: pimon_cpu
21
+ disk: pimon_disk
22
+ mem: pimon_mem
23
+ swap: pimon_swap
24
+ temp: pimon_temp
25
+ stats_collector:
26
+ number_of_stats: 12
27
+ time_period_in_min: 5