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
@@ -0,0 +1,185 @@
1
+ body {
2
+ max-width: 1280px;
3
+ margin: 0px auto;
4
+ }
5
+
6
+ body > header {
7
+ display: flex;
8
+ flex-wrap: wrap;
9
+ }
10
+
11
+ .logo {
12
+ display: flex;
13
+ margin: 0 0 24px 0;
14
+ padding: 0;
15
+ box-shadow: var(--box-shadow-m);
16
+ line-height: 48px;
17
+ }
18
+
19
+ .logo a {
20
+ padding: 0 24px;
21
+ background: rgba(var(--color-red-500), 1);
22
+ color: rgba(var(--color-grey-00), 1);
23
+ font-size: var(--font-size-40);
24
+ font-weight: 500;
25
+ text-decoration: none;
26
+ text-transform: uppercase;
27
+ letter-spacing: 0.05em;
28
+ box-shadow: var(--box-shadow-m);
29
+ }
30
+
31
+ body > header .server {
32
+ font-weight: 400;
33
+ display: block;
34
+ font-size: 1rem;
35
+ line-height: 48px;
36
+ padding: 0 24px;
37
+ margin: 0 0 24px 0;
38
+ background: rgba(var(--color-grey-00), 1);
39
+ box-shadow: var(--box-shadow-m);
40
+ }
41
+
42
+ .logo a:hover {
43
+ background: rgba(var(--color-red-600), 1);
44
+ color: rgba(var(--color-grey-00), 1);
45
+ }
46
+
47
+ body > header nav {
48
+ display: flex;
49
+ flex-wrap: wrap;
50
+ line-height: 48px;
51
+ margin: 0 0 24px auto;
52
+ background-color: rgba(var(--color-grey-00), 1);
53
+ box-shadow: var(--box-shadow-m);
54
+ }
55
+
56
+ body > header nav a:any-link {
57
+ padding: 0 24px;
58
+ font-weight: 500;
59
+ font-size: var(--font-size-40);
60
+ letter-spacing: 0.05em;;
61
+ text-decoration: none;
62
+ text-transform: uppercase;
63
+ }
64
+
65
+ body > header nav a:any-link.active,
66
+ body > header nav a:any-link.active:hover,
67
+ body > header nav a:any-link.active:focus {
68
+ background: rgba(var(--color-red-500), 1);
69
+ color: rgba(var(--color-grey-00), 1);
70
+ cursor: initial;
71
+ box-shadow: var(--box-shadow-m);
72
+ }
73
+
74
+ /* main */
75
+
76
+ main * + * {
77
+ margin-top: 24px;
78
+ }
79
+
80
+ /* table */
81
+
82
+ table,
83
+ th,
84
+ tr {
85
+ width: 100%;
86
+ }
87
+
88
+ tbody tr:nth-child(even) {
89
+ background: inherit;
90
+ }
91
+
92
+ th {
93
+ white-space: nowrap;
94
+ }
95
+
96
+ td {
97
+ color: rgba(var(--color-grey-700), 1);
98
+ font-family: var(--font-mono);
99
+ }
100
+
101
+ td small {
102
+ font-size: var(--font-size-40);
103
+ color: rgba(var(--color-grey-400), 1);
104
+ }
105
+
106
+ th,
107
+ td.key {
108
+ text-transform: uppercase;
109
+ font-family: var(--font-sans);
110
+ font-weight: 400;
111
+ font-size: var(--font-size-40);
112
+ letter-spacing: 0.05em;
113
+ color: rgba(var(--color-grey-500), 1);
114
+ }
115
+
116
+ td.key {
117
+ width: 30%;
118
+ word-break: break-all;
119
+ white-space: normal;
120
+ }
121
+
122
+ td.key.no-transform {
123
+ text-transform: none;
124
+ }
125
+
126
+ td.date {
127
+ white-space: nowrap;
128
+ }
129
+
130
+ td.wrap {
131
+ word-break: break-all;
132
+ white-space: normal;
133
+ }
134
+
135
+ /* card */
136
+
137
+ .card {
138
+ overflow-x: auto;
139
+ border-radius: 0;
140
+ padding: var(--space-3x);
141
+ }
142
+
143
+ .card p {
144
+ max-width: none;
145
+ }
146
+
147
+ .card > * + * {
148
+ margin-top: 24px;
149
+ }
150
+
151
+ .card table {
152
+ margin: -24px;
153
+ min-width: calc(100% + 48px);
154
+ outline-style: none;
155
+ }
156
+
157
+ .card * + table {
158
+ margin: 0 -24px -24px;
159
+ }
160
+
161
+ table li {
162
+ margin-top: 0;
163
+ list-style-type: none;
164
+ }
165
+
166
+ .card div .label {
167
+ color: rgba(var(--color-grey-500), 1);
168
+ text-transform: uppercase;
169
+ font-size: var(--font-size-30);
170
+ letter-spacing: 0.05em;
171
+ font-weight: 500;
172
+ display: block;
173
+ }
174
+
175
+ /* footer */
176
+
177
+ body > footer {
178
+ margin-top: 24px;
179
+ font-size: var(--font-size-40);
180
+ padding: 0 24px;
181
+ }
182
+
183
+ body > footer p {
184
+ max-width: none;
185
+ }
@@ -1,10 +1,2 @@
1
- @import "stylesheets/colors";
2
-
3
- @import "stylesheets/base";
4
- @import "stylesheets/typography";
5
- @import "stylesheets/link";
6
-
7
- @import "stylesheets/table";
8
-
9
- @import "stylesheets/page";
10
- @import "stylesheets/server-card";
1
+ @import "stylesheets/ariato";
2
+ @import "stylesheets/style";
@@ -1,26 +1,27 @@
1
- <div class="table">
1
+ <div class="card">
2
2
  <table>
