spoonsix-dognotgod 0.1.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.
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
+