amnesia 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 38e6536f54a144f1ca9cfbbf47725f278176cb392ec7a3c7e6e8e1782631a9ce
4
+ data.tar.gz: f4d82c911b950cabfbd87d93e79df8d53a4d7fe938089a7416a331ff2544b22d
5
+ SHA512:
6
+ metadata.gz: 5c4e0420c9dc06c9a5133b43ab5a8dee2b9557f5985970955a85e3e2d33da8752d25dc9b73819283abc0c82a72cb9b57d78e89bba67db6737202d786ef68192f
7
+ data.tar.gz: e05dbdfda49c7ba87c088fd63516c485b7e8271d3953b18951f83320d3c7e6b6b54faffef1f3d0c5206b26e11de6b3913e8f6018f18350a7a1f85a6e198dd382
data/README.markdown CHANGED
@@ -8,7 +8,7 @@ Hopefully with Amnesia you'll know exactly whats happening with memory when it c
8
8
 
9
9
  ## Why?
10
10
 
11
- Its always nice to have some statistics to see how everything is performing within your stack. Memcached seems to be a mystery box that people don't really pay alot of attention to.
11
+ Its always nice to have some statistics to see how everything is performing within your stack. Memcached seems to be a mystery box that people don't really pay a lot of attention to.
12
12
 
13
13
  Amnesia tells you how your application is performing, when it misses, when it is running sweet, when you're about to run out of memcached and (perhaps) fall down in a screaming heap.
14
14
 
@@ -16,7 +16,7 @@ Amnesia tells you how your application is performing, when it misses, when it is
16
16
 
17
17
  All stats are since each memcached instance was restarted
18
18
 
19
- Available as a cumluative result of all your memcached instances, or single instances alone:
19
+ Available as a cumulative result of all your memcached instances, or single instances alone:
20
20
 
21
21
  * Cache hits and misses
22
22
  * Reads and writes
@@ -35,16 +35,61 @@ Available for single instances only:
35
35
 
36
36
  gem install amnesia
37
37
 
38
- ### How to run it alongside your application
38
+ ### How to run it alongside your Rack application
39
39
 
40
40
  "config.ru":
41
41
 
42
42
  require 'amnesia'
43
- use Amnesia::Application, :hosts => ["localhost:11211"]
44
- run Sinatra::Application
43
+ rack_app = Rack::Builder.app do
44
+ map "/amnesia" do
45
+ run Amnesia::Application.new
46
+ end
47
+ run YourSinatra::Application
48
+ end
49
+ run rack_app
50
+
51
+ ### How to run it alongside your Rails application
52
+
53
+ "Gemfile":
54
+
55
+ gem 'amnesia', '>=1.0.2'
56
+
57
+
58
+ "config/routes.rb":
59
+
60
+ mount Amnesia::Application.new => "/amnesia"
61
+
45
62
 
46
63
  ### Then, cruise on over to `your-host.tld/amnesia`
47
64
 
65
+
66
+ ## Configuration options
67
+
68
+ ### Hosts
69
+ Amnesia will work automagically if you drop it on a Heroku powered app, likewise—for a "standard" memcache host (running on localhost:11211, the default.).
70
+
71
+ When you need to specify where your memcache hosts can be found, you can either set an environment variable:
72
+
73
+ ENV["MEMCACHE_SERVERS"] = ['localhost:11211']
74
+
75
+ or alternately, you can set it within your `config.ru`:
76
+
77
+ use Amnesia::Application, hosts: ["mc1.yourapp.com:11211", "mc2.yourapp.com:11211"]
78
+
79
+ ### Authentication
80
+
81
+ When you want to keep your Amnesia data private, you can set an environment variable that will enable http basic authentication:
82
+
83
+ ENV["AMNESIA_CREDS"] = ben:schwarz
84
+
85
+ in your shell, you might do it like this:
86
+
87
+ export AMNESIA_CREDS=ben:schwarz
88
+
89
+ on heroku, like this:
90
+
91
+ heroku config:add AMNESIA_CREDS=ben:schwarz
92
+
48
93
  ## Potential issues
49
94
 
50
95
  * Hosts are listed as "Inactive" or "Not Responding"
@@ -58,7 +103,7 @@ Within my slices, I punched a hole through `iptables`
58
103
 
