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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e48c79b5d3723da1e569b6ab98470b268a694b6f3d39a08666945a4349c09666
4
- data.tar.gz: f92ce3f1270fdfbf2c41744aa0c6f6c210dc4bd015ed44b645e924d814ffc3f8
3
+ metadata.gz: 625fca933d689410a7db50bb4108654ad7953f055825b46a13f8fd40e8833660
4
+ data.tar.gz: 280d3f28e6d82c33dff79a28190c878eefed38d939ce9ad9a2b3da634241085f
5
5
  SHA512:
6
- metadata.gz: d2246f99e9a53f9bc9cec38b06e95b967250cbab37104544f80f058d06402c6130d7d1f010e7b52cd71428a8c7d45a7d1c806f6628a372a368929119b4d7c8d4
7
- data.tar.gz: eac5fb2aea1185697a9ae819b06817b206db4adba61371462a182e5ab3ccf5d9430ddb4a03de80f1045bd4a7d33fa605d7958e07311146f605c4052644bab538
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.6)
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.5)
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.7)
97
+ nokogiri (1.10.8)
98
98
  mini_portile2 (~> 2.4.0)
99
- pagy (3.7.2)
100
- rack (2.1.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.0)
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 tu check the Memory usage, CPU and Redis clients.
13
+ The Dashboard allows you to check the Memory usage, CPU and Redis clients.
14
14
 
15
15
  ![RedisWebManager Dashboard](images/images_dashboard.png)
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(@keys)
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
- type = info.type(key)
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
- expire: info.expire(key),
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
@@ -18,7 +18,7 @@ module RedisWebManager
18
18
  content_tag(:kbd, value, class: 'bg-dark')
19
19
  end
20
20
 
21
- def expire(value)
21
+ def expiry(value)
22
22
  if value == -1
23
23
  'No expiration date'
24
24
  else
@@ -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
- <%= form_tag(keys_path, method: :get, class: 'p-4', enforce_utf8: false) do %>
13
- <div class="input-group">
14
- <%= text_field_tag :query, params[:query], class: 'form-control', placeholder: 'Search key(s)' %>
15
- <div class="input-group-append">
16
- <%= submit_tag 'Search', class: 'btn btn-primary', name: nil %>
17
- </div>
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><%= expire(key[:expire]) %></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 ml-2' %>
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>
@@ -11,7 +11,7 @@
11
11
  </p>
12
12
  <label class="font-weight-normal">Expires in:</label>
13
13
  <p class="font-weight-light">
14
- <%= expire(@key[:expire]) %>
14
+ <%= expiry(@key[:expiry]) %>
15
15
  </p>
16
16
  <label class="font-weight-normal">Size:</label>
17
17
  <p class="font-weight-light">
@@ -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 expire(key)
21
+ def expiry(key)
26
22
  redis.ttl(key)
27
23
  end
28
24
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RedisWebManager
4
- VERSION = '0.1.8'
4
+ VERSION = '0.2.0'
5
5
  end
@@ -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: 'Search' }
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.expire(-1)).to eql('No expiration date')
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.expire(86_400)).to eql('1 day')
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.expire('test')).to eql(20)
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.1.8
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-08 00:00:00.000000000 Z
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