redis_dashboard 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/Gemfile +0 -1
  4. data/Gemfile.lock +9 -13
  5. data/README.md +17 -15
  6. data/lib/redis_dashboard/application.rb +50 -17
  7. data/lib/redis_dashboard/client.rb +20 -3
  8. data/lib/redis_dashboard/public/ariato.css +739 -0
  9. data/lib/redis_dashboard/public/style.css +185 -0
  10. data/lib/redis_dashboard/views/application.scss +2 -10
  11. data/lib/redis_dashboard/views/clients.erb +18 -17
  12. data/lib/redis_dashboard/views/config.erb +6 -7
  13. data/lib/redis_dashboard/views/index.erb +10 -10
  14. data/lib/redis_dashboard/views/info.erb +6 -7
  15. data/lib/redis_dashboard/views/key/hash.erb +12 -0
  16. data/lib/redis_dashboard/views/key/list.erb +11 -0
  17. data/lib/redis_dashboard/views/key/metadata.erb +47 -0
  18. data/lib/redis_dashboard/views/key/set.erb +11 -0
  19. data/lib/redis_dashboard/views/key/string.erb +3 -0
  20. data/lib/redis_dashboard/views/key/unsupported.erb +2 -0
  21. data/lib/redis_dashboard/views/key/zset.erb +16 -0
  22. data/lib/redis_dashboard/views/key.erb +5 -0
  23. data/lib/redis_dashboard/views/keys.erb +26 -0
  24. data/lib/redis_dashboard/views/keyspace.erb +23 -0
  25. data/lib/redis_dashboard/views/layout.erb +34 -29
  26. data/lib/redis_dashboard/views/memory.erb +21 -20
  27. data/lib/redis_dashboard/views/slowlog.erb +25 -24
  28. data/lib/redis_dashboard/views/stats.erb +19 -15
  29. data/lib/redis_dashboard.rb +1 -1
  30. data/redis_dashboard.gemspec +1 -2
  31. data/screenshot.jpg +0 -0
  32. metadata +16 -24
  33. data/lib/redis_dashboard/views/stylesheets/base.scss +0 -17
  34. data/lib/redis_dashboard/views/stylesheets/colors.scss +0 -6
  35. data/lib/redis_dashboard/views/stylesheets/link.scss +0 -20
  36. data/lib/redis_dashboard/views/stylesheets/page.scss +0 -69
  37. data/lib/redis_dashboard/views/stylesheets/server-card.scss +0 -37
  38. data/lib/redis_dashboard/views/stylesheets/table.scss +0 -49
  39. data/lib/redis_dashboard/views/stylesheets/typography.scss +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c9f712009a2a6aaf18f7dc9ae5ffa8ed7fd82bdeddc415f140c250a9043652f8
4
- data.tar.gz: 3eebf9aa402bee15fcc14af27dc413c00880fad12742be6382a38c1f66a81848
3
+ metadata.gz: 9642ce8486ef1fc0d995d2c06380537aa7918335b1f90e8cbade6983e3a84940
4
+ data.tar.gz: 5221f10a927a48865bd0f598cddac86f9601a942b800d85543e336754c2682e8
5
5
  SHA512:
6
- metadata.gz: 0bf3538439851524bcc5cb5ee97d486b935a71995ae5d4be78cf12ab9f598297f9dc67d87e981918292575c56dc97e2d6dcd5875a19d9106853f2432fa915074
7
- data.tar.gz: c180db4825405d3e3dbee1d95756ca3954b91c2300ad8f4731938658387404b5b0512356778038a2842b402ac98f569d0a805608c310da86b87d8a46ba440b44
6
+ metadata.gz: 1865b8f9ef769bf860987722807e5c341d32c0303e5c115e9c09a9f8c97b91bf9a2de46bd8c2c17dc5b676f379ac1a96142c747f2a1d134611d51a101bff8389
7
+ data.tar.gz: be609cbe14b267d8421006103528db4afafbd99de6f7995bffc5880daf0f067b83d27a7230e8ed97e0fc014c4e76af53c6c2ef317587d688e309a8c82f0a9503
data/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ ## 0.3.0
2
+
3
+ * Add keyspace explorer
4
+ * Use friendly URLs with server host name
5
+ * Mute Redis error when server is too old to support memory command
6
+ * Use Ariato CSS framework https://ariato.org
7
+ * Remove sassc dependency to switch to plain CSS
8
+
9
+ ## 0.2.0
10
+
11
+ * Add memory stats
12
+ * Replace deprecated sass by sassc
13
+
14
+ ## 0.1.6
15
+
16
+ * Switch to erubi
17
+ * Escape HTML by default
18
+ * Fix cache hit ratio
data/Gemfile CHANGED
@@ -3,4 +3,3 @@ source "https://rubygems.org"
3
3
  gem "sinatra"
