fluent-diagtool 0.1.6 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +120 -102
- data/exclude_list01 +2 -0
- data/exe/{diagtool → fluent-diagtool} +1 -0
- data/lib/fluent/diagtool/collectutils.rb +266 -128
- data/lib/fluent/diagtool/diagutils.rb +83 -66
- data/lib/fluent/diagtool/validutils.rb +16 -13
- data/lib/fluent/diagtool/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bfb1e90d1be9a7723371f6ea3cf72ea4eec822d732e2d940e54871cf20ce02d0
|
4
|
+
data.tar.gz: bbc10274d97eef4e0c79b5da843947389607519dd8f34e66ebc775ecf7171736
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1917964e68291c9a4cef64fca18139a1235f3a8bacc6eac8071881e4303cf4b18a0217fd0a8085641e4881a4847542b53b4b2390af8a50298f72259f3d6cba9b
|
7
|
+
data.tar.gz: d8c90fa8083e37510c55e1ad3059767585bc0b9c9adff3709e58d0e4225329c4ef4b5e5509a1323ab7af4e48101bf06384db82c56ad1dce99cbef6e512218a08
|
data/README.md
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# Fluentd Diagnostic Tool
|
2
2
|
|
3
|
-
|
3
|
+
Diagtool enables users to automate the date collection which is required for troubleshooting. Diagtool gathers configuration and log files of Fluentd and diagnostic information from an operating system, such as process information and network status. In some cases, configuration and log files contain security sensitive information, such as IP addresses and Hostname. Diagtool has the functions to generate masks on IP addresses, Hostname(in FQDN style) and user defined keywords in the collected files.
|
4
|
+
|
4
5
|
The scope of data collection:
|
5
|
-
-
|
6
|
-
- configuration files
|
7
|
-
- log files
|
6
|
+
- Fluentd information
|
7
|
+
- configuration files
|
8
|
+
- log files
|
8
9
|
- td-agent environment values
|
9
10
|
- installed td-agent-gem list
|
10
11
|
- OS information
|
@@ -15,34 +16,46 @@ The scope of data collection:
|
|
15
16
|
- maximum number of file descriptor(ulimit -n)
|
16
17
|
- kernel network parameters(sysctl)
|
17
18
|
- snapshot of current process(ps)
|
18
|
-
- network
|
19
|
+
- network connectivity status/stats(netstat -plan/netstat -s)
|
19
20
|
- memory information(/proc/meminfo)
|
20
21
|
<br>
|
21
22
|
|
22
23
|
## Prerequisite
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
Diagtool has been developed for Fluentd(td-agent) and FluentBit(td-agent-bit) running on Linux OS and Diatool does not work for Windows.
|
25
|
+
Diagtool is written in Ruby and Ruby version should be higher than 2.3 for the installation.
|
26
|
+
The supported Linux OS is described in the following page:
|
27
|
+
https://docs.fluentd.org/quickstart/td-agent-v2-vs-v3-vs-v4
|
26
28
|
|
27
29
|
## Diagtool Installation
|
28
30
|
|
31
|
+
When you are using td-agent, you can install Diagtool easily with "/usr/sbin/td-agent-gem" command.
|
32
|
+
```
|
33
|
+
# /usr/sbin/td-agent-gem install fluent-diagtool
|
34
|
+
Successfully installed fluent-diagtool-1.0.0
|
35
|
+
Parsing documentation for fluent-diagtool-1.0.0
|
36
|
+
Installing ri documentation for fluent-diagtool-1.0.0
|
37
|
+
Done installing documentation for fluent-diagtool after 0 seconds
|
38
|
+
1 gem installed
|
39
|
+
```
|
40
|
+
When using /usr/sbin/td-agent-gem command, fluent-diagtool is installed under "/opt/td-agent/embedded/lib/ruby/gems/2.4.0/bin/" directory. You can add that directory to $PATH in .bash_profile.
|
41
|
+
|
42
|
+
Otherwise, you can install Diagtool with common gem command. In this case, Ruby version higher than 2.3 might be required to install.
|
29
43
|
```
|
30
44
|
# gem install fluent-diagtool
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
Fetching: fluent-diagtool-0.1.2.gem (100%)
|
37
|
-
Successfully installed fluent-diagtool-0.1.2
|
38
|
-
3 gems installed
|
45
|
+
Successfully installed fluent-diagtool-1.0.0
|
46
|
+
Parsing documentation for fluent-diagtool-1.0.0
|
47
|
+
Installing ri documentation for fluent-diagtool-1.0.0
|
48
|
+
Done installing documentation for fluent-diagtool after 0 seconds
|
49
|
+
1 gem installed
|
39
50
|
```
|
40
51
|
|
52
|
+
|
41
53
|
## Usage
|
42
54
|
```
|
43
|
-
# diagtool --help
|
44
|
-
Usage:
|
55
|
+
# fluent-diagtool --help
|
56
|
+
Usage: fluent-diagtool -o OUTPUT_DIR -m {yes | no} -w {word1,[word2...]} -f {listfile} -s {hash seed}
|
45
57
|
--precheck Run Precheck (Optional)
|
58
|
+
-t, --type fluentd|fluentbit Select the type of Fluentd (Mandatory)
|
46
59
|
-o, --output DIR Output directory (Mandatory)
|
47
60
|
-m, --mask yes|no Enable mask function (Optional : Default=no)
|
48
61
|
-w, --word-list word1,word2 Provide a list of user-defined words which will to be masked (Optional : Default=None)
|
@@ -51,25 +64,27 @@ Usage: /usr/local/bin/diagtool -o OUTPUT_DIR -m {yes | no} -w {word1,[word2...]}
|
|
51
64
|
-c, --conf config_file provide a full path of td-agent configuration file (Optional : Default=None)
|
52
65
|
-l, --log log_file provide a full path of td-agent log file (Optional : Default=None)
|
53
66
|
```
|
54
|
-
###
|
55
|
-
|
56
|
-
The following
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
2020-
|
61
|
-
2020-
|
62
|
-
2020-
|
63
|
-
2020-
|
64
|
-
2020-
|
65
|
-
2020-
|
66
|
-
2020-
|
67
|
-
2020-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
67
|
+
### Precheck
|
68
|
+
In order to run Diagtool correctly, it is required to ensure that Diagtool can obtain the fundamental information of Fluentd. Basically, Diagtool automatically parses the required information from the running Fluentd processes. The precheck option is useful to confirm if Diagtool certainly collects the information as expected.
|
69
|
+
The following output example shows the case where Diatool properly collects the required information.
|
70
|
+
|
71
|
+
```
|
72
|
+
# fluent-diagtool --precheck -t fluentd
|
73
|
+
2020-10-07 21:20:33 +0000: [Diagtool] [INFO] [Precheck] Fluentd Type = fluentd
|
74
|
+
2020-10-07 21:20:33 +0000: [Diagtool] [INFO] [Precheck] Check OS parameters...
|
75
|
+
2020-10-07 21:20:33 +0000: [Diagtool] [INFO] [Precheck] operating system = CentOS Linux 7 (Core)
|
76
|
+
2020-10-07 21:20:33 +0000: [Diagtool] [INFO] [Precheck] kernel version = Linux 3.10.0-1127.10.1.el7.x86_64
|
77
|
+
2020-10-07 21:20:33 +0000: [Diagtool] [INFO] [Precheck] Check td-agent parameters...
|
78
|
+
2020-10-07 21:20:33 +0000: [Diagtool] [INFO] [Precheck] td-agent conf path = /etc/td-agent/
|
79
|
+
2020-10-07 21:20:33 +0000: [Diagtool] [INFO] [Precheck] td-agent conf file = td-agent.conf
|
80
|
+
2020-10-07 21:20:33 +0000: [Diagtool] [INFO] [Precheck] td-agent log path = /var/log/td-agent/
|
81
|
+
2020-10-07 21:20:33 +0000: [Diagtool] [INFO] [Precheck] td-agent log = td-agent.log
|
82
|
+
2020-10-07 21:20:33 +0000: [Diagtool] [INFO] [Precheck] Precheck completed. You can run diagtool command without -c and -l options
|
83
|
+
```
|
84
|
+
In some cases, Dialtool, with custom command line options, may fail to identify the path of Fluentd configuration and log files. You need to specify this information manually with “-c” and “-l” options.
|
85
|
+
The following example shows pre-check returns failure resulting Diagtool is not able to extract the path of td-agent configuration and log files.
|
86
|
+
```
|
87
|
+
# fluent-diagtool --precheck -t fluentd
|
73
88
|
2020-05-28 05:45:14 +0000: [Diagtool] [INFO] [Precheck] Check OS parameters...
|
74
89
|
2020-05-28 05:45:14 +0000: [Diagtool] [INFO] [Precheck] operating system = CentOS Linux 8 (Core)
|
75
90
|
2020-05-28 05:45:14 +0000: [Diagtool] [INFO] [Precheck] kernel version = Linux 4.18.0-147.5.1.el8_1.x86_64
|
@@ -83,9 +98,72 @@ The following example shows the precheck results when the diagtool is not able t
|
|
83
98
|
```
|
84
99
|
|
85
100
|
### Run diagtool
|
101
|
+
Once the pre-check is completed, you are ready to run the tool. The “-o” is mandatory out of provided options and the output will be generated as a compressed file under the directory specified by “-o“ option.
|
102
|
+
(*) If the pre-check results mentioned that it is not able to find “td-agent conf path” and “td-agent log path“, you need to use “-c“ and “-l” respectively to specify the file path manually.
|
103
|
+
|
104
|
+
#### Command sample:
|
105
|
+
```
|
106
|
+
# fluent-diagtool -t fluentd -o /tmp -w passwd1,passwd2 -m yes
|
107
|
+
2020-10-07 21:29:28 +0000: [Diagtool] [INFO] Parsing command options...
|
108
|
+
2020-10-07 21:29:28 +0000: [Diagtool] [INFO] Option : Output directory = /tmp
|
109
|
+
2020-10-07 21:29:28 +0000: [Diagtool] [INFO] Option : Mask = yes
|
110
|
+
2020-10-07 21:29:28 +0000: [Diagtool] [INFO] Option : Word list = ["passwd1", "passwd2"]
|
111
|
+
2020-10-07 21:29:28 +0000: [Diagtool] [INFO] Option : Hash Seed =
|
112
|
+
2020-10-07 21:29:28 +0000: [Diagtool] [INFO] Initializing parameters...
|
113
|
+
2020-10-07 21:29:28 +0000: [Diagtool] [INFO] [Collect] Loading the environment parameters...
|
114
|
+
2020-10-07 21:29:28 +0000: [Diagtool] [INFO] [Collect] operating system = CentOS Linux 7 (Core)
|
115
|
+
2020-10-07 21:29:28 +0000: [Diagtool] [INFO] [Collect] kernel version = Linux 3.10.0-1127.10.1.el7.x86_64
|
116
|
+
2020-10-07 21:29:28 +0000: [Diagtool] [INFO] [Collect] td-agent conf path = /etc/td-agent/
|
117
|
+
2020-10-07 21:29:28 +0000: [Diagtool] [INFO] [Collect] td-agent conf file = td-agent.conf
|
118
|
+
2020-10-07 21:29:28 +0000: [Diagtool] [INFO] [Collect] td-agent log path = /var/log/td-agent/
|
119
|
+
2020-10-07 21:29:28 +0000: [Diagtool] [INFO] [Collect] td-agent log = td-agent.log
|
120
|
+
2020-10-07 21:29:28 +0000: [Diagtool] [INFO] [Collect] Collecting log files of td-agent...
|
121
|
+
2020-10-07 21:29:28 +0000: [Diagtool] [INFO] [Collect] Collecting config file of td-agent...
|
122
|
+
2020-10-07 21:29:28 +0000: [Diagtool] [INFO] [Collect] config file is stored in ["/tmp/20201007212928/etc/td-agent/td-agent.conf", "/tmp/20201007212928/etc/td-agent/http_fld_system.conf"]
|
123
|
+
2020-10-07 21:29:28 +0000: [Diagtool] [INFO] [Collect] Collecting td-agent gem information...
|
124
|
+
2020-10-07 21:29:29 +0000: [Diagtool] [INFO] [Collect] td-agent gem information is stored in /tmp/20201007212928/output/tdgem_list.output
|
125
|
+
2020-10-07 21:29:29 +0000: [Diagtool] [INFO] [Collect] Collecting config file of OS log...
|
126
|
+
2020-10-07 21:29:29 +0000: [Diagtool] [INFO] [Mask] Masking OS log file : /tmp/20201007212928/var/log/messages...
|
127
|
+
2020-10-07 21:29:29 +0000: [Diagtool] [INFO] [Collect] config file is stored in /tmp/20201007212928/var/log/messages.mask
|
128
|
+
2020-10-07 21:29:29 +0000: [Diagtool] [INFO] [Collect] Collecting date/time information...
|
129
|
+
2020-10-07 21:29:29 +0000: [Diagtool] [INFO] [Collect] date/time information is stored in /tmp/20201007212928/output/chronyc_sources.txt
|
130
|
+
2020-10-07 21:29:29 +0000: [Diagtool] [INFO] [Collect] Collecting command output : command = ps -eo pid,ppid,stime,time,%mem,%cpu,cmd
|
131
|
+
2020-10-07 21:29:29 +0000: [Diagtool] [INFO] [Mask] Masking command output file : /tmp/20201007212928/output/ps_-eo_pid_ppid_stime_time_%mem_%cpu_cmd.txt...
|
132
|
+
2020-10-07 21:29:29 +0000: [Diagtool] [INFO] [Collect] Collecting command output ps stored in /tmp/20201007212928/output/ps_-eo_pid_ppid_stime_time_%mem_%cpu_cmd.txt.mask
|
133
|
+
2020-10-07 21:29:29 +0000: [Diagtool] [INFO] [Collect] Collecting command output : command = cat /proc/meminfo
|
134
|
+
2020-10-07 21:29:29 +0000: [Diagtool] [INFO] [Mask] Masking command output file : /tmp/20201007212928/output/cat_-proc-meminfo.txt...
|
135
|
+
2020-10-07 21:29:29 +0000: [Diagtool] [INFO] [Collect] Collecting command output cat stored in /tmp/20201007212928/output/cat_-proc-meminfo.txt.mask
|
136
|
+
2020-10-07 21:29:29 +0000: [Diagtool] [INFO] [Collect] Collecting command output : command = netstat -plan
|
137
|
+
2020-10-07 21:29:29 +0000: [Diagtool] [INFO] [Mask] Masking command output file : /tmp/20201007212928/output/netstat_-plan.txt...
|
138
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Collect] Collecting command output netstat stored in /tmp/20201007212928/output/netstat_-plan.txt.mask
|
139
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Collect] Collecting command output : command = netstat -s
|
140
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Mask] Masking command output file : /tmp/20201007212928/output/netstat_-s.txt...
|
141
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Collect] Collecting command output netstat stored in /tmp/20201007212928/output/netstat_-s.txt.mask
|
142
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Collect] Collecting systctl information...
|
143
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Collect] sysctl information is stored in /tmp/20201007212928/output/sysctl_-a.txt
|
144
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Valid] Validating systctl information...
|
145
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Valid] Sysctl: net_core_netdev_max_backlog => 5000 is correct (recommendation is 5000)
|
146
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Valid] Sysctl: net_core_rmem_max => 16777216 is correct (recommendation is 16777216)
|
147
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Valid] Sysctl: net_core_somaxconn => 1024 is correct (recommendation is 1024)
|
148
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Valid] Sysctl: net_core_wmem_max => 16777216 is correct (recommendation is 16777216)
|
149
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Valid] Sysctl: net_ipv4_ip_local_port_range => ["10240", "65535"] is correct (recommendation is ["10240", "65535"])
|
150
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Valid] Sysctl: net_ipv4_tcp_max_syn_backlog => 8096 is correct (recommendation is 8096)
|
151
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Valid] Sysctl: net_ipv4_tcp_rmem => ["4096", "12582912", "16777216"] is correct (recommendation is ["4096", "12582912", "16777216"])
|
152
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Valid] Sysctl: net_ipv4_tcp_slow_start_after_idle => 0 is correct (recommendation is 0)
|
153
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Valid] Sysctl: net_ipv4_tcp_tw_reuse => 1 is correct (recommendation is 1)
|
154
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Valid] Sysctl: net_ipv4_tcp_wmem => ["4096", "12582912", "16777216"] is correct (recommendation is ["4096", "12582912", "16777216"])
|
155
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Collect] Collecting ulimit information...
|
156
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Collect] ulimit information is stored in /tmp/20201007212928/output/sh_-c_'ulimit_-n'.txt
|
157
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Valid] Validating ulimit information...
|
158
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Valid] ulimit => 65536 is correct (recommendation is >65535)
|
159
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Mask] Masking td-agent config file : /tmp/20201007212928/etc/td-agent/td-agent.conf...
|
160
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Mask] Masking td-agent config file : /tmp/20201007212928/etc/td-agent/http_fld_system.conf...
|
161
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Mask] Export mask log file : ./mask_20201007212928.json
|
162
|
+
2020-10-07 21:29:30 +0000: [Diagtool] [INFO] [Collect] Generate tar file /tmp/diagout-20201007212928.tar.gz
|
163
|
+
```
|
86
164
|
|
87
165
|
#### The "@include" directive in td-agent configuration file
|
88
|
-
The "@include" directive is a function to reuse configuration defined in
|
166
|
+
The "@include" directive is a function to reuse configuration defined in other configuration files. Diagtool reads Fluentd configuration and gathers the files described in "@include" directive as well. The details of "@include" directive are described in followed page:
|
89
167
|
https://docs.fluentd.org/configuration/config-file#6-re-use-your-config-the-include-directive
|
90
168
|
|
91
169
|
#### User defined words to be masked
|
@@ -98,67 +176,9 @@ centos8102
|
|
98
176
|
```
|
99
177
|
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.
|
100
178
|
|
101
|
-
#### Command sample:
|
102
|
-
```
|
103
|
-
# diagtool -o /tmp/work1 -w passwd1,passwd2 -f word_list_sample -m yes
|
104
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] Parsing command options...
|
105
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] Option : Output directory = /tmp/work1
|
106
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] Option : Mask = yes
|
107
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] Option : Word list = ["passwd1", "passwd2", "centos8101", "centos8102"]
|
108
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] Option : Hash Seed =
|
109
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] Initializing parameters...
|
110
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] [Collect] Loading the environment parameters...
|
111
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] [Collect] operating system = CentOS Linux 8 (Core)
|
112
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] [Collect] kernel version = Linux 4.18.0-147.el8.x86_64
|
113
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] [Collect] td-agent conf path = /etc/td-agent/
|
114
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] [Collect] td-agent conf file = td-agent.conf
|
115
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] [Collect] td-agent log path = /var/log/td-agent/
|
116
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] [Collect] td-agent log = td-agent.log
|
117
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] [Collect] Collecting log files of td-agent...
|
118
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] [Collect] log files of td-agent are stored in ["/tmp/work1/20200512182119/var/log/td-agent/td-agent.log-20200508.gz", "/tmp/work1/20200512182119/var/log/td-agent/td-agent.log-20200509.gz", "/tmp/work1/20200512182119/var/log/td-agent/td-agent.log-20200507.gz", "/tmp/work1/20200512182119/var/log/td-agent/td-agent.log-20200512", "/tmp/work1/20200512182119/var/log/td-agent/td-agent.log"]
|
119
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] [Collect] Collecting config file of td-agent...
|
120
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] [Collect] config file is stored in /tmp/work1/20200512182119/etc/td-agent/td-agent.conf
|
121
|
-
2020-05-12 18:21:19 -0400: [Diagtool] [INFO] [Collect] Collecting td-agent gem information...
|
122
|
-
2020-05-12 18:21:20 -0400: [Diagtool] [INFO] [Collect] td-agent gem information is stored in /tmp/work1/20200512182119/etc/td-agent/tdgem_list.output
|
123
|
-
2020-05-12 18:21:20 -0400: [Diagtool] [INFO] [Collect] Collecting config file of OS log...
|
124
|
-
2020-05-12 18:21:20 -0400: [Diagtool] [INFO] [Mask] Masking OS log file : /tmp/work1/20200512182119/var/log/messages...
|
125
|
-
2020-05-12 18:21:20 -0400: [Diagtool] [INFO] [Collect] config file is stored in /tmp/work1/20200512182119/var/log/messages.mask
|
126
|
-
2020-05-12 18:21:20 -0400: [Diagtool] [INFO] [Collect] Collecting OS memory information...
|
127
|
-
2020-05-12 18:21:20 -0400: [Diagtool] [INFO] [Collect] config file is stored in /tmp/work1/20200512182119/meminfo.output
|
128
|
-
2020-05-12 18:21:20 -0400: [Diagtool] [INFO] [Collect] Collecting date/time information...
|
129
|
-
2020-05-12 18:21:20 -0400: [Diagtool] [INFO] [Collect] date/time information is stored in /tmp/work1/20200512182119/ntp_info.output
|
130
|
-
2020-05-12 18:21:20 -0400: [Diagtool] [INFO] [Collect] Collecting netstat information...
|
131
|
-
2020-05-12 18:21:20 -0400: [Diagtool] [INFO] [Mask] Masking netstat file : /tmp/work1/20200512182119/netstat_n.output...
|
132
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Collect] netstat information is stored in /tmp/work1/20200512182119/netstat_n.output.mask and /tmp/work1/20200512182119/netstat_s.output
|
133
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Collect] Collecting systctl information...
|
134
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Collect] sysctl information is stored in /tmp/work1/20200512182119/etc/sysctl.conf
|
135
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Valid] Validating systctl information...
|
136
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Valid] Sysctl: net_core_somaxconn => 1024 is correct (recommendation is 1024)
|
137
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Valid] Sysctl: net_core_netdev_max_backlog => 5000 is correct (recommendation is 5000)
|
138
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Valid] Sysctl: net_core_rmem_max => 16777216 is correct (recommendation is 16777216)
|
139
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Valid] Sysctl: net_core_wmem_max => 16777216 is correct (recommendation is 16777216)
|
140
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Valid] Sysctl: net_ipv4_tcp_wmem => ["4096", "12582912", "16777216"] is correct (recommendation is ["4096", "12582912", "16777216"])
|
141
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Valid] Sysctl: net_ipv4_tcp_rmem => ["4096", "12582912", "16777216"] is correct (recommendation is ["4096", "12582912", "16777216"])
|
142
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Valid] Sysctl: net_ipv4_tcp_max_syn_backlog => 8096 is correct (recommendation is 8096)
|
143
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Valid] Sysctl: net_ipv4_tcp_slow_start_after_idle => 0 is correct (recommendation is 0)
|
144
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Valid] Sysctl: net_ipv4_tcp_tw_reuse => 1 is correct (recommendation is 1)
|
145
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Valid] Sysctl: net_ipv4_ip_local_port_range => ["10240", "65535"] is correct (recommendation is ["10240", "65535"])
|
146
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Collect] Collecting ulimit information...
|
147
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Collect] ulimit information is stored in /tmp/work1/20200512182119/ulimit_n.output
|
148
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Valid] Validating ulimit information...
|
149
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Valid] ulimit => 65536 is correct (recommendation is >65535)
|
150
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Mask] Masking td-agent config file : /tmp/work1/20200512182119/etc/td-agent/td-agent.conf...
|
151
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Mask] Masking td-agent log file : /tmp/work1/20200512182119/var/log/td-agent/td-agent.log-20200508.gz...
|
152
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Mask] Masking td-agent log file : /tmp/work1/20200512182119/var/log/td-agent/td-agent.log-20200509.gz...
|
153
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Mask] Masking td-agent log file : /tmp/work1/20200512182119/var/log/td-agent/td-agent.log-20200507.gz...
|
154
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Mask] Masking td-agent log file : /tmp/work1/20200512182119/var/log/td-agent/td-agent.log-20200512...
|
155
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Mask] Masking td-agent log file : /tmp/work1/20200512182119/var/log/td-agent/td-agent.log...
|
156
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Mask] Export mask log file : ./mask_20200512182119.json
|
157
|
-
2020-05-12 18:21:22 -0400: [Diagtool] [INFO] [Collect] Generate tar file /tmp/work1/diagout-20200512182119.tar.gz
|
158
|
-
```
|
159
179
|
#### Mask Function
|
160
|
-
When run
|
161
|
-
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.
|
180
|
+
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.
|
181
|
+
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.
|
162
182
|
#### Mask sample - IP address: IPv4_{md5hash}
|
163
183
|
```
|
164
184
|
"Line112-8": {
|
@@ -183,8 +203,6 @@ The diagtool provides hash-seed option with '-s'. When hash-seed is specified, t
|
|
183
203
|
```
|
184
204
|
|
185
205
|
## Tested Environment
|
186
|
-
- OS : CentOS 8.1
|
187
|
-
- Fluentd : td-agent version 3
|
206
|
+
- OS : CentOS 8.1 / Ubuntu 20.04
|
207
|
+
- Fluentd : td-agent version 3/4
|
188
208
|
https://docs.fluentd.org/quickstart/td-agent-v2-vs-v3
|
189
|
-
|
190
|
-
|
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'],
|
@@ -145,39 +216,134 @@ module Diagtool
|
|
145
216
|
FileUtils.cp(@tdconf_path+@tdconf, target_dir)
|
146
217
|
conf = @workdir+@tdconf_path+@tdconf
|
147
218
|
conf_list = []
|
148
|
-
conf_list.push
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
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
|
227
|
+
end
|
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
|
177
344
|
end
|
178
345
|
end
|
179
|
-
|
180
|
-
return conf_list
|
346
|
+
return plugins_conf
|
181
347
|
end
|
182
348
|
|
183
349
|
def collect_tdlog()
|
@@ -189,65 +355,20 @@ module Diagtool
|
|
189
355
|
return Dir.glob(target_dir+@tdlog+'*')
|
190
356
|
end
|
191
357
|
|
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
358
|
def collect_oslog()
|
200
359
|
target_dir = @workdir+@oslog_path
|
201
360
|
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)
|
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}")
|
220
369
|
end
|
221
|
-
return output
|
222
370
|
end
|
223
371
|
|
224
|
-
def collect_meminfo()
|
225
|
-
output = @outdir+'/meminfo.output'
|
226
|
-
stdout, stderr, status = Open3.capture3("cat /proc/meminfo")
|
227
|
-
File.open(output, 'w') do |f|
|
228
|
-
f.puts(stdout)
|
229
|
-
end
|
230
|
-
return output
|
231
|
-
end
|
232
|
-
|
233
|
-
def collect_netstat_plan()
|
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
372
|
def collect_ntp(command)
|
252
373
|
output = @outdir+'/ntp_info.output'
|
253
374
|
stdout_date, stderr_date, status_date = Open3.capture3("date")
|
@@ -257,9 +378,26 @@ module Diagtool
|
|
257
378
|
f.puts(stdout_date)
|
258
379
|
f.puts(stdout_ntp)
|
259
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
|
260
398
|
return output
|
261
399
|
end
|
262
|
-
|
400
|
+
|
263
401
|
def collect_tdgems()
|
264
402
|
output = @outdir+'/tdgem_list.output'
|
265
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,34 +185,40 @@ module Diagtool
|
|
189
185
|
end
|
190
186
|
|
191
187
|
if @conf[:mask] == 'yes'
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
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
|
+
}
|
205
|
+
end
|
205
206
|
end
|
206
207
|
|
207
208
|
if @conf[:mask] == 'yes'
|
208
209
|
diaglogger_info("[Mask] Export mask log file : #{@masklog}")
|
209
210
|
m.export_masklog(@masklog)
|
210
211
|
end
|
211
|
-
|
212
|
+
|
212
213
|
tar_file = c.compress_output()
|
213
214
|
diaglogger_info("[Collect] Generate tar file #{tar_file}")
|
214
215
|
end
|
215
216
|
|
216
217
|
def parse_diagconf(params)
|
217
218
|
options = {
|
218
|
-
:precheck => '', :basedir => '', :mask => '', :words => [], :wfile => '', :seed => '', :tdconf =>'', :tdlog => ''
|
219
|
+
:precheck => '', :basedir => '', :type =>'', :mask => '', :words => [], :wfile => '', :seed => '', :tdconf =>'', :tdlog => ''
|
219
220
|
}
|
221
|
+
### Parse precheck flag
|
220
222
|
if params[:precheck]
|
221
223
|
options[:precheck] = params[:precheck]
|
222
224
|
else
|
@@ -233,6 +235,13 @@ module Diagtool
|
|
233
235
|
raise "output directory '-o' must be specified"
|
234
236
|
end
|
235
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
|
236
245
|
if params[:mask] == nil
|
237
246
|
options[:mask] = 'no'
|
238
247
|
else
|
@@ -242,7 +251,11 @@ module Diagtool
|
|
242
251
|
raise "invalid arguments '#{params[:mask]}' : input of '-m|--mask' should be 'yes' or 'no'"
|
243
252
|
end
|
244
253
|
end
|
254
|
+
|
255
|
+
### Parse uder-defined keyword list which will be used in the mask function
|
245
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
|
246
259
|
if params[:"word-file"] != nil
|
247
260
|
f = params[:"word-file"]
|
248
261
|
if File.exist?(f)
|
@@ -254,8 +267,11 @@ module Diagtool
|
|
254
267
|
end
|
255
268
|
end
|
256
269
|
options[:words] = options[:words].uniq
|
270
|
+
|
271
|
+
### Parse hash seed which will be used in the mask function
|
257
272
|
options[:seed] = params[:"hash-seed"] if params[:"hash-seed"] != nil
|
258
|
-
|
273
|
+
|
274
|
+
### Parse the path of fluentd config file
|
259
275
|
if params[:conf] != nil
|
260
276
|
f = params[:conf]
|
261
277
|
if File.exist?(f)
|
@@ -265,6 +281,7 @@ module Diagtool
|
|
265
281
|
end
|
266
282
|
end
|
267
283
|
|
284
|
+
### Parse the path of fluentd log file
|
268
285
|
if params[:log] != nil
|
269
286
|
f = params[:log]
|
270
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.1
|
4
|
+
version: 1.0.1
|
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-29 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
|