3
3
  <thead>
4
4
  <% for key in (keys = clients.first.keys) %>
5
5
  <th title="<%= clients_column_description key %>"><%= key %></th>
6
6
  <% end %>
7
7
  </thead>
8
- <% for client in clients %>
9
- <tr>
10
- <% for key in keys %>
11
- <% if key == "events" %>
12
- <td title="<%= client_event_description client[key] %>"><%= client[key] %></td>
13
- <% else %>
14
- <td><%= client[key] %></td>
8
+ <tbody>
9
+ <% for client in clients %>
10
+ <tr>
11
+ <% for key in keys %>
12
+ <% if key == "events" %>
13
+ <td title="<%= client_event_description client[key] %>"><%= client[key] %></td>
14
+ <% else %>
15
+ <td><%= client[key] %></td>
16
+ <% end %>
15
17
  <% end %>
16
- <% end %>
17
- </tr>
18
- <% end %>
18
+ </tr>
19
+ <% end %>
20
+ </tbody>
19
21
  </table>
20
22
  </div>
21
-
22
- <a href="https://redis.io/commands/client-list">
23
- <svg viewBox="0 0 24 24">
24
- <path d="M14,3V5H17.59L7.76,14.83L9.17,16.24L19,6.41V10H21V3M19,19H5V5H12V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V12H19V19Z" />
25
- </svg> Redis client list documentation
26
- </a>
23
+ <div role="alert">
24
+ <a href="https://redis.io/commands/client-list" target="_blank" rel="noopener nofollower">
25
+ Redis client list documentation
26
+ </a>
27
+ </div>
@@ -1,4 +1,4 @@
1
- <div class="table">
1
+ <div class="card">
2
2
  <table>
3
3
  <% for (key, value) in config %>
4
4
  <tr>
@@ -8,9 +8,8 @@
8
8
  <% end %>
9
9
  </table>
10
10
  </div>