4
4
  gem "erubi"
5
5
  gem "redis"
6
- gem "sassc"
data/Gemfile.lock CHANGED
@@ -1,21 +1,18 @@
1
1
  GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
- erubi (1.9.0)
5
- ffi (1.12.2)
4
+ erubi (1.10.0)
6
5
  mustermann (1.1.1)
7
6
  ruby2_keywords (~> 0.0.1)
8
- rack (2.2.2)
9
- rack-protection (2.0.8.1)
7
+ rack (2.2.3)
8
+ rack-protection (2.1.0)
10
9
  rack
11
- redis (4.1.3)
12
- ruby2_keywords (0.0.2)
13
- sassc (2.2.1)
14
- ffi (~> 1.9)
15
- sinatra (2.0.8.1)
10
+ redis (4.5.1)
11
+ ruby2_keywords (0.0.5)
12
+ sinatra (2.1.0)
16
13
  mustermann (~> 1.0)
17
- rack (~> 2.0)
18
- rack-protection (= 2.0.8.1)
14
+ rack (~> 2.2)
15
+ rack-protection (= 2.1.0)
19
16
  tilt (~> 2.0)
20
17
  tilt (2.0.10)
21
18
 
@@ -25,8 +22,7 @@ PLATFORMS
25
22
  DEPENDENCIES
26
23
  erubi
27
24
  redis
28
- sassc
29
25
  sinatra
30
26
 
31
27
  BUNDLED WITH
32
- 1.17.2
28
+ 2.1.4
data/README.md CHANGED
@@ -20,38 +20,40 @@ You can run it in standalone or inside your Rails app.
20
20
 
21
21
  ## Installation inside a Rails app
22
22
 
23
- Add this line in your Gemfile:
24
- ```ruby
25
- gem "redis_dashboard"
26
- ```
27
-
28
- In your terminal run the following command:
29
- ```shell
30
- bundle install
31
- ```
23
+ Add to your Gemfile `gem "redis_dashboard"` and run `bundle install`.
32
24
 
33
25
  Then mount the app from `config/routes.rb`:
34
26
  ```ruby
35
- mount RedisDashboard::Application, at: "redis_dashboard"
27
+ mount RedisDashboard::Application, at: "redis"
36
28
  ```
37
29
 
38
- Specify the Redis URLs in `config/redis_dashboard.rb`:
30
+ By default Redis dashboard tries to connect to `REDIS_URL` environment variable or to `localhost`. You can specify any other URL by adding an initializer in `config/initializers/redis_dashboard.rb` :
39
31
  ```ruby
40
- RedisDashboard.urls = ["redis://localhost"]
32
+ RedisDashboard.urls = [ENV["REDIS_URL"] || "redis://localhost"]
41
33
  ```
42
34
 
43
- Finally visit http://localhost/redis_dashboard/.
35
+ Finally visit http://localhost:3000/redis.
44
36
 
45
- ## Authentication
37
+ ## Authentication and permissions
46
38
 
47
- To protect your dashboard you can setup a basic HTTP authentication:
39
+ To protect your dashboard you can setup a basic HTTP authentication :
48
40
 
49
41
  ```ruby
42
+ # config/initializers/redis_dashboard.rb
50
43
  RedisDashboard::Application.use(Rack::Auth::Basic) do |user, password|
51
44
  user == "USER" && password == "PASSWORD"
52
45
  end
53
46
  ```
54
47
 
48
+ In case you handle authentication with Devise, you can perform the permission verification directly from the routes :
49
+
50
+ ```ruby
51
+ # config/routes.rb
52
+ authenticate :user, -> (u) { u.admin? } do # Supposing there is a User#admin? method
53
+ mount RedisDashboard::Application, at: "redis"
54
+ end
55
+ ```
56
+
55
57
  ## MIT License
56
58
 
