amnesia 1.0.1 → 1.0.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.
- checksums.yaml +7 -0
- data/README.markdown +22 -5
- data/lib/amnesia.rb +16 -66
- data/lib/amnesia/authentication.rb +12 -0
- data/lib/amnesia/helpers.rb +44 -0
- data/lib/amnesia/host.rb +38 -14
- data/lib/amnesia/public/css/application.css +76 -27
- data/lib/amnesia/routes.rb +20 -0
- data/lib/amnesia/views/host.haml +29 -21
- data/lib/amnesia/views/index.haml +28 -23
- data/lib/amnesia/views/layout.haml +9 -9
- metadata +101 -95
- data/lib/core_ext/array.rb +0 -5
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 62ac67cfa06f569559611449d4f3a10cbd05c6683283b8fcbb6299dfcb78481e
|
4
|
+
data.tar.gz: a2cc20ea0a933faf55cb6562d3759c3b6d0a6e87661a0452382a330a7dded612
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f3fe2fe59c757c58dfb8c64a2a14f19eec9b0e6028e5140bc32fdbe22def7f09701da13e4413e5e29d078df03c5e39f4132efd4fc52aeecc84290c3a3a801764
|
7
|
+
data.tar.gz: f1e46efebdbf69f3ecc098b81ebb8f1a00cf5f213515c1024c142d2bd7c6e10a4cecd2fb7cfdac799ae845a6e23ecfdd9199ed96d7257a46b414636e0f5fb910
|
data/README.markdown
CHANGED
@@ -35,13 +35,30 @@ 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
|
-
|
44
|
-
|
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
|
|
@@ -57,7 +74,7 @@ When you need to specify where your memcache hosts can be found, you can either
|
|
57
74
|
|
58
75
|
or alternately, you can set it within your `config.ru`:
|
59
76
|
|
60
|
-
use Amnesia::Application, :
|
77
|
+
use Amnesia::Application, hosts: ["mc1.yourapp.com:11211", "mc2.yourapp.com:11211"]
|
61
78
|
|
62
79
|
### Authentication
|
63
80
|
|
@@ -86,7 +103,7 @@ Within my slices, I punched a hole through `iptables`
|
|
86
103
|
|
87
104
|
You won't need to do this unless you've explicitly blocked ports to your server. (When in doubt, block nearly everything)
|
88
105
|
|
89
|
-
Let me know if you come
|
106
|
+
Let me know if you come across any issues using Github messaging.
|
90
107
|
|
91
108
|
## Something missing?
|
92
109
|
|
data/lib/amnesia.rb
CHANGED
@@ -1,78 +1,28 @@
|
|
1
|
-
require 'sinatra'
|
2
|
-
require '
|
3
|
-
require 'gchart'
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'googlecharts'
|
4
3
|
require 'haml'
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
require 'amnesia/authentication'
|
5
|
+
require 'amnesia/helpers'
|
8
6
|
require 'amnesia/host'
|
9
|
-
require '
|
7
|
+
require 'amnesia/routes'
|
10
8
|
|
11
9
|
module Amnesia
|
12
|
-
class << self
|
13
|
-
attr_accessor :config
|
14
|
-
end
|
15
|
-
|
16
10
|
class Application < Sinatra::Base
|
17
|
-
|
18
|
-
|
11
|
+
include Amnesia::Authentication
|
12
|
+
include Amnesia::Helpers
|
13
|
+
include Amnesia::Routes
|
19
14
|
|
20
|
-
|
21
|
-
|
22
|
-
# Heroku
|
23
|
-
Amnesia.config[:hosts] ||= [nil] if ENV['MEMCACHE_SERVERS']
|
24
|
-
# Default if nothing set
|
25
|
-
Amnesia.config[:hosts] ||= ['127.0.0.1:11211']
|
26
|
-
super(app)
|
27
|
-
end
|
28
|
-
|
29
|
-
helpers do
|
30
|
-
def graph_url(data = [])
|
31
|
-
GChart.pie(:data => data, :size => '115x115').to_url
|
32
|
-
end
|
33
|
-
|
34
|
-
def number_to_human_size(size, precision=1)
|
35
|
-
size = Kernel.Float(size)
|
36
|
-
case
|
37
|
-
when size.to_i == 1; "1 Byte"
|
38
|
-
when size < 1.kilobyte; "%d Bytes" % size
|
39
|
-
when size < 1.megabyte; "%.#{precision}f KB" % (size / 1.0.kilobyte)
|
40
|
-
when size < 1.gigabyte; "%.#{precision}f MB" % (size / 1.0.megabyte)
|
41
|
-
when size < 1.terabyte; "%.#{precision}f GB" % (size / 1.0.gigabyte)
|
42
|
-
else "%.#{precision}f TB" % (size / 1.0.terabyte)
|
43
|
-
end.sub(/([0-9])\.?0+ /, '\1 ' )
|
44
|
-
rescue
|
45
|
-
nil
|
46
|
-
end
|
47
|
-
|
48
|
-
def protected!
|
49
|
-
unless authorized?
|
50
|
-
response['WWW-Authenticate'] = %(Basic realm="Amnesia")
|
51
|
-
throw(:halt, [401, "Not authorized\n"])
|
52
|
-
end
|
53
|
-
end
|
15
|
+
set :public_folder, File.join(__dir__, 'amnesia', 'public')
|
16
|
+
set :views, File.join(__dir__, 'amnesia', 'views')
|
54
17
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
@auth.provided? && @auth.basic? && @auth.credentials && @auth.credentials == ENV['AMNESIA_CREDS'].split(':')
|
59
|
-
else
|
60
|
-
# No auth needed.
|
61
|
-
true
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
get '/amnesia' do
|
67
|
-
protected!
|
68
|
-
@hosts = Amnesia.config[:hosts].map{|host| Amnesia::Host.new(host)}
|
69
|
-
haml :index
|
18
|
+
def initialize(app = nil, options = {})
|
19
|
+
@hosts = build_hosts options[:hosts] || ENV['MEMCACHE_SERVERS'] || '127.0.0.1:11211'
|
20
|
+
super app
|
70
21
|
end
|
71
22
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
haml :host
|
23
|
+
def build_hosts addresses
|
24
|
+
addresses = addresses.split "," if addresses.is_a? String
|
25
|
+
Array(addresses).flatten.map { |address| Amnesia::Host.new address }
|
76
26
|
end
|
77
27
|
end
|
78
28
|
end
|
@@ -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
|
+
Gchart.pie(data: data, size: '115x115', bg: 'ffffff00')
|
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,34 +1,58 @@
|
|
1
|
+
require 'dalli'
|
2
|
+
|
1
3
|
module Amnesia
|
2
4
|
class Host
|
5
|
+
FLOAT_STATS = %w[ rusage_user rusage_system ]
|
6
|
+
STRING_STATS = %w[ version libevent ]
|
7
|
+
|
3
8
|
def initialize(address)
|
4
9
|
@address = address
|
5
10
|
end
|
6
|
-
|
7
|
-
def alive?
|
8
|
-
return true if connection.stats
|
9
|
-
rescue
|
11
|
+
|
12
|
+
def alive?
|
13
|
+
return true if connection.stats[@address]
|
14
|
+
rescue Dalli::DalliError
|
10
15
|
return false
|
11
16
|
end
|
12
|
-
|
17
|
+
|
13
18
|
def method_missing(method, *args)
|
14
|
-
|
19
|
+
if stats.has_key? method.to_s
|
20
|
+
value = stats[method.to_s]
|
21
|
+
if FLOAT_STATS.include? method
|
22
|
+
Float(value)
|
23
|
+
elsif STRING_STATS.include? method
|
24
|
+
value
|
25
|
+
else
|
26
|
+
Integer(value)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
super
|
30
|
+
end
|
15
31
|
end
|
16
|
-
|
32
|
+
|
17
33
|
def stats
|
18
|
-
connection.stats
|
19
|
-
|
20
|
-
rescue Memcached::Error
|
21
|
-
return {}
|
34
|
+
stats_val = connection.stats
|
35
|
+
stats_val.values.first || {}
|
22
36
|
end
|
23
37
|
|
24
38
|
def address
|
25
39
|
@address || @connection.servers.join(', ')
|
26
40
|
end
|
27
|
-
|
41
|
+
|
28
42
|
private
|
29
|
-
|
43
|
+
|
30
44
|
def connection
|
31
|
-
@connection ||=
|
45
|
+
@connection ||= connect(@address)
|
32
46
|
end
|
47
|
+
|
48
|
+
def connect(address = nil)
|
49
|
+
if defined?(EM) && EM.respond_to?(:reactor_running?) && EM::reactor_running?
|
50
|
+
opts = {async: true}
|
51
|
+
else
|
52
|
+
opts = {}
|
53
|
+
end
|
54
|
+
Dalli::Client.new(address, opts)
|
55
|
+
end
|
56
|
+
|
33
57
|
end
|
34
58
|
end
|
@@ -1,38 +1,87 @@
|
|
1
|
-
|
2
|
-
|
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
|
-
|
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
|
-
|
9
|
-
|
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:
|
23
|
+
a:hover { color: #000; }
|
14
24
|
|
15
25
|
header { margin: 1em 0; }
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
22
|
-
|
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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
45
|
+
.stats {
|
46
|
+
display: flex;
|
47
|
+
align-items: center;
|
48
|
+
margin: 2em 0;
|
49
|
+
}
|
50
|
+
.stats-graph img { margin-left: -10px; }
|
51
|
+
.stats-text {
|
52
|
+
flex: 1 1;
|
53
|
+
margin-left: 1em;
|
54
|
+
}
|
29
55
|
|
30
|
-
|
56
|
+
.graph-indicator { color: #ff9900; }
|
31
57
|
|
32
|
-
|
33
|
-
|
34
|
-
|
58
|
+
.alive-host,
|
59
|
+
.dead-host {
|
60
|
+
margin: 0.5em 0;
|
61
|
+
}
|
62
|
+
.dead-host { color: #999; }
|
35
63
|
|
36
|
-
footer {
|
37
|
-
|
38
|
-
|
64
|
+
footer {
|
65
|
+
margin-top: 2em;
|
66
|
+
border-top: 0.1em solid #ccc;
|
67
|
+
margin: 2em auto;
|
68
|
+
padding: 0.5em 0;
|
69
|
+
font-size: 0.8em;
|
70
|
+
color: #ccc;
|
71
|
+
text-align: center;
|
72
|
+
}
|
73
|
+
footer a:hover { color: #999; }
|
74
|
+
|
75
|
+
@media (prefers-color-scheme: dark) {
|
76
|
+
html {
|
77
|
+
background: black;
|
78
|
+
color: white;
|
79
|
+
color: #ccc;
|
80
|
+
}
|
81
|
+
a:hover { color: #fff; }
|
82
|
+
footer { border-color: #454545; color: #454545; }
|
83
|
+
.host-details {
|
84
|
+
color: #fff;
|
85
|
+
}
|
86
|
+
|
87
|
+
}
|
@@ -0,0 +1,20 @@
|
|
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 '/:address' do
|
10
|
+
@host = find_host params[:address]
|
11
|
+
@host ? haml(:host) : halt(404)
|
12
|
+
end
|
13
|
+
|
14
|
+
def find_host address
|
15
|
+
@hosts.find { |h| h.address == address }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/amnesia/views/host.haml
CHANGED
@@ -1,24 +1,32 @@
|
|
1
|
-
%h2
|
2
|
-
%
|
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
|
-
%
|
5
|
-
%
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
%article.stats
|
8
|
+
%section.stats-graph
|
9
|
+
%img{src: graph_url(@host.bytes, @host.limit_maxbytes) }
|
10
|
+
%section.stats-text
|
11
|
+
%h3
|
12
|
+
%span.graph-indicator Used Memory (#{number_to_human_size(@host.bytes)})
|
13
|
+
\/ Free Memory (#{number_to_human_size(@host.limit_maxbytes)})
|
14
|
+
%p The cumulative amount of free memory and total 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) }
|
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
|
13
|
-
%
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
%
|
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) }
|
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
|
2
|
-
%
|
3
|
-
%section.stats
|
4
|
-
%img{:
|
1
|
+
- if alive_hosts.any?
|
2
|
+
%article.stats
|
3
|
+
%section.stats-graph
|
4
|
+
%img{src: graph_url(bytes_sum, limit_maxbytes_sum)}
|
5
|
+
%section.stats-text
|
5
6
|
%h3
|
6
|
-
%span.graph-indicator
|
7
|
-
\/
|
7
|
+
%span.graph-indicator Used Memory (#{number_to_human_size(bytes_sum)})
|
8
|
+
\/ Free Memory (#{number_to_human_size(limit_maxbytes_sum)})
|
9
|
+
%p The cumulative amount of free memory and total memory across all active hosts.
|
10
|
+
|
11
|
+
%article.stats
|
12
|
+
%section.stats-graph
|
13
|
+
%img{src: graph_url(get_hits_sum, get_misses_sum)}
|
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
|
-
|
10
|
-
|
19
|
+
|
20
|
+
%article.stats
|
21
|
+
%section.stats-graph
|
22
|
+
%img{src: graph_url(cmd_get_sum, cmd_set_sum)}
|
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
|
24
|
-
%p.sub
|
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{:
|
34
|
+
%li.alive-host
|
35
|
+
%a{href: url("/#{host.address}") }= host.address
|
30
36
|
- else
|
31
|
-
%li.
|
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{:
|
4
|
+
%meta{charset: "utf-8"}
|
5
5
|
%title Amnesia
|
6
|
-
%link{:
|
6
|
+
%link{rel: "stylesheet", href: url("/css/application.css")}
|
7
7
|
%body
|
8
8
|
%header
|
9
|
-
%h1
|
10
|
-
%a{:
|
9
|
+
%h1.brand
|
10
|
+
%a{href: url('/')} Amnesia
|
11
11
|
%p Statistics for Memcached. Wait—What?
|
12
|
-
%
|
12
|
+
%main
|
13
13
|
= yield
|
14
14
|
%footer
|
15
|
-
%p
|
15
|
+
%p
|
16
16
|
Another
|
17
|
-
%a{:
|
18
|
-
joint. Get the
|
19
|
-
%a{:
|
17
|
+
%a{href: "http://germanforblack.com"} Ben Schwarz
|
18
|
+
joint. Get the
|
19
|
+
%a{href: "http://github.com/benschwarz/amnesia"} Source.
|
metadata
CHANGED
@@ -1,132 +1,138 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: amnesia
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
segments:
|
6
|
-
- 1
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
version: 1.0.1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.2
|
10
5
|
platform: ruby
|
11
|
-
authors:
|
6
|
+
authors:
|
12
7
|
- Ben Schwarz
|
13
8
|
autorequire:
|
14
9
|
bindir: bin
|
15
10
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
dependencies:
|
20
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2020-04-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
21
14
|
name: sinatra
|
22
|
-
|
23
|
-
|
24
|
-
none: false
|
25
|
-
requirements:
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
26
17
|
- - ">="
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
- 1
|
30
|
-
- 0
|
31
|
-
version: "1.0"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
32
20
|
type: :runtime
|
33
|
-
version_requirements: *id001
|
34
|
-
- !ruby/object:Gem::Dependency
|
35
|
-
name: memcached-northscale
|
36
21
|
prerelease: false
|
37
|
-
|
38
|
-
|
39
|
-
|
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:
|
40
31
|
- - ">="
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
|
43
|
-
- 0
|
44
|
-
- 19
|
45
|
-
- 5
|
46
|
-
- 4
|
47
|
-
version: 0.19.5.4
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
48
34
|
type: :runtime
|
49
|
-
version_requirements: *id002
|
50
|
-
- !ruby/object:Gem::Dependency
|
51
|
-
name: gchart
|
52
35
|
prerelease: false
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: googlecharts
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.6.8
|
63
48
|
type: :runtime
|
64
|
-
version_requirements: *id003
|
65
|
-
- !ruby/object:Gem::Dependency
|
66
|
-
name: haml
|
67
49
|
prerelease: false
|
68
|
-
|
69
|
-
|
70
|
-
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.6.8
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: haml
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
71
59
|
- - ">="
|
72
|
-
- !ruby/object:Gem::Version
|
73
|
-
|
74
|
-
- 3
|
75
|
-
- 0
|
76
|
-
- 0
|
77
|
-
version: 3.0.0
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
78
62
|
type: :runtime
|
79
|
-
|
80
|
-
|
81
|
-
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.9'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.9'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rack-test
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: With Amnesia you'll know exactly whats happening with memory when it
|
98
|
+
comes to memcached.
|
99
|
+
email:
|
82
100
|
- ben.schwarz@gmail.com
|
83
101
|
executables: []
|
84
|
-
|
85
102
|
extensions: []
|
86
|
-
|
87
103
|
extra_rdoc_files: []
|
88
|
-
|
89
|
-
|
104
|
+
files:
|
105
|
+
- LICENCE
|
106
|
+
- README.markdown
|
107
|
+
- lib/amnesia.rb
|
108
|
+
- lib/amnesia/authentication.rb
|
109
|
+
- lib/amnesia/helpers.rb
|
90
110
|
- lib/amnesia/host.rb
|
91
111
|
- lib/amnesia/public/css/application.css
|
112
|
+
- lib/amnesia/routes.rb
|
92
113
|
- lib/amnesia/views/host.haml
|
93
114
|
- lib/amnesia/views/index.haml
|
94
115
|
- lib/amnesia/views/layout.haml
|
95
|
-
- lib/amnesia.rb
|
96
|
-
- lib/core_ext/array.rb
|
97
|
-
- LICENCE
|
98
|
-
- README.markdown
|
99
|
-
has_rdoc: true
|
100
116
|
homepage: http://github.com/benschwarz/amnesia
|
101
117
|
licenses: []
|
102
|
-
|
118
|
+
metadata: {}
|
103
119
|
post_install_message:
|
104
120
|
rdoc_options: []
|
105
|
-
|
106
|
-
require_paths:
|
121
|
+
require_paths:
|
107
122
|
- lib
|
108
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
-
|
110
|
-
requirements:
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
111
125
|
- - ">="
|
112
|
-
- !ruby/object:Gem::Version
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
-
none: false
|
118
|
-
requirements:
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
119
130
|
- - ">="
|
120
|
-
- !ruby/object:Gem::Version
|
121
|
-
|
122
|
-
- 0
|
123
|
-
version: "0"
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
124
133
|
requirements: []
|
125
|
-
|
126
|
-
rubyforge_project:
|
127
|
-
rubygems_version: 1.3.7
|
134
|
+
rubygems_version: 3.0.3
|
128
135
|
signing_key:
|
129
|
-
specification_version:
|
136
|
+
specification_version: 4
|
130
137
|
summary: Amnesia is what you get when you lose your memory
|
131
138
|
test_files: []
|
132
|
-
|