11
-
12
- <a href="https://raw.githubusercontent.com/antirez/redis/4.0/redis.conf">
13
- <svg viewBox="0 0 24 24">
14
- <path d="M14,3V5H17.59L7.76,14.83L9.17,16.24L19,6.41V10H21V3M19,19H5V5H12V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V12H19V19Z" />
15
- </svg> Redis config documentation
16
- </a>
11
+ <div role="alert">
12
+ <a href="https://raw.githubusercontent.com/antirez/redis/4.0/redis.conf" target="_blank" rel="noopener nofollower">
13
+ Redis config documentation
14
+ </a>
15
+ </div>
@@ -1,26 +1,26 @@
1
- <div class="server-list">
1
+ <div class="grid-auto">
2
2
  <% clients.each_with_index do |client, index| %>
3
3
  <% info = client.info %>
4
- <div class="server-card">
5
- <div class="server-card-title">
6
- <a href="<%= url("info?id=#{index}") %>"><%= URI(client.url).host %> (<%= info["role"] %>)</a>
7
- </div>
8
- <div class="server-card-content">
4
+ <div class="card">
5
+ <header>
6
+ <a href="<%= url("/#{client.host}") %>"><%= client.host %> (<%= info["role"] %>)</a>
7
+ </header>
8
+ <div class="grid-auto">
9
9
  <div>
10
10
  <span class="label">Connections</span>
11
- <span><%= info["connected_clients"] %></span>
11
+ <strong><%= info["connected_clients"] %></strong>
12
12
  </div>
13
13
  <div>
14
14
  <span class="label">Memory</span>
15
- <span><%= info["used_memory_human"] %></span>
15
+ <strong><%= info["used_memory_human"] %></strong>
16
16
  </div>
17
17
  <div>
18
18
  <span class="label">Commands per second</span>
19
- <span><%= info["instantaneous_ops_per_sec"] %></span>
19
+ <strong><%= info["instantaneous_ops_per_sec"] %></strong>
20
20
  </div>
21
21
  <div>
22
22
  <span class="label">Cache hit ratio</span>
23
- <span><%== format_impact_percentage compute_cache_hit_ratio(info) %></span>
23
+ <strong><%== format_impact_percentage compute_cache_hit_ratio(info) %></strong>
24
24
  </div>
25
25
  </div>
26
26
  </div>
@@ -1,4 +1,4 @@
1
- <div class="table">
1
+ <div class="card">
2
2
  <table>
3
3
  <% for (key,value) in info %>
4
4
  <tr>
@@ -8,9 +8,8 @@
8
8
  <% end %>
9
9
  </table>
10
10
  </div>