57
59
  Made by [Base Secrète](https://basesecrete.com).
@@ -12,36 +12,53 @@ class RedisDashboard::Application < Sinatra::Base
12
12
  erb(:index, locals: {clients: clients})
13
13
  end
14
14
 
15
- get "/info" do
16
- erb(:info, locals: {info: client.info})
17
- end
18
-
19
- get "/config" do
15
+ get "/:server/config" do
20
16
  erb(:config, locals: {config: client.config})
21
17
  end
22
18
 
23
- get "/clients" do
19
+ get "/:server/clients" do
24
20
  erb(:clients, locals: {clients: client.clients})
25
21
  end
26
22
 
27
- get "/stats" do
23
+ get "/:server/stats" do
28
24
  erb(:stats, locals: {stats: client.stats})
29
25
  end
30
26
 
31
- get "/slowlog" do
27
+ get "/:server/slowlog" do
32
28
  erb(:slowlog, locals: {client: client, commands: client.slow_commands})
33
29
  end
34
30
 
35
- get "/memory" do
36
- erb(:memory, locals: {client: client, stats: client.memory_stats})
31
+ get "/:server/memory" do
32
+ stats = mute_redis_command_error { client.memory_stats } || {}
33
+ erb(:memory, locals: {client: client, stats: stats })
34
+ end
35
+
36
+ get "/:server/keyspace" do
37
+ erb(:keyspace, locals: {keyspace: client.keyspace})
37
38
  end
38
39
 
39
- get "/application.css" do
40
- scss(:application, style: :expanded)
40
+ get "/:server/keyspace/:db" do
41
+ client.connection.select(params[:db].sub(/^db/, ""))
42
+ erb(:keys, locals: {client: client, keys: client.keys(params[:query])})
43
+ end
44
+
45
+ get "/:server/keyspace/:db/*" do
46
+ params[:key] = params[:splat].first
47
+ client.connection.select(params[:db].sub(/^db/, ""))
48
+ erb(:key, locals: {client: client})
49
+ end
50
+
51
+ get "/:server" do
52
+ erb(:info, locals: {info: client.info})
41
53
  end
42
54
 
43
55
  def client
44
- @client ||= RedisDashboard::Client.new(RedisDashboard.urls[redis_id.to_i])
56
+ return @client if @client
57
+ if url = RedisDashboard.urls.find { |url| URI(url).host == params[:server] }
58
+ @client ||= RedisDashboard::Client.new(url)
59
+ else
60
+ raise Sinatra::NotFound
61
+ end
45
62
  end
46
63
 
47
64
  def clients
@@ -64,12 +81,12 @@ class RedisDashboard::Application < Sinatra::Base
64
81
  Time.at(epoch).strftime("%b %d %H:%M")
65
82
  end
66
83
 
67
- def redis_id
68
- params[:id]
84
+ def active_page_css(path)
85
+ request.path_info == path && "active"
69
86
  end
70
87
 
71
- def active_page?(path='')
72
- request.path_info == '/' + path
88
+ def active_path_css(path)
89
+ request.path_info.start_with?(path) && "active"
73
90
  end
74
91
 
75
92
  def format_impact_percentage(percentage)
@@ -90,6 +107,22 @@ class RedisDashboard::Application < Sinatra::Base
90
107
  end
91
108
  end
92
109
 
110
+ def render_key_data(key)
111
+ type = client.connection.type(params[:key])
112
+ erb(:"key/#{type}", locals: {key: key})
113
+ rescue Errno::ENOENT
114
+ erb(:"key/unsupported", locals: {key: key})
115
+ end
116
+
117
+ def mute_redis_command_error(&block)
118
+ block.call
119
+ rescue Redis::CommandError
120
+ end
121
+
122
+ def escape_key(key)
123
+ key.gsub("#", "%23")
124
+ end
125
+
93
126
  def clients_column_description(col)
94
127
  # https://redis.io/commands/client-list
95
128
  @clients_column_description ||= {
@@ -3,6 +3,7 @@ class RedisDashboard::Client
3
3
 
4
4
  def initialize(url)
5
5
  @url = url
6
+ @connection ||= Redis.new(url: url)
6
7
  end
7
8
 
8
9
  def clients
@@ -39,16 +40,32 @@ class RedisDashboard::Client
39
40
  array_reply_to_hash(connection.memory("stats"))
40
41
  end
41
42
 
43
+ def keys(pattern)
44
+ connection.keys(pattern)
45
+ end
46
+
42
47
  def close
43
48
  connection.close if connection
44
49
  end
45
50
 
46
- private
51
+ def host
52
+ URI(url).host
53
+ end
47
54
 
48
- def connection
49
- @connection ||= Redis.new(url: url)
55
+ def keyspace
56
+ connection.info("KEYSPACE").inject({}) do |hash, space|
57
+ db, str = space
58
+ hash[db] = str.split(",").inject({}) do |h, s|
59
+ k, v = s.split("=")
60
+ h[k] = v
61
+ h
62
+ end
63
+ hash
64
+ end
50
65
  end
51
66
 
67
+ private
68
+
52
69
  # Array reply is a Redis format which is translated into a hash for convenience.
53
70
  def array_reply_to_hash(array)
54
71
  hash = {}