redis-stat 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 88b48d390b0584414c03baf3f3201af816bf89e9
4
- data.tar.gz: 8cba293490f939431fc0aa82a45f06ae3f7a140b
3
+ metadata.gz: f077a3bea5627a3c4a8facf1fe28f4f3f3d93672
4
+ data.tar.gz: 6f6441674aa5557d68ed441ed416e6ec5a1ae146
5
5
  SHA512:
6
- metadata.gz: fc1a3324b2f435c39edb17114fa96714ac3e1e24ba2e1f57a8f9d89ec6ad1c7bb54d209beb9e1f151d391d0ef94a5114850d79f19585f6d38606aba38429f04c
7
- data.tar.gz: 3fdc739c0858e5830760e2b227a8562e73b611f745f0456de1c150c6a240e9bdc10372ce78eb9b7b278c77b9932db18e88967fe44a0e26e83680b7b67e976728
6
+ metadata.gz: 7a1dd553225f59b1bc0bea4a7945e06ce721f90461789bc45ef6df1f889df5bb02b08fd2c33f8c4a1024a434b21c9d354480092efccde8cf6be4774925701d3a
7
+ data.tar.gz: 9fc292656976fd799d785bfcc1aed5b66a0e157333f8b552b48c38decb4606563fe30ce805eb7a38195d5ab7d2b1b8814c88ed6f9c2307557ea243daece3bde0
data/README.md CHANGED
@@ -103,7 +103,3 @@ the original [redis-stat](https://github.com/antirez/redis-tools/blob/master/red
103
103
  included in [redis-tools](https://github.com/antirez/redis-tools) written by the creator of Redis himself. (My bad)
104
104
  Although the original C-version hasn't been updated for the past couple of years, you might want to check it out first.
105
105
 
106
-
107
-
108
- [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/junegunn/redis-stat/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
109
-
data/lib/redis-stat.rb CHANGED
@@ -14,6 +14,7 @@ require 'parallelize'
14
14
  require 'si'
15
15
  require 'rbconfig'
16
16
  require 'lps'
17
+ require 'readline'
17
18
 
18
19
  class RedisStat
19
20
  attr_reader :hosts, :measures, :tab_measures, :verbose, :interval
@@ -26,9 +27,10 @@ class RedisStat
26
27
  options[:style] = :ascii if windows
27
28
 
28
29
  @hosts = options[:hosts]
29
- @redises = @hosts.map { |e|
30
+ @redises = @hosts.inject({}) { |hash, e|
30
31
  host, port = e.split(':')
31
- Redis.new(Hash[ {:host => host, :port => port, :timeout => DEFAULT_REDIS_TIMEOUT}.select { |k, v| v } ])
32
+ hash[e] = Redis.new(Hash[ {:host => host, :port => port, :timeout => DEFAULT_REDIS_TIMEOUT}.select { |k, v| v } ])
33
+ hash
32
34
  }
33
35
  @interval = options[:interval]
34
36
  @max_count = options[:count]
@@ -49,10 +51,6 @@ class RedisStat
49
51
  @elasticsearch = options[:es] && ElasticsearchSink.new(@hosts, options[:es])
50
52
  end
51
53
 
52
- def info
53
- collect
54
- end
55
-
56
54
  def start output_stream
57
55
  @os = output_stream
58
56
  trap('INT') { Thread.main.raise Interrupt }
@@ -65,37 +63,41 @@ class RedisStat
65
63
  @started_at = Time.now
66
64
  prev_info = nil
67
65
  server = start_server if @server_port
66
+ errors = 0
68
67
 
69
68
  LPS.interval(@interval).loop do
70
- errs = 0
71
- info =
69
+ info, exceptions =
72
70
  begin
73
71
  collect
74
72
  rescue Interrupt
75
73
  raise
76
- rescue Exception => e
77
- if need_auth?(e)
78
- authenticate!
79
- retry
80
- end
81
-
82
- errs += 1
83
- if server || errs < NUM_RETRIES
84
- @os.puts if errs == 1
85
- @os.puts "#{e} (#{ server ? "#{errs}" : [errs, NUM_RETRIES].join('/') })".red.bold
86
- server.alert "#{e} (#{errs})" if server
87
- sleep @interval
88
- retry
89
- else
90
- raise
91
- end
92
74
  end
75
+
76
+ if exceptions.any? { |k, v| need_auth? v }
77
+ authenticate!
78
+ next
79
+ end
80
+
81
+ output_es info if @elasticsearch
82
+
83
+ unless exceptions.empty?
84
+ now = Time.now.strftime('%Y/%m/%d %H:%M:%S')
85
+ msgs = exceptions.map { |h, x| "[#{now}@#{h}] #{x}" }
86
+ @os.puts if (errors += 1) == 1
87
+ @os.puts msgs.join($/).red.bold
88
+ server.alert msgs.first if server
89
+ sleep @interval
90
+ next
91
+ end
92
+
93
93
  info_output = process info, prev_info
94
- output info, info_output, csv
95
- server.push info, Hash[info_output] if server
94
+ output_static_info info if @count == 0
95
+ output info_output, csv
96
+ server.push @hosts, info, Hash[info_output] if server
96
97
  prev_info = info
97
98
 
98
99
  @count += 1
100
+ errors = 0
99
101
  break if @max_count && @count >= @max_count
100
102
  end
101
103
  @os.puts
@@ -107,7 +109,6 @@ class RedisStat
107
109
  @server_thr.join
108
110
  end
109
111
  rescue Exception => e
110
- @os.puts
111
112
  @os.puts e.to_s.red.bold
112
113
  raise
113
114
  ensure
@@ -120,7 +121,7 @@ private
120
121
  def start_server
121
122
  RedisStat::Server.set :port, @server_port
122
123
  RedisStat::Server.set :redis_stat, self
123
- RedisStat::Server.set :last_info, info
124
+ RedisStat::Server.set :last_info, collect.first
124
125
  @server_thr = Thread.new { RedisStat::Server.run! }
125
126
  RedisStat::Server.wait_until_running
126
127
  trap('INT') { Thread.main.raise Interrupt }
@@ -128,45 +129,47 @@ private
128
129
  end
129
130
 
130
131
  def collect
131
- {}.insensitive.tap do |info|
132
- class << info
133
- def sumf label
134
- (self[label] || []).map(&:to_f).inject(:+)
135
- end
132
+ info = {
133
+ :at => Time.now.to_f,
134
+ :instances => Hash.new { |h, k| h[k] = {}.insensitive }
135
+ }
136
+ class << info
137
+ def sumf label
138
+ self[:instances].values.map { |hash| hash[label].to_f }.inject(:+)
136
139
  end
140
+ end
141
+ exceptions = {}
137
142
 
138
- info[:at] = Time.now.to_f
139
- @redises.pmap(@redises.length) { |redis|
140
- redis.info.insensitive
141
- }.each do |rinfo|
143
+ @hosts.pmap(@hosts.length) { |host|
144
+ begin
145
+ [host, @redises[host].info.insensitive]
146
+ rescue Exception => e
147
+ [host, e]
148
+ end
149
+ }.each do |host, rinfo|
150
+ if rinfo.is_a?(Exception)
151
+ exceptions[host] = rinfo
152
+ else
142
153
  (@all_measures + rinfo.keys.select { |k| k =~ /^db[0-9]+$/ }).each do |k|
143
154
  ks = [*k]
144
155
  v = ks.map { |e| rinfo[e] }.compact.first
145
156
  k = ks.first
146
- info[k] ||= []
147
- info[k] << v
157
+ info[:instances][host][k] = v
148
158
  end
149
159
  end
150
160
  end
161
+ [info, exceptions]
151
162
  end
152
163
 
153
164
  def update_term_size!
154
165
  if RUBY_PLATFORM == 'java'
155
166
  require 'java'
156
167
  begin
157
- case JRUBY_VERSION
158
- when /^1\.7/
159
- # TODO Currently Windows terminal is not supported: always returns 80x24
160
- @term ||= Java::jline.console.ConsoleReader.new.getTerminal
161
- @term_width = (@term.width rescue DEFAULT_TERM_WIDTH)
162
- @term_height = (@term.height rescue DEFAULT_TERM_HEIGHT) - 4
163
- return
164
- when /^1\.6/
165
- @term ||= Java::jline.ConsoleReader.new.getTerminal
166
- @term_width = (@term.getTerminalWidth rescue DEFAULT_TERM_WIDTH)
167
- @term_height = (@term.getTerminalHeight rescue DEFAULT_TERM_HEIGHT) - 4
168
- return
169
- end
168
+ @term ||= (Java::jline.console.ConsoleReader.new.getTerminal) rescue
169
+ (Java::jline.ConsoleReader.new.getTerminal)
170
+ @term_width = (@term.width rescue DEFAULT_TERM_WIDTH)
171
+ @term_height = (@term.height rescue DEFAULT_TERM_HEIGHT) - 4
172
+ return
170
173
  rescue Exception
171
174
  # Fallback to tput (which yields incorrect values as of now)
172
175
  end
@@ -204,8 +207,6 @@ private
204
207
 
205
208
  movement = nil
206
209
  if @count == 0
207
- output_static_info info
208
-
209
210
  movement = 0
210
211
  elsif @count % @term_height == 0
211
212
  @first_batch = false
@@ -245,7 +246,7 @@ private
245
246
  @os.print $/ + lines.join($/)
246
247
  @os.flush
247
248
  rescue Interrupt
248
- move! -movement
249
+ move!(-movement)
249
250
  raise
250
251
  end
251
252
  end
@@ -259,15 +260,14 @@ private
259
260
  tab << [nil] + @hosts.map { |h| h.bold.green }
260
261
  tab.separator!
261
262
  @tab_measures.each do |key|
262
- tab << [key.to_s.bold] + info[key] unless info[key].compact.empty?
263
+ tab << [key.to_s.bold] + @hosts.map { |host| info[:instances][host][key] }
263
264
  end
264
265
  @os.puts tab
265
266
  end
266
267
 
267
- def output info, info_output, file
268
- output_term info_output unless @daemonized
268
+ def output info_output, file
269
+ output_term info_output unless @daemonized
269
270
  output_file info_output, file if file
270
- output_es info if @elasticsearch
271
271
  end
272
272
 
273
273
  def output_es info
@@ -380,7 +380,7 @@ private
380
380
  end
381
381
 
382
382
  def authenticate!
383
- @redises.each do |r|
383
+ @redises.values.each do |r|
384
384
  r.ping rescue (r.auth @auth)
385
385
  end if @auth
386
386
  end
@@ -4,8 +4,6 @@ class RedisStat
4
4
  DEFAULT_SERVER_PORT = 63790
5
5
  DEFAULT_REDIS_TIMEOUT = 30
6
6
 
7
- NUM_RETRIES = 5
8
-
9
7
  MEASURES = {
10
8
  :static => [
11
9
  :redis_version,
@@ -38,14 +38,13 @@ class ElasticsearchSink
38
38
  end
39
39
 
40
40
  def output info
41
- results = convert_to_i info
42
- results.map do |host, entries|
41
+ convert_to_i(info).map do |host, entries|
43
42
  time = entries[:at]
44
43
  entry = {
45
44
  :index => index,
46
45
  :type => "redis",
47
46
  :body => entries.merge({
48
- :@timestamp => Time.at(time).strftime("%FT%T%:z"),
47
+ :@timestamp => format_time(time),
49
48
  :host => host
50
49
  }),
51
50
  }
@@ -55,29 +54,29 @@ class ElasticsearchSink
55
54
  end
56
55
 
57
56
  private
58
- def link_hosts_to_info info
59
- {}.tap do |output|
60
- hosts.each_with_index do |host, index|
61
- output[host] = {}.tap do |host_output|
62
- info.each do |name, entries|
63
- value = name == :at ? entries : entries[index]
64
- host_output[name] = value
65
- end
66
- end
67
- end
57
+ if RUBY_VERSION.start_with? '1.8.'
58
+ def format_time time
59
+ fmt = Time.at(time).strftime("%FT%T%z")
60
+ fmt[0..-3] + ':' + fmt[-2..-1]
61
+ end
62
+ else
63
+ def format_time time
64
+ Time.at(time).strftime("%FT%T%:z")
68
65
  end
69
66
  end
70
67
 
71
68
  def convert_to_i info
72
- info = link_hosts_to_info info
73
- info.each do |host, entries|
69
+ Hash[info[:instances].map { |host, entries|
70
+ output = {}
71
+ output[:at] = info[:at].to_i
74
72
  entries.each do |name, value|
75
73
  convert = RedisStat::LABELS[name] || TO_I[name]
76
74
  if convert
77
- entries[name] = value.to_i
75
+ output[name] = value.to_i
78
76
  end
79
77
  end
80
- end
78
+ [host, output]
79
+ }]
81
80
  end
82
81
  end
83
82
  end
@@ -14,7 +14,7 @@ module Option
14
14
  argv = argv.reject { |e| e == '-h' }
15
15
 
16
16
  options = DEFAULT.dup
17
- opts = ::OptionParser.new { |opts|
17
+ op = ::OptionParser.new { |opts|
18
18
  opts.banner = "usage: redis-stat [HOST[:PORT] ...] [INTERVAL [COUNT]]"
19
19
  opts.separator ''
20
20
 
@@ -69,7 +69,7 @@ module Option
69
69
  }
70
70
 
71
71
  begin
72
- opts.parse! argv
72
+ op.parse! argv
73
73
 
74
74
  is_number = lambda { |str| str =~ /^([0-9]\.?[0-9]*)$|^([1-9][0-9]*)$/ }
75
75
 
@@ -87,7 +87,7 @@ module Option
87
87
  exit e.status
88
88
  rescue Exception => e
89
89
  puts e.to_s
90
- puts opts
90
+ puts op
91
91
  exit 1
92
92
  end
93
93
  end
@@ -83,9 +83,9 @@ class Server < Sinatra::Base
83
83
  end
84
84
  end
85
85
 
86
- def push info, data
86
+ def push hosts, info, data
87
87
  static = Hash[settings.redis_stat.tab_measures.map { |stat|
88
- [stat, info[stat]]
88
+ [stat, hosts.map { |h| info[:instances][h][stat] }]
89
89
  }]
90
90
  data = {:at => (Time.now.to_f * 1000).to_i, :static => static, :dynamic => data}
91
91
 
@@ -101,9 +101,9 @@
101
101
  <tbody>
102
102
  <% @tab_measures.each do |stat| %>
103
103
  <tr id="<%= stat %>">
104
- <% @hosts.each_with_index do |host, idx| %>
104
+ <% @hosts.each do |host| %>
105
105
  <td>
106
- <%= @info[stat][idx] %>
106
+ <%= @info[:instances][host][stat] %>
107
107
  </td>
108
108
  <% end %>
109
109
  </tr>
@@ -1,3 +1,3 @@
1
1
  class RedisStat
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.1"
3
3
  end
@@ -203,7 +203,7 @@ class TestRedisStat < MiniTest::Unit::TestCase
203
203
  {
204
204
  'localhost/index' => %w[http://localhost index],
205
205
  'https://localhost/index' => %w[https://localhost index],
206
- 'https://localhost' => %w[https://localhost services],
206
+ 'https://localhost' => %w[https://localhost redis-stat],
207
207
  'httpserver:9200/index' => %w[http://httpserver:9200 index],
208
208
  }.each do |arg, ret|
209
209
  assert_equal ret, RedisStat::ElasticsearchSink.parse_url(arg)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-stat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Junegunn Choi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-03 00:00:00.000000000 Z
11
+ date: 2014-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ansi256