11
-
12
- <a href="https://redis.io/commands/info">
13
- <svg viewBox="0 0 24 24">
14
- <path d="M14,3V5H17.59L7.76,14.83L9.17,16.24L19,6.41V10H21V3M19,19H5V5H12V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V12H19V19Z" />
15
- </svg> Redis documentation
16
- </a>
11
+ <div role="alert">
12
+ <a href="https://redis.io/commands/info" target="_blank" rel="noopener nofollower">
13
+ Redis documentation
14
+ </a>
15
+ </div>
@@ -0,0 +1,12 @@
1
+ <h3>Data</h3>
2
+
3
+ <table>
4
+ <tbody>
5
+ <% for (name, value) in client.connection.hgetall(key) %>
6
+ <tr>
7
+ <td class="key no-transform"><%= name %></td>
8
+ <td class="wrap"><%= value %></td>
9
+ </tr>
10
+ <% end %>
11
+ </tbody>
12
+ </table>
@@ -0,0 +1,11 @@
1
+ <h3>Data</h3>
2
+
3
+ <table>
4
+ <tbody>
5
+ <% for value in client.connection.lrange(key, 0, -1) %>
6
+ <tr>
7
+ <td><%= value %></td>
8
+ </tr>
9
+ <% end %>
10
+ </tbody>
11
+ </table>
@@ -0,0 +1,47 @@
1
+ <h3>Metadata</h3>
2
+
3
+ <table>
4
+ <tbody>
5
+ <tr>
6
+ <td class="key">Key</td>
7
+ <td class="wrap"><%= key %></td>
8
+ </tr>
9
+
10
+ <tr>
11
+ <td class="key">Type</td>
12
+ <td class="wrap"><%= key_type = client.connection.type(key) %></td>
13
+ </tr>
14
+
15
+ <tr>
16
+ <td class="key">Bytes</td>
17
+ <td class="wrap"><%= mute_redis_command_error { client.connection.memory(:usage, key) } %></td>
18
+ </tr>
19
+
20
+ <tr>
21
+ <td class="key">TTL</td>
22
+ <td class="wrap"><%= client.connection.ttl(key) %></td>
23
+ </tr>
24
+
25
+ <tr>
26
+ <td class="key">Object refcount</td>
27
+ <td class="wrap"><%= client.connection.object("REFCOUNT", key) %></td>
28
+ </tr>
29
+
30
+ <tr>
31
+ <td class="key">Object encoding</td>
32
+ <td class="wrap"><%= client.connection.object("ENCODING", key) %></td>
33
+ </tr>
34
+
35
+ <tr>
36
+ <td class="key">Object idletime</td>
37
+ <td class="wrap"><%= client.connection.object("IDLETIME", key) %></td>
38
+ </tr>
39
+
40
+ <% if key_type == "list" %>
41
+ <tr>
42
+ <td class="key">Length</td>
43
+ <td class="wrap"><%= client.connection.llen(key) %></td>
44
+ </tr>
45
+ <% end %>
46
+ </tbody>
47
+ </table>
@@ -0,0 +1,11 @@
1
+ <h3>Data</h3>
2
+
3
+ <table>
4
+ <tbody>
5
+ <% for value in client.connection.smembers(key) %>
6
+ <tr>
7
+ <td><%= value %></td>
8
+ </tr>
9
+ <% end %>
10
+ </tbody>
11
+ </table>
@@ -0,0 +1,3 @@
1
+ <h3>Data</h3>
2
+
3
+ <code><%= client.connection.get(key) %></code>
@@ -0,0 +1,2 @@
1
+ <h3>Data</h3>
2
+ <p>Sorry, but <code><%= client.connection.type(params[:key]) %></code> type is not supported.</p>
@@ -0,0 +1,16 @@
1
+ <h3>Data</h3>
2
+
3
+ <table>
4
+ <tbody>
5
+ <tr>
6
+ <td>Score</td>
7
+ <td>Value</td>
8
+ </tr>
9
+ <% client.connection.call([:zrange, key, 0, -1, "WITHSCORES"]).each_slice(2) do |value, score| %>
10
+ <tr>
11
+ <td><%= score %></td>
12
+ <td><%= value %></td>
13
+ </tr>
14
+ <% end %>
15
+ </tbody>
16
+ </table>
@@ -0,0 +1,5 @@
1
+ <div class="card">
2
+ <%== erb(:"key/metadata", locals: {key: params[:key]}) %>
3
+ <br/>
4
+ <%== render_key_data(params[:key]) %>
5
+ </div>
@@ -0,0 +1,26 @@
1
+ <div class="card">
2
+ <form action="<%= url("/#{params[:server]}/keyspace/#{params[:db]}") %>" method="get">
3
+ <input type="text" name="query" value="<%= "#{params[:query]}" %>" placeholder="Filter key names with patterns such as foo*"/>
4
+ </form>
5
+ <% if !params[:query].to_s.empty? %>
6
+ <p>
7
+ <% if keys.size == 1 %>
8
+ <%= keys.size %> key found
9
+ <% else %>
10
+ <%= keys.size %> keys found
11
+ <% end %>
12
+ <% if keys.size > 1000 %>
13
+ <small>(only 1000 are listed)</small>
14
+ <% end %>
15
+ </p>
16
+ <table>
17
+ <tbody>
18
+ <% for key in keys[0..1000] %>
19
+ <tr>
20
+ <td class="wrap"><a href="<%= url("/#{params[:server]}/keyspace/#{params[:db]}/#{escape_key(key)}") %>"><%= key %></a></td>
21
+ </tr>
22
+ <% end %>
23
+ </tbody>
24
+ </table>
25
+ <% end %>
26
+ </div>
@@ -0,0 +1,23 @@
1
+ <div class="card">
2
+ <table>
3
+ <thead>
4
+ <tr>
5
+ <th>db</th>
6
+ <th class="is-right">keys</th>
7
+ <th class="is-right">expires</th>
8
+ <th class="is-right">avg_ttl</th>
9
+ </tr>
10
+ </thead>
11
+
12
+ <% for (db, stats) in keyspace %>
13
+ <tr>
14
+ <td>
15
+ <a href="<%= url(File.join(params[:server], "keyspace", db)) %>"><%= db %></a>
16
+ </td>
17
+ <td class="is-right"><%= stats["keys"] %></td>
18
+ <td class="is-right"><%= stats["expires"] %></td>
19
+ <td class="is-right"><%= stats["avg_ttl"] %></td>
20
+ </tr>
21
+ <% end %>
22
+ </table>
23
+ </div>
@@ -1,37 +1,42 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="en">
3
3
  <head>
