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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 459fd1aefd11e12f79ef9f12cd99e289412fc99c3711191508aa3b17af985a6d
4
- data.tar.gz: 8ed32d7c995ec7a6afb9a618421eb49590f44db96ed10f4babb8440cb3fde271
3
+ metadata.gz: bfb1e90d1be9a7723371f6ea3cf72ea4eec822d732e2d940e54871cf20ce02d0
4
+ data.tar.gz: bbc10274d97eef4e0c79b5da843947389607519dd8f34e66ebc775ecf7171736
5
5
  SHA512:
6
- metadata.gz: 97adbb75557f1c7c2cf0624e2c9f4aa8ac1631a91d1b30f269fa137223ee20855ceb5764d47cf32f3b01ec0b1e80d541b0ecb069c27d136e456809b935f91efe
7
- data.tar.gz: e6bc2057366a4f864d7d081235f29bcc0ddbc118412695f52fc6516a642421e9d9770a5a1fd6c7fc2deb7f4cd90a1d3e8d90cb0bcec07e99fd8ef4dc41a90f8a
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
- The diagtool enable users to automate the date collection which is required for trouble shooting. The data collected by diagtool include the configuration and log files of the td-agent and diagnostic information of operating system such as network and memory status and stats. In some cases, configuration and log files contains the security sensitive information, such as IP addresses and Hostname. The diagtool also provides the functions to generate mask on IP addresses, Hostname(in FQDN style) and user defined keywords described in the collected data.
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
- - TD Agent information
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 conectivity status/stats(netstat -plan/netstat -s)
19
+ - network connectivity status/stats(netstat -plan/netstat -s)
19
20
  - memory information(/proc/meminfo)
20
21
  <br>
21
22
 
22
23
  ## Prerequisite
