mmtop 0.9.6 → 0.9.7
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/mmtop/commands/kill.rb +38 -10
- data/lib/mmtop/filters/map_topology.rb +12 -12
- data/lib/mmtop/host.rb +3 -1
- data/lib/mmtop/mmconfig.rb +1 -1
- data/lib/mmtop/process.rb +2 -2
- data/lib/mmtop/qps.rb +2 -2
- data/lib/mmtop/term_input.rb +2 -2
- data/lib/mmtop/term_printer.rb +7 -7
- metadata +107 -80
data/lib/mmtop/commands/kill.rb
CHANGED
@@ -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 "
|
15
|
-
|
16
|
-
|
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
|
-
|
19
|
-
|
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
data/lib/mmtop/mmconfig.rb
CHANGED
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
|
|
data/lib/mmtop/term_input.rb
CHANGED
@@ -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?
|
data/lib/mmtop/term_printer.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
19
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
25
|
none: false
|
39
|
-
requirements:
|
40
|
-
- -
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
-
|
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
|
-
|
57
|
-
segments:
|
58
|
-
- 0
|
59
|
-
version: "0"
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
60
70
|
type: :development
|
61
|
-
|
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
|
-
|
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/
|
115
|
+
- lib/mmtop/string_colorize.rb
|
116
|
+
- lib/mmtop/term_input.rb
|
84
117
|
- lib/mmtop/term_printer.rb
|
85
|
-
- lib/mmtop
|
86
|
-
-
|
87
|
-
|
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
|
-
|
104
|
-
segments:
|
129
|
+
requirements:
|
130
|
+
- - ! '>='
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
segments:
|
105
134
|
- 0
|
106
|
-
|
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
|
-
|
113
|
-
segments:
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
segments:
|
114
143
|
- 0
|
115
|
-
|
144
|
+
hash: 3103276699408599022
|
116
145
|
requirements: []
|
117
|
-
|
118
146
|
rubyforge_project:
|
119
|
-
rubygems_version: 1.8.
|
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
|
-
|