redis-stat 0.3.0-java
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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +85 -0
- data/Rakefile +8 -0
- data/bin/redis-stat +16 -0
- data/lib/redis-stat/constants.rb +118 -0
- data/lib/redis-stat/option.rb +134 -0
- data/lib/redis-stat/server/public/bootstrap/css/bootstrap-responsive.min.css +9 -0
- data/lib/redis-stat/server/public/bootstrap/css/bootstrap.min.css +9 -0
- data/lib/redis-stat/server/public/bootstrap/img/glyphicons-halflings-white.png +0 -0
- data/lib/redis-stat/server/public/bootstrap/img/glyphicons-halflings.png +0 -0
- data/lib/redis-stat/server/public/bootstrap/js/bootstrap.min.js +6 -0
- data/lib/redis-stat/server/public/css/site.css +67 -0
- data/lib/redis-stat/server/public/favicon.ico +0 -0
- data/lib/redis-stat/server/public/favicon.png +0 -0
- data/lib/redis-stat/server/public/jqplot/jqplot.canvasAxisLabelRenderer.min.js +57 -0
- data/lib/redis-stat/server/public/jqplot/jqplot.canvasAxisTickRenderer.min.js +57 -0
- data/lib/redis-stat/server/public/jqplot/jqplot.canvasTextRenderer.min.js +57 -0
- data/lib/redis-stat/server/public/jqplot/jquery.jqplot.min.css +1 -0
- data/lib/redis-stat/server/public/jqplot/jquery.jqplot.min.js +57 -0
- data/lib/redis-stat/server/public/jquery-1.8.2.min.js +2 -0
- data/lib/redis-stat/server/public/js/site.js +192 -0
- data/lib/redis-stat/server/views/index.erb +145 -0
- data/lib/redis-stat/server.rb +57 -0
- data/lib/redis-stat/version.rb +3 -0
- data/lib/redis-stat.rb +314 -0
- data/redis-stat.gemspec +33 -0
- data/test/bin_helper.rb +9 -0
- data/test/test_redis-stat.rb +193 -0
- metadata +194 -0
data/lib/redis-stat.rb
ADDED
@@ -0,0 +1,314 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'redis-stat/version'
|
4
|
+
require 'redis-stat/constants'
|
5
|
+
require 'redis-stat/option'
|
6
|
+
require 'redis-stat/server' unless RUBY_PLATFORM == 'java'
|
7
|
+
require 'insensitive_hash'
|
8
|
+
require 'redis'
|
9
|
+
require 'tabularize'
|
10
|
+
require 'ansi'
|
11
|
+
require 'csv'
|
12
|
+
require 'parallelize'
|
13
|
+
require 'si'
|
14
|
+
|
15
|
+
class RedisStat
|
16
|
+
attr_reader :hosts, :measures
|
17
|
+
|
18
|
+
def initialize options = {}
|
19
|
+
options = RedisStat::Option::DEFAULT.merge options
|
20
|
+
@hosts = options[:hosts]
|
21
|
+
@redises = @hosts.map { |e|
|
22
|
+
host, port = e.split(':')
|
23
|
+
Redis.new(Hash[ {:host => host, :port => port, :timeout => DEFAULT_REDIS_TIMEOUT}.select { |k, v| v } ])
|
24
|
+
}
|
25
|
+
@interval = options[:interval]
|
26
|
+
@max_count = options[:count]
|
27
|
+
@mono = options[:mono]
|
28
|
+
@colors = options[:colors] || COLORS
|
29
|
+
@csv = options[:csv]
|
30
|
+
@auth = options[:auth]
|
31
|
+
@measures = MEASURES[ options[:verbose] ? :verbose : :default ]
|
32
|
+
@all_measures= MEASURES.values.inject(:+).uniq - [:at]
|
33
|
+
@count = 0
|
34
|
+
@style = options[:style]
|
35
|
+
@first_batch = true
|
36
|
+
@server_port = options[:server_port]
|
37
|
+
@daemonized = options[:daemon]
|
38
|
+
end
|
39
|
+
|
40
|
+
def info
|
41
|
+
collect
|
42
|
+
end
|
43
|
+
|
44
|
+
def start output_stream
|
45
|
+
@os = output_stream
|
46
|
+
trap('INT') { Thread.main.raise Interrupt }
|
47
|
+
|
48
|
+
begin
|
49
|
+
csv = File.open(@csv, 'w') if @csv
|
50
|
+
update_term_size!
|
51
|
+
|
52
|
+
# Warm-up / authenticate only when needed
|
53
|
+
@redises.each do |r|
|
54
|
+
begin
|
55
|
+
r.info
|
56
|
+
rescue Redis::CommandError
|
57
|
+
r.auth @auth if @auth
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
@started_at = Time.now
|
63
|
+
prev_info = nil
|
64
|
+
server = start_server if @server_port
|
65
|
+
|
66
|
+
loop do
|
67
|
+
info = collect
|
68
|
+
info_output = process info, prev_info
|
69
|
+
output info, info_output, csv unless @daemonized
|
70
|
+
server.push info, Hash[info_output] if server
|
71
|
+
prev_info = info
|
72
|
+
|
73
|
+
@count += 1
|
74
|
+
break if @max_count && @count >= @max_count
|
75
|
+
sleep @interval
|
76
|
+
end
|
77
|
+
@os.puts
|
78
|
+
rescue Interrupt
|
79
|
+
@os.puts
|
80
|
+
@os.puts ansi(:yellow, :bold) { "Interrupted." }
|
81
|
+
rescue Exception => e
|
82
|
+
@os.puts ansi(:red, :bold) { e.to_s }
|
83
|
+
raise
|
84
|
+
ensure
|
85
|
+
csv.close if csv
|
86
|
+
end
|
87
|
+
@os.puts ansi(:blue, :bold) {
|
88
|
+
"Elapsed: #{"%.2f" % (Time.now - @started_at)} sec."
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
def start_server
|
94
|
+
RedisStat::Server.set :port, @server_port
|
95
|
+
RedisStat::Server.set :redis_stat, self
|
96
|
+
Thread.new { RedisStat::Server.run! }
|
97
|
+
RedisStat::Server.wait_until_running
|
98
|
+
trap('INT') { Thread.main.raise Interrupt }
|
99
|
+
RedisStat::Server
|
100
|
+
end
|
101
|
+
|
102
|
+
def collect
|
103
|
+
{}.insensitive.tap do |info|
|
104
|
+
class << info
|
105
|
+
def sumf label
|
106
|
+
(self[label] || []).map(&:to_f).inject(:+)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
info[:at] = Time.now.to_f
|
111
|
+
@redises.pmap(@redises.length) { |redis|
|
112
|
+
redis.info.insensitive
|
113
|
+
}.each do |rinfo|
|
114
|
+
(@all_measures + rinfo.keys.select { |k| k =~ /^db[0-9]+$/ }).each do |k|
|
115
|
+
info[k] ||= []
|
116
|
+
info[k] << rinfo[k]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def update_term_size!
|
123
|
+
if RUBY_PLATFORM == 'java'
|
124
|
+
require 'java'
|
125
|
+
begin
|
126
|
+
case JRUBY_VERSION
|
127
|
+
when /^1\.7/
|
128
|
+
@term ||= Java::jline.console.ConsoleReader.new.getTerminal
|
129
|
+
@term_width = (@term.width rescue DEFAULT_TERM_WIDTH)
|
130
|
+
@term_height = (@term.height rescue DEFAULT_TERM_HEIGHT) - 4
|
131
|
+
return
|
132
|
+
when /^1\.6/
|
133
|
+
@term ||= Java::jline.ConsoleReader.new.getTerminal
|
134
|
+
@term_width = (@term.getTerminalWidth rescue DEFAULT_TERM_WIDTH)
|
135
|
+
@term_height = (@term.getTerminalHeight rescue DEFAULT_TERM_HEIGHT) - 4
|
136
|
+
return
|
137
|
+
end
|
138
|
+
rescue Exception
|
139
|
+
# Fallback to tput (which yields incorrect values as of now)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
@term_width = (`tput cols` rescue DEFAULT_TERM_WIDTH).to_i
|
144
|
+
@term_height = (`tput lines` rescue DEFAULT_TERM_HEIGHT).to_i - 4
|
145
|
+
end
|
146
|
+
|
147
|
+
def move! lines
|
148
|
+
return if lines == 0
|
149
|
+
|
150
|
+
@os.print(
|
151
|
+
if defined?(Win32::Console)
|
152
|
+
if lines < 0
|
153
|
+
"\e[#{- lines}F"
|
154
|
+
else
|
155
|
+
"\e[#{lines}E"
|
156
|
+
end
|
157
|
+
else
|
158
|
+
if lines < 0
|
159
|
+
"\e[#{- lines}A\e[0G"
|
160
|
+
else
|
161
|
+
"\e[#{lines}B\e[0G"
|
162
|
+
end
|
163
|
+
end)
|
164
|
+
end
|
165
|
+
|
166
|
+
def output info, info_output, file
|
167
|
+
@table ||= init_table info_output
|
168
|
+
|
169
|
+
movement = nil
|
170
|
+
if @count == 0
|
171
|
+
output_static_info info
|
172
|
+
|
173
|
+
movement = 0
|
174
|
+
if file
|
175
|
+
file.puts CSV.generate_line(info_output.map { |pair|
|
176
|
+
LABELS[pair.first] || pair.first
|
177
|
+
})
|
178
|
+
end
|
179
|
+
elsif @count % @term_height == 0
|
180
|
+
@first_batch = false
|
181
|
+
movement = -1
|
182
|
+
update_term_size!
|
183
|
+
@table = init_table info_output
|
184
|
+
end
|
185
|
+
|
186
|
+
# Build output table
|
187
|
+
@table << info_output.map { |pair|
|
188
|
+
ansi(*@colors[pair.first]) { [*pair.last].first }
|
189
|
+
}
|
190
|
+
lines = @table.to_s.lines.map(&:chomp)
|
191
|
+
lines.delete_at @first_batch ? 1 : 0
|
192
|
+
width = lines.first.length
|
193
|
+
height = lines.length
|
194
|
+
|
195
|
+
# Calculate the number of lines to go upward
|
196
|
+
if movement.nil?
|
197
|
+
if @prev_width && @prev_width == width
|
198
|
+
lines = lines[-2..-1]
|
199
|
+
movement = -1
|
200
|
+
else
|
201
|
+
movement = -(height - 1)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
@prev_width = width
|
205
|
+
|
206
|
+
move! movement
|
207
|
+
begin
|
208
|
+
@os.print $/ + lines.join($/)
|
209
|
+
|
210
|
+
if file
|
211
|
+
file.puts CSV.generate_line(info_output.map { |pair|
|
212
|
+
[*pair.last].last
|
213
|
+
})
|
214
|
+
end
|
215
|
+
rescue Interrupt
|
216
|
+
move! -movement
|
217
|
+
raise
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def output_static_info info
|
222
|
+
tab = Tabularize.new(
|
223
|
+
:unicode => false, :align => :right,
|
224
|
+
:border_style => @style
|
225
|
+
)
|
226
|
+
tab << [nil] + @hosts.map { |h| ansi(:bold, :green) { h } }
|
227
|
+
tab.separator!
|
228
|
+
MEASURES[:static].each do |key|
|
229
|
+
tab << [ansi(:bold) { key }] + info[key] unless info[key].compact.empty?
|
230
|
+
end
|
231
|
+
@os.puts tab
|
232
|
+
end
|
233
|
+
|
234
|
+
def init_table info_output
|
235
|
+
table = Tabularize.new :unicode => false,
|
236
|
+
:align => :right,
|
237
|
+
:border_style => @style,
|
238
|
+
:border_color => @mono ? nil : ANSI::Code.red,
|
239
|
+
:vborder => ' ',
|
240
|
+
:pad_left => 0,
|
241
|
+
:pad_right => 0,
|
242
|
+
:screen_width => @term_width
|
243
|
+
table.separator!
|
244
|
+
table << info_output.map { |pair|
|
245
|
+
ansi(*((@colors[pair.first] || []) + [:underline])) {
|
246
|
+
LABELS[pair.first] || pair.first
|
247
|
+
}
|
248
|
+
}
|
249
|
+
table.separator!
|
250
|
+
table
|
251
|
+
end
|
252
|
+
|
253
|
+
def process info, prev_info
|
254
|
+
@measures.map { |key|
|
255
|
+
[ key, process_how(info, prev_info, key) ]
|
256
|
+
}.select { |pair| pair.last }
|
257
|
+
end
|
258
|
+
|
259
|
+
def process_how info, prev_info, key
|
260
|
+
dur = prev_info && (info[:at] - prev_info[:at])
|
261
|
+
|
262
|
+
get_diff = lambda do |label|
|
263
|
+
if dur && dur > 0
|
264
|
+
(info.sumf(label) - prev_info.sumf(label)) / dur
|
265
|
+
else
|
266
|
+
nil
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
case key
|
271
|
+
when :at
|
272
|
+
val = Time.now.strftime('%H:%M:%S')
|
273
|
+
[val, val]
|
274
|
+
when :used_cpu_user, :used_cpu_sys
|
275
|
+
val = get_diff.call(key)
|
276
|
+
val &&= (val * 100).round
|
277
|
+
[humanize_number(val), val]
|
278
|
+
when :keys
|
279
|
+
val = Hash[ info.select { |k, v| k =~ /^db[0-9]+$/ } ].values.inject(0) { |sum, vs|
|
280
|
+
sum + vs.map { |v| Hash[ v.split(',').map { |e| e.split '=' } ]['keys'].to_i }.inject(:+)
|
281
|
+
}
|
282
|
+
[humanize_number(val), val]
|
283
|
+
when :evicted_keys_per_second, :expired_keys_per_second, :keyspace_hits_per_second,
|
284
|
+
:keyspace_misses_per_second, :total_commands_processed_per_second
|
285
|
+
val = get_diff.call(key.to_s.gsub(/_per_second$/, '').to_sym)
|
286
|
+
[humanize_number(val), val]
|
287
|
+
when :used_memory, :used_memory_rss, :aof_current_size, :aof_base_size
|
288
|
+
val = info.sumf(key)
|
289
|
+
[humanize_number(val.to_i, true), val]
|
290
|
+
else
|
291
|
+
val = info.sumf(key)
|
292
|
+
[humanize_number(val), val]
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def humanize_number num, byte = false
|
297
|
+
return '-' if num.nil?
|
298
|
+
|
299
|
+
num = num.to_i if num == num.to_i
|
300
|
+
if byte
|
301
|
+
num.si_byte
|
302
|
+
else
|
303
|
+
num.si(:min_exp => 0)
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def ansi *args, &block
|
308
|
+
if @mono || args.empty?
|
309
|
+
block.call
|
310
|
+
else
|
311
|
+
ANSI::Code.ansi *args, &block
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
data/redis-stat.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/redis-stat/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Junegunn Choi"]
|
6
|
+
gem.email = ["junegunn.c@gmail.com"]
|
7
|
+
gem.description = %q{A Redis monitoring tool written in Ruby}
|
8
|
+
gem.summary = %q{A Redis monitoring tool written in Ruby}
|
9
|
+
gem.homepage = "https://github.com/junegunn/redis-stat"
|
10
|
+
|
11
|
+
gem.platform = 'java' if RUBY_PLATFORM == 'java'
|
12
|
+
gem.files = `git ls-files`.split("\n").reject { |f| f =~ /^screenshots/ }
|
13
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
14
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
15
|
+
gem.name = "redis-stat"
|
16
|
+
gem.require_paths = ["lib"]
|
17
|
+
gem.version = RedisStat::VERSION
|
18
|
+
|
19
|
+
gem.add_runtime_dependency "ansi", '~> 1.4.3'
|
20
|
+
gem.add_runtime_dependency "redis", '~> 3.0.1'
|
21
|
+
gem.add_runtime_dependency "tabularize", '~> 0.2.8'
|
22
|
+
gem.add_runtime_dependency "insensitive_hash", '~> 0.3.0'
|
23
|
+
gem.add_runtime_dependency "parallelize", '~> 0.4.0'
|
24
|
+
gem.add_runtime_dependency "si", '~> 0.1.3'
|
25
|
+
unless RUBY_PLATFORM == 'java'
|
26
|
+
gem.add_runtime_dependency "sinatra", '~> 1.3.3'
|
27
|
+
gem.add_runtime_dependency "thin", '~> 1.5.0'
|
28
|
+
gem.add_runtime_dependency "json", '~> 1.7.5'
|
29
|
+
gem.add_runtime_dependency "daemons", '~> 1.1.9'
|
30
|
+
end
|
31
|
+
|
32
|
+
gem.add_development_dependency 'test-unit'
|
33
|
+
end
|
data/test/bin_helper.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
# DISCLAIMER:
|
5
|
+
# Not a real test!
|
6
|
+
# Just a helper script for running scripts with local source
|
7
|
+
|
8
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '../lib')
|
9
|
+
load File.join(File.dirname(__FILE__), '../bin/', File.basename(ARGV.shift))
|
@@ -0,0 +1,193 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'test-unit'
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
require 'redis-stat'
|
8
|
+
require 'redis'
|
9
|
+
require 'stringio'
|
10
|
+
|
11
|
+
class TestRedisStat < Test::Unit::TestCase
|
12
|
+
def test_humanize_number
|
13
|
+
rs = RedisStat.new
|
14
|
+
assert_equal '0', rs.send(:humanize_number, 0.00)
|
15
|
+
assert_equal '7', rs.send(:humanize_number, 7)
|
16
|
+
assert_equal '0.01', rs.send(:humanize_number, 0.00751)
|
17
|
+
assert_equal '0.08', rs.send(:humanize_number, 0.0751)
|
18
|
+
assert_equal '0.75', rs.send(:humanize_number, 0.751)
|
19
|
+
assert_equal '7.51', rs.send(:humanize_number, 7.51)
|
20
|
+
assert_equal '75.1', rs.send(:humanize_number, 75.1)
|
21
|
+
assert_equal '7.51k', rs.send(:humanize_number, 7510)
|
22
|
+
assert_equal '75.1k', rs.send(:humanize_number, 75100)
|
23
|
+
assert_equal '751k', rs.send(:humanize_number, 751000)
|
24
|
+
assert_equal '7.51M', rs.send(:humanize_number, 7510000)
|
25
|
+
assert_equal '75.1M', rs.send(:humanize_number, 75100000)
|
26
|
+
assert_equal '751M', rs.send(:humanize_number, 751000000)
|
27
|
+
assert_equal '7.51G', rs.send(:humanize_number, 7510000000)
|
28
|
+
assert_equal '75.1G', rs.send(:humanize_number, 75100000000)
|
29
|
+
assert_equal '751G', rs.send(:humanize_number, 751000000000)
|
30
|
+
assert_equal '7.51T', rs.send(:humanize_number, 7510000000000)
|
31
|
+
assert_equal '75.1T', rs.send(:humanize_number, 75100000000000)
|
32
|
+
assert_equal '751T', rs.send(:humanize_number, 751000000000000)
|
33
|
+
assert_equal '7.51P', rs.send(:humanize_number, 7510000000000000)
|
34
|
+
assert_equal '75.1P', rs.send(:humanize_number, 75100000000000000)
|
35
|
+
assert_equal '751P', rs.send(:humanize_number, 751000000000000000)
|
36
|
+
assert_equal '7.51E', rs.send(:humanize_number, 7510000000000000000)
|
37
|
+
assert_equal '75.1E', rs.send(:humanize_number, 75100000000000000000)
|
38
|
+
assert_equal '751E', rs.send(:humanize_number, 751000000000000000000)
|
39
|
+
assert_equal '7.51Z', rs.send(:humanize_number, 7510000000000000000000)
|
40
|
+
|
41
|
+
assert_equal '7.51PB', rs.send(:humanize_number, 7.51 * (1024 ** 5), true)
|
42
|
+
assert_equal '-7.51PB', rs.send(:humanize_number, -7.51 * (1024 ** 5), true)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_option_parse
|
46
|
+
options = RedisStat::Option.parse([])
|
47
|
+
assert_equal RedisStat::Option::DEFAULT.sort, options.sort
|
48
|
+
|
49
|
+
options = RedisStat::Option.parse(%w[localhost:1000 20])
|
50
|
+
assert_equal({
|
51
|
+
:hosts => ['localhost:1000'],
|
52
|
+
:interval => 20,
|
53
|
+
:count => nil,
|
54
|
+
:csv => nil,
|
55
|
+
:style => :unicode
|
56
|
+
}.sort, options.sort)
|
57
|
+
|
58
|
+
options = RedisStat::Option.parse(%w[localhost:1000 20 30])
|
59
|
+
assert_equal({
|
60
|
+
:hosts => ['localhost:1000'],
|
61
|
+
:interval => 20,
|
62
|
+
:count => 30,
|
63
|
+
:csv => nil,
|
64
|
+
:style => :unicode
|
65
|
+
}.sort, options.sort)
|
66
|
+
|
67
|
+
options = RedisStat::Option.parse(%w[20])
|
68
|
+
assert_equal({
|
69
|
+
:hosts => ['127.0.0.1:6379'],
|
70
|
+
:interval => 20,
|
71
|
+
:count => nil,
|
72
|
+
:csv => nil,
|
73
|
+
:style => :unicode
|
74
|
+
}.sort, options.sort)
|
75
|
+
|
76
|
+
options = RedisStat::Option.parse(%w[20 30])
|
77
|
+
assert_equal({
|
78
|
+
:hosts => ['127.0.0.1:6379'],
|
79
|
+
:interval => 20,
|
80
|
+
:count => 30,
|
81
|
+
:csv => nil,
|
82
|
+
:style => :unicode
|
83
|
+
}.sort, options.sort)
|
84
|
+
|
85
|
+
options = RedisStat::Option.parse(%w[localhost:8888 10 --csv=/tmp/a.csv --style=ascii --auth password])
|
86
|
+
assert_equal({
|
87
|
+
:auth => 'password',
|
88
|
+
:hosts => ['localhost:8888'],
|
89
|
+
:interval => 10,
|
90
|
+
:count => nil,
|
91
|
+
:csv => '/tmp/a.csv',
|
92
|
+
:style => :ascii
|
93
|
+
}.sort, options.sort)
|
94
|
+
|
95
|
+
options = RedisStat::Option.parse(%w[-h localhost:8888 10 -a password --csv=/tmp/a.csv --style=ascii])
|
96
|
+
assert_equal({
|
97
|
+
:auth => 'password',
|
98
|
+
:hosts => ['localhost:8888'],
|
99
|
+
:interval => 10,
|
100
|
+
:count => nil,
|
101
|
+
:csv => '/tmp/a.csv',
|
102
|
+
:style => :ascii
|
103
|
+
}.sort, options.sort)
|
104
|
+
|
105
|
+
# Server
|
106
|
+
if RUBY_PLATFORM == 'java'
|
107
|
+
assert_raise(SystemExit) {
|
108
|
+
RedisStat::Option.parse(%w[-h localhost:8888 10 -a password --csv=/tmp/a.csv --style=ascii --server=5555])
|
109
|
+
}
|
110
|
+
assert_raise(SystemExit) {
|
111
|
+
RedisStat::Option.parse(%w[-h localhost:8888 10 -a password --csv=/tmp/a.csv --style=ascii --server=5555 --daemon])
|
112
|
+
}
|
113
|
+
else
|
114
|
+
options = RedisStat::Option.parse(%w[-h localhost:8888 10 -a password --csv=/tmp/a.csv --style=ascii --server=5555 --daemon])
|
115
|
+
assert_equal({
|
116
|
+
:auth => 'password',
|
117
|
+
:hosts => ['localhost:8888'],
|
118
|
+
:interval => 10,
|
119
|
+
:count => nil,
|
120
|
+
:csv => '/tmp/a.csv',
|
121
|
+
:server_port => "5555",
|
122
|
+
:style => :ascii,
|
123
|
+
:daemon => true
|
124
|
+
}.sort, options.sort)
|
125
|
+
end
|
126
|
+
|
127
|
+
options = RedisStat::Option.parse(%w[--no-color])
|
128
|
+
assert_equal true, options[:mono]
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_option_parse_invalid
|
132
|
+
[
|
133
|
+
%w[localhost 0],
|
134
|
+
%w[localhost 5 0]
|
135
|
+
].each do |argv|
|
136
|
+
assert_raise(SystemExit) {
|
137
|
+
options = RedisStat::Option.parse(argv)
|
138
|
+
}
|
139
|
+
end
|
140
|
+
|
141
|
+
assert_raise(SystemExit) {
|
142
|
+
RedisStat::Option.parse(%w[--style=html])
|
143
|
+
}
|
144
|
+
|
145
|
+
assert_raise(SystemExit) {
|
146
|
+
RedisStat::Option.parse(%w[--daemon])
|
147
|
+
}
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_start
|
151
|
+
csv = '/tmp/redis-stat.csv'
|
152
|
+
cnt = 100
|
153
|
+
rs = RedisStat.new :hosts => %w[localhost] * 5, :interval => 0.01, :count => cnt,
|
154
|
+
:verbose => true, :csv => csv, :auth => 'pw'
|
155
|
+
rs.start $stdout
|
156
|
+
|
157
|
+
assert_equal cnt + 1, File.read(csv).lines.to_a.length
|
158
|
+
ensure
|
159
|
+
File.unlink csv
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_mono
|
163
|
+
[true, false].each do |mono|
|
164
|
+
rs = RedisStat.new :hosts => %w[localhost] * 5, :interval => 0.02, :count => 20,
|
165
|
+
:verbose => true, :auth => 'pw', :mono => mono
|
166
|
+
output = StringIO.new
|
167
|
+
rs.start output
|
168
|
+
puts output.string
|
169
|
+
assert_equal mono, output.string !~ /\e\[\d*(;\d+)*m/
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_static_info_of_mixed_versions
|
174
|
+
# prerequisite
|
175
|
+
r1 = Redis.new(:host => 'localhost')
|
176
|
+
r2 = Redis.new(:host => 'localhost', :port => 6380)
|
177
|
+
|
178
|
+
if r1.info['redis_version'] =~ /^2\.4/ && r2.info['redis_version'] =~ /^2\.2/
|
179
|
+
rs = RedisStat.new :hosts => %w[localhost:6380 localhost], :interval => 1, :count => 1,
|
180
|
+
:auth => 'pw', :style => :ascii
|
181
|
+
output = StringIO.new
|
182
|
+
rs.start output
|
183
|
+
vline = output.string.lines.select { |line| line =~ /gcc_version/ }.first
|
184
|
+
puts vline.gsub(/ +/, ' ')
|
185
|
+
assert vline.gsub(/ +/, ' ').include?('| | 4.2.1 |')
|
186
|
+
else
|
187
|
+
raise NotImplementedError.new # FIXME
|
188
|
+
end
|
189
|
+
rescue Redis::CannotConnectError, NotImplementedError
|
190
|
+
pend "redises not ready"
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|