59
104
  You won't need to do this unless you've explicitly blocked ports to your server. (When in doubt, block nearly everything)
60
105
 
61
- Let me know if you come accross any issues using Github messaging.
106
+ Let me know if you come across any issues using Github messaging.
62
107
 
63
108
  ## Something missing?
64
109
 
@@ -0,0 +1,12 @@
1
+ module Amnesia
2
+ module Authentication
3
+ def self.included app
4
+ app.class_eval do
5
+ use Rack::Auth::Basic, "Amnesia" do |username, password|
6
+ user, pass = ENV['AMNESIA_CREDS'].split(':')
7
+ username == user and password == pass
8
+ end if ENV['AMNESIA_CREDS']
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,44 @@
1
+ module Amnesia
2
+ module Helpers
3
+ def self.included app
4
+ app.helpers do
5
+ include HelperMethods
6
+ end
7
+ end
8
+
9
+ module HelperMethods
10
+ SIZE_UNITS = %w[ Bytes KB MB GB TB PB EB ]
11
+
12
+ def graph_url(*data)
13
+ url "/pie?d="+data.join(',')
14
+ end
15
+
16
+ # https://github.com/rails/rails/blob/fbe335cfe09bf0949edfdf0c4b251f4d081bd5d7/activesupport/lib/active_support/number_helper/number_to_human_size_converter.rb
17
+ def number_to_human_size(number, precision=1)
18
+ number, base = Float(number), 1024
19
+
20
+ if number.to_i < base
21
+ "%d %s" % [ number.to_i, SIZE_UNITS.first ]
22
+ else
23
+ max = SIZE_UNITS.size - 1
24
+ exp = (Math.log(number) / Math.log(base)).to_i
25
+ exp = max if exp > max # avoid overflow for the highest unit
26
+ result = number / (base**exp)
27
+ "%.#{precision}f %s" % [ result, SIZE_UNITS[exp] ]
28
+ end
29
+ end
30
+
31
+ def alive_hosts
32
+ @alive_hosts ||= @hosts.select(&:alive?)
33
+ end
34
+
35
+ %w[ bytes limit_maxbytes get_hits get_misses cmd_get cmd_set ].each do |stat|
36
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
37
+ def #{stat}_sum
38
+ alive_hosts.map(&:#{stat}).sum
39
+ end
40
+ RUBY
41
+ end
42
+ end
43
+ end
44
+ end
data/lib/amnesia/host.rb CHANGED
@@ -1,29 +1,65 @@
1
- class Host
2
- attr_reader :address
3
-
4
- def initialize(address)
5
- @address = address
6
- end
7
-
8
- def alive?
9
- return true if connection.stats
10
- rescue MemCache::MemCacheError
11
- return false
12
- end
13
-
14
- def method_missing(method, *args)
15
- return stats[method.to_s] if stats.has_key? method.to_s
16
- end
17
-
18
- def stats
19
- connection.stats[connection.stats.keys.first]
20
- rescue MemCache::MemCacheError
21
- return {}
22
- end
23
-
24
- private
25
-
26
- def connection
27
- @connection ||= MemCache.new(@address)
1
+ require 'dalli'
2
+
3
+ module Amnesia
4
+ class Host
5
+ FLOAT_STATS = %w[ rusage_user rusage_system ]
6
+ STRING_STATS = %w[ version libevent ]
7
+ DEFAULT_PORT = 11_211
8
+
9
+ def self.normalize_address address
10
+ return "#{address}:#{DEFAULT_PORT}" unless address.include? ":"
11
+
12
+ address
13
+ end
14
+
15
+ def initialize(address)
16
+ @address = self.class.normalize_address address
17
+ end
18
+
19
+ def alive?
20
+ return true if connection.stats[@address]
21
+ rescue Dalli::DalliError
22
+ return false
23
+ end
24
+
25
+ def method_missing(method, *args)
26
+ if stats.has_key? method.to_s
27
+ value = stats[method.to_s]
28
+ if FLOAT_STATS.include? method
29
+ Float(value)
30
+ elsif STRING_STATS.include? method
31
+ value
32
+ else
33
+ Integer(value)
34
+ end
35
+ else
36
+ super
37
+ end
38
+ end
39
+
40
+ def stats
41
+ stats_val = connection.stats
42
+ stats_val.values.first || {}
43
+ end
44
+
45
+ def address
46
+ @address || @connection.servers.join(', ')
47
+ end
48
+
49
+ private
50
+
51
+ def connection
52
+ @connection ||= connect(@address)
53
+ end
54
+
55
+ def connect(address = nil)
56
+ if defined?(EM) && EM.respond_to?(:reactor_running?) && EM::reactor_running?
57
+ opts = {async: true}
58
+ else
59
+ opts = {}
60
+ end
61
+ Dalli::Client.new(address, opts)
62
+ end
63
+
28
64
  end
29
65
  end
@@ -1,38 +1,86 @@
1
- /* HTML5 */
2
- header, footer, article, section, aside, nav, menu, figure { display: block; }
1
+ body, h1, h2, h3, h4, h5, h6, p, a, ul, ol, dl, dt, dd, table, caption, th, td,
2
+ fieldset, legend, blockquote {
3
+ font-weight: normal;
4
+ margin: 0;
5
+ padding: 0;
6
+ color: inherit;
7
+ list-style-type: none;
8
+ }
9
+ a img, form, legend {border: 0; }
3
10
 
4
- /* Resets */
5
- body, h1, h2, h3, h4, h5, h6, p, a, ul, ol, dl, dt, dd, table, caption, th, td, fieldset, legend, blockquote { font-weight: normal; margin: 0; padding: 0; color: inherit; list-style-type: none; }
6
- a img, form, legend { border: 0; }
11
+ html { color: #454545;}
7
12
 
8
- /* Layout */
9
- body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; margin: 0 auto; width: 450px; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; }
13
+ body {
14
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
15
+ margin: 0 auto;
16
+ padding: 0 1em;
17
+ max-width: 450px;
18
+ text-rendering: optimizeLegibility;
19
+ -webkit-font-smoothing: antialiased;
20
+ }
10
21
 
11
- h1, h2, h3 { color: #1f1f1f; }
12
22
  img { display: block; }
13
- a { color: inherit; }
23
+ a:hover { color: #000; }
14
24
 
15
25
  header { margin: 1em 0; }
16
- header h1 { font-size: 3.5em; }
17
- header h1 a { color: #1f1f1f; text-decoration: none; }
18
- header h1 a:hover:after { content: "—Huh?";}
19
- header p { font-size: 0.8em; color: #454545; }
26
+ .brand { font-size: 3.5em; }
27
+ .brand a { display: block; text-decoration: none; }
28
+ .brand a:hover:after { content: "—Huh?";}
20
29
 
21
- section#main h2 { font-size: 1em; float: right; }
22
- section#main p.sub { color: #666; font-size: 0.9em; font-style: italic; }
30
+ .host {
31
+ font-size: 1em;
32
+ color: #fff;
33
+ }
34
+ .host-address {
35
+ font-weight: bold;
36
+ color: #ff9900;
37
+ border-radius: 2px;
38
+ font-size: 0.9em;
39
+ }
40
+ .host-details {
41
+ color: #000;
42
+ padding: 2px 4px;
43
+ }
23
44
 
24
- section#main .stats { clear: left; padding: 1.75em 0; }
25
- section#main :last-child { border: none; }
26
- section#main .graph img { float: left; margin-top: -1.5em; margin-left: -1em; }
27
- section#main .stats h3 { font-size: 1.1em; margin-left: 110px; line-height: 1.5em; }
28
- section#main .stats p { line-height: 1.4em; font-size: 0.75em; color: #454545; margin-left: 110px; }
45
+ .stats {
46
+ display: flex;
47
+ align-items: center;
48
+ margin: 2em 0;
49
+ }
50
+ .stats-text {
51
+ flex: 1 1;
52
+ margin-left: 1.5em;
53
+ }
29
54
 
30
- section#main .stats h3 span.graph-indicator { color: #ff9900; }
55
+ .graph-indicator { color: #ff9900; }
31
56
 
32
- nav#hosts { clear: left; margin: 2em 0; }
33
- nav#hosts li { margin: 0.5em 0; }
34
- nav#hosts li.inactive { color: #999; }
57
+ .alive-host,
58
+ .dead-host {
59
+ margin: 0.5em 0;
60
+ }
61
+ .dead-host { color: #999; }
35
62
 
36
- footer { margin-top: 2em; border-top: 0.1em dotted #eee; width: 50%; margin: 2em auto; padding: 0.5em 0; }
37
- footer p { font-size: 0.6em; color: #ccc; text-align: center; }
38
- footer p a:hover { color: #999; }
63
+ footer {
64
+ margin-top: 2em;
65
+ border-top: 0.1em solid #ccc;
66
+ margin: 2em auto;
67
+ padding: 0.5em 0;
68
+ font-size: 0.8em;
69
+ color: #ccc;
70
+ text-align: center;
71
+ }
72
+ footer a:hover { color: #999; }
73
+
74
+ @media (prefers-color-scheme: dark) {
75
+ html {
76
+ background: black;
77
+ color: white;
78
+ color: #ccc;
79
+ }
80
+ a:hover { color: #fff; }
81
+ footer { border-color: #454545; color: #454545; }
82
+ .host-details {
83
+ color: #fff;
84
+ }
85
+
86
+ }
@@ -0,0 +1,41 @@
1
+ module Amnesia
2
+ module Routes
3
+ def self.included app
4
+ app.class_eval do
5
+ get '/' do
6
+ haml :index
7
+ end
8
+
9
+ get '/pie' do
10
+ data = params[:d].to_s.split(",").map(&:to_i)
11
+
12
+ r = 25
13
+ c = (2*Math::PI*r).ceil
14
+ v = data.first.to_f / data.last * 100 * c / 100
15
+ v = v.nan? ? 0 : v.ceil
16
+
17
+ content_type "image/svg+xml"
18
+ <<~BODY
19
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"
20
+ style="transform:rotate(-90deg);">
21
+ <circle r="#{r*2}" cx="50" cy="50" fill="#FFEBCC" />
22
+ <circle r="#{r}" cx="50" cy="50"
23
+ fill="transparent" stroke="#FF9901"
24
+ stroke-width="#{r*2}" stroke-dasharray="#{v} #{c}"
25
+ />
26
+ </svg>
27
+ BODY
28
+ end
29
+
30
+ get '/:address' do
31
+ @host = find_host params[:address]
32
+ @host ? haml(:host) : halt(404)
33
+ end
34
+
35
+ def find_host address
36
+ @hosts.find { |h| h.address == address }
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,24 +1,32 @@
1
- %h2= @host.address
2
- %p.sub #{@host.curr_items} item/s in cache, with #{@host.curr_connections} active connections
1
+ %h2.host
2
+ %span.host-address
3
+ = @host.address
4
+ %small.host-details
5
+ = "#{@host.curr_items} item/s in cache, with #{@host.curr_connections} active connections"
3
6
 
4
- %section.stats.graph
5
- %img{:src => graph_url([@host.bytes, @host.limit_maxbytes]) }
6
- %h3
7
- %span.graph-indicator Used Memory (#{number_to_human_size(@host.bytes)})
8
- \/ Free Memory (#{number_to_human_size(@host.limit_maxbytes)})
9
- %p The cumulative amount of free memory and total memory across all active hosts.
7
+ %article.stats
8
+ %section.stats-graph
9
+ %img{src: graph_url(@host.bytes, @host.limit_maxbytes), width: 90}
10
+ %section.stats-text
11
+ %h3
12
+ %span.graph-indicator Used (#{number_to_human_size(@host.bytes)})
13
+ \/ Available Memory (#{number_to_human_size(@host.limit_maxbytes)})
14
+ %p The cumulative amount of available memory across all active hosts.
10
15
 
16
+ %article.stats
17
+ %section.stats-graph
18
+ %img{src: graph_url(@host.get_hits, @host.get_misses), width: 90}
19
+ %section.stats-text
20
+ %h3
21
+ %span.graph-indicator Hit (#{@host.get_hits})
22
+ \/ Miss (#{@host.get_misses})
23
+ %p The amount of returned caches vs misses, misses usually require your application servers to work harder.
11
24
 
12
- %section.stats.graph
13
- %img{:src => graph_url([@host.get_hits, @host.get_misses]) }
14
- %h3
15
- %span.graph-indicator Hit (#{@host.get_hits})
16
- \/ Miss (#{@host.get_misses})
17
- %p The amount of returned caches vs misses, misses usually require your application servers to work harder.
18
-
19
- %section.stats.graph
20
- %img{:src => graph_url([@host.cmd_get, @host.cmd_set]) }
21
- %h3
22
- %span.graph-indicator Read (#{@host.cmd_get})
23
- \/ Write (#{@host.cmd_set})
24
- %p More writes than reads can often mean that you’re caching too early, or that you’ve not been monitoring for very long.
25
+ %section.stats
26
+ %section.stats-graph
27
+ %img{src: graph_url(@host.cmd_get, @host.cmd_set), width: 90}
28
+ %section.stats-text
29
+ %h3
30
+ %span.graph-indicator Read (#{@host.cmd_get})
31
+ \/ Write (#{@host.cmd_set})
32
+ %p More writes than reads can often mean that you’re caching too early, or that you’ve not been monitoring for very long.
@@ -1,34 +1,39 @@
1
- - if @hosts.any?{|host| host.alive? }
2
- %section#overall
3
- %section.stats.graph
4
- %img{:src => graph_url([@hosts.collect{|h| h.get_hits if h.alive? }.compact.sum, @hosts.collect{|h| h.get_misses if h.alive? }.compact.sum])}
1
+ - if alive_hosts.any?
2
+ %article.stats
3
+ %section.stats-graph
4
+ %img{src: graph_url(bytes_sum, limit_maxbytes_sum), width: 90}
5
+ %section.stats-text
5
6
  %h3
6
- %span.graph-indicator Hit
7
- \/ Miss
7
+ %span.graph-indicator Used (#{number_to_human_size(bytes_sum)})
8
+ \/ Available Memory (#{number_to_human_size(limit_maxbytes_sum)})
9
+ %p The cumulative amount of available memory across all active hosts.
10
+
11
+ %article.stats
12
+ %section.stats-graph
13
+ %img{src: graph_url(get_hits_sum, get_misses_sum), width: 90}
14
+ %section.stats-text
15
+ %h3
16
+ %span.graph-indicator Hit (#{get_hits_sum})
17
+ \/ Miss (#{get_misses_sum})
8
18
  %p The amount of returned caches vs misses, misses usually require your application servers to work harder.
9
- %section.stats.graph
10
- %img{:src => graph_url([@hosts.collect{|h| h.cmd_get if h.alive? }.compact.sum, @hosts.collect{|h| h.cmd_set if h.alive? }.compact.sum])}
19
+
20
+ %article.stats
21
+ %section.stats-graph
22
+ %img{src: graph_url(cmd_get_sum, cmd_set_sum), width: 90}
23
+ %section.stats-text
11
24
  %h3
12
- %span.graph-indicator Read
13
- \/ Write
25
+ %span.graph-indicator Read (#{cmd_get_sum})
26
+ \/ Write (#{cmd_set_sum})
14
27
  %p More writes than reads can often mean that you’re caching too early, or that you’ve not been monitoring for very long.
15
-
16
- %section.stats.graph
17
- %img{:src => graph_url([@hosts.collect{|h| h.bytes if h.alive? }.compact.sum, @hosts.collect{|h| h.limit_maxbytes if h.alive? }.compact.sum])}
18
- %h3
19
- %span.graph-indicator Used Memory
20
- \/ Free Memory
21
- %p The cumulative amount of free memory and total memory across all active hosts.
22
28
 
23
- %nav#hosts
24
- %p.sub Active Hosts
29
+ %nav
30
+ %p.sub Known Hosts
25
31
  %ul
26
32
  - for host in @hosts
27
33
  - if host.alive?
28
- %li
29
- %a{:href => "/amnesia/" + host.address }= host.address
34
+ %li.alive-host
35
+ %a{href: url("/#{host.address}") }= host.address
30
36
  - else
31
- %li.inactive
37
+ %li.dead-host
32
38
  = host.address
33
39
  (Inactive)
34
-
@@ -1,19 +1,19 @@
1
1
  !!!
2
2
  %html
3
3
  %head
4
- %meta{:charset => "utf-8"}
4
+ %meta{charset: "utf-8"}
5
5
  %title Amnesia
6
- %link{:rel => "stylesheet", :href => "/css/application.css"}
6
+ %link{rel: "stylesheet", href: url("/css/application.css")}
7
7
  %body
8
8
  %header
9
- %h1
10
- %a{:href => '/amnesia'} Amnesia
9
+ %h1.brand
10
+ %a{href: url('/')} Amnesia
11
11
  %p Statistics for Memcached. Wait—What?
12
- %section#main
12
+ %main
13
13
  = yield
14
14
  %footer
15
- %p
15
+ %p
16
16
  Another
17
- %a{:href => "http://germanforblack.com"} Ben Schwarz
18
- joint. Get the
19
- %a{:href => "http://github.com/benschwarz/amnesia"} Source.
17
+ %a{href: "http://germanforblack.com"} Ben Schwarz
18
+ joint. Get the
19
+ %a{href: "http://github.com/benschwarz/amnesia"} Source.
data/lib/amnesia.rb CHANGED
@@ -1,55 +1,27 @@
1
- require 'sinatra'
2
- require 'memcache'
3
- require 'gchart'
1
+ require 'sinatra/base'
4
2
  require 'haml'
5
-
6
- $:<< File.dirname(__FILE__)
7
-
3
+ require 'amnesia/authentication'
4
+ require 'amnesia/helpers'
8
5
  require 'amnesia/host'
9
- require 'core_ext/array'
6
+ require 'amnesia/routes'
10
7
 
11
8
  module Amnesia
12
- class << self
13
- attr_accessor :config
14
- end
15
-
16
9
  class Application < Sinatra::Base
17
- set :public, File.join(File.dirname(__FILE__), 'amnesia', 'public')
18
- set :views, File.join(File.dirname(__FILE__), 'amnesia', 'views')
10
+ include Amnesia::Authentication
11
+ include Amnesia::Helpers
12
+ include Amnesia::Routes
19
13
 
20
- def initialize(app, configuration = {})
21
- Amnesia.config = configuration
22
- super(app)
23
- end
24
-
25
- helpers do
26
- def graph_url(data = [])
27
- GChart.pie(:data => data, :size => '115x115').to_url
28
- end
29
-
30
- def number_to_human_size(size, precision=1)
31
- size = Kernel.Float(size)
32
- case
33
- when size.to_i == 1; "1 Byte"
34
- when size < 1.kilobyte; "%d Bytes" % size
35
- when size < 1.megabyte; "%.#{precision}f KB" % (size / 1.0.kilobyte)
36
- when size < 1.gigabyte; "%.#{precision}f MB" % (size / 1.0.megabyte)
37
- when size < 1.terabyte; "%.#{precision}f GB" % (size / 1.0.gigabyte)
38
- else "%.#{precision}f TB" % (size / 1.0.terabyte)
39
- end.sub(/([0-9])\.?0+ /, '\1 ' )
40
- rescue
41
- nil
42
- end
43
- end
44
-
45
- get '/amnesia' do
46
- @hosts = Amnesia.config[:hosts].map{|host| Host.new(host)}
47
- haml :index
14
+ set :public_folder, File.join(__dir__, 'amnesia', 'public')
15
+ set :views, File.join(__dir__, 'amnesia', 'views')
16
+
17
+ def initialize(app = nil, options = {})
18
+ @hosts = build_hosts options[:hosts] || ENV['MEMCACHE_SERVERS'] || '127.0.0.1:11211'
19
+ super app
48
20
  end
49
21
 
50
- get '/amnesia/:host' do
51
- @host = Host.new(params[:host])
52
- haml :host
22
+ def build_hosts addresses
23
+ addresses = addresses.split "," if addresses.is_a? String
24
+ Array(addresses).flatten.map { |address| Amnesia::Host.new address }
53
25
  end
54
26
  end
55
- end
27
+ end
metadata CHANGED
@@ -1,138 +1,124 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: amnesia
3
- version: !ruby/object:Gem::Version
4
- hash: 23
5
- prerelease: false
6
- segments:
7
- - 1
8
- - 0
9
- - 0
10
- version: 1.0.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Ben Schwarz
14
- autorequire:
8
+ autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2010-09-28 00:00:00 +10:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
11
+ date: 2022-05-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
22
14
  name: sinatra
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
27
17
  - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 15
30
- segments:
31
- - 1
32
- - 0
33
- version: "1.0"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
34
20
  type: :runtime
35
- version_requirements: *id001
36
- - !ruby/object:Gem::Dependency
37
- name: memcache-client
38
21
  prerelease: false
39
- requirement: &id002 !ruby/object:Gem::Requirement
40
- none: false
41
- requirements:
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: dalli
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
42
31
  - - ">="
43
- - !ruby/object:Gem::Version
44
- hash: 3
45
- segments:
46
- - 1
47
- - 5
48
- - 0
49
- version: 1.5.0
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
50
34
  type: :runtime
51
- version_requirements: *id002
52
- - !ruby/object:Gem::Dependency
53
- name: gchart
54
35
  prerelease: false
55
- requirement: &id003 !ruby/object:Gem::Requirement
56
- none: false
57
- requirements:
58
- - - "="
59
- - !ruby/object:Gem::Version
60
- hash: 23
61
- segments:
62
- - 1
63
- - 0
64
- - 0
65
- version: 1.0.0
66
- type: :runtime
67
- version_requirements: *id003
68
- - !ruby/object:Gem::Dependency
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
69
42
  name: haml
70
- prerelease: false
71
- requirement: &id004 !ruby/object:Gem::Requirement
72
- none: false
73
- requirements:
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
74
45
  - - ">="
75
- - !ruby/object:Gem::Version
76
- hash: 7
77
- segments:
78
- - 3
79
- - 0
80
- - 0
81
- version: 3.0.0
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
82
48
  type: :runtime
83
- version_requirements: *id004
84
- description: With Amnesia you'll know exactly whats happening with memory when it comes to memcached.
85
- email:
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.9'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.9'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rack-test
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: With Amnesia you'll know exactly whats happening with memory when it
84
+ comes to memcached.
85
+ email:
86
86
  - ben.schwarz@gmail.com
87
87
  executables: []
88
-
89
88
  extensions: []
90
-
91
89
  extra_rdoc_files: []
92
-
93
- files:
90
+ files:
91
+ - LICENCE
92
+ - README.markdown
93
+ - lib/amnesia.rb
94
+ - lib/amnesia/authentication.rb
95
+ - lib/amnesia/helpers.rb
94
96
  - lib/amnesia/host.rb
95
97
  - lib/amnesia/public/css/application.css
98
+ - lib/amnesia/routes.rb
96
99
  - lib/amnesia/views/host.haml
97
100
  - lib/amnesia/views/index.haml
98
101
  - lib/amnesia/views/layout.haml
99
- - lib/amnesia.rb
100
- - lib/core_ext/array.rb
101
- - LICENCE
102
- - README.markdown
103
- has_rdoc: true
104
102
  homepage: http://github.com/benschwarz/amnesia
105
103
  licenses: []
106
-
107
- post_install_message:
104
+ metadata: {}
105
+ post_install_message:
108
106
  rdoc_options: []
109
-
110
- require_paths:
107
+ require_paths:
111
108
  - lib
112
- required_ruby_version: !ruby/object:Gem::Requirement
113
- none: false
114
- requirements:
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
115
111
  - - ">="
116
- - !ruby/object:Gem::Version
117
- hash: 3
118
- segments:
119
- - 0
120
- version: "0"
121
- required_rubygems_version: !ruby/object:Gem::Requirement
122
- none: false
123
- requirements:
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
124
116
  - - ">="
125
- - !ruby/object:Gem::Version
126
- hash: 3
127
- segments:
128
- - 0
129
- version: "0"
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
130
119
  requirements: []
131
-
132
- rubyforge_project:
133
- rubygems_version: 1.3.7
134
- signing_key:
135
- specification_version: 3
120
+ rubygems_version: 3.0.3
121
+ signing_key:
122
+ specification_version: 4
136
123
  summary: Amnesia is what you get when you lose your memory
137
124
  test_files: []
138
-
@@ -1,5 +0,0 @@
1
- class Array
2
- def sum
3
- inject( nil ) { |sum,x| sum ? sum+x : x }
4
- end
5
- end