fluent-diagtool 0.1.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +35 -15
- data/exclude_list01 +2 -0
- data/exe/{diagtool → fluent-diagtool} +1 -0
- data/lib/fluent/diagtool/collectutils.rb +271 -100
- data/lib/fluent/diagtool/diagutils.rb +82 -63
- data/lib/fluent/diagtool/validutils.rb +16 -13
- data/lib/fluent/diagtool/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c852c088190fa51d4232c45aa7afd4013473c8089e194511a0910a8ca4794e5
|
4
|
+
data.tar.gz: 96b031de365ad1d47c71b7ffe25dfbd53f4909fe07be484944f7814cfead4939
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c6c96dd92c4c8db2975c84395288817b5053b3cdb4b0897970a5e253fc2714886baf0799dd5bd4161439e043c4827a65c178adefde241e2e974de53265bebef8
|
7
|
+
data.tar.gz: e7d24f7ca1d450e70bc037c74bf1ff8a88e2d174cc77c04211ba164bf7e7e97961b0d2970c8e3e00e0ab57f357c6c13aa8640afc1ffa8b9d7b63d5867630c9e4
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Fluentd Diagnostic Tool
|
2
2
|
|
3
|
-
The diagtool
|
3
|
+
The diagtool enables users to automate the date collection which is required for troubleshooting. The data collected by diagtool include the configuration and log files of the td-agent and diagnostic information from an operating system such as network and memory status and stats. In some cases, configuration and log files contain security sensitive information, such as IP addresses and Hostname. The diagtool also provides the functions to generate masks on IP addresses, Hostname(in FQDN style) and user defined keywords described in the collected data.
|
4
4
|
The scope of data collection:
|
5
5
|
- TD Agent information
|
6
6
|
- configuration files (*)
|
@@ -15,7 +15,7 @@ The scope of data collection:
|
|
15
15
|
- maximum number of file descriptor(ulimit -n)
|
16
16
|
- kernel network parameters(sysctl)
|
17
17
|
- snapshot of current process(ps)
|
18
|
-
- network
|
18
|
+
- network connectivity status/stats(netstat -plan/netstat -s)
|
19
19
|
- memory information(/proc/meminfo)
|
20
20
|
<br>
|
21
21
|
|
@@ -33,16 +33,28 @@ Successfully installed fileutils-1.0.2
|
|
33
33
|
Fetching: json-2.1.0.gem (100%)
|
34
34
|
Building native extensions. This could take a while...
|
35
35
|
Successfully installed json-2.1.0
|
36
|
-
Fetching: fluent-diagtool-0.
|
37
|
-
Successfully installed fluent-diagtool-0.
|
36
|
+
Fetching: fluent-diagtool-1.0.0.gem (100%)
|
37
|
+
Successfully installed fluent-diagtool-1.0.0
|
38
38
|
3 gems installed
|
39
39
|
```
|
40
|
+
When you are using td-agent, fluent-adiagtool should be installed using /usr/sbin/td-agent-gem command instead of gem command.
|
41
|
+
```
|
42
|
+
# /usr/sbin/td-agent-gem install fluent-diagtool
|
43
|
+
Fetching fluent-diagtool-1.0.0.gem
|
44
|
+
Successfully installed fluent-diagtool-1.0.0
|
45
|
+
Parsing documentation for fluent-diagtool-1.0.0
|
46
|
+
Installing ri documentation for fluent-diagtool-1.0.0
|
47
|
+
Done installing documentation for fluent-diagtool after 0 seconds
|
48
|
+
1 gem installed
|
49
|
+
```
|
40
50
|
|
41
51
|
## Usage
|
52
|
+
There are a few options in Diagtool. You can check the options of Diagtool with "--help" options. Diagtool performs the validation function in the process by default but you can turn on/off the mask function depending on the use cases.
|
42
53
|
```
|
43
54
|
# diagtool --help
|
44
55
|
Usage: /usr/local/bin/diagtool -o OUTPUT_DIR -m {yes | no} -w {word1,[word2...]} -f {listfile} -s {hash seed}
|
45
56
|
--precheck Run Precheck (Optional)
|
57
|
+
-t, --type fluentd|fluentbit Select the type of Fluentd (Mandatory)
|
46
58
|
-o, --output DIR Output directory (Mandatory)
|
47
59
|
-m, --mask yes|no Enable mask function (Optional : Default=no)
|
48
60
|
-w, --word-list word1,word2 Provide a list of user-defined words which will to be masked (Optional : Default=None)
|
@@ -52,10 +64,11 @@ Usage: /usr/local/bin/diagtool -o OUTPUT_DIR -m {yes | no} -w {word1,[word2...]}
|
|
52
64
|
-l, --log log_file provide a full path of td-agent log file (Optional : Default=None)
|
53
65
|
```
|
54
66
|
### Pre-check
|
55
|
-
The diagtool automatically
|
67
|
+
The diagtool automatically parses the path of Fluentd configuration and log files from running Fluentd processes and daemon. The precheck options provides the function to confirm if the diagtool could gather the fluentd information as expected.
|
56
68
|
The following command output shows the case when the diagtool successfully gather information from daemon.
|
69
|
+
You need to specify the type of Fluentd, "fluentd" or "fluentbit".
|
57
70
|
```
|
58
|
-
# diagtool --precheck
|
71
|
+
# diagtool --precheck -t fluentd
|
59
72
|
2020-05-28 00:39:02 -0400: [Diagtool] [INFO] [Precheck] Check OS parameters...
|
60
73
|
2020-05-28 00:39:02 -0400: [Diagtool] [INFO] [Precheck] operating system = CentOS Linux 8 (Core)
|
61
74
|
2020-05-28 00:39:02 -0400: [Diagtool] [INFO] [Precheck] kernel version = Linux 4.18.0-147.el8.x86_64
|
@@ -66,10 +79,10 @@ The following command output shows the case when the diagtool successfully gathe
|
|
66
79
|
2020-05-28 00:39:02 -0400: [Diagtool] [INFO] [Precheck] td-agent log = td-agent.log
|
67
80
|
2020-05-28 00:39:02 -0400: [Diagtool] [INFO] [Precheck] Precheck completed. You can run diagtool command without -c and -l options
|
68
81
|
```
|
69
|
-
In some cases, users do not manage td-agent as daemon but use own
|
82
|
+
In some cases, users do not manage td-agent as daemon but use their own scripts to run td-agent with command line options. In that cases, users need to specify the path of td-agent configuration and log files with -c and -l options respectively.
|
70
83
|
The following example shows the precheck results when the diagtool is not able to extract the path of td-agent configuration and log files.
|
71
84
|
```
|
72
|
-
# diagtool --precheck
|
85
|
+
# diagtool --precheck -t fluentd
|
73
86
|
2020-05-28 05:45:14 +0000: [Diagtool] [INFO] [Precheck] Check OS parameters...
|
74
87
|
2020-05-28 05:45:14 +0000: [Diagtool] [INFO] [Precheck] operating system = CentOS Linux 8 (Core)
|
75
88
|
2020-05-28 05:45:14 +0000: [Diagtool] [INFO] [Precheck] kernel version = Linux 4.18.0-147.5.1.el8_1.x86_64
|
@@ -81,6 +94,14 @@ The following example shows the precheck results when the diagtool is not able t
|
|
81
94
|
2020-05-28 05:45:14 +0000: [Diagtool] [WARN] [Precheck] can not find td-agent conf path: please run diagtool command with -c /path/to/<td-agent conf file>
|
82
95
|
2020-05-28 05:45:14 +0000: [Diagtool] [WARN] [Precheck] can not find td-agent log path: please run diagtool command with -l /path/to/<td-agent log file>
|
83
96
|
```
|
97
|
+
|
98
|
+
### Run diagtool
|
99
|
+
|
100
|
+
#### The "@include" directive in td-agent configuration file
|
101
|
+
The "@include" directive is a function to reuse configuration defined in other configuration files. The diagtool reads the td-agent configuration and collects the files described in "@include" directive as well. The details of "@include" directive are described in followed url:
|
102
|
+
https://docs.fluentd.org/configuration/config-file#6-re-use-your-config-the-include-directive
|
103
|
+
|
104
|
+
#### User defined words to be masked
|
84
105
|
The user-defined words can be specified both -e option and -f option and the words are merged when both options are selected.
|
85
106
|
The format of user-defined words list file specified in -f option should be followed format.
|
86
107
|
```
|
@@ -90,10 +111,9 @@ centos8102
|
|
90
111
|
```
|
91
112
|
NOTE: When user specified the keywork, only the exact match words will be masked. For instance, when users like to mask words like "nginx1" and "nginx2", users need to specify "nginx1" and "nginx2" respectively and "nginx*" should not work in the tool.
|
92
113
|
|
93
|
-
### Run diagtool
|
94
114
|
#### Command sample:
|
95
115
|
```
|
96
|
-
# diagtool -o /tmp/work1 -w passwd1,passwd2 -f word_list_sample -m yes
|
116
|
+
# diagtool -t fluentd -o /tmp/work1 -w passwd1,passwd2 -f word_list_sample -m yes
|
97
117
|
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] Parsing command options...
|
98
118
|
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] Option : Output directory = /tmp/work1
|
99
119
|
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] Option : Mask = yes
|
@@ -149,9 +169,9 @@ NOTE: When user specified the keywork, only the exact match words will be masked
|
|
149
169
|
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Mask] Export mask log file : ./mask_20200512182119.json
|
150
170
|
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Collect] Generate tar file /tmp/work1/diagout-20200512182119.tar.gz
|
151
171
|
```
|
152
|
-
|
153
|
-
When run diagtool with mask option, the log of mask is also created in 'mask_{timestamp}.json' file. Users are able to confirm how the mask was generated on each
|
154
|
-
The diagtool provides hash-seed option with '-s'. When hash-seed is specified, the mask will be generated with original word and hash-seed so that users could use unique mask value.
|
172
|
+
#### Mask Function
|
173
|
+
When run diagtool with the mask option, the log of mask is also created in 'mask_{timestamp}.json' file. Users are able to confirm how the mask was generated on each file.
|
174
|
+
The diagtool provides a hash-seed option with '-s'. When hash-seed is specified, the mask will be generated with the original word and hash-seed so that users could use a unique mask value.
|
155
175
|
#### Mask sample - IP address: IPv4_{md5hash}
|
156
176
|
```
|
157
177
|
"Line112-8": {
|
@@ -177,7 +197,7 @@ The diagtool provides hash-seed option with '-s'. When hash-seed is specified, t
|
|
177
197
|
|
178
198
|
## Tested Environment
|
179
199
|
- OS : CentOS 8.1
|
180
|
-
- Fluentd : td-agent version 3
|
200
|
+
- Fluentd : td-agent version 3/4
|
181
201
|
https://docs.fluentd.org/quickstart/td-agent-v2-vs-v3
|
182
|
-
|
202
|
+
- Fluentbit : td-agent-bit
|
183
203
|
|
data/exclude_list01
ADDED
@@ -27,6 +27,7 @@ params = {}
|
|
27
27
|
OptionParser.new do |opt|
|
28
28
|
opt.banner = "Usage: #{$0} -o OUTPUT_DIR -m {yes | no} -w {word1,[word2...]} -f {listfile} -s {hash seed}"
|
29
29
|
opt.on('--precheck', 'Run Precheck (Optional)')
|
30
|
+
opt.on('-t','--type fluentd|fluentbit', String, 'Select the type of Fluentd (Mandatory)')
|
30
31
|
opt.on('-o','--output DIR', String, 'Output directory (Mandatory)')
|
31
32
|
opt.on('-m','--mask yes|no', String, 'Enable mask function (Optional : Default=no)')
|
32
33
|
opt.on('-w','--word-list word1,word2', Array, 'Provide a list of user-defined words which will to be masked (Optional : Default=None)')
|
@@ -17,26 +17,39 @@
|
|
17
17
|
require 'fileutils'
|
18
18
|
require 'open3'
|
19
19
|
require 'logger'
|
20
|
+
require 'net/http'
|
21
|
+
require 'uri'
|
20
22
|
|
21
23
|
module Diagtool
|
22
24
|
class CollectUtils
|
23
25
|
def initialize(conf, log_level)
|
24
26
|
@logger = Logger.new(STDOUT, level: log_level, formatter: proc {|severity, datetime, progname, msg|
|
25
|
-
"#{datetime}: [
|
27
|
+
"#{datetime}: [Collectutils] [#{severity}] #{msg}\n"
|
26
28
|
})
|
27
29
|
@precheck = conf[:precheck]
|
30
|
+
@type = conf[:type]
|
28
31
|
@time_format = conf[:time]
|
29
32
|
@basedir = conf[:basedir]
|
30
33
|
@workdir = conf[:workdir]
|
31
|
-
@outdir = conf[:outdir]
|
32
|
-
|
33
|
-
|
34
|
+
@outdir = conf[:outdir]
|
35
|
+
@tdenv = {
|
36
|
+
'FLUENT_CONF' => '',
|
37
|
+
'TD_AGENT_LOG_FILE' => ''
|
38
|
+
}
|
39
|
+
|
40
|
+
case @type
|
41
|
+
when 'fluentd'
|
42
|
+
_find_fluentd_info()
|
43
|
+
when 'fluentbit'
|
44
|
+
_find_fluentbit_info()
|
45
|
+
end
|
46
|
+
|
34
47
|
if not conf[:tdconf].empty?
|
35
|
-
|
48
|
+
@tdconf = conf[:tdconf].split('/')[-1]
|
36
49
|
@tdconf_path = conf[:tdconf].gsub(@tdconf,'')
|
37
50
|
elsif
|
38
|
-
|
39
|
-
|
51
|
+
if not @tdenv['FLUENT_CONF'].empty?
|
52
|
+
@tdconf = @tdenv['FLUENT_CONF'].split('/')[-1]
|
40
53
|
@tdconf_path = @tdenv['FLUENT_CONF'].gsub(@tdconf,'')
|
41
54
|
else
|
42
55
|
raise "The path of td-agent configuration file need to be specified." if conf[:precheck] == false
|
@@ -50,14 +63,20 @@ module Diagtool
|
|
50
63
|
@tdlog = @tdenv['TD_AGENT_LOG_FILE'].split('/')[-1]
|
51
64
|
@tdlog_path = @tdenv['TD_AGENT_LOG_FILE'].gsub(@tdlog,'')
|
52
65
|
else
|
53
|
-
|
54
|
-
|
66
|
+
case @type
|
67
|
+
when 'fluentd'
|
68
|
+
raise "The path of td-agent log file need to be specified." if conf[:precheck] == false
|
69
|
+
when 'fluentbit'
|
70
|
+
@logger.warn("FluentBit logs are redirected to the standard output interface ")
|
71
|
+
end
|
72
|
+
end
|
55
73
|
end
|
56
|
-
@osenv =
|
74
|
+
@osenv = _find_os_info()
|
57
75
|
@oslog_path = '/var/log/'
|
58
76
|
@oslog = 'messages'
|
77
|
+
@syslog = 'syslog'
|
59
78
|
@sysctl_path = '/etc/'
|
60
|
-
@sysctl = 'sysctl.conf'
|
79
|
+
@sysctl = 'sysctl.conf'
|
61
80
|
|
62
81
|
@logger.info("Loading the environment parameters...")
|
63
82
|
@logger.info(" operating system = #{@osenv['Operating System']}")
|
@@ -68,7 +87,7 @@ module Diagtool
|
|
68
87
|
@logger.info(" td-agent log = #{@tdlog}")
|
69
88
|
end
|
70
89
|
|
71
|
-
def
|
90
|
+
def _find_os_info()
|
72
91
|
stdout, stderr, status = Open3.capture3('hostnamectl')
|
73
92
|
os_dict = {}
|
74
93
|
stdout.each_line { |l|
|
@@ -83,50 +102,102 @@ module Diagtool
|
|
83
102
|
return os_dict
|
84
103
|
end
|
85
104
|
|
86
|
-
def
|
105
|
+
def _find_fluentd_info()
|
106
|
+
### check if the td-agent is run as daemon
|
87
107
|
stdout, stderr, status = Open3.capture3('systemctl cat td-agent')
|
88
|
-
env_dict = {}
|
89
108
|
if status.success?
|
90
|
-
|
109
|
+
if @precheck == false # SKip if precheck is true
|
91
110
|
File.open(@outdir+'/td-agent_env.output', 'w') do |f|
|
92
111
|
f.puts(stdout)
|
93
112
|
end
|
94
|
-
|
113
|
+
end
|
95
114
|
stdout.split().each do | l |
|
96
115
|
if l.include?('Environment')
|
97
|
-
|
116
|
+
@tdenv[l.split('=')[1]] = l.split('=')[2]
|
98
117
|
end
|
99
|
-
|
118
|
+
end
|
100
119
|
else
|
101
|
-
|
102
|
-
stdout, stderr, status = Open3.capture3(
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
120
|
+
### check if the td-agent is not run as daemon or run Fluentd with customized script
|
121
|
+
stdout, stderr, status = Open3.capture3('ps aux | grep fluentd | grep -v ".*\(grep\|diagtool\)"')
|
122
|
+
if status.success?
|
123
|
+
line = stdout.split(/\n/)
|
124
|
+
line.each do |l|
|
125
|
+
cmd = l.split.drop(10)
|
126
|
+
i = 0
|
127
|
+
if cmd[-1] != '--under-supervisor'
|
128
|
+
cmd.each do |c|
|
129
|
+
case
|
130
|
+
when c == "-c"
|
131
|
+
@tdenv['FLUENT_CONF'] = cmd[i+1]
|
132
|
+
when c == "-l"
|
133
|
+
@tdenv['TD_AGENT_LOG_FILE'] = cmd[i+1]
|
134
|
+
when c.include?("--conf")
|
135
|
+
@tdenv['FLUENT_CONF'] = c.split("=")[1]
|
136
|
+
when c.include?("--log")
|
137
|
+
@tdenv['TD_AGENT_LOG_FILE'] = c.split("=")[1]
|
138
|
+
end
|
139
|
+
i+=1
|
119
140
|
end
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
env_dict['TD_AGENT_LOG_FILE'] = log_path
|
141
|
+
end
|
142
|
+
end
|
143
|
+
else
|
144
|
+
@logger.warn("No Fluentd daemon or proccess running")
|
145
|
+
end
|
126
146
|
end
|
127
|
-
return env_dict
|
128
147
|
end
|
129
148
|
|
149
|
+
def _find_fluentbit_info()
|
150
|
+
### check if the td-agent-bit is run as daemon
|
151
|
+
stdout, stderr, status = Open3.capture3('systemctl cat td-agent-bit')
|
152
|
+
if status.success?
|
153
|
+
if @precheck == false # SKip if precheck is true
|
154
|
+
File.open(@outdir+'/td-agent-bit_env.output', 'w') do |f|
|
155
|
+
f.puts(stdout)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
stdout.split(/\n/).each do | line |
|
159
|
+
if line.start_with?("ExecStart")
|
160
|
+
cmd = line.split("=")[1]
|
161
|
+
i =0
|
162
|
+
cmd.split().each do | c |
|
163
|
+
case
|
164
|
+
when c == "-c"
|
165
|
+
@tdenv['FLUENT_CONF'] = cmd.split()[i+1]
|
166
|
+
when c == "-l"
|
167
|
+
@tdenv['TD_AGENT_LOG_FILE'] = cmd.split()[i+1]
|
168
|
+
when c.include?("--conf")
|
169
|
+
@tdenv['FLUENT_CONF'] = c.split("=")[1]
|
170
|
+
when c.include?("--log")
|
171
|
+
@tdenv['TD_AGENT_LOG_FILE'] = c.split("=")[1]
|
172
|
+
end
|
173
|
+
i+=1
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
else
|
178
|
+
### check if the td-agent-bit is not run as daemon or run FluentdBit with customized script
|
179
|
+
stdout, stderr, status = Open3.capture3('ps aux | grep fluent-bit | grep -v ".*\(grep\|diagtool\)"')
|
180
|
+
if status.success?
|
181
|
+
i = 0
|
182
|
+
stdout.split().each do | line |
|
183
|
+
case
|
184
|
+
when line.include?("--conf")
|
185
|
+
@tdenv['FLUENT_CONF'] = line.split("=")[1]
|
186
|
+
when line.include?("--log")
|
187
|
+
@tdenv['TD_AGENT_LOG_FILE'] = line.split("=")[1]
|
188
|
+
when line == "-c"
|
189
|
+
@tdenv['FLUENT_CONF'] = stdout.split()[i+1]
|
190
|
+
when line == "-l"
|
191
|
+
@tdenv['TD_AGENT_LOG_FILE'] = stdout.split()[i+1]
|
192
|
+
end
|
193
|
+
i+=1
|
194
|
+
end
|
195
|
+
else
|
196
|
+
@logger.warn("No FluentBit daemon or proccess running")
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
130
201
|
def export_env()
|
131
202
|
env = {
|
132
203
|
:os => @osenv['Operating System'],
|
@@ -143,12 +214,140 @@ module Diagtool
|
|
143
214
|
target_dir = @workdir+@tdconf_path
|
144
215
|
FileUtils.mkdir_p(target_dir)
|
145
216
|
FileUtils.cp(@tdconf_path+@tdconf, target_dir)
|
146
|
-
|
217
|
+
conf = @workdir+@tdconf_path+@tdconf
|
218
|
+
conf_list = []
|
219
|
+
conf_list.push conf
|
220
|
+
case @type
|
221
|
+
when 'fluentd'
|
222
|
+
conf_list = conf_list + _collect_tdconf_include(conf)
|
223
|
+
when 'fluentbit'
|
224
|
+
conf_list = conf_list + _collect_tdconf_include(conf) + _collect_tdbit_parser(conf) + _collect_tdbit_plugins(conf)
|
225
|
+
end
|
226
|
+
return conf_list
|
147
227
|
end
|
148
|
-
|
228
|
+
|
229
|
+
def _collect_tdconf_include(conf)
|
230
|
+
target_dir = @workdir+@tdconf_path
|
231
|
+
inc_list = []
|
232
|
+
File.readlines(conf).each do |line|
|
233
|
+
if line.start_with?('@include')
|
234
|
+
l = line.split()[1]
|
235
|
+
if l.start_with?('http')
|
236
|
+
uri = URI(l)
|
237
|
+
inc_http = target_dir + 'http' + uri.path.gsub('/','_')
|
238
|
+
File.open(inc_http, 'w') do |f|
|
239
|
+
f.puts(Net::HTTP.get(uri))
|
240
|
+
end
|
241
|
+
inc_list.push inc_http
|
242
|
+
else
|
243
|
+
if l.start_with?(/\//) # /tmp/work1/b.conf
|
244
|
+
if l.include?('*')
|
245
|
+
Dir.glob(l).each { |ll|
|
246
|
+
inc_conf = target_dir + ll.gsub(/\//,'-')
|
247
|
+
FileUtils.cp(ll, inc_conf)
|
248
|
+
inc_list.push inc_conf
|
249
|
+
}
|
250
|
+
else
|
251
|
+
inc_conf = target_dir+l.gsub(/\//,'-')
|
252
|
+
FileUtils.cp(l, inc_conf)
|
253
|
+
inc_list.push inc_conf
|
254
|
+
end
|
255
|
+
else
|
256
|
+
l = l.gsub('./','') if l.include?('./')
|
257
|
+
if l.include?('*')
|
258
|
+
Dir.glob(@tdconf_path+f).each{ |ll|
|
259
|
+
inc_conf = target_dir + ll.gsub(@tdconf_path,'').gsub(/\//,'-')
|
260
|
+
FileUtils.cp(ll, inc_conf)
|
261
|
+
inc_list.push inc_conf
|
262
|
+
}
|
263
|
+
else
|
264
|
+
inc_conf = target_dir+l.gsub(/\//,'-')
|
265
|
+
FileUtils.cp(@tdconf_path+l, inc_conf)
|
266
|
+
inc_list.push inc_conf
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
return inc_list
|
273
|
+
end
|
274
|
+
|
275
|
+
def _collect_tdbit_parser(conf)
|
276
|
+
target_dir = @workdir+@tdconf_path
|
277
|
+
parser_conf = []
|
278
|
+
File.readlines(conf).each do |line|
|
279
|
+
if line.strip.start_with?('parsers_file') || line.strip.start_with?('Parsers_File')
|
280
|
+
l = line.split()[1]
|
281
|
+
if l.start_with?(/\//) # /tmp/work1/b.conf
|
282
|
+
if l.include?('*')
|
283
|
+
Dir.glob(l).each { |ll|
|
284
|
+
pconf = target_dir + ll.gsub(/\//,'-')
|
285
|
+
FileUtils.cp(ll, pconf)
|
286
|
+
parser_conf.push(pconf)
|
287
|
+
}
|
288
|
+
else
|
289
|
+
pconf = target_dir+l.gsub(/\//,'-')
|
290
|
+
FileUtils.cp(l, pconf)
|
291
|
+
parser_conf.push(pconf)
|
292
|
+
end
|
293
|
+
else
|
294
|
+
l = l.gsub('./','') if l.include?('./')
|
295
|
+
if l.include?('*')
|
296
|
+
Dir.glob(@tdconf_path+f).each{ |ll|
|
297
|
+
pconf = target_dir + ll.gsub(@tdconf_path,'').gsub(/\//,'-')
|
298
|
+
FileUtils.cp(ll, pconf)
|
299
|
+
parser_conf.push(pconf)
|
300
|
+
}
|
301
|
+
else
|
302
|
+
pconf = target_dir+l.gsub(/\//,'-')
|
303
|
+
FileUtils.cp(@tdconf_path+l, pconf)
|
304
|
+
parser_conf.push(pconf)
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
return parser_conf
|
310
|
+
end
|
311
|
+
|
312
|
+
def _collect_tdbit_plugins(conf)
|
313
|
+
target_dir = @workdir+@tdconf_path
|
314
|
+
plugins_conf = []
|
315
|
+
File.readlines(conf).each do |line|
|
316
|
+
if line.strip.start_with?('plugins_file') || line.strip.start_with?('Plugins_File')
|
317
|
+
l = line.split()[1]
|
318
|
+
if l.start_with?(/\//) # /tmp/work1/b.conf
|
319
|
+
if l.include?('*')
|
320
|
+
Dir.glob(l).each { |ll|
|
321
|
+
pconf = target_dir + ll.gsub(/\//,'-')
|
322
|
+
FileUtils.cp(ll, pconf)
|
323
|
+
plugins_conf.push(pconf)
|
324
|
+
}
|
325
|
+
else
|
326
|
+
pconf = target_dir+l.gsub(/\//,'-')
|
327
|
+
FileUtils.cp(l, pconf)
|
328
|
+
plugins_conf.push(pconf)
|
329
|
+
end
|
330
|
+
else
|
331
|
+
l = l.gsub('./','') if l.include?('./')
|
332
|
+
if l.include?('*')
|
333
|
+
Dir.glob(@tdconf_path+f).each{ |ll|
|
334
|
+
pconf = target_dir + ll.gsub(@tdconf_path,'').gsub(/\//,'-')
|
335
|
+
FileUtils.cp(ll, pconf)
|
336
|
+
plugins_conf.push(pconf)
|
337
|
+
}
|
338
|
+
else
|
339
|
+
pconf = target_dir+l.gsub(/\//,'-')
|
340
|
+
FileUtils.cp(@tdconf_path+l, pconf)
|
341
|
+
plugins_conf.push(pconf)
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
return plugins_conf
|
347
|
+
end
|
348
|
+
|
149
349
|
def collect_tdlog()
|
150
350
|
target_dir = @workdir+@tdlog_path
|
151
|
-
p target_dir
|
152
351
|
FileUtils.mkdir_p(target_dir)
|
153
352
|
Dir.glob(@tdlog_path+@tdlog+'*').each{ |f|
|
154
353
|
FileUtils.cp(f, target_dir)
|
@@ -156,65 +355,20 @@ module Diagtool
|
|
156
355
|
return Dir.glob(target_dir+@tdlog+'*')
|
157
356
|
end
|
158
357
|
|
159
|
-
def collect_sysctl()
|
160
|
-
target_dir = @workdir+@sysctl_path
|
161
|
-
FileUtils.mkdir_p(target_dir)
|
162
|
-
FileUtils.cp(@sysctl_path+@sysctl, target_dir)
|
163
|
-
return target_dir+@sysctl
|
164
|
-
end
|
165
|
-
|
166
358
|
def collect_oslog()
|
167
359
|
target_dir = @workdir+@oslog_path
|
168
360
|
FileUtils.mkdir_p(target_dir)
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
f.puts(stdout)
|
178
|
-
end
|
179
|
-
return output
|
180
|
-
end
|
181
|
-
|
182
|
-
def collect_ps_eo()
|
183
|
-
output = @outdir+'/ps_eo.output'
|
184
|
-
stdout, stderr, status = Open3.capture3("ps -eo pid,ppid,stime,time,%mem,%cpu,cmd")
|
185
|
-
File.open(output, 'w') do |f|
|
186
|
-
f.puts(stdout)
|
361
|
+
if File.exist? @oslog_path+@oslog
|
362
|
+
FileUtils.cp(@oslog_path+@oslog, target_dir)
|
363
|
+
return target_dir+@oslog
|
364
|
+
elsif File.exist? @oslog_path+@syslog
|
365
|
+
FileUtils.cp(@oslog_path+@syslog, target_dir)
|
366
|
+
return target_dir+@syslog
|
367
|
+
else
|
368
|
+
@logger.warn("Can not find OS log file in #{oslog} or #{syslog}")
|
187
369
|
end
|
188
|
-
return output
|
189
370
|
end
|
190
371
|
|
191
|
-
def collect_meminfo()
|
192
|
-
output = @outdir+'/meminfo.output'
|
193
|
-
stdout, stderr, status = Open3.capture3("cat /proc/meminfo")
|
194
|
-
File.open(output, 'w') do |f|
|
195
|
-
f.puts(stdout)
|
196
|
-
end
|
197
|
-
return output
|
198
|
-
end
|
199
|
-
|
200
|
-
def collect_netstat_plan()
|
201
|
-
output = @outdir+'/netstat_plan.output'
|
202
|
-
stdout, stderr, status = Open3.capture3("netstat -plan")
|
203
|
-
File.open(output, 'w') do |f|
|
204
|
-
f.puts(stdout)
|
205
|
-
end
|
206
|
-
return output
|
207
|
-
end
|
208
|
-
|
209
|
-
def collect_netstat_s()
|
210
|
-
output = @outdir+'/netstat_s.output'
|
211
|
-
stdout, stderr, status = Open3.capture3("netstat -s")
|
212
|
-
File.open(output, 'w') do |f|
|
213
|
-
f.puts(stdout)
|
214
|
-
end
|
215
|
-
return output
|
216
|
-
end
|
217
|
-
|
218
372
|
def collect_ntp(command)
|
219
373
|
output = @outdir+'/ntp_info.output'
|
220
374
|
stdout_date, stderr_date, status_date = Open3.capture3("date")
|
@@ -224,9 +378,26 @@ module Diagtool
|
|
224
378
|
f.puts(stdout_date)
|
225
379
|
f.puts(stdout_ntp)
|
226
380
|
end
|
381
|
+
end
|
382
|
+
|
383
|
+
def collect_cmd_output(cmd)
|
384
|
+
if system(cmd + '> /dev/null 2>&1')
|
385
|
+
cmd_name = cmd.gsub(/\s/,'_').gsub(/\//,'-').gsub(',','_')
|
386
|
+
output = @outdir+'/'+cmd_name+'.txt'
|
387
|
+
stdout, stderr, status = Open3.capture3(cmd)
|
388
|
+
if status.success?
|
389
|
+
File.open(output, 'w') do |f|
|
390
|
+
f.puts(stdout)
|
391
|
+
end
|
392
|
+
else
|
393
|
+
@logger.warn("Command #{cmd} failed due to the following message - #{stderr.chomp}")
|
394
|
+
end
|
395
|
+
else
|
396
|
+
@logger.warn("Command #{cmd} does not exist - skip collecting #{cmd} output")
|
397
|
+
end
|
227
398
|
return output
|
228
399
|
end
|
229
|
-
|
400
|
+
|
230
401
|
def collect_tdgems()
|
231
402
|
output = @outdir+'/tdgem_list.output'
|
232
403
|
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()
|
@@ -56,6 +42,7 @@ module Diagtool
|
|
56
42
|
loglevel = 'WARN'
|
57
43
|
c = CollectUtils.new(@conf, loglevel)
|
58
44
|
c_env = c.export_env()
|
45
|
+
prechecklog.info("[Precheck] Fluentd Type = #{@conf[:type]}")
|
59
46
|
prechecklog.info("[Precheck] Check OS parameters...")
|
60
47
|
prechecklog.info("[Precheck] operating system = #{c_env[:os]}")
|
61
48
|
prechecklog.info("[Precheck] kernel version = #{c_env[:kernel]}")
|
@@ -65,13 +52,13 @@ module Diagtool
|
|
65
52
|
prechecklog.info("[Precheck] td-agent log path = #{c_env[:tdlog_path]}")
|
66
53
|
prechecklog.info("[Precheck] td-agent log = #{c_env[:tdlog]}")
|
67
54
|
if c_env[:tdconf_path] == nil || c_env[:tdconf] == nil
|
68
|
-
|
55
|
+
prechecklog.warn("[Precheck] can not find td-agent conf path: please run diagtool command with -c /path/to/<td-agent conf file>")
|
69
56
|
end
|
70
57
|
if c_env[:tdlog_path] == nil || c_env[:tdlog] == nil
|
71
58
|
prechecklog.warn("[Precheck] can not find td-agent log path: please run diagtool command with -l /path/to/<td-agent log file>")
|
72
59
|
end
|
73
60
|
if c_env[:tdconf_path] != nil && c_env[:tdconf] != nil && c_env[:tdlog_path] != nil && c_env[:tdlog] != nil
|
74
|
-
|
61
|
+
prechecklog.info("[Precheck] Precheck completed. You can run diagtool command without -c and -l options")
|
75
62
|
end
|
76
63
|
end
|
77
64
|
|
@@ -111,8 +98,19 @@ module Diagtool
|
|
111
98
|
v = ValidUtils.new(loglevel)
|
112
99
|
|
113
100
|
diaglogger_info("[Collect] Collecting log files of td-agent...")
|
114
|
-
|
115
|
-
|
101
|
+
case @type
|
102
|
+
when 'fluentd'
|
103
|
+
tdlog = c.collect_tdlog()
|
104
|
+
diaglogger_info("[Collect] log files of td-agent are stored in #{tdlog}")
|
105
|
+
when 'fleuntbit'
|
106
|
+
if tdlog.empty?
|
107
|
+
diaglogger_info("FluentBit logs are redirected to the standard output interface ")
|
108
|
+
tdlog = ''
|
109
|
+
else
|
110
|
+
tdlog = c.collect_tdlog()
|
111
|
+
diaglogger_info("[Collect] log files of td-agent are stored in #{tdlog}")
|
112
|
+
end
|
113
|
+
end
|
116
114
|
|
117
115
|
diaglogger_info("[Collect] Collecting config file of td-agent...")
|
118
116
|
tdconf = c.collect_tdconf()
|
@@ -130,39 +128,37 @@ module Diagtool
|
|
130
128
|
end
|
131
129
|
diaglogger_info("[Collect] config file is stored in #{oslog}")
|
132
130
|
|
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
131
|
diaglogger_info("[Collect] Collecting date/time information...")
|
142
132
|
if system('which chronyc > /dev/null 2>&1')
|
143
|
-
ntp = c.
|
133
|
+
ntp = c.collect_cmd_output(command="chronyc sources")
|
134
|
+
diaglogger_info("[Collect] date/time information is stored in #{ntp}")
|
144
135
|
elsif system('which ntpq > /dev/null 2>&1')
|
145
|
-
ntp = c.
|
136
|
+
ntp = c.collect_cmd_output(command="ntpq -p")
|
137
|
+
diaglogger_info("[Collect] date/time information is stored in #{ntp}")
|
146
138
|
else
|
147
139
|
diaglogger_warn("[Collect] chrony/ntp does not exist. skip collectig date/time information")
|
148
140
|
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
141
|
|
142
|
+
###
|
143
|
+
# Correct OS information
|
144
|
+
###
|
145
|
+
@cmd_list.each { |cmd|
|
146
|
+
diaglogger_info("[Collect] Collecting command output : command = #{cmd}")
|
147
|
+
if system(cmd + '> /dev/null 2>&1')
|
148
|
+
out = c.collect_cmd_output(cmd)
|
149
|
+
if @conf[:mask] == 'yes'
|
150
|
+
diaglogger_info("[Mask] Masking command output file : #{out}...")
|
151
|
+
out = m.mask_tdlog(out, clean = true)
|
152
|
+
end
|
153
|
+
diaglogger_info("[Collect] Collecting command output #{cmd.split[0]} stored in #{out}")
|
154
|
+
end
|
155
|
+
}
|
156
|
+
|
157
|
+
###
|
158
|
+
# Correct information to be validated
|
159
|
+
###
|
164
160
|
diaglogger_info("[Collect] Collecting systctl information...")
|
165
|
-
sysctl = c.
|
161
|
+
sysctl = c.collect_cmd_output("sysctl -a")
|
166
162
|
diaglogger_info("[Collect] sysctl information is stored in #{sysctl}")
|
167
163
|
|
168
164
|
diaglogger_info("[Valid] Validating systctl information...")
|
@@ -177,7 +173,7 @@ module Diagtool
|
|
177
173
|
end
|
178
174
|
|
179
175
|
diaglogger_info("[Collect] Collecting ulimit information...")
|
180
|
-
ulimit = c.
|
176
|
+
ulimit = c.collect_cmd_output(cmd="sh -c 'ulimit -n'")
|
181
177
|
diaglogger_info("[Collect] ulimit information is stored in #{ulimit}")
|
182
178
|
|
183
179
|
diaglogger_info("[Valid] Validating ulimit information...")
|
@@ -189,16 +185,23 @@ module Diagtool
|
|
189
185
|
end
|
190
186
|
|
191
187
|
if @conf[:mask] == 'yes'
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
188
|
+
tdconf.each { | file |
|
189
|
+
diaglogger_info("[Mask] Masking td-agent config file : #{file}...")
|
190
|
+
m.mask_tdlog(file, clean = true)
|
191
|
+
}
|
192
|
+
end
|
193
|
+
|
194
|
+
if @conf[:mask] == 'yes'
|
195
|
+
if tdlog != nil
|
196
|
+
tdlog.each { | file |
|
197
|
+
diaglogger_info("[Mask] Masking td-agent log file : #{file}...")
|
198
|
+
filename = file.split("/")[-1]
|
199
|
+
if filename.include?(".gz")
|
200
|
+
m.mask_tdlog_gz(file, clean = true)
|
201
|
+
elsif
|
202
|
+
m.mask_tdlog(file, clean = true)
|
203
|
+
end
|
204
|
+
}
|
202
205
|
end
|
203
206
|
end
|
204
207
|
|
@@ -206,15 +209,16 @@ module Diagtool
|
|
206
209
|
diaglogger_info("[Mask] Export mask log file : #{@masklog}")
|
207
210
|
m.export_masklog(@masklog)
|
208
211
|
end
|
209
|
-
|
212
|
+
|
210
213
|
tar_file = c.compress_output()
|
211
214
|
diaglogger_info("[Collect] Generate tar file #{tar_file}")
|
212
215
|
end
|
213
216
|
|
214
217
|
def parse_diagconf(params)
|
215
218
|
options = {
|
216
|
-
:precheck => '', :basedir => '', :mask => '', :words => [], :wfile => '', :seed => '', :tdconf =>'', :tdlog => ''
|
219
|
+
:precheck => '', :basedir => '', :type =>'', :mask => '', :words => [], :wfile => '', :seed => '', :tdconf =>'', :tdlog => ''
|
217
220
|
}
|
221
|
+
### Parse precheck flag
|
218
222
|
if params[:precheck]
|
219
223
|
options[:precheck] = params[:precheck]
|
220
224
|
else
|
@@ -231,6 +235,13 @@ module Diagtool
|
|
231
235
|
raise "output directory '-o' must be specified"
|
232
236
|
end
|
233
237
|
end
|
238
|
+
### Parse fluent type
|
239
|
+
if params[:type] == 'fluentd' || params[:type] == 'fluentbit'
|
240
|
+
options[:type] = params[:type]
|
241
|
+
else
|
242
|
+
raise "fluentd type '-t' must be specified (fluentd or fluentbit)"
|
243
|
+
end
|
244
|
+
### Parse mask flag
|
234
245
|
if params[:mask] == nil
|
235
246
|
options[:mask] = 'no'
|
236
247
|
else
|
@@ -240,7 +251,11 @@ module Diagtool
|
|
240
251
|
raise "invalid arguments '#{params[:mask]}' : input of '-m|--mask' should be 'yes' or 'no'"
|
241
252
|
end
|
242
253
|
end
|
254
|
+
|
255
|
+
### Parse uder-defined keyword list which will be used in the mask function
|
243
256
|
options[:words] = params[:"word-list"] if params[:"word-list"] != nil
|
257
|
+
|
258
|
+
### Parse uder-defined keyword file which will be used in the mask function
|
244
259
|
if params[:"word-file"] != nil
|
245
260
|
f = params[:"word-file"]
|
246
261
|
if File.exist?(f)
|
@@ -252,8 +267,11 @@ module Diagtool
|
|
252
267
|
end
|
253
268
|
end
|
254
269
|
options[:words] = options[:words].uniq
|
270
|
+
|
271
|
+
### Parse hash seed which will be used in the mask function
|
255
272
|
options[:seed] = params[:"hash-seed"] if params[:"hash-seed"] != nil
|
256
|
-
|
273
|
+
|
274
|
+
### Parse the path of fluentd config file
|
257
275
|
if params[:conf] != nil
|
258
276
|
f = params[:conf]
|
259
277
|
if File.exist?(f)
|
@@ -263,6 +281,7 @@ module Diagtool
|
|
263
281
|
end
|
264
282
|
end
|
265
283
|
|
284
|
+
### Parse the path of fluentd log file
|
266
285
|
if params[:log] != nil
|
267
286
|
f = params[:log]
|
268
287
|
if File.exist?(f)
|
@@ -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.
|
4
|
+
version: 1.0.0
|
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-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fileutils
|
@@ -44,7 +44,7 @@ description: Bringing productivity of trouble shooting to the next level by aut
|
|
44
44
|
email:
|
45
45
|
- tkubota@ctc-america.com
|
46
46
|
executables:
|
47
|
-
- diagtool
|
47
|
+
- fluent-diagtool
|
48
48
|
extensions: []
|
49
49
|
extra_rdoc_files: []
|
50
50
|
files:
|
@@ -58,7 +58,8 @@ files:
|
|
58
58
|
- bin/console
|
59
59
|
- bin/setup
|
60
60
|
- bin/word_list_sample
|
61
|
-
-
|
61
|
+
- exclude_list01
|
62
|
+
- exe/fluent-diagtool
|
62
63
|
- fluent-diagtool.gemspec
|
63
64
|
- lib/fluent/diagtool/collectutils.rb
|
64
65
|
- lib/fluent/diagtool/diagutils.rb
|
@@ -84,8 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
84
85
|
- !ruby/object:Gem::Version
|
85
86
|
version: '0'
|
86
87
|
requirements: []
|
87
|
-
|
88
|
-
rubygems_version: 2.7.6.2
|
88
|
+
rubygems_version: 3.1.2
|
89
89
|
signing_key:
|
90
90
|
specification_version: 4
|
91
91
|
summary: Diagnostic Tool for Fluentd
|