fluent-diagtool 0.1.7 → 0.1.8
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.
- checksums.yaml +4 -4
- data/bin/diagtool.rb +87 -0
- data/exclude_list01 +2 -0
- data/lib/fluent/diagtool/collectutils.rb +21 -63
- data/lib/fluent/diagtool/diagutils.rb +36 -58
- data/lib/fluent/diagtool/validutils.rb +16 -13
- data/lib/fluent/diagtool/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1afbc81ebf5fe6ab013818ac124776418b3c909bef5ac5a649210499c14ff2c9
|
4
|
+
data.tar.gz: ec4b237dcbe9f065f6645181c5cade9cc118cdfbc376460fbbf3108014d360f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71a1b513b1d55e3033ce8cd90d3060a6316c48358f2a374c75f23b43ddb32693dcb0107a96706a1c961445d23b93ada33edfaf7cda37c3ff415482af58c661a1
|
7
|
+
data.tar.gz: 92d4ed8273c892e623487ec0089a606d30bb14798d46c73d7c2469d2c167c8489293776c9750b0a1812edb9d61df0c70c3d2fb1caf75243cd8ed16ee8ae3ac63
|
data/bin/diagtool.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'logger'
|
3
|
+
require '../lib/diagutils'
|
4
|
+
include Diagtool
|
5
|
+
|
6
|
+
logger = Logger.new(STDOUT, formatter: proc {|severity, datetime, progname, msg|
|
7
|
+
"#{datetime}: [Diagtool] [#{severity}] #{msg}\n"
|
8
|
+
})
|
9
|
+
|
10
|
+
output_dir = '../output'
|
11
|
+
mask = 'yes'
|
12
|
+
exlist= Array.new
|
13
|
+
|
14
|
+
opt = OptionParser.new
|
15
|
+
opt.banner = "Usage: #{$0} -o OUTPUT_DIR -m {yes | no} -e {word1,[word2...]} -f {listfile}"
|
16
|
+
opt.on('-o','--output DIR', String, 'Output directory (Default=./output)') { |o|
|
17
|
+
output_dir = o
|
18
|
+
}
|
19
|
+
opt.on('-m','--mask YES|NO', String, 'Enable mask function (Default=True)') { |m|
|
20
|
+
if m == 'yes' || m == 'no'
|
21
|
+
mask = m
|
22
|
+
else
|
23
|
+
logger.error("Invalid value '#{m}' : -m | --mask should be yes or no")
|
24
|
+
exit!
|
25
|
+
end
|
26
|
+
}
|
27
|
+
opt.on('-e','--exclude-list LIST', Array, 'Provide a list of exclude words which will to be masked (Default=None)') { |e| exlist += e }
|
28
|
+
opt.on('-f','--exclude-file FILE', String, 'provide a file which describes a List of exclude words (Default=None)') { |f|
|
29
|
+
if File.exist?(f)
|
30
|
+
File.readlines(f).each do |l|
|
31
|
+
exlist.append(l.gsub(/\n/,''))
|
32
|
+
end
|
33
|
+
else
|
34
|
+
logger.error("No such file or directory")
|
35
|
+
exit!
|
36
|
+
end
|
37
|
+
}
|
38
|
+
opt.parse(ARGV)
|
39
|
+
exlist = exlist.uniq
|
40
|
+
|
41
|
+
logger.info("Parsing command options...")
|
42
|
+
logger.info(" Option : Output directory = #{output_dir}")
|
43
|
+
logger.info(" Option : Mask = #{mask}")
|
44
|
+
logger.info(" Option : Exclude list = #{exlist}")
|
45
|
+
|
46
|
+
logger.info("Initializing parameters...")
|
47
|
+
node1 = Diagutils.new(output_dir,exlist, 'INFO')
|
48
|
+
|
49
|
+
logger.info("Collecting log files of td-agent...")
|
50
|
+
tdlog = node1.collect_tdlog()
|
51
|
+
logger.info("log files of td-agent are stored in #{tdlog}")
|
52
|
+
|
53
|
+
logger.info("Collecting config file of td-agent...")
|
54
|
+
tdconf = node1.collect_tdconf()
|
55
|
+
logger.info("config file is stored in #{tdconf}")
|
56
|
+
|
57
|
+
logger.info("Collecting systctl information...")
|
58
|
+
sysctl = node1.collect_sysctl()
|
59
|
+
logger.info("sysctl information is stored in #{sysctl}")
|
60
|
+
|
61
|
+
logger.info("Collecting date/time information...")
|
62
|
+
ntp = node1.collect_ntp()
|
63
|
+
logger.info("date/time information is stored in #{ntp}")
|
64
|
+
|
65
|
+
logger.info("Collecting ulimit information...")
|
66
|
+
ulimit = node1.collect_ulimit()
|
67
|
+
logger.info("ulimit information is stored in #{ulimit}")
|
68
|
+
|
69
|
+
if mask == 'yes'
|
70
|
+
logger.info("Masking td-agent config file : #{tdconf}...")
|
71
|
+
node1.mask_tdconf(tdconf)
|
72
|
+
tdlog.each do | file |
|
73
|
+
logger.info("Masking td-agent log file : #{file}...")
|
74
|
+
filename = file.split("/")[-1]
|
75
|
+
if filename.include?(".gz")
|
76
|
+
node1.mask_tdlog_gz(file)
|
77
|
+
elsif
|
78
|
+
node1.mask_tdlog(file)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
tar_file = node1.compress_output()
|
84
|
+
logger.info("Generate tar file #{tar_file}")
|
85
|
+
|
86
|
+
|
87
|
+
|
data/exclude_list01
ADDED
@@ -22,7 +22,7 @@ module Diagtool
|
|
22
22
|
class CollectUtils
|
23
23
|
def initialize(conf, log_level)
|
24
24
|
@logger = Logger.new(STDOUT, level: log_level, formatter: proc {|severity, datetime, progname, msg|
|
25
|
-
"#{datetime}: [
|
25
|
+
"#{datetime}: [Collectutils] [#{severity}] #{msg}\n"
|
26
26
|
})
|
27
27
|
@precheck = conf[:precheck]
|
28
28
|
@time_format = conf[:time]
|
@@ -56,6 +56,7 @@ module Diagtool
|
|
56
56
|
@osenv = gen_osenv()
|
57
57
|
@oslog_path = '/var/log/'
|
58
58
|
@oslog = 'messages'
|
59
|
+
@syslog = 'syslog'
|
59
60
|
@sysctl_path = '/etc/'
|
60
61
|
@sysctl = 'sysctl.conf'
|
61
62
|
|
@@ -189,77 +190,34 @@ module Diagtool
|
|
189
190
|
return Dir.glob(target_dir+@tdlog+'*')
|
190
191
|
end
|
191
192
|
|
192
|
-
def collect_sysctl()
|
193
|
-
target_dir = @workdir+@sysctl_path
|
194
|
-
FileUtils.mkdir_p(target_dir)
|
195
|
-
FileUtils.cp(@sysctl_path+@sysctl, target_dir)
|
196
|
-
return target_dir+@sysctl
|
197
|
-
end
|
198
|
-
|
199
193
|
def collect_oslog()
|
200
194
|
target_dir = @workdir+@oslog_path
|
201
195
|
FileUtils.mkdir_p(target_dir)
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
f.puts(stdout)
|
211
|
-
end
|
212
|
-
return output
|
213
|
-
end
|
214
|
-
|
215
|
-
def collect_ps_eo()
|
216
|
-
output = @outdir+'/ps_eo.output'
|
217
|
-
stdout, stderr, status = Open3.capture3("ps -eo pid,ppid,stime,time,%mem,%cpu,cmd")
|
218
|
-
File.open(output, 'w') do |f|
|
219
|
-
f.puts(stdout)
|
196
|
+
if File.exist? @oslog_path+@oslog
|
197
|
+
FileUtils.cp(@oslog_path+@oslog, target_dir)
|
198
|
+
return target_dir+@oslog
|
199
|
+
elsif File.exist? @oslog_path+@syslog
|
200
|
+
FileUtils.cp(@oslog_path+@syslog, target_dir)
|
201
|
+
return target_dir+@syslog
|
202
|
+
else
|
203
|
+
@logger.warn("Can not find OS log file in #{oslog} or #{syslog}")
|
220
204
|
end
|
221
|
-
return output
|
222
205
|
end
|
223
206
|
|
224
|
-
def
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
output = @outdir+'/netstat_plan.output'
|
235
|
-
stdout, stderr, status = Open3.capture3("netstat -plan")
|
236
|
-
File.open(output, 'w') do |f|
|
237
|
-
f.puts(stdout)
|
238
|
-
end
|
239
|
-
return output
|
240
|
-
end
|
241
|
-
|
242
|
-
def collect_netstat_s()
|
243
|
-
output = @outdir+'/netstat_s.output'
|
244
|
-
stdout, stderr, status = Open3.capture3("netstat -s")
|
245
|
-
File.open(output, 'w') do |f|
|
246
|
-
f.puts(stdout)
|
247
|
-
end
|
248
|
-
return output
|
249
|
-
end
|
250
|
-
|
251
|
-
def collect_ntp(command)
|
252
|
-
output = @outdir+'/ntp_info.output'
|
253
|
-
stdout_date, stderr_date, status_date = Open3.capture3("date")
|
254
|
-
stdout_ntp, stderr_ntp, status_ntp = Open3.capture3("chronyc sources") if command == "chrony"
|
255
|
-
stdout_ntp, stderr_ntp, status_ntp = Open3.capture3("ntpq -p") if command == "ntp"
|
256
|
-
File.open(output, 'w') do |f|
|
257
|
-
f.puts(stdout_date)
|
258
|
-
f.puts(stdout_ntp)
|
207
|
+
def collect_cmd_output(cmd)
|
208
|
+
cmd_name = cmd.gsub(/\s/,'_').gsub(/\//,'-').gsub(',','_')
|
209
|
+
output = @outdir+'/'+cmd_name+'.txt'
|
210
|
+
stdout, stderr, status = Open3.capture3(cmd)
|
211
|
+
if status.success?
|
212
|
+
File.open(output, 'w') do |f|
|
213
|
+
f.puts(stdout)
|
214
|
+
end
|
215
|
+
else
|
216
|
+
@logger.warn("Command #{cmd} failed due to the following message - #{stderr.chomp}")
|
259
217
|
end
|
260
218
|
return output
|
261
219
|
end
|
262
|
-
|
220
|
+
|
263
221
|
def collect_tdgems()
|
264
222
|
output = @outdir+'/tdgem_list.output'
|
265
223
|
stdout, stderr, status = Open3.capture3("td-agent-gem list | grep fluent")
|
@@ -27,26 +27,12 @@ module Diagtool
|
|
27
27
|
time = Time.new
|
28
28
|
@time_format = time.strftime("%Y%m%d%0k%M%0S")
|
29
29
|
@conf = parse_diagconf(params)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
#diaglog = @conf[:workdir] + '/diagtool.output'
|
38
|
-
#@masklog = './mask_' + @time_format + '.json'
|
39
|
-
#@logger = Logger.new(STDOUT, formatter: proc {|severity, datetime, progname, msg|
|
40
|
-
# "#{datetime}: [Diagtool] [#{severity}] #{msg}\n"
|
41
|
-
#})
|
42
|
-
#@logger_file = Logger.new(diaglog, formatter: proc {|severity, datetime, progname, msg|
|
43
|
-
# "#{datetime}: [Diagtool] [#{severity}] #{msg}\n"
|
44
|
-
#})
|
45
|
-
#diaglogger_info("Parsing command options...")
|
46
|
-
#diaglogger_info(" Option : Output directory = #{@conf[:basedir]}")
|
47
|
-
#diaglogger_info(" Option : Mask = #{@conf[:mask]}")
|
48
|
-
#diaglogger_info(" Option : Word list = #{@conf[:words]}")
|
49
|
-
#diaglogger_info(" Option : Hash Seed = #{@conf[:seed]}")
|
30
|
+
@cmd_list = [
|
31
|
+
"ps -eo pid,ppid,stime,time,%mem,%cpu,cmd",
|
32
|
+
"cat /proc/meminfo",
|
33
|
+
"netstat -plan",
|
34
|
+
"netstat -s",
|
35
|
+
]
|
50
36
|
end
|
51
37
|
|
52
38
|
def run_precheck()
|
@@ -130,39 +116,35 @@ module Diagtool
|
|
130
116
|
end
|
131
117
|
diaglogger_info("[Collect] config file is stored in #{oslog}")
|
132
118
|
|
133
|
-
diaglogger_info("[Collect] Collecting process information...")
|
134
|
-
meminfo = c.collect_ps_eo()
|
135
|
-
diaglogger_info("[Collect] process informationis stored in #{meminfo}")
|
136
|
-
|
137
|
-
diaglogger_info("[Collect] Collecting OS memory information...")
|
138
|
-
meminfo = c.collect_meminfo()
|
139
|
-
diaglogger_info("[Collect] OS memory information is stored in #{meminfo}")
|
140
|
-
|
141
119
|
diaglogger_info("[Collect] Collecting date/time information...")
|
142
120
|
if system('which chronyc > /dev/null 2>&1')
|
143
|
-
ntp = c.
|
121
|
+
ntp = c.collect_cmd_output(command="chronyc sources")
|
122
|
+
diaglogger_info("[Collect] date/time information is stored in #{ntp}")
|
144
123
|
elsif system('which ntpq > /dev/null 2>&1')
|
145
|
-
ntp = c.collect_ntp(command="
|
124
|
+
ntp = c.collect_ntp(command="ntpq -p")
|
125
|
+
diaglogger_info("[Collect] date/time information is stored in #{ntp}")
|
146
126
|
else
|
147
127
|
diaglogger_warn("[Collect] chrony/ntp does not exist. skip collectig date/time information")
|
148
128
|
end
|
149
|
-
diaglogger_info("[Collect] date/time information is stored in #{ntp}")
|
150
|
-
|
151
|
-
diaglogger_info("[Collect] Collecting netstat information...")
|
152
|
-
if system('which netstat > /dev/null 2>&1')
|
153
|
-
netstat_n = c.collect_netstat_plan()
|
154
|
-
netstat_s = c.collect_netstat_s()
|
155
|
-
if @conf[:mask] == 'yes'
|
156
|
-
diaglogger_info("[Mask] Masking netstat file : #{netstat_n}...")
|
157
|
-
netstat_n = m.mask_tdlog(netstat_n, clean = true)
|
158
|
-
end
|
159
|
-
diaglogger_info("[Collect] netstat information is stored in #{netstat_n} and #{netstat_s}")
|
160
|
-
else
|
161
|
-
diaglogger_warn("[Collect] netstat does not exist. skip collectig netstat")
|
162
|
-
end
|
163
129
|
|
130
|
+
###
|
131
|
+
# Correct OS information
|
132
|
+
###
|
133
|
+
@cmd_list.each { |cmd|
|
134
|
+
diaglogger_info("[Collect] Collecting command output : command = #{cmd}")
|
135
|
+
out = c.collect_cmd_output(cmd)
|
136
|
+
if @conf[:mask] == 'yes'
|
137
|
+
diaglogger_info("[Mask] Masking netstat file : #{out}...")
|
138
|
+
out = m.mask_tdlog(out, clean = true)
|
139
|
+
end
|
140
|
+
diaglogger_info("[Collect] Collecting command output #{cmd.split[0]} stored in #{out}")
|
141
|
+
}
|
142
|
+
|
143
|
+
###
|
144
|
+
# Correct information to be validated
|
145
|
+
###
|
164
146
|
diaglogger_info("[Collect] Collecting systctl information...")
|
165
|
-
sysctl = c.
|
147
|
+
sysctl = c.collect_cmd_output("sysctl -a")
|
166
148
|
diaglogger_info("[Collect] sysctl information is stored in #{sysctl}")
|
167
149
|
|
168
150
|
diaglogger_info("[Valid] Validating systctl information...")
|
@@ -176,20 +158,16 @@ module Diagtool
|
|
176
158
|
end
|
177
159
|
end
|
178
160
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
diaglogger_info("[Collect] ulimit information is stored in #{ulimit}")
|
161
|
+
diaglogger_info("[Collect] Collecting ulimit information...")
|
162
|
+
ulimit = c.collect_cmd_output(cmd="sh -c 'ulimit -n'")
|
163
|
+
diaglogger_info("[Collect] ulimit information is stored in #{ulimit}")
|
183
164
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
else
|
189
|
-
diaglogger_warn("[Valid] ulimit => #{val} is incorrect (recommendation is >#{rec})")
|
190
|
-
end
|
165
|
+
diaglogger_info("[Valid] Validating ulimit information...")
|
166
|
+
ret, rec, val = v.valid_ulimit(ulimit)
|
167
|
+
if ret == true
|
168
|
+
diaglogger_info("[Valid] ulimit => #{val} is correct (recommendation is >#{rec})")
|
191
169
|
else
|
192
|
-
diaglogger_warn("[
|
170
|
+
diaglogger_warn("[Valid] ulimit => #{val} is incorrect (recommendation is >#{rec})")
|
193
171
|
end
|
194
172
|
|
195
173
|
if @conf[:mask] == 'yes'
|
@@ -212,7 +190,7 @@ module Diagtool
|
|
212
190
|
diaglogger_info("[Mask] Export mask log file : #{@masklog}")
|
213
191
|
m.export_masklog(@masklog)
|
214
192
|
end
|
215
|
-
|
193
|
+
|
216
194
|
tar_file = c.compress_output()
|
217
195
|
diaglogger_info("[Collect] Generate tar file #{tar_file}")
|
218
196
|
end
|
@@ -33,7 +33,8 @@ module Diagtool
|
|
33
33
|
:net_ipv4_tcp_max_syn_backlog => "8096",
|
34
34
|
:net_ipv4_tcp_slow_start_after_idle => "0",
|
35
35
|
:net_ipv4_tcp_tw_reuse => "1",
|
36
|
-
:net_ipv4_ip_local_port_range => ["10240", "65535"]
|
36
|
+
:net_ipv4_ip_local_port_range => ["10240", "65535"]
|
37
|
+
}
|
37
38
|
@logger.debug("Initialize Validation Utils:")
|
38
39
|
@logger.debug(" Default ulimit: #{@def_ulimit}")
|
39
40
|
@logger.debug(" Default sysctl: #{@def_sysctl}")
|
@@ -57,7 +58,7 @@ module Diagtool
|
|
57
58
|
v = Hash.new { |i,j| i[j] = Hash.new(&h.default_proc) }
|
58
59
|
@logger.info("Loading sysctl file: #{sysctl_file}")
|
59
60
|
File.readlines(sysctl_file).each{ |line|
|
60
|
-
if line.include?
|
61
|
+
if line.include? "net"
|
61
62
|
line_net = line.chomp.gsub(".","_").split("=")
|
62
63
|
key = line_net[0].strip.to_sym
|
63
64
|
if line_net[1].strip! =~ /\s/
|
@@ -66,17 +67,19 @@ module Diagtool
|
|
66
67
|
value= line_net[1]
|
67
68
|
end
|
68
69
|
h[key] = value
|
69
|
-
|
70
|
-
@
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
70
|
+
if @def_sysctl.key? key
|
71
|
+
if @def_sysctl[key] == value
|
72
|
+
@logger.info("#{key} => #{value} is correct")
|
73
|
+
v[key]['value'] = value
|
74
|
+
v[key]['recommend'] = @def_sysctl[key]
|
75
|
+
v[key]['result'] = "correct"
|
76
|
+
else
|
77
|
+
@logger.warn("#{key} => #{value} is incorrect, should be #{@def_sysctl[key]}")
|
78
|
+
v[key]['value'] = value
|
79
|
+
v[key]['recommend'] = @def_sysctl[key]
|
80
|
+
v[key]['result'] = "incorrect"
|
81
|
+
end
|
82
|
+
end
|
80
83
|
end
|
81
84
|
}
|
82
85
|
if h == @sysctl
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-diagtool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kubotat
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fileutils
|
@@ -56,8 +56,10 @@ files:
|
|
56
56
|
- README.md
|
57
57
|
- Rakefile
|
58
58
|
- bin/console
|
59
|
+
- bin/diagtool.rb
|
59
60
|
- bin/setup
|
60
61
|
- bin/word_list_sample
|
62
|
+
- exclude_list01
|
61
63
|
- exe/diagtool
|
62
64
|
- fluent-diagtool.gemspec
|
63
65
|
- lib/fluent/diagtool/collectutils.rb
|