diff --git a/pom.xml b/pom.xml index 7c627e1f..d51dade0 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.elasticsearch support-diagnostics - 2.0.7 + 2.0.8 jar Support Diagnostics Utilities diff --git a/src/main/java/com/elastic/support/diagnostics/DiagnosticApp.java b/src/main/java/com/elastic/support/diagnostics/DiagnosticApp.java index 994f3212..3446c52f 100644 --- a/src/main/java/com/elastic/support/diagnostics/DiagnosticApp.java +++ b/src/main/java/com/elastic/support/diagnostics/DiagnosticApp.java @@ -43,7 +43,6 @@ public static void main(String[] args) throws Exception { long interval = inputs.getInterval() * 1000; for (int i = 1; i <= reps; i++) { - //diags.run(inputs); dc.runDiagnostic(ctx); System.out.println("Run " + i + " of " + reps + " completed."); if (reps > 1) { diff --git a/src/main/java/com/elastic/support/diagnostics/InputParams.java b/src/main/java/com/elastic/support/diagnostics/InputParams.java index eaccb7e3..6a06b5ea 100644 --- a/src/main/java/com/elastic/support/diagnostics/InputParams.java +++ b/src/main/java/com/elastic/support/diagnostics/InputParams.java @@ -4,7 +4,7 @@ public class InputParams { - @Parameter(names = {"-?", "--help"}, help = true) + @Parameter(names = {"-?", "--help"}, description = "Help contents.", help = true) private boolean help; @Parameter(names = {"-o", "--out", "--output", "--outputDir"}, description = "Fully qualified path to output directory or c for current working directory.") @@ -13,10 +13,10 @@ public class InputParams { @Parameter(names = {"-h", "--host",}, description = "Required field. Hostname, IP Address, or localhost. HTTP access must be enabled.") private String host = ""; - @Parameter(names = {"--port"}, description = "HTTP or HTTPS listening port. Defaults to 9200") + @Parameter(names = {"--port"}, description = "HTTP or HTTPS listening port. Defaults to 9200.") private int port = 9200; - @Parameter(names = {"-u", "--user"}, description = "Username") + @Parameter(names = {"-u", "--user"}, description = "Username.") private String username; @Parameter(names = {"-p", "--password", "--pwd"}, description = "Prompt for a password? No password value required, only the option. Hidden from the command line on entry.", password = true) @@ -50,6 +50,7 @@ public class InputParams { private boolean skipVerification = false; private boolean secured = false; + private boolean wasPortSet = false; public boolean isSkipVerification() { return skipVerification; @@ -89,6 +90,7 @@ public int getPort() { public void setPort(int port) { this.port = port; + wasPortSet = true; } public String getUsername() { @@ -189,6 +191,12 @@ public void setBzip(boolean bzip) { public String getUrl() { String protocol; + if(diagType.equalsIgnoreCase("logstash")){ + if(! wasPortSet){ + this.port = 9600; + } + } + if (this.isSsl) { protocol = "https"; } else { diff --git a/src/main/java/com/elastic/support/diagnostics/RestModule.java b/src/main/java/com/elastic/support/diagnostics/RestModule.java index 2afcebc7..828965a4 100644 --- a/src/main/java/com/elastic/support/diagnostics/RestModule.java +++ b/src/main/java/com/elastic/support/diagnostics/RestModule.java @@ -2,43 +2,27 @@ import org.apache.commons.compress.utils.IOUtils; import org.apache.http.HttpResponse; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.utils.HttpClientUtils; import org.apache.http.conn.HttpHostConnectException; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/* -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.ResponseEntity; -import org.springframework.web.client.RestClientException; -import org.springframework.web.client.RestTemplate; -*/ import java.io.FileOutputStream; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.concurrent.TimeUnit; public class RestModule { -/* RestTemplate restTemplate; - HttpEntity request;*/ HttpClient client; private final static Logger logger = LoggerFactory.getLogger(RestModule.class); -/* public RestModule(RestTemplate restTemplate, HttpEntity request) { - this.restTemplate = restTemplate; - this.request = request; - }*/ - public RestModule(HttpClient client){ this.client = client; } @@ -60,7 +44,8 @@ public String submitRequest(String url){ catch (Exception e){ logger.error("Error handling response for " + url, e); } finally { - HttpClientUtils.closeQuietly(response); } + HttpClientUtils.closeQuietly(response); + } } catch (HttpHostConnectException e){ throw new RuntimeException("Error connecting to host " + url, e); @@ -102,7 +87,9 @@ public void submitRequest(String url, String queryName, String destination){ catch (Exception e){ logger.error("Error writing response for " + queryName + " to disk.", e); } finally { - HttpClientUtils.closeQuietly(response); } + HttpClientUtils.closeQuietly(response); + Thread.sleep(2000); + } } catch (Exception e){ if (url.contains("_license")) { @@ -133,32 +120,4 @@ private void checkResponseCode(String name, HttpResponse response){ } } -/* - public String submitRequest(String url) { - - String result; - try { - ; - logger.debug("Submitting: " + url); - ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, request, String.class); - result = response.getBody(); - logger.debug(result); - - } catch (RestClientException e) { - if (url.contains("_license")) { - logger.info("There were no licenses installed"); - return "No licenses installed"; - } - String msg = "Please check log file for additional details."; - logger.error("Error submitting request\n:", e); - if (e.getMessage().contains("401 Unauthorized")) { - msg = "Authentication failure: invalid login credentials.\n" + msg; - } - throw new RuntimeException(msg); - } - - return result; - - } - */ } \ No newline at end of file diff --git a/src/main/java/com/elastic/support/diagnostics/commands/RestModuleSetupCmd.java b/src/main/java/com/elastic/support/diagnostics/commands/RestModuleSetupCmd.java index c45519c0..4f0f51c2 100644 --- a/src/main/java/com/elastic/support/diagnostics/commands/RestModuleSetupCmd.java +++ b/src/main/java/com/elastic/support/diagnostics/commands/RestModuleSetupCmd.java @@ -29,9 +29,6 @@ public boolean execute(DiagnosticContext context) { } DiagnosticRequestFactory diagnosticRequestFactory = new DiagnosticRequestFactory(connectTimeout, requestTimeout, isSecured, user, pass); - //RestTemplate restTemplate = new RestTemplate(diagnosticRequestFactory.getSslReqFactory()); - //HttpEntity request = configureAuth(context.getInputParams()); - //RestModule restModule = new RestModule(restTemplate, request); HttpClient client = null; if (bypassVerify) { client = diagnosticRequestFactory.getUnverifiedSslClient(); @@ -51,21 +48,4 @@ public boolean execute(DiagnosticContext context) { return true; } -/* public HttpEntity configureAuth(InputParams inputs) { - - HttpHeaders headers = new HttpHeaders(); - - // If we need authentication - if (inputs.isSecured()) { - String plainCreds = inputs.getUsername() - + ":" + inputs.getPassword(); - byte[] plainCredsBytes = plainCreds.getBytes(); - byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes); - String base64Creds = new String(base64CredsBytes); - headers.add("Authorization", "Basic " + base64Creds); - } - - return new HttpEntity<>(headers); - - }*/ } diff --git a/src/main/java/com/elastic/support/diagnostics/commands/RunClusterQueriesCmd.java b/src/main/java/com/elastic/support/diagnostics/commands/RunClusterQueriesCmd.java index 561f28a3..1697b38e 100644 --- a/src/main/java/com/elastic/support/diagnostics/commands/RunClusterQueriesCmd.java +++ b/src/main/java/com/elastic/support/diagnostics/commands/RunClusterQueriesCmd.java @@ -23,10 +23,9 @@ public boolean execute(DiagnosticContext context) { String queryName = null; String fileName = null; - String majorVersion = context.getVersion().substring(0, 1); List textFileExtensions = (List) config.get("textFileExtensions"); - Map statements = (Map) config.get("restQueries-" + majorVersion); + Map statements = (Map) config.get("logstash"); Set> entries = statements.entrySet(); logger.debug("Generating full diagnostic."); @@ -47,8 +46,6 @@ public boolean execute(DiagnosticContext context) { fileName = context.getTempDir() + SystemProperties.fileSeparator + queryName + ext; restModule.submitRequest(url, queryName, fileName); - - //Files.write(Paths.get(fileName), result.getBytes()); } return true; diff --git a/src/main/java/com/elastic/support/diagnostics/commands/RunLogstashQueriesCmd.java b/src/main/java/com/elastic/support/diagnostics/commands/RunLogstashQueriesCmd.java new file mode 100644 index 00000000..9887ebae --- /dev/null +++ b/src/main/java/com/elastic/support/diagnostics/commands/RunLogstashQueriesCmd.java @@ -0,0 +1,43 @@ +package com.elastic.support.diagnostics.commands; + +import com.elastic.support.SystemProperties; +import com.elastic.support.diagnostics.DiagnosticContext; +import com.elastic.support.diagnostics.InputParams; +import com.elastic.support.diagnostics.RestModule; + +import java.util.Map; +import java.util.Set; + +public class RunLogstashQueriesCmd extends AbstractDiagnosticCmd { + + public boolean execute(DiagnosticContext context) { + + InputParams inputs = context.getInputParams(); + Map config = context.getConfig(); + RestModule restModule = context.getRestModule(); + String queryName; + String fileName; + + Map statements = (Map) config.get("logstash"); + Set> entries = statements.entrySet(); + + logger.debug("Generating full diagnostic."); + + for (Map.Entry entry : entries) { + queryName = entry.getKey(); + String query = entry.getValue(); + logger.debug(": now processing " + queryName + ", " + query); + String url = inputs.getUrl() + "/" + query; + logger.info("Currently running the following query:" + queryName); + + String ext = ".json"; + + fileName = context.getTempDir() + SystemProperties.fileSeparator + queryName + ext; + restModule.submitRequest(url, queryName, fileName); + } + + return true; + } + + +} diff --git a/src/main/java/com/elastic/support/diagnostics/commands/SystemCallsCmd.java b/src/main/java/com/elastic/support/diagnostics/commands/SystemCallsCmd.java index a6c27ff6..ddffb5ce 100644 --- a/src/main/java/com/elastic/support/diagnostics/commands/SystemCallsCmd.java +++ b/src/main/java/com/elastic/support/diagnostics/commands/SystemCallsCmd.java @@ -8,60 +8,61 @@ public class SystemCallsCmd extends AbstractDiagnosticCmd { - public boolean execute(DiagnosticContext context){ - - String os = checkOS(); - Map osCmds = (Map) context.getConfig().get(os); - - ProcessBuilder pb = new ProcessBuilder(); - pb.redirectErrorStream(true); - - Iterator> iter = osCmds.entrySet().iterator(); - List cmds = new ArrayList(); - - try { - while (iter.hasNext()) { - Map.Entry entry = (Map.Entry) iter.next(); - String cmdLabel = entry.getKey(); - String cmdText = entry.getValue(); - - // One off hack for process limits - if (cmdLabel.equals("proc-limit")){ - //cmdText.replaceAll("PID", ); - cmdText = "cat /proc/" + context.getPid() + "/limits"; - } - - StringTokenizer st = new StringTokenizer(cmdText, " "); - while (st.hasMoreTokens()) { - cmds.add(st.nextToken()); - } - - pb.redirectOutput(new File(context.getTempDir() + SystemProperties.fileSeparator + cmdLabel + ".txt")); - pb.command(cmds); - Process pr = pb.start(); - pr.waitFor(); - cmds.clear(); - - } - } catch (Exception e) { - logger.error("Error processing system commands", e); + public boolean execute(DiagnosticContext context) { + + String os = checkOS(); + Map osCmds = (Map) context.getConfig().get(os); + + ProcessBuilder pb = new ProcessBuilder(); + pb.redirectErrorStream(true); + + Iterator> iter = osCmds.entrySet().iterator(); + List cmds = new ArrayList(); + + while (iter.hasNext()) { + + try { + Map.Entry entry = iter.next(); + String cmdLabel = entry.getKey(); + String cmdText = entry.getValue(); + + // One off hack for process limits + if (cmdLabel.equals("proc-limit")) { + cmdText = "cat /proc/" + context.getPid() + "/limits"; } - return true; - } - - public String checkOS() { - String osName = SystemProperties.osName.toLowerCase(); - if (osName.contains("windows")) { - return "winOS"; - } else if (osName.contains("linux")) { - return "linuxOS"; - } else if (osName.contains("darwin") || osName.contains("mac os x")) { - return "macOS"; - } else { - logger.error("Failed to detect operating system!"); - throw new RuntimeException("Unsupported OS"); - } - } + StringTokenizer st = new StringTokenizer(cmdText, " "); + while (st.hasMoreTokens()) { + cmds.add(st.nextToken()); + } + + pb.redirectOutput(new File(context.getTempDir() + SystemProperties.fileSeparator + cmdLabel + ".txt")); + pb.command(cmds); + Process pr = pb.start(); + pr.waitFor(); + } catch (Exception e) { + logger.error("Error processing system command", e); + } finally { + cmds.clear(); + } + } + + + return true; + } + + public String checkOS() { + String osName = SystemProperties.osName.toLowerCase(); + if (osName.contains("windows")) { + return "winOS"; + } else if (osName.contains("linux")) { + return "linuxOS"; + } else if (osName.contains("darwin") || osName.contains("mac os x")) { + return "macOS"; + } else { + logger.error("Failed to detect operating system!"); + throw new RuntimeException("Unsupported OS"); + } + } } diff --git a/src/main/resources/chains.yml b/src/main/resources/chains.yml index aa0ec4ac..ff58edc9 100644 --- a/src/main/resources/chains.yml +++ b/src/main/resources/chains.yml @@ -20,3 +20,11 @@ remote: - com.elastic.support.diagnostics.commands.GenerateManifestCmd - com.elastic.support.diagnostics.commands.ArchiveResultsCmd - com.elastic.support.diagnostics.commands.CleanupCmd + +logstash: + - com.elastic.support.diagnostics.commands.DirectorySetupCmd + - com.elastic.support.diagnostics.commands.RestModuleSetupCmd + - com.elastic.support.diagnostics.commands.RunLogstashQueriesCmd + - com.elastic.support.diagnostics.commands.ArchiveResultsCmd + - com.elastic.support.diagnostics.commands.CleanupCmd + diff --git a/src/main/resources/diags.yml b/src/main/resources/diags.yml index 6b31be6d..5df4c4a2 100644 --- a/src/main/resources/diags.yml +++ b/src/main/resources/diags.yml @@ -10,6 +10,7 @@ textFileExtensions: - cat_master - cat_nodes - cat_indices + - cat_fielddata - cat_count - cat_segments - cat_health @@ -19,9 +20,8 @@ textFileExtensions: - cat_recovery - watcher - restQueries-1: - alias: "_alias?pretty" + alias: "_alias?pretty&human" allocation: "_cat/allocation?v" cat_master: "_cat/master?format=json" cat_nodes: "_cat/nodes?v" @@ -32,18 +32,19 @@ restQueries-1: cat_pending_tasks: "_cat/pending_tasks?v" cat_aliases: "_cat/aliases?v" cat_thread_pool: "_cat/thread_pool?v" - cat_fielddata: "_cat/fielddata?fields=*&format=json&pretty" +# cat_fielddata: "_cat/fielddata?fields=*&format=json&pretty" + cat_fielddata: "_cat/fielddata?v" cat_shards: "_cat/shards" cat_recovery: "_cat/recovery?v" - cluster_health: "_cluster/health?pretty" + cluster_health: "_cluster/health?pretty&human" cluster_pending_tasks: "_cluster/pending_tasks?pretty&human" - cluster_settings: "_cluster/settings?pretty" - cluster_state: "_cluster/state?pretty" - cluster_stats: "_cluster/stats?&pretty=human&output_uuid=true" - count: "_count?pretty" + cluster_settings: "_cluster/settings?pretty&human" + cluster_state: "_cluster/state?pretty&human" + cluster_stats: "_cluster/stats?pretty&human&output_uuid=true" + count: "_count?pretty&human" indices_stats: "_stats?pretty&human" - licenses: "_licenses?pretty" - mapping: "_mapping?pretty" + licenses: "_licenses?pretty&human" + mapping: "_mapping?pretty&human" nodes_hot_threads: "_nodes/hot_threads?threads=10000" nodes_stats: "_nodes/stats?pretty&human" fielddata_stats: "/_nodes/stats/indices/fielddata?level=indices&pretty=true&fields=*" @@ -51,13 +52,13 @@ restQueries-1: plugins: "_cat/plugins?v" recovery: "_recovery" segments: "_segments?pretty&human" - settings: "_settings?pretty" + settings: "_settings?pretty&human" version: "" nodes: "_nodes?all&pretty&human" warmers: "_all/_warmer" watcher_stats: "/_watcher/stats/_all" watcher_stack: "/_watcher/stats?emit_stacktraces=true" - templates: "_template?pretty" + templates: "_template?pretty&human" restQueries-2: alias: "_alias?pretty" @@ -90,7 +91,7 @@ restQueries-2: recovery: "_recovery" shards: "_cat/shards?format=json" segments: "_segments?pretty&human" - settings: "_settings?pretty" + settings: "_settings?pretty&human" version: "" nodes: "_nodes?all&pretty&human" warmers: "_all/_warmer" @@ -98,11 +99,16 @@ restQueries-2: watcher_stack: "/_watcher/stats?emit_stacktraces=true" templates: "_template?pretty" nodeattrs: "/_cat/nodeattrs" - tasks: "_tasks" - + tasks: "_tasks?pretty&human" logstash: - + version: "?pretty&human" + hot_threads: "_node/hot_threads?pretty&human" + node_stats: "_node/stats/?pretty&human" + event_stats: "_node/stats/events?pretty&human" + jvm_node_stats: "_node/stats/jvm?pretty&human" + jvm_stats: "_stats/jvm?pretty&human" + plugins: "_plugins?pretty&human" linuxOS: top: "top -b -n1"