nutcracker-web 0.0.1

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.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +10 -0
  3. data/Gemfile.lock +63 -0
  4. data/README.md +56 -0
  5. data/Rakefile +26 -0
  6. data/assets/javascripts/application.js +10 -0
  7. data/assets/javascripts/collections/clusters.js.coffee +4 -0
  8. data/assets/javascripts/collections/nodes.js.coffee +19 -0
  9. data/assets/javascripts/models/cluster.js.coffee +16 -0
  10. data/assets/javascripts/models/node.js.coffee +14 -0
  11. data/assets/javascripts/models/overview.js.coffee +27 -0
  12. data/assets/javascripts/nutcracker.js.coffee +20 -0
  13. data/assets/javascripts/routers/nutcracker_router.js.coffee +29 -0
  14. data/assets/javascripts/utils/region_manager.js.coffee +12 -0
  15. data/assets/javascripts/utils/underscore_ext.js.coffee +6 -0
  16. data/assets/javascripts/vendor/backbone.js +1571 -0
  17. data/assets/javascripts/vendor/bootstrap.js +2276 -0
  18. data/assets/javascripts/vendor/google_chart.js.coffee +124 -0
  19. data/assets/javascripts/vendor/humanize.js +459 -0
  20. data/assets/javascripts/vendor/jquery.js +8842 -0
  21. data/assets/javascripts/vendor/underscore.js +1227 -0
  22. data/assets/javascripts/views/cluster.js.coffee +58 -0
  23. data/assets/javascripts/views/config.js.coffee +6 -0
  24. data/assets/javascripts/views/footer.js.coffee +8 -0
  25. data/assets/javascripts/views/navbar.js.coffee +28 -0
  26. data/assets/javascripts/views/node.js.coffee +54 -0
  27. data/assets/javascripts/views/overview.js.coffee +6 -0
  28. data/assets/stylesheets/application.css +24 -0
  29. data/assets/stylesheets/bootstrap-responsive.css +1109 -0
  30. data/assets/stylesheets/bootstrap.css +6158 -0
  31. data/assets/templates/cluster.jst.eco +87 -0
  32. data/assets/templates/config.jst.eco +15 -0
  33. data/assets/templates/footer.jst.eco +1 -0
  34. data/assets/templates/navbar.jst.eco +55 -0
  35. data/assets/templates/node.jst.eco +73 -0
  36. data/assets/templates/overview.jst.eco +32 -0
  37. data/lib/nutcracker/web/app.rb +51 -0
  38. data/lib/nutcracker/web/version.rb +5 -0
  39. data/lib/nutcracker/web.rb +29 -0
  40. 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
@@ -0,0 +1,10 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'sinatra'
4
+ gem 'sinatra-reloader'
5
+ gem 'haml'
6
+ gem 'thin'
7
+ gem 'sprockets'
8
+ gem 'coffee-script'
9
+ gem 'eco'
10
+ gem 'json'
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,10 @@
1
+ //= require ./vendor/jquery
2
+ //= require ./vendor/underscore
3
+ //= require ./vendor/backbone
4
+ //= require ./vendor/bootstrap
5
+ //= require ./vendor/humanize
6
+ //= require_tree ./../templates
7
+ //= require nutcracker
8
+ //= require_tree .
9
+ //= require_self
10
+
@@ -0,0 +1,4 @@
1
+ class Nutcracker.Collections.Clusters extends Backbone.Collection
2
+ initialize: ( object ) =>
3
+ @model = Nutcracker.Models.Cluster
4
+
@@ -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
+
@@ -0,0 +1,6 @@
1
+ _.prototype.sum = ->
2
+ _.reduce(@_wrapped,((acc,num)-> acc+num),0)
3
+
4
+ _.prototype.average = ->
5
+ @sum() / parseFloat @_wrapped.length
6
+