4
- <title>Redis Dashboard</title>
5
- <link rel="stylesheet" href="<%= url("application.css") %>">
4
+ <title>
5
+ <% if params[:server] %>
6
+ <%= page_title %> |
7
+ <% end %>
8
+ Redis Dashboard</title>
9
+ <link rel="stylesheet" href="<%= url("ariato.css") %>">
10
+ <link rel="stylesheet" href="<%= url("style.css") %>">
6
11
  </head>
7
12
 
8
13
  <body>
9
- <div class="page">
10
- <div class="page-header">
11
- <h2 class="page-title">
12
- <a href="<%= url("/") %>" class="<%= 'active' if active_page?('') %>">Redis Dashboard</a>
13
- <% if params[:id] %>
14
- <span><%= page_title %></span>
15
- <% end %>
16
- </h2>
17
- <% if params[:id] %>
18
- <div class="page-menu">
19
- <a class="page-menu-item <%= 'active' if active_page?('info') %>" href="<%= url("/info?id=#{redis_id}") %>">Info</a>
20
- <a class="page-menu-item <%= 'active' if active_page?('config') %>" href="<%= url("/config?id=#{redis_id}") %>">Config</a>
21
- <a class="page-menu-item <%= 'active' if active_page?('clients') %>" href="<%= url("/clients?id=#{redis_id}") %>">Clients</a>
22
- <a class="page-menu-item <%= 'active' if active_page?('stats') %>" href="<%= url("/stats?id=#{redis_id}") %>">Stats</a>
23
- <a class="page-menu-item <%= 'active' if active_page?('slowlog') %>" href="<%= url("/slowlog?id=#{redis_id}") %>">Slowlog</a>
24
- <a class="page-menu-item <%= 'active' if active_page?('memory') %>" href="<%= url("/memory?id=#{redis_id}") %>">Memory</a>
25
- </div>
26
- <% end %>
27
- </div>
14
+ <header>
15
+ <h1 class="logo">
16
+ <a href="<%= url("/") %>">Redis Dashboard</a>
17
+ </h1>
18
+ <% if params[:server] %>
19
+ <span class="server"><%= page_title %></span>
20
+ <% end %>
21
+ <% if params[:server] %>
22
+ <nav aria-label="site">
23
+ <a class="page-menu-item <%= active_page_css("/#{params[:server]}") %>" href="<%= url("/#{params[:server]}") %>">Info</a>
24
+ <a class="page-menu-item <%= active_page_css("/#{params[:server]}/config") %>" href="<%= url("/#{params[:server]}/config") %>">Config</a>
25
+ <a class="page-menu-item <%= active_page_css("/#{params[:server]}/clients") %>" href="<%= url("/#{params[:server]}/clients") %>">Clients</a>
26
+ <a class="page-menu-item <%= active_page_css("/#{params[:server]}/stats") %>" href="<%= url("/#{params[:server]}/stats") %>">Stats</a>
27
+ <a class="page-menu-item <%= active_page_css("/#{params[:server]}/slowlog") %>" href="<%= url("/#{params[:server]}/slowlog") %>">Slowlog</a>
28
+ <a class="page-menu-item <%= active_page_css("/#{params[:server]}/memory") %>" href="<%= url("/#{params[:server]}/memory") %>">Memory</a>
29
+ <a class="page-menu-item <%= active_path_css("/#{params[:server]}/keyspace") %>" href="<%= url("/#{params[:server]}/keyspace") %>">Keyspace</a>
30
+ </nav>
31
+ <% end %>
32
+ </header>
33
+ <main>
28
34
  <%== yield %>