23
- The diagtool provides support for td-agent based installation running on Linux OS. The td-agent is a stable distribution package of Fluentd.
24
- The differences between Fluentd and td-agent are described in followed url:
25
- https://www.fluentd.org/faqs
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
- Fetching: fileutils-1.0.2.gem (100%)
32
- Successfully installed fileutils-1.0.2
33
- Fetching: json-2.1.0.gem (100%)
34
- Building native extensions. This could take a while...
35
- Successfully installed json-2.1.0
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: /usr/local/bin/diagtool -o OUTPUT_DIR -m {yes | no} -w {word1,[word2...]} -f {listfile} -s {hash seed}
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
- ### Pre-check
55
- The diagtool automatically extract the path of td-agent configuration and log files from td-agent daemon and use them during data collection if the td-agent is managed as daemon. The precheck options provides the function to confirm if the diagtool could gather the td-agent information as expected.
56
- The following command output shows the case when the diagtool successfully gather information from daemon.
57
- ```
58
- # diagtool --precheck
59
- 2020-05-28 00:39:02 -0400: [Diagtool] [INFO] [Precheck] Check OS parameters...
60
- 2020-05-28 00:39:02 -0400: [Diagtool] [INFO] [Precheck] operating system = CentOS Linux 8 (Core)
61
- 2020-05-28 00:39:02 -0400: [Diagtool] [INFO] [Precheck] kernel version = Linux 4.18.0-147.el8.x86_64
62
- 2020-05-28 00:39:02 -0400: [Diagtool] [INFO] [Precheck] Check td-agent parameters...
63
- 2020-05-28 00:39:02 -0400: [Diagtool] [INFO] [Precheck] td-agent conf path = /etc/td-agent/
64
- 2020-05-28 00:39:02 -0400: [Diagtool] [INFO] [Precheck] td-agent conf file = td-agent.conf
65
- 2020-05-28 00:39:02 -0400: [Diagtool] [INFO] [Precheck] td-agent log path = /var/log/td-agent/
66
- 2020-05-28 00:39:02 -0400: [Diagtool] [INFO] [Precheck] td-agent log = td-agent.log
67
- 2020-05-28 00:39:02 -0400: [Diagtool] [INFO] [Precheck] Precheck completed. You can run diagtool command without -c and -l options
68
- ```
69
- In some cases, users do not manage td-agent as daemon but use own script to run td-agent with command line options. In that cases, users need to speccify the path of td-agent configuration and log files with -c and -l options respectively.
70
- 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
- ```
72
- # diagtool --precheck
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 another configuration files. The diagtool read the td-agent configuration and collect the files described in "@include" directive as well. The details of "@include" directive are described in followed url:
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 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 files.
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
-
@@ -0,0 +1,2 @@
1
+ centos8101
2
+ centos8102
@@ -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}: [Diagutils] [#{severity}] #{msg}\n"
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
- @tdenv = gen_tdenv()
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
- @tdconf = conf[:tdconf].split('/')[-1]
48
+ @tdconf = conf[:tdconf].split('/')[-1]
36
49
  @tdconf_path = conf[:tdconf].gsub(@tdconf,'')
37
50
  elsif
38
- if not @tdenv['FLUENT_CONF'].empty?
39
- @tdconf = @tdenv['FLUENT_CONF'].split('/')[-1]
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
- raise "The path of td-agent log file need to be specified." if conf[:precheck] == false
54
- end
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 = gen_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 gen_osenv()
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 gen_tdenv()
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
- if @precheck == false # SKip if precheck is true
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
- end
113
+ end
95
114
  stdout.split().each do | l |
96
115
  if l.include?('Environment')
97
- env_dict[l.split('=')[1]] = l.split('=')[2]
116
+ @tdenv[l.split('=')[1]] = l.split('=')[2]
98
117
  end
99
- end
118
+ end
100
119
  else
101
- exe = 'fluentd'
102
- stdout, stderr, status = Open3.capture3("ps aux | grep #{exe} | grep -v grep")
103
- line = stdout.split(/\n/)
104
- log_path = ''
105
- conf_path = ''
106
- line.each { |l|
107
- cmd = l.split.drop(10)
108
- i = 0
109
- log_pos = 0
110
- conf_pos = 0
111
- if cmd[-1] != '--under-supervisor'
112
- cmd.each { |c|
113
- if c.include?("--log") || c.include?("-l")
114
- log_pos = i + 1
115
- log_path = cmd[log_pos]
116
- elsif c.include?("--conf") || c.include?("-c")
117
- conf_pos = i + 1
118
- conf_path = cmd[conf_pos]
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
- i+=1
121
- }
122
- end
123
- }
124
- env_dict['FLUENT_CONF'] = conf_path
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 target_dir + @tdconf
149
- File.readlines(conf).each { |line|
150
- if line.include? '@include'
151
- f = line.split()[1]
152
- if f.start_with?(/\//) # /tmp/work1/b.conf
153
- if f.include?('*')
154
- Dir.glob(f).each { |ff|
155
- conf_inc = target_dir + ff.gsub(/\//,'__')
156
- FileUtils.cp(ff, conf_inc)
157
- conf_list.push conf_inc
158
- }
159
- else
160
- conf_inc = target_dir+f.gsub(/\//,'__')
161
- FileUtils.cp(f, conf_inc)
162
- conf_list.push conf_inc
163
- end
164
- else
165
- f = f.gsub('./','') if f.include?('./')
166
- if f.include?('*')
167
- Dir.glob(@tdconf_path+f).each{ |ff|
168
- conf_inc = target_dir + ff.gsub(@tdconf_path,'').gsub(/\//,'__')
169
- FileUtils.cp(ff, conf_inc)
170
- conf_list.push conf_inc
171
- }
172
- else
173
- conf_inc = target_dir+f.gsub(/\//,'__')
174
- FileUtils.cp(@tdconf_path+f, conf_inc)
175
- conf_list.push conf_inc
176
- end
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
- FileUtils.cp(@oslog_path+@oslog, target_dir)
203
- return target_dir+@oslog
204
- end
205
-
206
- def collect_ulimit()
207
- output = @outdir+'/ulimit_n.output'
208
- stdout, stderr, status = Open3.capture3("ulimit -n")
209
- File.open(output, 'w') do |f|
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
- #@conf[:time] = @time_format
31
- #@conf[:workdir] = @conf[:basedir] + '/' + @time_format
32
- #@conf[:outdir] = @conf[:workdir] + '/output'
33
-
34
- #FileUtils.mkdir_p(@conf[:workdir])
35
- #FileUtils.mkdir_p(@conf[:outdir])
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
- prechecklog.warn("[Precheck] can not find td-agent conf path: please run diagtool command with -c /path/to/<td-agent conf file>")
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
- prechecklog.info("[Precheck] Precheck completed. You can run diagtool command without -c and -l options")
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
- tdlog = c.collect_tdlog()
115
- diaglogger_info("[Collect] log files of td-agent are stored in #{tdlog}")
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.collect_ntp(command="chrony")
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.collect_ntp(command="ntp")
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.collect_sysctl()
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.collect_ulimit()
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
- tdconf.each { | file |
193
- diaglogger_info("[Mask] Masking td-agent config file : #{file}...")
194
- m.mask_tdlog(file, clean = true)
195
- }
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
- }
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?("net")
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
- if @def_sysctl[key] == value
70
- @logger.info("#{key} => #{value} is correct")
71
- v[key]['value'] = value
72
- v[key]['recommend'] = @def_sysctl[key]
73
- v[key]['result'] = "correct"
74
- else
75
- @logger.warn("#{key} => #{value} is incorrect, should be #{@def_sysctl[key]}")
76
- v[key]['value'] = value
77
- v[key]['recommend'] = @def_sysctl[key]
78
- v[key]['result'] = "incorrect"
79
- end
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
@@ -1,5 +1,5 @@
1
1
  module Fluent
2
2
  module Diagtool
3
- VERSION = "0.1.6"
3
+ VERSION = "1.0.1"
4
4
  end
5
5
  end
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.6
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-05-29 00:00:00.000000000 Z
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
- - exe/diagtool
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