redis_dashboard 0.2.0 → 0.3.0

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 (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 = {}