server_status 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -10,6 +10,7 @@ gem 'slim'
10
10
  gem 'thin'
11
11
  gem 'settingslogic'
12
12
  gem 'rest-client'
13
+ gem 'daemons'
13
14
 
14
15
  group :development do
15
16
  gem "rspec"
data/Gemfile.lock CHANGED
@@ -49,6 +49,7 @@ PLATFORMS
49
49
 
50
50
  DEPENDENCIES
51
51
  bundler
52
+ daemons
52
53
  jeweler
53
54
  rdoc
54
55
  rest-client
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
data/bin/statusd CHANGED
@@ -1,10 +1,32 @@
1
1
  #!/usr/bin/env ruby
2
- if ARGV.length < 1
3
- puts 'usage: statusd <config file>'
2
+ if ARGV.length < 2
3
+ puts "usage: #{File.basename __FILE__} (run|start|stop) <path_to_config_file>"
4
4
  exit 1
5
5
  end
6
6
 
7
7
  require 'server_status'
8
+ require 'daemons'
8
9
 
9
- set_config ARGV[0]
10
- ServerStatusApp.run!
10
+ set_config ARGV[1]
11
+
12
+ conf_name = File.expand_path ARGV[1]
13
+ pid_name = "#{File.basename __FILE__}.pid"
14
+ pid_path = pid_name
15
+
16
+ case ARGV[0]
17
+ when 'run'
18
+ ServerStatusApp.run!
19
+ when 'start'
20
+ Daemons.daemonize app_name: "#{File.basename __FILE__}"
21
+ ServerStatusApp.run!
22
+ when 'stop'
23
+ pid = 0
24
+ File.open("#{pid_path}", 'r') do |file|
25
+ pid = file.read.to_i
26
+ end
27
+ if pid != 0
28
+ Process.kill('SIGINT', pid)
29
+ end
30
+ else
31
+ puts "usage: #{File.basename __FILE__} (run|start|stop) <path_to_config_file>"
32
+ end
@@ -20,7 +20,12 @@ class ServerStatusApp < Sinatra::Base
20
20
  end
21
21
 
22
22
  get '/servers' do
23
- ServerStatusConfig.servers.keys.to_json
23
+ result = []
24
+ ServerStatusConfig.servers.each do |k, v|
25
+ result.push({name: k, description: v[:description.to_s]})
26
+ end
27
+
28
+ result.to_json
24
29
  end
25
30
 
26
31
  get '/:server/status' do
@@ -25,6 +25,8 @@ class ServerStatusClient
25
25
  response = RestClient.post "#@url#{@default[:url.to_s]}", params.to_json, header
26
26
  end
27
27
  response.code
28
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
29
+ return 503
28
30
  rescue => e
29
31
  e.response.code
30
32
  end
