pimon 0.1.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.
@@ -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