mmtop 0.9.6 → 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,22 +1,52 @@
1
+ require 'ruby-debug'
1
2
  module MMTop
2
3
  class Command
4
+ def self.parse_kill_selection(str)
5
+ strs = str.split(/\s*,\s*/).map(&:strip)
6
+ strs.map { |s|
7
+ if not s =~ /^[0-9-\*]+$/
8
+ $stdout.puts("Invalid query selection, try again")
9
+ return nil
10
+ else
11
+ if s.include?("-")
12
+ a = s.split("-").map(&:strip)
13
+ ((a[0].to_i)..(a[1].to_i)).to_a
14
+ elsif s == "*"
15
+ s
16
+ else
17
+ s.to_i
18
+ end
19
+ end
20
+ }.flatten
21
+ end
22
+
3
23
  def self.kill_prompt(queries)
4
24
  if queries.empty?
5
25
  puts "No queries matched."
6
26
  return
7
27
  end
8
-
28
+
9
29
  puts "killing: "
10
30
  queries.each_with_index do |q, i|
11
31
  puts "#{i}: #{q.host.name}\t\t#{q.sql[0..80]}"
12
32
  end
13
33
 
14
- print "Please confirm (y|n)> "
15
- if $stdin.readline != "y\n"
16
- puts "no, ok."
34
+ print "What shall I kill? (ex: 1-4,5,9|*)> "
35
+
36
+ line = $stdin.readline
37
+ if line == "\n"
38
+ puts "nothing, ok."
17
39
  else
18
- queries.each(&:kill!)
19
- puts "killed."
40
+ indexes = parse_kill_selection(line)
41
+ indexes.each { |i|
42
+ if i == "*"
43
+ queries.each(&:kill!)
44
+ elsif queries[i]
45
+ queries[i].kill!
46
+ else
47
+ puts "No such query: #{i}"
48
+ end
49
+ }
20
50
  end
21
51
  end
22
52
  end
@@ -51,7 +81,7 @@ MMTop::Command.register do |c|
51
81
  cmd =~ c.regexp
52
82
  time = $3.to_i
53
83
  server = $4.strip
