nutcracker-web 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +63 -0
- data/README.md +56 -0
- data/Rakefile +26 -0
- data/assets/javascripts/application.js +10 -0
- data/assets/javascripts/collections/clusters.js.coffee +4 -0
- data/assets/javascripts/collections/nodes.js.coffee +19 -0
- data/assets/javascripts/models/cluster.js.coffee +16 -0
- data/assets/javascripts/models/node.js.coffee +14 -0
- data/assets/javascripts/models/overview.js.coffee +27 -0
- data/assets/javascripts/nutcracker.js.coffee +20 -0
- data/assets/javascripts/routers/nutcracker_router.js.coffee +29 -0
- data/assets/javascripts/utils/region_manager.js.coffee +12 -0
- data/assets/javascripts/utils/underscore_ext.js.coffee +6 -0
- data/assets/javascripts/vendor/backbone.js +1571 -0
- data/assets/javascripts/vendor/bootstrap.js +2276 -0
- data/assets/javascripts/vendor/google_chart.js.coffee +124 -0
- data/assets/javascripts/vendor/humanize.js +459 -0
- data/assets/javascripts/vendor/jquery.js +8842 -0
- data/assets/javascripts/vendor/underscore.js +1227 -0
- data/assets/javascripts/views/cluster.js.coffee +58 -0
- data/assets/javascripts/views/config.js.coffee +6 -0
- data/assets/javascripts/views/footer.js.coffee +8 -0
- data/assets/javascripts/views/navbar.js.coffee +28 -0
- data/assets/javascripts/views/node.js.coffee +54 -0
- data/assets/javascripts/views/overview.js.coffee +6 -0
- data/assets/stylesheets/application.css +24 -0
- data/assets/stylesheets/bootstrap-responsive.css +1109 -0
- data/assets/stylesheets/bootstrap.css +6158 -0
- data/assets/templates/cluster.jst.eco +87 -0
- data/assets/templates/config.jst.eco +15 -0
- data/assets/templates/footer.jst.eco +1 -0
- data/assets/templates/navbar.jst.eco +55 -0
- data/assets/templates/node.jst.eco +73 -0
- data/assets/templates/overview.jst.eco +32 -0
- data/lib/nutcracker/web/app.rb +51 -0
- data/lib/nutcracker/web/version.rb +5 -0
- data/lib/nutcracker/web.rb +29 -0
- metadata +122 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4de81d42ba8fb87567ef53b49d4d1bf15386731b
|
4
|
+
data.tar.gz: 0798f7badbd2de2a6ab14e9c4730f6bb07a5a87f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3209ed81b50aa9e0acca2783920ff6f1b4cf3dd49ede94833c2b2cda43f84bb20de24c184ce4bb2929e8cf8737522ebe524a2e7c61fc8f6b6da7c688cc583a4d
|
7
|
+
data.tar.gz: 544850254f729c31c9e7e14a9c145197a5ad67fc7aa5de985d3cabb513122ff1ef31e96afae8a780cced35f9c4af933c27b98b15ceff049a003223e44e1ed873
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
backports (3.3.1)
|
5
|
+
coffee-script (2.2.0)
|
6
|
+
coffee-script-source
|
7
|
+
execjs
|
8
|
+
coffee-script-source (1.6.2)
|
9
|
+
daemons (1.1.9)
|
10
|
+
eco (1.0.0)
|
11
|
+
coffee-script
|
12
|
+
eco-source
|
13
|
+
execjs
|
14
|
+
eco-source (1.1.0.rc.1)
|
15
|
+
eventmachine (1.0.3)
|
16
|
+
execjs (1.4.0)
|
17
|
+
multi_json (~> 1.0)
|
18
|
+
haml (4.0.3)
|
19
|
+
tilt
|
20
|
+
hike (1.2.2)
|
21
|
+
json (1.8.0)
|
22
|
+
multi_json (1.7.5)
|
23
|
+
rack (1.5.2)
|
24
|
+
rack-protection (1.5.0)
|
25
|
+
rack
|
26
|
+
rack-test (0.6.2)
|
27
|
+
rack (>= 1.0)
|
28
|
+
sinatra (1.4.2)
|
29
|
+
rack (~> 1.5, >= 1.5.2)
|
30
|
+
rack-protection (~> 1.4)
|
31
|
+
tilt (~> 1.3, >= 1.3.4)
|
32
|
+
sinatra-contrib (1.4.0)
|
33
|
+
backports (>= 2.0)
|
34
|
+
eventmachine
|
35
|
+
rack-protection
|
36
|
+
rack-test
|
37
|
+
sinatra (~> 1.4.2)
|
38
|
+
tilt (~> 1.3)
|
39
|
+
sinatra-reloader (1.0)
|
40
|
+
sinatra-contrib
|
41
|
+
sprockets (2.10.0)
|
42
|
+
hike (~> 1.2)
|
43
|
+
multi_json (~> 1.0)
|
44
|
+
rack (~> 1.0)
|
45
|
+
tilt (~> 1.1, != 1.3.0)
|
46
|
+
thin (1.5.1)
|
47
|
+
daemons (>= 1.0.9)
|
48
|
+
eventmachine (>= 0.12.6)
|
49
|
+
rack (>= 1.0.0)
|
50
|
+
tilt (1.4.1)
|
51
|
+
|
52
|
+
PLATFORMS
|
53
|
+
ruby
|
54
|
+
|
55
|
+
DEPENDENCIES
|
56
|
+
coffee-script
|
57
|
+
eco
|
58
|
+
haml
|
59
|
+
json
|
60
|
+
sinatra
|
61
|
+
sinatra-reloader
|
62
|
+
sprockets
|
63
|
+
thin
|
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
Nutcracker Web
|
2
|
+
=============
|
3
|
+
|
4
|
+
[Nutcracker](https://github.com/kontera-technologies/nutcracker) web interface plugin
|
5
|
+
|
6
|
+
<img src="https://github.com/kontera-technologies/nutcracker-web/raw/master/pics/pic1.png"/></br>
|
7
|
+
<img src="https://github.com/kontera-technologies/nutcracker-web/raw/master/pics/pic2.png"/></br>
|
8
|
+
<img src="https://github.com/kontera-technologies/nutcracker-web/raw/master/pics/pic3.png"/></br>
|
9
|
+
<img src="https://github.com/kontera-technologies/nutcracker-web/raw/master/pics/pic4.png"/></br>
|
10
|
+
|
11
|
+
### Installation
|
12
|
+
add this to your Gemfile
|
13
|
+
```
|
14
|
+
gem 'nutcracker-web'
|
15
|
+
```
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
```
|
19
|
+
$ bundle install
|
20
|
+
```
|
21
|
+
|
22
|
+
### Usage
|
23
|
+
example app
|
24
|
+
```ruby
|
25
|
+
require 'nutcracker'
|
26
|
+
require 'nutcracker/web'
|
27
|
+
|
28
|
+
# Start nutcracker
|
29
|
+
nutcracker = Nutcracker.start(config_file: 'cluster.conf')
|
30
|
+
|
31
|
+
# Start the web service on port 1234 using Webrick
|
32
|
+
nutcracker.use(:graphite, Port: 1234)
|
33
|
+
|
34
|
+
# Sleeping....
|
35
|
+
nutcracker.join
|
36
|
+
```
|
37
|
+
|
38
|
+
`Nutcracker-Web` takes default [Rack](https://github.com/rack/rack) [options](https://github.com/rack/rack/blob/master/lib/rack/server.rb#L187..L199)
|
39
|
+
|
40
|
+
### Custom Webserver
|
41
|
+
default webserver is `Webrick`, to use a different one, like [thin](http://code.macournoyer.com/thin/):
|
42
|
+
|
43
|
+
```
|
44
|
+
$ gem install thin
|
45
|
+
```
|
46
|
+
|
47
|
+
tell `Nutcracker-Web` to use it
|
48
|
+
```ruby
|
49
|
+
require 'nutcracker'
|
50
|
+
require 'nutcracker/web'
|
51
|
+
require 'thin'
|
52
|
+
|
53
|
+
nutcracker = Nutcracker.start(config_file: 'cluster.conf')
|
54
|
+
nutcracker.use(:graphite, Port: 1234, server: :thin)
|
55
|
+
nutcracker.join
|
56
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
$:.unshift File.expand_path '../lib', __FILE__
|
2
|
+
require 'nutcracker/web/version'
|
3
|
+
require 'rake'
|
4
|
+
require 'rubygems/package_task'
|
5
|
+
require "rake/testtask"
|
6
|
+
|
7
|
+
Nutcracker::Web::GemSpec = eval File.read 'nutcracker-web.gemspec'
|
8
|
+
|
9
|
+
task :gem => [:clobber_package]
|
10
|
+
|
11
|
+
Gem::PackageTask.new Nutcracker::Web::GemSpec do |p|
|
12
|
+
p.gem_spec = Nutcracker::Web::GemSpec
|
13
|
+
end
|
14
|
+
|
15
|
+
task :install => [:gem] do
|
16
|
+
sh "gem install pkg/nutcracker"
|
17
|
+
Rake::Task['clobber_package'].execute
|
18
|
+
end
|
19
|
+
|
20
|
+
## Tests stuff
|
21
|
+
task :default => :test
|
22
|
+
|
23
|
+
Rake::TestTask.new(:test) do |t|
|
24
|
+
t.libs << "tests"
|
25
|
+
t.pattern = "tests/**/*_test.rb"
|
26
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Nutcracker.Collections.Nodes extends Backbone.Collection
|
2
|
+
initialize: ->
|
3
|
+
@model = Nutcracker.Models.Node
|
4
|
+
|
5
|
+
add: (nodes)=>
|
6
|
+
@any((obj)-> obj.get("server_url") == nodes[0].server_url) or super
|
7
|
+
|
8
|
+
serverConnections: =>
|
9
|
+
_(@pluck("server_connections")).sum()
|
10
|
+
|
11
|
+
freeMemory: =>
|
12
|
+
_(@pluck("freeMemory")).sum()
|
13
|
+
|
14
|
+
maxMemory: =>
|
15
|
+
_(@pluck("maxMemory")).sum()
|
16
|
+
|
17
|
+
usedMemory: =>
|
18
|
+
_(@pluck("usedMemory")).sum()
|
19
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Nutcracker.Models.Cluster extends Backbone.Model
|
2
|
+
@routeURL: (name)-> "#/clusters/#{name}"
|
3
|
+
|
4
|
+
initialize: ->
|
5
|
+
@set("routeURL",@constructor.routeURL @get 'name')
|
6
|
+
|
7
|
+
set: ( attributes, options ) =>
|
8
|
+
if attributes.nodes? and attributes.nodes not instanceof Nutcracker.Collections.Nodes
|
9
|
+
attributes.nodes = new Nutcracker.Collections.Nodes attributes.nodes
|
10
|
+
|
11
|
+
attributes.nodes?.map (model)=>
|
12
|
+
model.get("clusters").push @
|
13
|
+
model.set("clusters",_(model.get("clusters")).uniq())
|
14
|
+
|
15
|
+
Backbone.Model.prototype.set.call(@, attributes, options)
|
16
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Nutcracker.Models.Node extends Backbone.Model
|
2
|
+
@routeURL: (hostname)->
|
3
|
+
"#/nodes/#{hostname.split(":")[0..1].join(":")}"
|
4
|
+
|
5
|
+
initialize: ->
|
6
|
+
@set 'clusters', []
|
7
|
+
@set 'hostname', @get('server_url')?.replace(/redis:\/\//,'')
|
8
|
+
@set 'maxMemory', @get('info').max_memory
|
9
|
+
@set 'usedMemory', @get('info').used_memory
|
10
|
+
@set 'freeMemory', @get('info').max_memory - @get('info').used_memory
|
11
|
+
@set 'usedMemoryRss', @get('info').used_memory_rss
|
12
|
+
@set 'fragmentation', @get('info').fragmentation
|
13
|
+
@set 'freeMemory', 0 if @get('freeMemory') < 0
|
14
|
+
@set 'routeURL', @constructor.routeURL @get('hostname')
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Nutcracker.Models.Overview extends Backbone.Model
|
2
|
+
initialize: ->
|
3
|
+
clientConnections = _(@get("clusters").pluck("client_connections")).sum()
|
4
|
+
|
5
|
+
serverConnections = 0
|
6
|
+
for nodesCollection in @get("clusters").pluck("nodes")
|
7
|
+
serverConnections += nodesCollection.serverConnections()
|
8
|
+
|
9
|
+
@set "serverConnections", serverConnections
|
10
|
+
@set "clientConnections", clientConnections
|
11
|
+
|
12
|
+
nodes: =>
|
13
|
+
new Backbone.Collection(_(@get("clusters").pluck("nodes")).chain()
|
14
|
+
.pluck("models")
|
15
|
+
.uniq((o)-> o.server_name)
|
16
|
+
.flatten()
|
17
|
+
.value()
|
18
|
+
)
|
19
|
+
|
20
|
+
clusters: =>
|
21
|
+
@get "clusters"
|
22
|
+
|
23
|
+
set: ( attributes, options ) ->
|
24
|
+
if attributes.clusters? and attributes.clusters not instanceof Nutcracker.Collections.Clusters
|
25
|
+
attributes.clusters = new Nutcracker.Collections.Clusters attributes.clusters
|
26
|
+
|
27
|
+
Backbone.Model.prototype.set.call(@, attributes, options)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Namespace
|
2
|
+
window.Nutcracker =
|
3
|
+
Models: {}
|
4
|
+
Collections: {}
|
5
|
+
Views: {}
|
6
|
+
Routers: {}
|
7
|
+
Utils: {}
|
8
|
+
|
9
|
+
initialize: ->
|
10
|
+
model = new Nutcracker.Models.Overview $('#container').data("clusters")
|
11
|
+
Nutcracker.overview = model
|
12
|
+
Nutcracker.screen = new Nutcracker.Utils.RegionManager
|
13
|
+
Nutcracker.screen.navbar new Nutcracker.Views.Navbar {model}
|
14
|
+
Nutcracker.screen.footer new Nutcracker.Views.Footer {model}
|
15
|
+
Nutcracker.router = new Nutcracker.Routers.Overview
|
16
|
+
Backbone.history.start()
|
17
|
+
|
18
|
+
$( document ).ready ->
|
19
|
+
Nutcracker.initialize()
|
20
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Nutcracker.Routers.Overview extends Backbone.Router
|
2
|
+
routes:
|
3
|
+
'' : 'showOverview'
|
4
|
+
'config' : 'showConfig'
|
5
|
+
'clusters/:cluster' : 'showCluster'
|
6
|
+
'nodes/:node' : 'showNode'
|
7
|
+
|
8
|
+
initialize: ->
|
9
|
+
@showOverview()
|
10
|
+
|
11
|
+
showOverview: =>
|
12
|
+
@_show Nutcracker.Views.Overview
|
13
|
+
|
14
|
+
showCluster: (cluster)=>
|
15
|
+
collection = Nutcracker.overview.clusters()
|
16
|
+
model = collection.findWhere name: cluster
|
17
|
+
@_show Nutcracker.Views.Cluster, {model, collection}
|
18
|
+
|
19
|
+
showNode: ( node )=>
|
20
|
+
collection = Nutcracker.overview.nodes()
|
21
|
+
model = collection.findWhere hostname: node
|
22
|
+
@_show Nutcracker.Views.Node, {model,collection}
|
23
|
+
|
24
|
+
showConfig: ()=>
|
25
|
+
@_show Nutcracker.Views.Config
|
26
|
+
|
27
|
+
_show: (view,options = model: Nutcracker.overview) =>
|
28
|
+
Nutcracker.screen.body new view options
|
29
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Nutcracker.Utils.RegionManager
|
2
|
+
constructor: (@navbarID="#navbar",@bodyID="#container",@footerID="#footer",@current={})->
|
3
|
+
navbar: ( view )=> @_render(@navbarID,view)
|
4
|
+
body: ( view )=> @_render(@bodyID, view)
|
5
|
+
footer: ( view )=> @_render(@footerID,view)
|
6
|
+
|
7
|
+
_render:(id,view)=>
|
8
|
+
$(id).html view.render().el
|
9
|
+
@current[id]?.remove
|
10
|
+
@current[id]=view
|
11
|
+
|
12
|
+
|