29
- <div class="page-footer">
30
- Made by <a href="https://basesecrete.com/en/">Base Secrète</a>. MIT License. <a href="https://github.com/BaseSecrete/redis_dashboard">Fork on GitHub</a>.
31
- <div class="rorvswild">
32
- Rails developer? Check out <a href="https://rorvswild.com">RoRvsWild</a>, our Ruby on Rails application monitoring tool.
33
- </div>
34
- </div>
35
- </div>
35
+ </main>
36
+ <footer>
37
+ <p>Made by <a href="https://basesecrete.com/en/" target="_blank" rel="noopener">Base Secrète</a>. MIT License. <a href="https://github.com/BaseSecrete/redis_dashboard" target="_blank" rel="noopener nofollower">Fork on GitHub</a>.<br>
38
+ <b>Rails developer?</b> Check out <a href="https://rorvswild.com" target="_blank" rel="noopener">RoRvsWild</a>, our Ruby on Rails application monitoring tool.
39
+ </p>
40
+ </footer>
36
41
  </body>
37
42
  </html>
@@ -1,24 +1,25 @@
1
- <div class="table">
1
+ <div class="card">
2
2
  <table>
3
- <% for (key,value) in stats %>
4
- <tr>
5
- <td class="key"><%= key %></td>
6
- <td>
7
- <% if value.is_a?(Hash) %>
8
- <% for (sub_key, sub_value) in value %>
9
- <%= "#{sub_key}: #{sub_value}" %><br/>
3
+ <tbody>
4
+ <% for (key,value) in stats %>
5
+ <tr>
6
+ <td class="key"><%= key %></td>
7
+ <td>
8
+ <% if value.is_a?(Hash) %>
9
+ <% for (sub_key, sub_value) in value %>
10
+ <%= "#{sub_key}: #{sub_value}" %><br/>
11
+ <% end %>
12
+ <% else %>
13
+ <%= value %>
10
14
  <% end %>
11
- <% else %>
12
- <%= value %>
13
- <% end %>
14
- </td>
15
- </tr>
16
- <% end %>
15
+ </td>
16
+ </tr>
17
+ <% end %>
18
+ </tbody>
17
19
  </table>
18
20
  </div>
19
-
20
- <a href="https://github.com/antirez/redis/blob/unstable/redis.conf">
21
- <svg viewBox="0 0 24 24">
22
- <path d="M14,3V5H17.59L7.76,14.83L9.17,16.24L19,6.41V10H21V3M19,19H5V5H12V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V12H19V19Z" />
23
- </svg> Redis memory stats documentation
24
- </a>
21
+ <div role="alert">
22
+ <a href="https://github.com/antirez/redis/blob/unstable/redis.conf" target="_blank" rel="noopener nofollower">
23
+ Redis memory stats documentation
24
+ </a>
25
+ </div>