54
- list = config.all_processes.select { |p|
84
+ list = config.all_processes.select { |p|
55
85
  p.time > time && p.sql =~ /select/i && (server.nil? || server.size == 0 || (server == p.host.name))
56
86
  }
57
87
  MMTop::Command.kill_prompt(list)
@@ -59,15 +89,13 @@ MMTop::Command.register do |c|
59
89
  end
60
90
 
61
91
 
62
-
63
-
64
92
  MMTop::Command.register do |c|
65
93
  c.regexp %r{^k(ill)?\s+(/.*/\w*)}
66
94
  c.usage "kill /REGEXP/"
67
95
  c.explain "Kill a number of queries by REGEXP"
68
96
  c.command do |cmd, config|
69
97
  cmd =~ c.regexp
70
- r = eval($2)
98
+ r = eval($2)
71
99
  if !r.is_a?(Regexp)
72
100
  puts "Invalid regexp \"#{$1}\""
73
101
  else
@@ -18,7 +18,7 @@ module MMTop
18
18
  hosts.each { |h|
19
19
  top = new_top.find { |t| t[:hostname] == h.name }
20
20
  next unless top
21
- if top[:levels] > 0
21
+ if top[:levels] > 0
22
22
  h.display_name = (" " * top[:levels]) + '\_' + h.name
23
23
  end
24
24
  }
@@ -27,13 +27,13 @@ module MMTop
27
27
 
28
28
  def insert_host_into_sort_array(t, host, array)
29
29
  array << host
30
- t.select { |k, v|
30
+ t.select { |k, v|
31
31
  # find hosts who are our slaves
32
- v[:master] == host[:ip]
33
- }.sort_by { |k, v|
32
+ v[:master] == host[:ip]
33
+ }.sort_by { |k, v|
34
34
  # add those without children of their own first
35
- v[:is_master].to_i
36
- }.each { |k, s|
35
+ v[:is_master].to_i
36
+ }.each { |k, s|
37
37
  insert_host_into_sort_array(t, s, array)
38
38
  }
39
39
  array
@@ -43,8 +43,8 @@ module MMTop
43
43
  def create_sort_array(t)
44
44
  array = []
45
45
  t.values.select { |v|
46
- v[:levels] == 0
47
- }.sort_by { |v|
46
+ v[:levels] == 0
47
+ }.sort_by { |v|
48
48
  v[:hostname]
49
49
  }.each { |v|
50
50
  insert_host_into_sort_array(t, v, array)
@@ -60,7 +60,7 @@ module MMTop
60
60
  # loop detection
61
61
  break if stack.include?(master)
62
62
 
63
- last_master = master
63
+ last_master = master
64
64
  levels += 1
65
65
  stack.push(master)
66
66
  end
@@ -72,13 +72,13 @@ module MMTop
72
72
  return nil if hostname.nil?
73
73
  return hostname if hostname =~ /\d+\.\d+\.\d+\.\d+\./
74
74
 
75
- arr = Socket::gethostbyname(hostname)
75
+ arr = Socket::gethostbyname(hostname)
76
76
  arr && arr.last.unpack("CCCC").join(".")
77
77
  end
78
78
 
79
79
  def find_master_slave
80
80
  @config.hosts.each { |host|
81
- host.ip = resolve_to_ip(host.name)
81
+ host.ip = resolve_to_ip(host.name)
82
82
  }
83
83
 
84
84
  topology = @config.hosts.inject({}) { |accum, h|
@@ -101,7 +101,7 @@ module MMTop
101
101
  master_top = topology[v[:master]]
102
102
  if master_top
103
103
  master_top[:is_master] = 1
104
- end
104
+ end
105
105
  }
106
106
  topology
107
107
  end
data/lib/mmtop/host.rb CHANGED
@@ -22,7 +22,9 @@ module MMTop
22
22
  if e.error_number == 2003
23
23
  mark_dead!
24
24
  else
25
- raise e
25
+ $stdout.puts("Got Error Number #{e.error_number} (#{e.inspect}) trying to connect to #{@name}")
26
+ mark_dead!
27
+ sleep(1)
26
28
  end
27
29
  end
28
30
 
@@ -19,7 +19,7 @@ module MMTop
19
19
  h['wedge_monitor'] ||= config['wedge_monitor']
20
20
 
21
21
  Host.new(h['host'], h['user'], h['password'], h)
22
- end.compact
22
+ end.compact.uniq { |h| h.name }
23
23
 
24
24
  @filters = MMTop::Filter.default_filters
25
25
  config['sleep'] ||= 5
data/lib/mmtop/process.rb CHANGED
@@ -5,7 +5,7 @@ module MMTop
5
5
  @query = result[:Info]
6
6
  @status = result[:State]
7
7
  @time = result[:Time]
8
- @client, @client_port = result[:Host] && result[:Host].split(":")
8
+ @client, @client_port = result[:Host] && result[:Host].split(":")
9
9
  @client ||= "(slave)"
10
10
  @client_port ||= ""
11
11
  @db = result[:db]
@@ -19,7 +19,7 @@ module MMTop
19
19
  end
20
20
 
21
21
  def kill!
22
- begin
22
+ begin
23
23
  @host.query("KILL #{@real_id}")
24
24
  rescue Mysql2::Error => e
25
25
  puts e
data/lib/mmtop/qps.rb CHANGED
@@ -7,7 +7,7 @@ module MMTop
7
7
  def self.window
8
8
  @window || DEFAULT_WINDOW
9
9
  end
10
-
10
+
11
11
  def self.window=(window)
12
12
  @window = window
13
13
  end
@@ -27,7 +27,7 @@ module MMTop
27
27
 
28
28
  queries = samples.last[QUERIES] - samples.first[QUERIES]
29
29
  time = samples.last[TIME].to_i - samples.first[TIME].to_i
30
-
30
+
31
31
  queries / time
32
32
  end
33
33
 
@@ -1,5 +1,5 @@
1
1
  require 'timeout'
2
- require 'readline'
2
+ require 'readline'
3
3
 
4
4
  module MMTop
5
5
  class TermInput
@@ -23,7 +23,7 @@ module MMTop
23
23
  while true
24
24
  cmdline = Readline::readline('> ')
25
25
  exit if cmdline.nil?
26
- Readline::HISTORY.push(cmdline)
26
+ Readline::HISTORY.push(cmdline)
27
27
  return if cmdline.empty?
28
28
  c = find_command(cmdline)
29
29
  if c.nil?
@@ -58,7 +58,7 @@ module MMTop
58
58
  def sep_fill
59
59
  fill * sep.size
60
60
  end
61
-
61
+
62
62
  def column_value_with_fill(index, str, fill, align)
63
63
  fill_str = fill * (table_header_columns[index].size - str.size)
64
64
  if align == :left
@@ -115,13 +115,13 @@ module MMTop
115
115
  def format_process(process, sz)
116
116
  query = process.sql ? process.sql[0..sz-2] : ''
117
117
  case process.time
118
- when 0..2:
118
+ when 0..2
119
119
  query
120
- when 2..10:
120
+ when 2..10
121
121
  query.white.bold
122
122
  else
123
123
  query.red
124
- end
124
+ end
125
125
  end
126
126
 
127
127
  def clear_screen
@@ -163,11 +163,11 @@ module MMTop
163
163
  table_header_columns[-1] = ''
164
164
  end
165
165
 
166
- str = pipe + " " + table_header_columns.join(sep)
166
+ str = pipe + " " + table_header_columns.join(sep)
167
167
  fill_len = (@x - str.size) - 1
168
-
168
+
169
169
  print str
170
- print ' ' * fill_len if fill_len > 0
170
+ print ' ' * fill_len if fill_len > 0
171
171
  puts pipe
172
172
  end
173
173
 
metadata CHANGED
@@ -1,124 +1,151 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: mmtop
3
- version: !ruby/object:Gem::Version
4
- hash: 55
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.7
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 9
9
- - 6
10
- version: 0.9.6
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Ben Osheroff
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-02-03 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2012-12-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: mysql2
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- hash: 3
29
- segments:
30
- - 0
31
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
32
22
  type: :runtime
33
- version_requirements: *id001
34
- - !ruby/object:Gem::Dependency
35
- name: getopt-declare
36
23
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
38
25
  none: false
39
- requirements:
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- hash: 3
43
- segments:
44
- - 0
45
- version: "0"
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: getopt-declare
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
46
38
  type: :runtime
47
- version_requirements: *id002
48
- - !ruby/object:Gem::Dependency
49
- name: ruby-debug
50
39
  prerelease: false
51
- requirement: &id003 !ruby/object:Gem::Requirement
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: debugger
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: yaggy
64
+ requirement: !ruby/object:Gem::Requirement
52
65
  none: false
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- hash: 3
57
- segments:
58
- - 0
59
- version: "0"
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
60
70
  type: :development
61
- version_requirements: *id003
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rake
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
62
94
  description:
63
- email:
95
+ email:
64
96
  - ben@gimbo.net
65
- executables:
97
+ executables:
66
98
  - mmtop
67
99
  extensions: []
68
-
69
100
  extra_rdoc_files: []
70
-
71
- files:
72
- - lib/mmtop.rb
73
- - lib/mmtop/string_colorize.rb
101
+ files:
102
+ - lib/mmtop/command.rb
74
103
  - lib/mmtop/commands/basic.rb
75
104
  - lib/mmtop/commands/filters.rb
76
105
  - lib/mmtop/commands/kill.rb
77
106
  - lib/mmtop/filter.rb
107
+ - lib/mmtop/filters/basic.rb
108
+ - lib/mmtop/filters/map_topology.rb
109
+ - lib/mmtop/filters/reverse_lookup.rb
110
+ - lib/mmtop/host.rb
111
+ - lib/mmtop/mmconfig.rb
78
112
  - lib/mmtop/pid.rb
79
113
  - lib/mmtop/process.rb
80
- - lib/mmtop/host.rb
81
- - lib/mmtop/term_input.rb
82
114
  - lib/mmtop/qps.rb
83
- - lib/mmtop/mmconfig.rb
115
+ - lib/mmtop/string_colorize.rb
116
+ - lib/mmtop/term_input.rb
84
117
  - lib/mmtop/term_printer.rb
85
- - lib/mmtop/command.rb
86
- - lib/mmtop/filters/basic.rb
87
- - lib/mmtop/filters/map_topology.rb
88
- - lib/mmtop/filters/reverse_lookup.rb
89
- - bin/mmtop
118
+ - lib/mmtop.rb
119
+ - !binary |-
120
+ YmluL21tdG9w
90
121
  homepage: http://github.com/osheroff/mmtop
91
122
  licenses: []
92
-
93
123
  post_install_message:
94
124
  rdoc_options: []
95
-
96
- require_paths:
125
+ require_paths:
97
126
  - lib
98
- required_ruby_version: !ruby/object:Gem::Requirement
127
+ required_ruby_version: !ruby/object:Gem::Requirement
99
128
  none: false
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- hash: 3
104
- segments:
129
+ requirements:
130
+ - - ! '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ segments:
105
134
  - 0
106
- version: "0"
107
- required_rubygems_version: !ruby/object:Gem::Requirement
135
+ hash: 3103276699408599022
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
137
  none: false
109
- requirements:
110
- - - ">="
111
- - !ruby/object:Gem::Version
112
- hash: 3
113
- segments:
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ segments:
114
143
  - 0
115
- version: "0"
144
+ hash: 3103276699408599022
116
145
  requirements: []
117
-
118
146
  rubyforge_project:
119
- rubygems_version: 1.8.10
147
+ rubygems_version: 1.8.24
120
148
  signing_key:
121
149
  specification_version: 3
122
150
  summary: A mytop-ish variant that can watch many mysql servers
123
151
  test_files: []
124
-