redis_web_manager 0.1.8 → 0.2.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +6 -6
- data/README.md +1 -2
- data/app/controllers/redis_web_manager/keys_controller.rb +33 -14
- data/app/helpers/redis_web_manager/application_helper.rb +1 -1
- data/app/helpers/redis_web_manager/keys_helper.rb +33 -0
- data/app/views/redis_web_manager/keys/_search.html.erb +31 -0
- data/app/views/redis_web_manager/keys/index.html.erb +8 -10
- data/app/views/redis_web_manager/keys/show.html.erb +1 -1
- data/lib/redis_web_manager/info.rb +2 -6
- data/lib/redis_web_manager/version.rb +1 -1
- data/spec/controllers/redis_web_manager/keys_controller_spec.rb +9 -1
- data/spec/helpers/application_helper_spec.rb +2 -2
- data/spec/helpers/keys_helper_spec.rb +39 -0
- data/spec/redis_web_manager_info_spec.rb +1 -4
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 625fca933d689410a7db50bb4108654ad7953f055825b46a13f8fd40e8833660
|
4
|
+
data.tar.gz: 280d3f28e6d82c33dff79a28190c878eefed38d939ce9ad9a2b3da634241085f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b70d680f8dd17128e020fc872717077012bb8fc1f13be495b4c2b5baa2b81f76ee76b624647fa74356325fcc25cf49ca78c2b2a107d9951acf7d9dbbc646dc54
|
7
|
+
data.tar.gz: f138a669c0d71f1afbba53db6c2a3657f30f756e0a3100a2926f851b39b204be0f62c654560cd4c3b2d7a973ee92bcc8bd573ca231364e0601d6b16d5d236dda
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
redis_web_manager (0.1.
|
4
|
+
redis_web_manager (0.1.9)
|
5
5
|
pagy (~> 3.7)
|
6
6
|
rails (>= 5.2, < 7)
|
7
7
|
redis (~> 4.1.0)
|
@@ -65,7 +65,7 @@ GEM
|
|
65
65
|
tzinfo (~> 1.1)
|
66
66
|
zeitwerk (~> 2.2)
|
67
67
|
builder (3.2.4)
|
68
|
-
concurrent-ruby (1.1.
|
68
|
+
concurrent-ruby (1.1.6)
|
69
69
|
coveralls (0.8.23)
|
70
70
|
json (>= 1.8, < 3)
|
71
71
|
simplecov (~> 0.16.1)
|
@@ -94,10 +94,10 @@ GEM
|
|
94
94
|
mini_portile2 (2.4.0)
|
95
95
|
minitest (5.14.0)
|
96
96
|
nio4r (2.5.2)
|
97
|
-
nokogiri (1.10.
|
97
|
+
nokogiri (1.10.8)
|
98
98
|
mini_portile2 (~> 2.4.0)
|
99
|
-
pagy (3.7.
|
100
|
-
rack (2.
|
99
|
+
pagy (3.7.3)
|
100
|
+
rack (2.2.2)
|
101
101
|
rack-test (1.1.0)
|
102
102
|
rack (>= 1.0, < 3)
|
103
103
|
rails (6.0.2.1)
|
@@ -162,7 +162,7 @@ GEM
|
|
162
162
|
tins (~> 1.0)
|
163
163
|
thor (1.0.1)
|
164
164
|
thread_safe (0.3.6)
|
165
|
-
tins (1.24.
|
165
|
+
tins (1.24.1)
|
166
166
|
sync
|
167
167
|
tzinfo (1.2.6)
|
168
168
|
thread_safe (~> 0.1)
|
data/README.md
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
Web interface that allows you to manage easily your Redis instance (see keys, memory used, connected client, etc...).
|
11
11
|
|
12
12
|
### Check your stats
|
13
|
-
The Dashboard allows you
|
13
|
+
The Dashboard allows you to check the Memory usage, CPU and Redis clients.
|
14
14
|
|
15
15
|

|
16
16
|
|
@@ -103,7 +103,6 @@ end
|
|
103
103
|
|
104
104
|
|
105
105
|
## Todo
|
106
|
-
* [ ] Add filters to redis keys (filter by type, by expiration date...)
|
107
106
|
* [ ] Add graph for most used commands
|
108
107
|
* [ ] Manage multiple redis instances
|
109
108
|
* [ ] Real time chart update
|
@@ -10,15 +10,9 @@ module RedisWebManager
|
|
10
10
|
|
11
11
|
# GET /keys
|
12
12
|
def index
|
13
|
-
query = params[:query].presence
|
14
|
-
@keys = if query.present?
|
15
|
-
info.search(query).map { |key| format_key(key) }
|
16
|
-
else
|
17
|
-
info.keys.map { |key| format_key(key) }
|
18
|
-
end
|
19
13
|
@status = info.status
|
20
14
|
@url = connection.id
|
21
|
-
@pagy, @keys = pagy_array(
|
15
|
+
@pagy, @keys = pagy_array(keys)
|
22
16
|
end
|
23
17
|
|
24
18
|
# GET /key/:key
|
@@ -54,13 +48,14 @@ module RedisWebManager
|
|
54
48
|
|
55
49
|
private
|
56
50
|
|
51
|
+
# FIXME: - Refactoring
|
52
|
+
# - Move this part
|
57
53
|
def item_type(value)
|
58
54
|
['json', JSON.parse(value)]
|
59
55
|
rescue JSON::ParserError
|
60
56
|
['string', value]
|
61
57
|
end
|
62
58
|
|
63
|
-
# Get values for Redis List type
|
64
59
|
def get_list(key)
|
65
60
|
start = 0
|
66
61
|
stop = 99
|
@@ -74,7 +69,6 @@ module RedisWebManager
|
|
74
69
|
{ length: length, values: values }
|
75
70
|
end
|
76
71
|
|
77
|
-
# Get values for Redis Set type
|
78
72
|
def get_set(key)
|
79
73
|
values = info.smembers(key).map do |e|
|
80
74
|
type, value = item_type(e)
|
@@ -84,7 +78,6 @@ module RedisWebManager
|
|
84
78
|
{ values: values }
|
85
79
|
end
|
86
80
|
|
87
|
-
# Get values for Redis Zset type
|
88
81
|
def get_zset(key)
|
89
82
|
values = info.zrange(key, 0, -1, withscores: true).map do |e, score|
|
90
83
|
type, value = item_type(e)
|
@@ -94,7 +87,6 @@ module RedisWebManager
|
|
94
87
|
{ values: values }
|
95
88
|
end
|
96
89
|
|
97
|
-
# Get values for Redis Hash type
|
98
90
|
def get_hash(key)
|
99
91
|
value = Hash[info.hgetall(key).map do |k, v|
|
100
92
|
type, value = item_type(v)
|
@@ -105,8 +97,7 @@ module RedisWebManager
|
|
105
97
|
end
|
106
98
|
|
107
99
|
def get_value(key)
|
108
|
-
|
109
|
-
case type
|
100
|
+
case info.type(key)
|
110
101
|
when 'string'
|
111
102
|
{ value: info.get(key) }
|
112
103
|
when 'list'
|
@@ -125,11 +116,39 @@ module RedisWebManager
|
|
125
116
|
def format_key(key)
|
126
117
|
{
|
127
118
|
key: key,
|
128
|
-
|
119
|
+
expiry: info.expiry(key),
|
129
120
|
node: get_value(key),
|
130
121
|
type: info.type(key),
|
131
122
|
memory: info.memory_usage(key)
|
132
123
|
}
|
133
124
|
end
|
125
|
+
|
126
|
+
def keys
|
127
|
+
keys = info.search(params[:query].presence).map { |key| format_key(key) }
|
128
|
+
keys = filter_by_type(keys, params[:type].presence)
|
129
|
+
keys = filter_by_expiry(keys, params[:expiry].presence)
|
130
|
+
filter_by_memory(keys, params[:expiry].presence)
|
131
|
+
end
|
132
|
+
|
133
|
+
def filter_by_type(keys, type)
|
134
|
+
return keys if invalid_option(type)
|
135
|
+
keys.select { |key| key[:type] == type }
|
136
|
+
end
|
137
|
+
|
138
|
+
def filter_by_expiry(keys, expiry)
|
139
|
+
return keys if invalid_option(expiry)
|
140
|
+
duration = expiry.to_i
|
141
|
+
return keys.select { |key| key[:expiry] == -1 } if duration == -1
|
142
|
+
keys.select { |key| key[:expiry] != -1 && key[:expiry] < duration }
|
143
|
+
end
|
144
|
+
|
145
|
+
def filter_by_memory(keys, memory)
|
146
|
+
return keys if invalid_option(memory)
|
147
|
+
keys.select { |key| key[:memory] < memory.to_i }
|
148
|
+
end
|
149
|
+
|
150
|
+
def invalid_option(option)
|
151
|
+
option.nil? || option == 'all'
|
152
|
+
end
|
134
153
|
end
|
135
154
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RedisWebManager
|
4
|
+
module KeysHelper
|
5
|
+
def types_filters
|
6
|
+
[%w[All all],
|
7
|
+
%w[String string],
|
8
|
+
%w[Hash hash],
|
9
|
+
%w[Set set],
|
10
|
+
%w[Zset zset],
|
11
|
+
%w[List list]]
|
12
|
+
end
|
13
|
+
|
14
|
+
def expiry_filters
|
15
|
+
[%w[All all],
|
16
|
+
['No expiry', -1],
|
17
|
+
['Less than 1 hour', 3600],
|
18
|
+
['Less than 1 week', 604_800],
|
19
|
+
['Less than 1 month', 2_592_000],
|
20
|
+
['Less than 6 months', 15_552_000]]
|
21
|
+
end
|
22
|
+
|
23
|
+
def memory_filters
|
24
|
+
[%w[All all],
|
25
|
+
['Less than 1 KB', 1000],
|
26
|
+
['Less than 10 KB', 10_000],
|
27
|
+
['Less than 100 KB', 100_000],
|
28
|
+
['Less than 1 MB', 1_000_000],
|
29
|
+
['Less than 10 MB', 10_000_000],
|
30
|
+
['Less than 100 MB', 100_000_000]]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<%= form_tag(keys_path, method: :get, class: 'p-4', enforce_utf8: false) do %>
|
2
|
+
<div class="row">
|
3
|
+
<div class="col-12">
|
4
|
+
<div class="form-group">
|
5
|
+
<%= label_tag :query, 'Name', class: 'font-weight-bolder' %>
|
6
|
+
<%= text_field_tag :query, params[:query], class: 'form-control', placeholder: 'Search key(s)' %>
|
7
|
+
</div>
|
8
|
+
</div>
|
9
|
+
</div>
|
10
|
+
<div class="row">
|
11
|
+
<div class="col-4">
|
12
|
+
<div class="form-group">
|
13
|
+
<%= label_tag :type, 'Type', class: 'font-weight-bolder' %>
|
14
|
+
<%= select_tag :type, options_for_select(types_filters, params[:type]), class: 'form-control custom-select' %>
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
<div class="col-4">
|
18
|
+
<div class="form-group">
|
19
|
+
<%= label_tag :expiry, 'Expiry', class: 'font-weight-bolder' %>
|
20
|
+
<%= select_tag :expiry, options_for_select(expiry_filters, params[:expiry]), class: 'form-control custom-select' %>
|
21
|
+
</div>
|
22
|
+
</div>
|
23
|
+
<div class="col-4">
|
24
|
+
<div class="form-group">
|
25
|
+
<%= label_tag :memory, 'Memory', class: 'font-weight-bolder' %>
|
26
|
+
<%= select_tag :memory, options_for_select(memory_filters, params[:memory]), class: 'form-control custom-select' %>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
<%= submit_tag 'Search', class: 'btn btn-primary btn-block', name: nil %>
|
31
|
+
<% end %>
|
@@ -9,14 +9,12 @@
|
|
9
9
|
</h5>
|
10
10
|
</div>
|
11
11
|
<div class="card-body p-0">
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
</div>
|
19
|
-
<% end %>
|
12
|
+
<a class="btn btn-link p-2" data-toggle="collapse" href="#search" role="button" aria-expanded="false" aria-controls="search">
|
13
|
+
View search
|
14
|
+
</a>
|
15
|
+
<div class="collapse" id="search">
|
16
|
+
<%= render partial: 'redis_web_manager/keys/search' %>
|
17
|
+
</div>
|
20
18
|
<div class="table-responsive">
|
21
19
|
<table class="table mb-0">
|
22
20
|
<thead>
|
@@ -32,11 +30,11 @@
|
|
32
30
|
<% @keys.each do |key| %>
|
33
31
|
<tr>
|
34
32
|
<td><%= link_to (key[:key]).truncate(45), key_path(key: key[:key]), title: "Show #{key[:key]}" %></td>
|
35
|
-
<td><%=
|
33
|
+
<td><%= expiry(key[:expiry]) %></td>
|
36
34
|
<td><code><%= number_to_human_size(key[:memory]) %></code></td>
|
37
35
|
<td><kbd class="bg-dark"><%= key[:type] %></kbd></td>
|
38
36
|
<td>
|
39
|
-
<%= link_to 'Edit', edit_key_path(key: key[:key]), title: "Edit #{key[:key]}", class: 'btn btn-sm btn-primary
|
37
|
+
<%= link_to 'Edit', edit_key_path(key: key[:key]), title: "Edit #{key[:key]}", class: 'btn btn-sm btn-primary' %>
|
40
38
|
<%= link_to 'Delete', destroy_key_path(key: key[:key]), method: :delete, data: {confirm: 'Are you sure ?'}, title: "Delete #{key[:key]}", class: 'btn btn-sm btn-danger ml-2' %>
|
41
39
|
</td>
|
42
40
|
</tr>
|
@@ -10,19 +10,15 @@ module RedisWebManager
|
|
10
10
|
@stats ||= redis.info
|
11
11
|
end
|
12
12
|
|
13
|
-
def keys
|
14
|
-
@keys ||= redis.keys
|
15
|
-
end
|
16
|
-
|
17
13
|
def search(query)
|
18
|
-
redis.scan_each(match: "*#{query.downcase}*").to_a
|
14
|
+
redis.scan_each(match: "*#{query.try(:downcase)}*").to_a
|
19
15
|
end
|
20
16
|
|
21
17
|
def type(key)
|
22
18
|
redis.type(key)
|
23
19
|
end
|
24
20
|
|
25
|
-
def
|
21
|
+
def expiry(key)
|
26
22
|
redis.ttl(key)
|
27
23
|
end
|
28
24
|
|
@@ -12,7 +12,15 @@ RSpec.describe RedisWebManager::KeysController, type: :controller do
|
|
12
12
|
it 'returns a success response' do
|
13
13
|
get :index
|
14
14
|
expect(response).to be_successful
|
15
|
-
get :index, params: { query: '
|
15
|
+
get :index, params: { query: 'test' }
|
16
|
+
expect(response).to be_successful
|
17
|
+
get :index, params: { type: 'string' }
|
18
|
+
expect(response).to be_successful
|
19
|
+
get :index, params: { expiry: '-1' }
|
20
|
+
expect(response).to be_successful
|
21
|
+
get :index, params: { expiry: '3600' }
|
22
|
+
expect(response).to be_successful
|
23
|
+
get :index, params: { memory: '1000' }
|
16
24
|
expect(response).to be_successful
|
17
25
|
end
|
18
26
|
end
|
@@ -17,11 +17,11 @@ RSpec.describe RedisWebManager::ApplicationHelper, type: :helper do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'returns a no expiration' do
|
20
|
-
expect(helper.
|
20
|
+
expect(helper.expiry(-1)).to eql('No expiration date')
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'returns a expiration' do
|
24
|
-
expect(helper.
|
24
|
+
expect(helper.expiry(86_400)).to eql('1 day')
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe RedisWebManager::KeysHelper, type: :helper do
|
6
|
+
describe 'helper' do
|
7
|
+
it 'returns Array of types' do
|
8
|
+
expect(helper.types_filters).to eql([%w[All all],
|
9
|
+
%w[String string],
|
10
|
+
%w[Hash hash],
|
11
|
+
%w[Set set],
|
12
|
+
%w[Zset zset],
|
13
|
+
%w[List list]])
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'returns Array of expiration' do
|
17
|
+
expect(helper.expiry_filters).to eq(
|
18
|
+
[%w[All all],
|
19
|
+
['No expiry', -1],
|
20
|
+
['Less than 1 hour', 3600],
|
21
|
+
['Less than 1 week', 604_800],
|
22
|
+
['Less than 1 month', 2_592_000],
|
23
|
+
['Less than 6 months', 15_552_000]]
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'returns Array of memories' do
|
28
|
+
expect(helper.memory_filters).to eq(
|
29
|
+
[%w[All all],
|
30
|
+
['Less than 1 KB', 1000],
|
31
|
+
['Less than 10 KB', 10_000],
|
32
|
+
['Less than 100 KB', 100_000],
|
33
|
+
['Less than 1 MB', 1_000_000],
|
34
|
+
['Less than 10 MB', 10_000_000],
|
35
|
+
['Less than 100 MB', 100_000_000]]
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -20,9 +20,6 @@ RSpec.describe RedisWebManager::Info do
|
|
20
20
|
expect(info.stats).to be_a_kind_of(Hash)
|
21
21
|
end
|
22
22
|
|
23
|
-
it 'returns a Array class (keys)' do
|
24
|
-
expect(info.keys).to be_a_kind_of(Array)
|
25
|
-
end
|
26
23
|
|
27
24
|
it 'returns a string value (type)' do
|
28
25
|
redis.set('test', 'test', ex: 20.seconds)
|
@@ -35,7 +32,7 @@ RSpec.describe RedisWebManager::Info do
|
|
35
32
|
end
|
36
33
|
|
37
34
|
it 'returns a ttl value (expire)' do
|
38
|
-
expect(info.
|
35
|
+
expect(info.expiry('test')).to eql(20)
|
39
36
|
end
|
40
37
|
|
41
38
|
it 'returns a memory usage value (memory_usage)' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis_web_manager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boris BRESCIANI
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2020-02-
|
13
|
+
date: 2020-02-18 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: coveralls
|
@@ -143,11 +143,13 @@ files:
|
|
143
143
|
- app/helpers/redis_web_manager/application_helper.rb
|
144
144
|
- app/helpers/redis_web_manager/clients_helper.rb
|
145
145
|
- app/helpers/redis_web_manager/dashboard_helper.rb
|
146
|
+
- app/helpers/redis_web_manager/keys_helper.rb
|
146
147
|
- app/views/layouts/redis_web_manager/application.html.erb
|
147
148
|
- app/views/redis_web_manager/clients/index.html.erb
|
148
149
|
- app/views/redis_web_manager/configuration/index.html.erb
|
149
150
|
- app/views/redis_web_manager/dashboard/index.html.erb
|
150
151
|
- app/views/redis_web_manager/information/index.html.erb
|
152
|
+
- app/views/redis_web_manager/keys/_search.html.erb
|
151
153
|
- app/views/redis_web_manager/keys/edit.html.erb
|
152
154
|
- app/views/redis_web_manager/keys/index.html.erb
|
153
155
|
- app/views/redis_web_manager/keys/show.html.erb
|
@@ -343,6 +345,7 @@ files:
|
|
343
345
|
- spec/helpers/application_helper_spec.rb
|
344
346
|
- spec/helpers/clients_helper_spec.rb
|
345
347
|
- spec/helpers/dashboard_helper_spec.rb
|
348
|
+
- spec/helpers/keys_helper_spec.rb
|
346
349
|
- spec/rails_helper.rb
|
347
350
|
- spec/redis_web_manager_action_spec.rb
|
348
351
|
- spec/redis_web_manager_connection_spec.rb
|
@@ -570,3 +573,4 @@ test_files:
|
|
570
573
|
- spec/helpers/application_helper_spec.rb
|
571
574
|
- spec/helpers/clients_helper_spec.rb
|
572
575
|
- spec/helpers/dashboard_helper_spec.rb
|
576
|
+
- spec/helpers/keys_helper_spec.rb
|