@@ -0,0 +1,90 @@
1
+ (function ($) {
2
+ var ServerModel = Backbone.Model.extend({
3
+ url:function () {
4
+ return '/' + this.get('name') + '/status'
5
+ }
6
+ });
7
+ var ServerCollection = Backbone.Collection.extend({
8
+ model:ServerModel,
9
+ url:'/servers'
10
+ });
11
+ var ItemView = Backbone.View.extend({
12
+ tagName:'tr',
13
+ initialize:function () {
14
+ _.bindAll(this, 'render');
15
+ this.model.bind('change', this.render);
16
+ this.nameTemplate = _.template('<td class="center"><%= name %></td>');
17
+ this.descriptionTemplate = _.template('<td><%= description %></td>');
18
+ this.portTemplate = _.template('<td class="center"><i class="icon-<%= port %>"/></td>');
19
+ this.apiTemplate = _.template('<td class="center"><i class="icon-<%= api %>"/> <span class="label label-<%= label %>"><%= code %></span></td>')
20
+ this.template = _.template('<td class="center"><i class="icon-<%= api %>"/> <span class="label label-<%="></span></td>');
21
+ },
22
+ render:function () {
23
+ var nameMarkup = this.nameTemplate({name:this.model.get('name')});
24
+ var descriptionMarkup = this.descriptionTemplate({description:this.model.get('description')});
25
+ var portMarkup = '<td></td>';
26
+ var apiMarkup = '<td></td>';
27
+ if (this.model.has('is_open')) {
28
+ var isOpen = this.model.get('is_open');
29
+ portMarkup = this.portTemplate({port:isOpen ? 'ok' : 'remove'});
30
+ }
31
+ if (this.model.has('code')) {
32
+ var isLive = this.model.get('code') == 200;
33
+ apiMarkup = this.apiTemplate({api:isLive ? 'ok' : 'remove', code:this.model.get('code'), label:isLive ? 'success' : 'important'});
34
+ }
35
+
36
+ if (this.model.has('is_open') && this.model.has('code')) {
37
+ $(this.el).attr('class', isLive && isOpen ? 'success' : 'error');
38
+ }
39
+ $(this.el).html([nameMarkup, descriptionMarkup, portMarkup, apiMarkup].join());
40
+ return this;
41
+ },
42
+ update:function () {
43
+ this.model.fetch({success:this.render});
44
+ }
45
+ });
46
+ var CollectionView = Backbone.View.extend({
47
+ el:$('table.server tbody'),
48
+ initialize:function () {
49
+ _.bindAll(this, 'render', 'append');
50
+ this.fetched = false;
51
+ this.collection = new ServerCollection();
52
+ this.childViews = {};
53
+ this.collection.bind('add', this.append);
54
+ this.collection.bind('change', this.render);
55
+ this.collection.fetch({
56
+ success:_.bind(this.render, this)
57
+ });
58
+ },
59
+ render:function () {
60
+ var self = this;
61
+ this.collection.models.forEach(_.bind(function (item) {
62
+ var keys = _.keys(self.childViews);
63
+ if (!_.contains(keys, item.get('name'))) {
64
+ self.append(item);
65
+ }
66
+ }, self));
67
+ this.fetched = true;
68
+ },
69
+ append:function (item) {
70
+ var itemView = new ItemView({model:item});
71
+ $(this.el).append(itemView.render().el);
72
+ this.childViews[item.get('name')] = itemView;
73
+ },
74
+ update:function () {
75
+ if (!this.fetched) {
76
+ _.delay(_.bind(this.update, this), 300);
77
+ return;
78
+ }
79
+ this.collection.models.forEach(function (item) {
80
+ item.fetch();
81
+ });
82
+ }
83
+ });
84
+
85
+ var serverView = new CollectionView();
86
+ serverView.update();
87
+ setInterval(function () {
88
+ serverView.update();
89
+ }, 3000);
90
+ })(jQuery);
data/views/index.slim CHANGED
@@ -1,34 +1,7 @@
1
- table.table.table-striped
1
+ table.table.table-striped.server
2
2
  thead
3
- th.span1.center Name
4
- th.span8.center Description
3
+ th.span2.center Name
4
+ th.span6.center Description
5
5
  th.span2.center Connection
6
6
  th.span2.center API Status
7
7
  tbody
8
- - for status in @server_status do
9
- - if status.code.eql? 200
10
- tr.success
11
- td.center = status.name
12
- td = status.description
13
- td.center
14
- - if status.is_open?
15
- i.icon-ok
16
- - else
17
- i.icon-remove
18
- td.center
19
- i.icon-ok
20
- = ' '
21
- span.label.label-success = status.code
22
- - else
23
- tr.error
24
- td.center = status.name
25
- td = status.description
26
- td.center
27
- - if status.is_open?
28
- i.icon-ok
29
- - else
30
- i.icon-remove
31
- td.center
32
- i.icon-remove
33
- = ' '
34
- span.label.label-important = status.code
data/views/layout.slim CHANGED
@@ -36,3 +36,4 @@ html
36
36
  script src='/js/bootstrap.min.js'
37
37
  script src='/js/underscore.min.js'
38
38
  script src='/js/backbone.min.js'
39
+ script src='/js/status.js'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: server_status
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-26 00:00:00.000000000 Z
12
+ date: 2012-11-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sinatra
@@ -91,6 +91,22 @@ dependencies:
91
91
  - - ! '>='
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: daemons
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
94
110
  - !ruby/object:Gem::Dependency
95
111
  name: rspec
96
112
  requirement: !ruby/object:Gem::Requirement
@@ -204,6 +220,7 @@ files:
204
220
  - public/js/bootstrap.js
205
221
  - public/js/bootstrap.min.js
206
222
  - public/js/jquery.min.js
223
+ - public/js/status.js
207
224
  - public/js/underscore.min.js
208
225
  - spec/sample.yml
209
226
  - spec/server_status_spec.rb
@@ -225,7 +242,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
225
242
  version: '0'
226
243
  segments:
227
244
  - 0
228
- hash: 1420205633251635331
245
+ hash: 1518391760238564387
229
246
  required_rubygems_version: !ruby/object:Gem::Requirement
230
247
  none: false
231
248
  requirements: