spoonsix-dognotgod 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,52 @@
1
+ # dog not god: performance monitoring simplified
2
+
3
+ dog not god is a performance monitoring tool for *nix based servers.
4
+
5
+ ## How does it work
6
+
7
+ There are two components to dog not god.
8
+
9
+ ### Server
10
+
11
+ The server plays two roles. First, it captures performance data, second, it presents it via a web based interface.
12
+
13
+ ### Installation
14
+
15
+ gem install dognotgod
16
+ dognotgod start
17
+
18
+ This will kick off a thin server on port 4567. It will also create the folder ~/.dognotgod and store the sqlite database at this location.
19
+
20
+ ### Client
21
+
22
+ The client sits on the target machine - the machine to be monitored - captures performance data and sends it to the server. Note that this works on the machine acting as the server as well.
23
+
24
+ ### Installation
25
+
26
+ gem install dognotgod-client
27
+
28
+ Add an entry to crontab
29
+
30
+ crontab -e
31
+ */1 * * * * ruby /path/to/gem/client.rb >> /dev/null 2>&1
32
+
33
+ This will run the client every minute.
34
+
35
+ ## License
36
+
37
+ dog not god: performance monitoring simplified
38
+ Copyright (C) 2009 Luis Correa d'Almeida
39
+
40
+ This program is free software; you can redistribute it and/or
41
+ modify it under the terms of the GNU General Public License
42
+ as published by the Free Software Foundation; either version 2
43
+ of the License, or (at your option) any later version.
44
+
45
+ This program is distributed in the hope that it will be useful,
46
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
47
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48
+ GNU General Public License for more details.
49
+
50
+ You should have received a copy of the GNU General Public License
51
+ along with this program; if not, write to the Free Software
52
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@@ -0,0 +1,120 @@
1
+ class Host < Sequel::Model
2
+
3
+ one_to_many :loads
4
+
5
+ unless table_exists?
6
+ set_schema do
7
+ primary_key :id
8
+ text :hostname
9
+ timestamp :created_at
10
+ end
11
+ create_table
12
+ end
13
+
14
+ def last_contacted_on
15
+ self.loads.last.created_at if self.loads.last
16
+ end
17
+
18
+ def distance_to_last_heartbeat_in_seconds
19
+ (Time.now - self.loads.last.created_at) if self.loads.last
20
+ end
21
+
22
+ def loads2(start_time, end_time)
23
+ load = DB.fetch("SELECT AVG(load_5_min) AS load_5_min, AVG(load_10_min) AS load_10_min, AVG(load_15_min) AS load_15_min, grain_5_min FROM loads WHERE host_id = #{self.id} AND grain_5_min >= '#{start_time.to_five_minute_grain_format.to_sql_format}' AND grain_5_min <= '#{end_time.to_five_minute_grain_format.to_sql_format}' GROUP BY grain_5_min;").all
24
+ end
25
+
26
+ def loads_5_min_grain(start_time, end_time)
27
+ load = DB.fetch("SELECT ROUND(AVG(load_5_min),1) AS load_5_min, ROUND(AVG(load_10_min),1) AS load_10_min, ROUND(AVG(load_15_min),1) AS load_15_min, grain_5_min FROM loads WHERE host_id = #{self.id} AND grain_5_min >= '#{start_time.to_five_minute_grain_format.to_sql_format}' AND grain_5_min <= '#{end_time.to_five_minute_grain_format.to_sql_format}' GROUP BY grain_5_min;").all
28
+
29
+ time_range = (start_time..end_time)
30
+
31
+ series = []
32
+ series[0] = []
33
+ series[1] = []
34
+ series[2] = []
35
+ series[3] = []
36
+ time_range.step(300) do |five|
37
+ series[0] << five.to_minute_format
38
+ if load.size > 0 and load[0][:grain_5_min].to_minute_format == five.to_minute_format
39
+ load_for_this_dim = load.shift
40
+ series[1] << load_for_this_dim[:load_5_min]
41
+ series[2] << load_for_this_dim[:load_10_min]
42
+ series[3] << load_for_this_dim[:load_15_min]
43
+ else
44
+ series[1] << -1
45
+ series[2] << -1
46
+ series[3] << -1
47
+ end
48
+ end
49
+
50
+ series
51
+ end
52
+
53
+ #
54
+ # Returns the load for this host in the following format
55
+ #
56
+ # series[0] will contain the time series data. This method will return the data in 15 min intervals.
57
+ # series[1] will contain the 5 min load averages
58
+ # series[2] will contain the 10 min load averages
59
+ # series[3] will contain the 15 min load averages
60
+ #
61
+ # If not data exists for a particular time period, then the value is -1
62
+ #
63
+ def loads_15_min_grain(start_time, end_time)
64
+ load = DB.fetch("SELECT ROUND(AVG(load_5_min),1) AS load_5_min, ROUND(AVG(load_10_min),1) AS load_10_min, ROUND(AVG(load_15_min),1) AS load_15_min, grain_15_min FROM loads WHERE host_id = #{self.id} AND grain_15_min >= '#{start_time.to_fifteen_minute_grain_format.to_sql_format}' AND grain_15_min <= '#{end_time.to_fifteen_minute_grain_format.to_sql_format}' GROUP BY grain_15_min;").all
65
+
66
+ time_range = (start_time..end_time)
67
+
68
+ series = []
69
+ series[0] = []
70
+ series[1] = []
71
+ series[2] = []
72
+ series[3] = []
73
+ time_range.step(900) do |fifteen|
74
+ series[0] << fifteen.to_minute_format
75
+ if load.size > 0 and load[0][:grain_15_min].to_minute_format == fifteen.to_minute_format
76
+ load_for_this_dim = load.shift
77
+ series[1] << load_for_this_dim[:load_5_min]
78
+ series[2] << load_for_this_dim[:load_10_min]
79
+ series[3] << load_for_this_dim[:load_15_min]
80
+ else
81
+ series[1] << -1
82
+ series[2] << -1
83
+ series[3] << -1
84
+ end
85
+ end
86
+
87
+ series
88
+ end
89
+
90
+ def load_5_min
91
+ self.loads.last.load_5_min if self.loads.last
92
+ end
93
+
94
+ def load_10_min
95
+ self.loads.last.load_10_min if self.loads.last
96
+ end
97
+
98
+ def load_15_min
99
+ self.loads.last.load_15_min if self.loads.last
100
+ end
101
+
102
+ def status
103
+ if self.last_contacted_on == nil
104
+ 0
105
+ elsif Time.now - self.last_contacted_on < 90
106
+ 5
107
+ elsif Time.now - self.last_contacted_on < 180
108
+ 3
109
+ elsif Time.now - self.last_contacted_on < 300
110
+ 2
111
+ else
112
+ 1
113
+ end
114
+ end
115
+
116
+ def to_google_params
117
+
118
+ end
119
+
120
+ end
@@ -0,0 +1,28 @@
1
+ class Load < Sequel::Model
2
+
3
+ many_to_one :hosts
4
+
5
+ unless table_exists?
6
+ set_schema do
7
+ primary_key :id
8
+ integer :host_id
9
+ float :load_5_min
10
+ float :load_10_min
11
+ float :load_15_min
12
+ timestamp :created_at
13
+ timestamp :grain_5_min
14
+ timestamp :grain_15_min
15
+ timestamp :grain_30_min
16
+ timestamp :grain_60_min
17
+ end
18
+ create_table
19
+ end
20
+
21
+ before_create do
22
+ self.created_at = Time.now unless self.created_at
23
+ self.grain_5_min = self.created_at.to_five_minute_grain_format
24
+ self.grain_15_min = self.created_at.to_fifteen_minute_grain_format
25
+ self.grain_30_min = self.created_at.to_thirty_minute_grain_format
26
+ self.grain_60_min = self.created_at.to_sixty_minute_grain_format
27
+ end
28
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'thin.rb'
4
+
5
+ DOGNOTGOD_DIR = "#{File.dirname(__FILE__)}/.."
6
+ Dir.chdir(DOGNOTGOD_DIR)
7
+ Thin::Runner.new(["-C", "config/thin.yml", ARGV.shift]).run!
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+
4
+ DOGNOTGOD_DIR = "#{File.dirname(__FILE__)}/.."
5
+ Dir.chdir(DOGNOTGOD_DIR)
6
+ load 'client.rb'
@@ -0,0 +1,64 @@
1
+ require 'rubygems'
2
+ require 'optparse'
3
+ require 'restclient'
4
+
5
+ module DogNotGod
6
+
7
+ class Client
8
+
9
+ def initialize(argv)
10
+ @argv = argv
11
+
12
+ # Default options values
13
+ @options = {
14
+ :server_addr => "127.0.0.1",
15
+ :server_port => "4567",
16
+ :timeout => 5
17
+ }
18
+
19
+ parse!
20
+
21
+ @endpoint = "http://#{@options[:server_addr]}:#{@options[:server_port]}"
22
+ end
23
+
24
+ def parser
25
+ # NOTE: If you add an option here make sure the key in the +options+ hash is the
26
+ # same as the name of the command line option.
27
+ # +option+ keys are used to build the command line to launch other processes,
28
+ # see <tt>lib/thin/command.rb</tt>.
29
+ @parser ||= OptionParser.new do |opts|
30
+ opts.banner = "Usage: dognotgod-client [options]"
31
+ opts.separator ""
32
+ opts.separator "Server options:"
33
+
34
+ opts.on("-a", "--server-addr HOST", "HOST address to call (default: #{@options[:server_addr]})") { |host| @options[:server_addr] = host }
35
+ opts.on("-p", "--server-port PORT", "use PORT (default: #{@options[:server_port]})") { |port| @options[:server_port] = port.to_i }
36
+ #opts.on("-t", "--timeout SECONDS", "timeout after SECONDS (default: #{@options[:timeout]})") { |port| @options[:timeout] = port.to_i }
37
+ opts.separator ""
38
+ end
39
+ end
40
+
41
+ # Parse the options.
42
+ def parse!
43
+ parser.parse! @argv
44
+ @arguments = @argv
45
+ end
46
+
47
+ def run!
48
+ hostname = %x[hostname].split("\n")[0]
49
+ uptime = %x[uptime]
50
+ avgs = uptime.scan(/(\d+\.\d\d)/)
51
+
52
+ begin
53
+ RestClient.post("#{@endpoint}/loads", :load_5_min => avgs[0], :load_10_min => avgs[1], :load_15_min => avgs[2], :hostname => hostname)
54
+ puts "OK"
55
+ rescue
56
+ puts "There was a problem connecting to the server on #{@endpoint}."
57
+ end
58
+ end
59
+
60
+ end
61
+
62
+ end
63
+
64
+ DogNotGod::Client.new(ARGV).run!
@@ -0,0 +1,4 @@
1
+ require 'sinatra'
2
+ Sinatra::Application.default_options.merge!( :run => false, :env => :production )
3
+ require 'server'
4
+ run Sinatra.application
@@ -0,0 +1,11 @@
1
+ ---
2
+ pid: tmp/thin.pid
3
+ log: tmp/thin.log
4
+ rackup: config.ru
5
+ timeout: 10
6
+ port: 4567
7
+ max_conns: 32
8
+ max_persistent_conns: 128
9
+ environment: production
10
+ address: 0.0.0.0
11
+ daemonize: true
@@ -0,0 +1,127 @@
1
+ require 'rubygems'
2
+ require 'sinatra'
3
+
4
+ configure do
5
+ DB_DIR = "#{ENV['HOME']}/.dognotgod"
6
+
7
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/app/models'
8
+ require 'sequel'
9
+ require 'logger'
10
+
11
+ Dir.mkdir(DB_DIR) unless File.exists?(DB_DIR)
12
+ DB = Sequel.connect("sqlite://#{DB_DIR}/dog.db")
13
+ DB.loggers << Logger.new($stdout)
14
+
15
+ # require 'ostruct'
16
+ require 'host'
17
+ require 'load'
18
+ end
19
+
20
+ error do
21
+ e = request.env['sinatra.error']
22
+ puts e.to_s
23
+ puts e.backtrace.join("\n")
24
+ "<pre>" + e + "<br /><br />" + e.backtrace.join("\n")
25
+
26
+ # "Application error"
27
+ end
28
+
29
+ helpers do
30
+ def admin?
31
+ # request.cookies[Blog.admin_cookie_key] == Blog.admin_cookie_value
32
+ end
33
+
34
+ def auth
35
+ stop [ 401, 'Not authorized' ] unless admin?
36
+ end
37
+ end
38
+
39
+ get "/" do
40
+ @hosts = Host.order(:hostname).all
41
+
42
+ @end_now = Time.now.to_fifteen_minute_grain_format
43
+ @start_24h_ago = @end_now - (60*60*24)
44
+ @start_6h_ago = @end_now - (60*60*6)
45
+
46
+ haml :main
47
+ end
48
+
49
+ get "/hosts/:id/loads.xml" do
50
+ @host = Host[params[:id]]
51
+
52
+ @end_time = Time.now.to_five_minute_grain_format # Round to zero seconds on the minute
53
+ @start_time = @end_time - (60*60*24)
54
+ @time_range = (@start_time..@end_time)
55
+
56
+ @loads = @host.loads2(@start_time, @end_time)
57
+
58
+ content_type 'application/xml', :charset => 'utf-8'
59
+ haml :loads_xml, :layout => false
60
+ end
61
+
62
+ post "/loads" do
63
+ host = DB[:hosts].filter(:hostname => params[:hostname]).first
64
+
65
+ # create an entry for a new host if it doesn't exist
66
+ unless host
67
+ DB[:hosts] << {:hostname => params[:hostname]}
68
+ host = DB[:hosts].filter(:hostname => params[:hostname]).first
69
+ end
70
+
71
+ @now = Time.now
72
+
73
+ load = Load.new({:load_5_min => params[:load_5_min], :load_10_min => params[:load_10_min], :load_15_min => params[:load_15_min], :host_id => host[:id], :created_at => @now})
74
+ if load.save
75
+ status(201)
76
+ # response['Location'] = ""
77
+ else
78
+ status(500)
79
+ end
80
+ end
81
+
82
+ get '/stylesheets/style.css' do
83
+ header 'Content-Type' => 'text/css; charset=utf-8'
84
+ sass :style
85
+ end
86
+
87
+
88
+ class Time
89
+
90
+ # Rounds up to the 5 min intervals
91
+ def to_five_minute_grain_format
92
+ offset = (5-(self.min.to_i%5)) * 60
93
+ Time.parse((self + offset).strftime("%Y-%m-%d %H:%M"))
94
+ end
95
+
96
+ # Rounds up to the 10 min intervals
97
+ def to_ten_minute_grain_format
98
+ offset = (10-(self.min.to_i%10)) * 60
99
+ Time.parse((self + offset).strftime("%Y-%m-%d %H:%M"))
100
+ end
101
+
102
+ # Rounds up to the 15 min intervals
103
+ def to_fifteen_minute_grain_format
104
+ offset = (15-(self.min.to_i%15)) * 60
105
+ Time.parse((self + offset).strftime("%Y-%m-%d %H:%M"))
106
+ end
107
+
108
+ # Rounds up to the 30 min intervals
109
+ def to_thirty_minute_grain_format
110
+ offset = (30-(self.min.to_i%30)) * 60
111
+ Time.parse((self + offset).strftime("%Y-%m-%d %H:%M"))
112
+ end
113
+
114
+ # Rounds up to the 60 min intervals
115
+ def to_sixty_minute_grain_format
116
+ offset = (60-(self.min.to_i%60)) * 60
117
+ Time.parse((self + offset).strftime("%Y-%m-%d %H:%M"))
118
+ end
119
+
120
+ def to_minute_format
121
+ self.strftime("%Y-%m-%d %H:%M")
122
+ end
123
+
124
+ def to_sql_format
125
+ self.strftime("%Y-%m-%dT%H:%M")
126
+ end
127
+ end
@@ -0,0 +1,17 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %title dog not god
5
+ %link{:rel=>'stylesheet', :href=>'/stylesheets/style.css', :type => "text/css"}
6
+
7
+ %body
8
+ #header
9
+ #content
10
+ %h1 dog not god
11
+ =yield
12
+ #footer
13
+ %p
14
+ %a{ :href => "http://github.com/luiscorreadalmeida/dog" } dog not god
15
+ is released under the
16
+ %a{ :href => "http://www.gnu.org/licenses/gpl.html" } GPL license
17
+
@@ -0,0 +1,23 @@
1
+ !!! XML
2
+ %chart
3
+ %series
4
+ -i=0
5
+ -@time_range.step(300) do |five|
6
+ %value{:xid => i+=1}
7
+ =five.to_minute_format
8
+ %graphs
9
+ %graph{:gid => "1"}
10
+ -i=0
11
+ -load = Array.new(@loads)
12
+ -@time_range.step(300) do |five|
13
+ %value{:xid => i+=1}= load.shift[:load_5_min] if load.size > 0 and load[0][:grain_5_min].to_minute_format == five.to_minute_format
14
+ %graph{:gid => "2"}
15
+ -i=0
16
+ -load = Array.new(@loads)
17
+ -@time_range.step(300) do |five|
18
+ %value{:xid => i+=1}= load.shift[:load_10_min] if load.size > 0 and load[0][:grain_5_min].to_minute_format == five.to_minute_format
19
+ %graph{:gid => "3"}
20
+ -i=0
21
+ -load = Array.new(@loads)
22
+ -@time_range.step(300) do |five|
23
+ %value{:xid => i+=1}= load.shift[:load_15_min] if load.size > 0 and load[0][:grain_5_min].to_minute_format == five.to_minute_format
@@ -0,0 +1,37 @@
1
+ %h2 Summary
2
+ #summary-section
3
+ %table{:id => "summary-table", :cellspacing => 0, :cellpading => 0}
4
+ %tr
5
+ %th Host
6
+ %th 5 min average
7
+ %th 10 min average
8
+ %th 15 min average
9
+ %th Last heartbeat
10
+ -for host in @hosts
11
+ %tr{:class => "level#{host.status}"}
12
+ %td= host.hostname
13
+ %td= host.load_5_min
14
+ %td= host.load_10_min
15
+ %td= host.load_15_min
16
+ %td= "#{host.distance_to_last_heartbeat_in_seconds.to_i} seconds ago" unless host.status == 0
17
+
18
+
19
+
20
+ %table{:id => "section-table"}
21
+ %tr
22
+ -for host in @hosts
23
+ - series_6h = host.loads_5_min_grain(@start_6h_ago, @end_now)
24
+ - params_for_6h = "cht=lc&chs=350x120&chco=FF0000,00FF00,0000FF&chm=r,DDDDDD,0,0.2,0.21&chxt=x,y&chxr=1,0,5,1&chds=0,5&chl=&chd=t:#{series_6h[1].join(",")}|#{series_6h[2].join(",")}|#{series_6h[3].join(",")}"
25
+ - series_24h = host.loads_15_min_grain(@start_24h_ago, @end_now)
26
+ - params_for_24h = "cht=lc&chs=350x120&chco=FF0000,00FF00,0000FF&chm=r,DDDDDD,0,0.2,0.21&chxt=x,y&chxr=1,0,5,1&chds=0,5&chl=&chd=t:#{series_24h[1].join(",")}|#{series_24h[2].join(",")}|#{series_24h[3].join(",")}"
27
+ %td
28
+ .section
29
+ %h2=host.hostname
30
+ %p== Last heard from on #{host.last_contacted_on}
31
+ %h4 Load averages for the last 24 hours
32
+ %img{ :src => "http://chart.apis.google.com/chart?#{params_for_24h}"}
33
+ %h4 Load averages for the last 6 hours
34
+ %img{ :src => "http://chart.apis.google.com/chart?#{params_for_6h}"}
35
+
36
+
37
+
@@ -0,0 +1,96 @@
1
+ body
2
+ :margin 0
3
+ :padding 0
4
+ :font-family Courier
5
+ :font-size 1.0em
6
+
7
+ a, a:visited
8
+ :color #AAA
9
+
10
+ h1, h2, h3, h4, h5, h6
11
+ :font-family Georgia, serif
12
+ :font-weight normal
13
+ :margin 0px 10px 10px 0px
14
+ :white-space nowrap
15
+
16
+ h1
17
+ :padding-bottom 10px
18
+ :margin-bottom 30px
19
+ :border-bottom double #DDDDDD
20
+
21
+ h2
22
+ :text-decoration underline
23
+
24
+ h4
25
+ :margin 20px 10px 20px 5px
26
+ :padding 5px
27
+ :background-color #EFEFEF
28
+
29
+ #header
30
+ :height 10px
31
+ :background-color #EFEFEF
32
+ :margin-bottom 20px
33
+
34
+ #content
35
+ :margin 0px 30px 10px 20px
36
+
37
+ #summary-section
38
+ :font-size 0.7em
39
+ :margin-bottom 30px
40
+ :padding-bottom 20px
41
+ :border-bottom 1px solid #DDD
42
+
43
+ #summary-table
44
+ :border-top 1px solid #DDD
45
+ :border-left 1px solid #DDD
46
+
47
+
48
+ #summary-table tr.level5
49
+ :background-color #99FF99
50
+
51
+ #summary-table tr.level3
52
+ :background-color #999933
53
+
54
+ #summary-table tr.level1
55
+ :background-color #DD3333
56
+
57
+ #summary-table tr.level0
58
+ :background-color #EFEFEF
59
+
60
+ #summary-table th, #summary-table td
61
+ :border-bottom 1px solid #DDD
62
+ :border-right 1px solid #DDD
63
+
64
+
65
+ #summary-table th
66
+ :background-color #EFEFEF
67
+ :padding-left 15px
68
+ :padding-right 15px
69
+
70
+ #summary-table td
71
+ :padding-left 5px
72
+ :padding-right 5px
73
+
74
+ #section-table
75
+ :border 0px
76
+
77
+ .section
78
+ :margin-bottom 20px
79
+ :margin-left 20px
80
+ :border-right 1px solid #DDD
81
+
82
+ p
83
+ :font-size 0.7em
84
+ :margin 0px
85
+ :padding 0px
86
+
87
+ #footer
88
+ :margin-top 20px
89
+ :clear both
90
+ :padding 10px
91
+ :color #AAA
92
+ :text-align left
93
+ :font-family sans-serif
94
+ :text-align center
95
+
96
+
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spoonsix-dognotgod
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Luis Correa d'Almeida
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-28 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: sinatra
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.9.0.4
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: sequel
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.10.0
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: haml
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 2.0.7
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: thin
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.0.0
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: sqlite3-ruby
57
+ type: :runtime
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 1.2.4
64
+ version:
65
+ - !ruby/object:Gem::Dependency
66
+ name: rest-client
67
+ type: :runtime
68
+ version_requirement:
69
+ version_requirements: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0.9"
74
+ version:
75
+ description: dog not god is a performance monitoring tool.
76
+ email: luis.ca@gmail.com
77
+ executables:
78
+ - dognotgod
79
+ - dognotgod-client
80
+ extensions: []
81
+
82
+ extra_rdoc_files: []
83
+
84
+ files:
85
+ - app/models
86
+ - app/models/host.rb
87
+ - app/models/load.rb
88
+ - config.ru
89
+ - README
90
+ - views/layout.haml
91
+ - views/loads_xml.haml
92
+ - views/main.haml
93
+ - views/style.sass
94
+ - config/thin.yml
95
+ - server.rb
96
+ - client.rb
97
+ has_rdoc: false
98
+ homepage: http://github.com/spoonsix/dognotgod
99
+ post_install_message:
100
+ rdoc_options: []
101
+
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: "0"
109
+ version:
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: "0"
115
+ version:
116
+ requirements: []
117
+
118
+ rubyforge_project:
119
+ rubygems_version: 1.2.0
120
+ signing_key:
121
+ specification_version: 2
122
+ summary: dog not god is a performance monitoring tool.
123
+ test_files: []
124
+