From fd2f62993d4fae153f792ad545379612a3a2755e Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Mon, 23 Feb 2015 18:04:58 +0100 Subject: [PATCH] SONAR-5936 improve Elasticsearch information displayed in System Info --- .../java/org/sonar/server/es/EsClient.java | 15 - .../server/platform/ServerComponents.java | 4 +- .../platform/monitoring/EsClusterMonitor.java | 99 ------ .../server/platform/monitoring/EsMonitor.java | 136 ++++++++ ...rMonitorMBean.java => EsMonitorMBean.java} | 9 +- .../platform/monitoring/EsNodesMonitor.java | 109 ------ .../monitoring/EsNodesMonitorMBean.java | 26 -- .../platform/monitoring/PluginsMonitor.java | 5 +- .../sonar/server/search/ClusterHealth.java | 42 --- .../org/sonar/server/search/IndexHealth.java | 57 ---- .../org/sonar/server/search/NodeHealth.java | 313 ------------------ .../org/sonar/server/search/SearchClient.java | 45 --- .../org/sonar/server/search/SearchHealth.java | 78 ----- .../org/sonar/server/es/EsClientTest.java | 1 - .../search/NodeHealthPerformanceTest.java | 54 --- .../server/search/SearchHealthMediumTest.java | 105 ------ .../app/controllers/system_controller.rb | 3 +- .../app/views/system/_monitor.html.erb | 29 +- .../org/sonar/api/utils/text/JsonWriter.java | 2 + .../sonar/api/utils/text/JsonWriterTest.java | 7 +- 20 files changed, 180 insertions(+), 959 deletions(-) delete mode 100644 server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsClusterMonitor.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsMonitor.java rename server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/{EsClusterMonitorMBean.java => EsMonitorMBean.java} (84%) delete mode 100644 server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsNodesMonitor.java delete mode 100644 server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsNodesMonitorMBean.java delete mode 100644 server/sonar-server/src/main/java/org/sonar/server/search/ClusterHealth.java delete mode 100644 server/sonar-server/src/main/java/org/sonar/server/search/IndexHealth.java delete mode 100644 server/sonar-server/src/main/java/org/sonar/server/search/NodeHealth.java delete mode 100644 server/sonar-server/src/main/java/org/sonar/server/search/SearchHealth.java delete mode 100644 server/sonar-server/src/test/java/org/sonar/server/search/NodeHealthPerformanceTest.java delete mode 100644 server/sonar-server/src/test/java/org/sonar/server/search/SearchHealthMediumTest.java diff --git a/server/sonar-server/src/main/java/org/sonar/server/es/EsClient.java b/server/sonar-server/src/main/java/org/sonar/server/es/EsClient.java index 30ef5b63da7..5c252935bc4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/es/EsClient.java +++ b/server/sonar-server/src/main/java/org/sonar/server/es/EsClient.java @@ -24,7 +24,6 @@ import org.elasticsearch.action.admin.cluster.health.ClusterHealthStatus; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsRequestBuilder; import org.elasticsearch.action.admin.cluster.state.ClusterStateRequestBuilder; import org.elasticsearch.action.admin.cluster.stats.ClusterStatsRequestBuilder; -import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse; import org.elasticsearch.action.admin.indices.cache.clear.ClearIndicesCacheRequestBuilder; import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequestBuilder; @@ -70,7 +69,6 @@ import org.sonar.server.es.request.ProxyPutMappingRequestBuilder; import org.sonar.server.es.request.ProxyRefreshRequestBuilder; import org.sonar.server.es.request.ProxySearchRequestBuilder; import org.sonar.server.es.request.ProxySearchScrollRequestBuilder; -import org.sonar.server.search.ClusterHealth; import org.sonar.server.search.SearchClient; /** @@ -90,19 +88,6 @@ public class EsClient implements Startable { this.client = client; } - public ClusterHealth getClusterHealth() { - ClusterHealth health = new ClusterHealth(); - ClusterStatsResponse clusterStatsResponse = this.prepareClusterStats().get(); - - // Cluster health - health.setClusterAvailable(clusterStatsResponse.getStatus() != ClusterHealthStatus.RED); - - // Number of nodes - health.setNumberOfNodes(clusterStatsResponse.getNodesStats().getCounts().getTotal()); - - return health; - } - public RefreshRequestBuilder prepareRefresh(String... indices) { return new ProxyRefreshRequestBuilder(client).setIndices(indices); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java index 7965e3f04a9..959fe205322 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java @@ -246,7 +246,6 @@ class ServerComponents { // Elasticsearch SearchClient.class, IndexClient.class, - SearchHealth.class, EsClient.class, // users @@ -639,8 +638,7 @@ class ServerComponents { SystemWs.class, SystemMonitor.class, SonarQubeMonitor.class, - EsClusterMonitor.class, - EsNodesMonitor.class, + EsMonitor.class, PluginsMonitor.class, JvmPropertiesMonitor.class, DatabaseMonitor.class diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsClusterMonitor.java b/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsClusterMonitor.java deleted file mode 100644 index 890a86f9b0c..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsClusterMonitor.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package org.sonar.server.platform.monitoring; - -import com.google.common.base.Joiner; -import org.sonar.server.search.ClusterHealth; -import org.sonar.server.search.IndexHealth; -import org.sonar.server.search.SearchHealth; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; - -import static org.sonar.api.utils.DateUtils.formatDateTimeNullSafe; - -public class EsClusterMonitor extends BaseMonitorMBean - implements EsClusterMonitorMBean { - - private final SearchHealth searchHealth; - - public EsClusterMonitor(SearchHealth searchHealth) { - this.searchHealth = searchHealth; - } - - @Override - public String getClusterState() { - return clusterHealth().isClusterAvailable() ? "Available" : "Unavailable"; - } - - @Override - public int getNumberOfNodes() { - return clusterHealth().getNumberOfNodes(); - } - - @Override - public String getIndexesHealth() { - Map formattedIndexes = new HashMap<>(); - for (Map.Entry healthEntry : searchHealth.getIndexHealth().entrySet()) { - formattedIndexes.put(healthEntry.getKey(), formatIndexHealth(healthEntry.getValue())); - } - - return Joiner.on(" | ").withKeyValueSeparator(": ").join(formattedIndexes); - } - - @Override - public String name() { - return "ElasticSearchCluster"; - } - - @Override - public LinkedHashMap attributes() { - LinkedHashMap attributes = new LinkedHashMap<>(); - attributes.put("Cluster State", getClusterState()); - attributes.put("Number of Nodes", getNumberOfNodes()); - for (Map.Entry healthEntry : searchHealth.getIndexHealth().entrySet()) { - attributes.put(healthEntry.getKey() + " - Document Count", healthEntry.getValue().getDocumentCount()); - attributes.put(healthEntry.getKey() + " - Last Sync", formatDateTimeNullSafe(healthEntry.getValue().getLastSynchronization())); - attributes.put(healthEntry.getKey() + " - Optimization", formatIndexHealthOptimisation(healthEntry.getValue())); - } - return attributes; - } - - private String formatIndexHealthOptimisation(IndexHealth indexHealth) { - return indexHealth.isOptimized() ? "Optimized" : "Unoptimized " + - "(Segments: " + indexHealth.getSegmentcount() + ", Pending Deletions: " - + indexHealth.getPendingDeletion() + ")"; - } - - private ClusterHealth clusterHealth() { - return searchHealth.getClusterHealth(); - } - - private String formatIndexHealth(IndexHealth indexHealth) { - return new StringBuilder() - .append(indexHealth.getDocumentCount()) - .append("/") - .append(formatDateTimeNullSafe(indexHealth.getLastSynchronization())) - .append("/") - .append(formatIndexHealthOptimisation(indexHealth)).toString(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsMonitor.java b/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsMonitor.java new file mode 100644 index 00000000000..ec32f0a120e --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsMonitor.java @@ -0,0 +1,136 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.server.platform.monitoring; + +import org.elasticsearch.action.admin.cluster.health.ClusterHealthStatus; +import org.elasticsearch.action.admin.cluster.node.stats.NodeStats; +import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse; +import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse; +import org.elasticsearch.action.admin.indices.stats.IndexStats; +import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse; +import org.elasticsearch.monitor.process.ProcessStats; +import org.sonar.server.es.EsClient; + +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map; + +import static org.apache.commons.io.FileUtils.byteCountToDisplaySize; +import static org.sonar.api.utils.DateUtils.formatDateTime; + +public class EsMonitor extends BaseMonitorMBean implements EsMonitorMBean { + + private final EsClient esClient; + + public EsMonitor(EsClient esClient) { + this.esClient = esClient; + } + + @Override + public String name() { + return "ElasticSearch"; + } + + /** + * MXBean does not allow to return enum {@link ClusterHealthStatus}, so + * returning String. + */ + @Override + public String getState() { + return getStateAsEnum().name(); + } + + private ClusterHealthStatus getStateAsEnum() { + return clusterStats().getStatus(); + } + + @Override + public int getNumberOfNodes() { + return clusterStats().getNodesStats().getCounts().getTotal(); + } + + @Override + public LinkedHashMap attributes() { + LinkedHashMap attributes = new LinkedHashMap<>(); + attributes.put("State", getStateAsEnum()); + attributes.put("Indices", indexAttributes()); + attributes.put("Number of Nodes", getNumberOfNodes()); + attributes.put("Nodes", nodeAttributes()); + return attributes; + } + + private LinkedHashMap> indexAttributes() { + LinkedHashMap> indices = new LinkedHashMap<>(); + IndicesStatsResponse indicesStats = esClient.prepareStats().all().get(); + + for (Map.Entry indexStats : indicesStats.getIndices().entrySet()) { + LinkedHashMap attributes = new LinkedHashMap<>(); + indices.put(indexStats.getKey(), attributes); + attributes.put("Docs", indexStats.getValue().getPrimaries().getDocs().getCount()); + attributes.put("Shards", indexStats.getValue().getShards().length); + attributes.put("Store Size", byteCountToDisplaySize(indexStats.getValue().getPrimaries().getStore().getSizeInBytes())); + } + return indices; + } + + /** + * map of {node name -> node attributes} + */ + private LinkedHashMap> nodeAttributes() { + LinkedHashMap> nodes = new LinkedHashMap<>(); + NodesStatsResponse nodesStats = esClient.prepareNodesStats().all().get(); + for (Map.Entry entry : nodesStats.getNodesMap().entrySet()) { + + LinkedHashMap nodeAttributes = new LinkedHashMap<>(); + nodes.put(entry.getKey(), nodeAttributes); + NodeStats stats = entry.getValue(); + nodeAttributes.put("Address", stats.getNode().getAddress().toString()); + nodeAttributes.put("Type", stats.getNode().isMasterNode() ? "Master" : "Slave"); + nodeAttributes.put("Disk Usage", byteCountToDisplaySize(stats.getFs().getTotal().getTotal().bytes())); + nodeAttributes.put("Disk Available", byteCountToDisplaySize(stats.getFs().getTotal().getAvailable().bytes())); + nodeAttributes.put("Store Size", byteCountToDisplaySize(stats.getIndices().getStore().getSizeInBytes())); + nodeAttributes.put("Open Files", stats.getProcess().getOpenFileDescriptors()); + ProcessStats.Cpu cpu = stats.getProcess().getCpu(); + if (cpu != null) { + nodeAttributes.put("CPU Load Average", formatPercent(cpu.getPercent())); + } + nodeAttributes.put("JVM Heap Usage", formatPercent(stats.getJvm().getMem().getHeapUsedPrecent())); + nodeAttributes.put("JVM Heap Used", byteCountToDisplaySize(stats.getJvm().getMem().getHeapUsed().bytes())); + nodeAttributes.put("JVM Heap Max", byteCountToDisplaySize(stats.getJvm().getMem().getHeapMax().bytes())); + nodeAttributes.put("JVM Non Heap Used", byteCountToDisplaySize(stats.getJvm().getMem().getNonHeapUsed().bytes())); + nodeAttributes.put("JVM Threads", stats.getJvm().getThreads().count()); + nodeAttributes.put("JVM Started Since", formatDateTime(new Date(stats.getJvm().getUptime().getMillis()))); + nodeAttributes.put("Field Cache Memory", byteCountToDisplaySize(stats.getIndices().getFieldData().getMemorySizeInBytes())); + nodeAttributes.put("Filter Cache Memory", byteCountToDisplaySize(stats.getIndices().getFilterCache().getMemorySizeInBytes())); + nodeAttributes.put("ID Cache Memory", byteCountToDisplaySize(stats.getIndices().getIdCache().getMemorySizeInBytes())); + nodeAttributes.put("Query Cache Memory", byteCountToDisplaySize(stats.getIndices().getQueryCache().getMemorySizeInBytes())); + } + return nodes; + } + + private ClusterStatsResponse clusterStats() { + return esClient.prepareClusterStats().get(); + } + + private String formatPercent(long amount) { + return String.format("%.1f%%", 100 * amount * 1.0D / 100L); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsClusterMonitorMBean.java b/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsMonitorMBean.java similarity index 84% rename from server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsClusterMonitorMBean.java rename to server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsMonitorMBean.java index a51e29c7668..93a3571458a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsClusterMonitorMBean.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsMonitorMBean.java @@ -20,8 +20,11 @@ package org.sonar.server.platform.monitoring; -public interface EsClusterMonitorMBean { - String getClusterState(); +/** + * The public attributes of {@link org.sonar.server.platform.monitoring.EsMonitor} + * to be exported in JMX bean. + */ +public interface EsMonitorMBean { + String getState(); int getNumberOfNodes(); - String getIndexesHealth(); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsNodesMonitor.java b/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsNodesMonitor.java deleted file mode 100644 index ead31204d55..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsNodesMonitor.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package org.sonar.server.platform.monitoring; - -import com.google.common.base.Joiner; -import com.google.common.collect.HashBasedTable; -import com.google.common.collect.Table; -import org.sonar.server.search.NodeHealth; -import org.sonar.server.search.NodeHealth.Performance; -import org.sonar.server.search.SearchHealth; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import static org.apache.commons.io.FileUtils.byteCountToDisplaySize; -import static org.sonar.api.utils.DateUtils.formatDateTime; - -public class EsNodesMonitor extends BaseMonitorMBean implements EsNodesMonitorMBean { - - private final SearchHealth searchHealth; - - public EsNodesMonitor(SearchHealth searchHealth) { - this.searchHealth = searchHealth; - } - - @Override - public String getNodes() { - List formattedNodes = new ArrayList<>(); - Table nodes = nodes(); - - for (String nodeName : nodes.rowKeySet()) { - StringBuilder formattedNode = new StringBuilder(); - formattedNode.append(nodeName) - .append(" - ") - .append(Joiner.on(", ").withKeyValueSeparator(": ").join(nodes.row(nodeName))); - formattedNodes.add(formattedNode.toString()); - } - - return Joiner.on(" | ").join(formattedNodes); - } - - @Override - public String name() { - return "ElasticSearchNodes"; - } - - @Override - public LinkedHashMap attributes() { - LinkedHashMap attributes = new LinkedHashMap<>(); - Table nodes = nodes(); - for (String nodeName : nodes.rowKeySet()) { - attributes.put(nodeName, nodes.row(nodeName)); - } - return attributes; - } - - private Table nodes() { - Table nodes = HashBasedTable.create(); - for (Map.Entry nodeEntry : searchHealth.getNodesHealth().entrySet()) { - String name = nodeEntry.getKey(); - nodes.put(name, "Name", nodeEntry.getKey()); - NodeHealth nodeHealth = nodeEntry.getValue(); - nodes.put(name, "Type", nodeHealth.isMaster() ? "Master" : "Slave"); - nodes.put(name, "Address", nodeHealth.getAddress()); - nodes.put(name, "JVM Heap Usage", nodeHealth.getJvmHeapUsedPercent()); - nodes.put(name, "JVM Threads", String.valueOf(nodeHealth.getJvmThreads())); - nodes.put(name, "JVM Started Since", formatDateTime(nodeHealth.getJvmUpSince())); - nodes.put(name, "Disk Usage", nodeHealth.getFsUsedPercent()); - nodes.put(name, "Open Files", String.valueOf(nodeHealth.getOpenFiles())); - nodes.put(name, "CPU Load Average", nodeHealth.getProcessCpuPercent()); - nodes.put(name, "Field Cache Size", byteCountToDisplaySize(nodeHealth.getFieldCacheMemory())); - nodes.put(name, "Filter Cache Size", byteCountToDisplaySize(nodeHealth.getFilterCacheMemory())); - - for (Performance performance : nodeHealth.getPerformanceStats()) { - String message = ""; - if (Performance.Status.ERROR.equals(performance.getStatus()) || Performance.Status.WARN.equals(performance.getStatus())) { - message = String.format("- %s: %s", performance.getStatus(), performance.getMessage()); - } - if (performance.getName().contains("Eviction")) { - nodes.put(name, performance.getName(), String.format("%f %s", performance.getValue(), message)); - } else { - nodes.put(name, performance.getName(), String.format("%.1f ms %s", performance.getValue(), message)); - } - } - } - - return nodes; - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsNodesMonitorMBean.java b/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsNodesMonitorMBean.java deleted file mode 100644 index fc855255497..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/EsNodesMonitorMBean.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package org.sonar.server.platform.monitoring; - -public interface EsNodesMonitorMBean { - - String getNodes(); -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/PluginsMonitor.java b/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/PluginsMonitor.java index 2f2ee647e63..9ec58dc4044 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/PluginsMonitor.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/monitoring/PluginsMonitor.java @@ -48,7 +48,10 @@ public class PluginsMonitor implements Monitor { public LinkedHashMap attributes() { LinkedHashMap attributes = new LinkedHashMap<>(); for (PluginMetadata plugin : plugins()) { - attributes.put(plugin.getName(), plugin.getVersion()); + LinkedHashMap pluginAttributes = new LinkedHashMap<>(); + pluginAttributes.put("Name", plugin.getName()); + pluginAttributes.put("Version", plugin.getVersion()); + attributes.put(plugin.getKey(), pluginAttributes); } return attributes; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/search/ClusterHealth.java b/server/sonar-server/src/main/java/org/sonar/server/search/ClusterHealth.java deleted file mode 100644 index ab9e61a37c1..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/search/ClusterHealth.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.search; - -public class ClusterHealth { - - private boolean clusterAvailable; - private int numberOfNodes; - - public void setClusterAvailable(boolean clusterAvailable) { - this.clusterAvailable = clusterAvailable; - } - - public boolean isClusterAvailable() { - return clusterAvailable; - } - - public void setNumberOfNodes(int total) { - this.numberOfNodes = total; - } - - public int getNumberOfNodes() { - return numberOfNodes; - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/search/IndexHealth.java b/server/sonar-server/src/main/java/org/sonar/server/search/IndexHealth.java deleted file mode 100644 index c49838ab705..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/search/IndexHealth.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.search; - -import java.util.Date; - -public class IndexHealth { - private static final int SEGMENTS_THRESHOLD = 5; - private static final double PENDING_DELETION_THRESHOLD = 0.08D; - - String name; - long documentCount; - Date lastSync; - long segmentCount; - long pendingDeletion; - - public String getName() { - return name; - } - - public long getDocumentCount() { - return documentCount; - } - - public Date getLastSynchronization() { - return lastSync; - } - - public boolean isOptimized() { - return segmentCount < SEGMENTS_THRESHOLD && pendingDeletion < documentCount * PENDING_DELETION_THRESHOLD; - } - - public long getSegmentcount() { - return segmentCount; - } - - public long getPendingDeletion() { - return pendingDeletion; - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/search/NodeHealth.java b/server/sonar-server/src/main/java/org/sonar/server/search/NodeHealth.java deleted file mode 100644 index 49c8911f4e7..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/search/NodeHealth.java +++ /dev/null @@ -1,313 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.search; - -import org.elasticsearch.action.admin.cluster.node.stats.NodeStats; - -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.List; - -public class NodeHealth { - - private boolean master; - private String address; - private long jvmHeapMax; - private long jvmHeapUsed; - private long fsAvailable; - private long fsTotal; - private long jvmThreads; - private int cpuPercent; - private long openFiles; - private long jvmUptimeMillis; - private long fieldCacheMemory; - private long filterCacheMemory; - private List performanceStats; - - NodeHealth(NodeStats nodesStats) { - // Master/slave - setMaster(nodesStats.getNode().isMasterNode()); - - // Host IP and port - setAddress(nodesStats.getNode().getAddress().toString()); - - // JVM Heap Usage - setJvmHeapMax(nodesStats.getJvm().getMem().getHeapMax().bytes()); - setJvmHeapUsed(nodesStats.getJvm().getMem().getHeapUsed().bytes()); - - // Disk Usage - setFsTotal(nodesStats.getFs().getTotal().getTotal().bytes()); - setFsAvailable(nodesStats.getFs().getTotal().getAvailable().bytes()); - - // Ping ? - - // Threads - setJvmThreads(nodesStats.getJvm().getThreads().count()); - - // CPU - if (nodesStats.getProcess().getCpu() != null) { - setProcessCpuPercent(nodesStats.getProcess().cpu().getPercent()); - } - - // Open Files - setOpenFiles(nodesStats.getProcess().getOpenFileDescriptors()); - - // Uptime - setJvmUptimeMillis(nodesStats.getJvm().getUptime().getMillis()); - - initPerformanceStats(nodesStats); - } - - public boolean isMaster() { - return master; - } - - void setMaster(boolean master) { - this.master = master; - } - - public String getAddress() { - return address; - } - - void setAddress(String address) { - this.address = address; - } - - public long getJvmHeapMax() { - return jvmHeapMax; - } - - void setJvmHeapMax(long bytes) { - this.jvmHeapMax = bytes; - } - - public long getJvmHeapUsed() { - return jvmHeapUsed; - } - - void setJvmHeapUsed(long bytes) { - this.jvmHeapUsed = bytes; - } - - public String getJvmHeapUsedPercent() { - return formatPercent(getJvmHeapUsed(), getJvmHeapMax()); - } - - void setFsAvailable(long bytes) { - this.fsAvailable = bytes; - } - - void setFsTotal(long bytes) { - this.fsTotal = bytes; - } - - public String getFsUsedPercent() { - return formatPercent(fsTotal - fsAvailable, fsTotal); - } - - private String formatPercent(long amount, long total) { - return String.format("%.1f%%", 100 * amount * 1.0D / total); - } - - public long getJvmThreads() { - return jvmThreads; - } - - void setJvmThreads(long threads) { - this.jvmThreads = threads; - } - - public String getProcessCpuPercent() { - return formatPercent(cpuPercent, 100L); - } - - void setProcessCpuPercent(int cpuPercent) { - this.cpuPercent = cpuPercent; - } - - public long getOpenFiles() { - return openFiles; - } - - void setOpenFiles(long avgOpenFileDescriptors) { - this.openFiles = avgOpenFileDescriptors; - } - - public long getJvmUptimeMillis() { - return jvmUptimeMillis; - } - - void setJvmUptimeMillis(long millis) { - this.jvmUptimeMillis = millis; - } - - public Date getJvmUpSince() { - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(calendar.getTimeInMillis() - getJvmUptimeMillis()); - return calendar.getTime(); - } - - public List getPerformanceStats() { - return performanceStats; - } - - public long getFieldCacheMemory() { - return fieldCacheMemory; - } - - public long getFilterCacheMemory() { - return filterCacheMemory; - } - - private void initPerformanceStats(NodeStats nodesStats) { - // Performance Stat - performanceStats = new ArrayList(); - - // IndexStat - long indexCount = nodesStats.getIndices().getIndexing().getTotal().getIndexCount(); - long indexTotalTime = nodesStats.getIndices().getIndexing().getTotal().getIndexTimeInMillis(); - performanceStats.add( - new Performance("Average Indexing Time") - .setWarnThreshold(10) - .setErrorThreshold(50) - .setMessage("Too complex documents or low IO/CPU") - .setValue(indexCount > 0L ? indexTotalTime / (double) indexCount : 0.0)); - - // Query stats - long queryCount = nodesStats.getIndices().getSearch().getTotal().getQueryCount(); - long queryTotalTime = nodesStats.getIndices().getSearch().getTotal().getQueryTimeInMillis(); - performanceStats.add( - new Performance("Average Querying Time") - .setWarnThreshold(50) - .setErrorThreshold(500) - .setMessage("Inefficient query and/or filters") - .setValue(queryCount > 0L ? queryTotalTime / (double) queryCount : 0.0)); - - // Fetch stats - long fetchCount = nodesStats.getIndices().getSearch().getTotal().getFetchCount(); - long fetchTotalTime = nodesStats.getIndices().getSearch().getTotal().getFetchTimeInMillis(); - performanceStats.add( - new Performance("Average Fetching Time") - .setWarnThreshold(8) - .setErrorThreshold(15) - .setMessage("Slow IO, fetch-size too large or documents too big") - .setValue(fetchCount > 0L ? fetchTotalTime / (double) fetchCount : 0.0)); - - // Get stats - long getCount = nodesStats.getIndices().getGet().getCount(); - long getTotalTime = nodesStats.getIndices().getGet().getTimeInMillis(); - performanceStats.add( - new Performance("Average Get Time") - .setWarnThreshold(5) - .setErrorThreshold(10) - .setMessage("Slow IO") - .setValue(getCount > 0L ? getTotalTime / (double) getCount : 0.0)); - - // Refresh Stat - long refreshCount = nodesStats.getIndices().getRefresh().getTotal(); - long refreshTotalTime = nodesStats.getIndices().getRefresh().getTotalTimeInMillis(); - performanceStats.add( - new Performance("Average Refreshing Time") - .setWarnThreshold(10) - .setErrorThreshold(20) - .setMessage("Slow IO") - .setValue(refreshCount > 0L ? refreshTotalTime / (double) refreshCount : 0.0)); - - // Field Cache - fieldCacheMemory = nodesStats.getIndices().getFieldData().getMemorySizeInBytes(); - long fieldCacheEviction = nodesStats.getIndices().getFieldData().getEvictions(); - performanceStats.add( - new Performance("Field Cache Eviction Count") - .setWarnThreshold(1) - .setErrorThreshold(1) - .setMessage("Insufficient RAM available for queries") - .setValue(fieldCacheEviction)); - - // Filter Cache - filterCacheMemory = nodesStats.getIndices().getFilterCache().getMemorySizeInBytes(); - long filterCacheEviction = nodesStats.getIndices().getFilterCache().getEvictions(); - performanceStats.add( - new Performance("Filter Cache Eviction Count") - .setWarnThreshold(1) - .setErrorThreshold(1) - .setMessage("Insufficient RAM or too many orphaned filters") - .setValue(filterCacheEviction)); - } - - public static class Performance { - - private final String name; - private String message; - private double value; - private double warnThreshold; - private double errorThreshold; - public Performance(String name) { - this.name = name; - } - - public Status getStatus() { - if (value >= errorThreshold) { - return Status.ERROR; - } else if (value >= warnThreshold) { - return Status.WARN; - } else { - return Status.OK; - } - } - - public String getName() { - return name; - } - - public String getMessage() { - return message; - } - - public Performance setMessage(String message) { - this.message = message; - return this; - } - - public double getValue() { - return value; - } - - public Performance setValue(double value) { - this.value = value; - return this; - } - - public Performance setWarnThreshold(long warnThreshold) { - this.warnThreshold = warnThreshold; - return this; - } - - public Performance setErrorThreshold(long errorThreshold) { - this.errorThreshold = errorThreshold; - return this; - } - - public static enum Status { - OK, WARN, ERROR - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/search/SearchClient.java b/server/sonar-server/src/main/java/org/sonar/server/search/SearchClient.java index 0a75ce63a32..83bc7c3d368 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/search/SearchClient.java +++ b/server/sonar-server/src/main/java/org/sonar/server/search/SearchClient.java @@ -21,17 +21,10 @@ package org.sonar.server.search; import org.apache.commons.lang.StringUtils; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthStatus; -import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsRequestBuilder; -import org.elasticsearch.action.admin.cluster.state.ClusterStateRequestBuilder; -import org.elasticsearch.action.admin.cluster.stats.ClusterStatsRequestBuilder; -import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse; import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequestBuilder; -import org.elasticsearch.action.admin.indices.flush.FlushRequestBuilder; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder; import org.elasticsearch.action.admin.indices.refresh.RefreshRequestBuilder; -import org.elasticsearch.action.admin.indices.stats.IndicesStatsRequestBuilder; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.count.CountRequestBuilder; import org.elasticsearch.action.delete.DeleteRequestBuilder; @@ -62,18 +55,13 @@ import org.sonar.api.config.Settings; import org.sonar.process.LoopbackAddress; import org.sonar.process.ProcessConstants; import org.sonar.server.es.request.ProxyBulkRequestBuilder; -import org.sonar.server.es.request.ProxyClusterStateRequestBuilder; -import org.sonar.server.es.request.ProxyClusterStatsRequestBuilder; import org.sonar.server.es.request.ProxyCountRequestBuilder; import org.sonar.server.es.request.ProxyCreateIndexRequestBuilder; import org.sonar.server.es.request.ProxyDeleteByQueryRequestBuilder; import org.sonar.server.es.request.ProxyDeleteRequestBuilder; -import org.sonar.server.es.request.ProxyFlushRequestBuilder; import org.sonar.server.es.request.ProxyGetRequestBuilder; import org.sonar.server.es.request.ProxyIndicesExistsRequestBuilder; -import org.sonar.server.es.request.ProxyIndicesStatsRequestBuilder; import org.sonar.server.es.request.ProxyMultiGetRequestBuilder; -import org.sonar.server.es.request.ProxyNodesStatsRequestBuilder; import org.sonar.server.es.request.ProxyPutMappingRequestBuilder; import org.sonar.server.es.request.ProxyRefreshRequestBuilder; import org.sonar.server.es.request.ProxySearchRequestBuilder; @@ -96,19 +84,6 @@ public class SearchClient extends TransportClient implements Startable { settings.getInt(ProcessConstants.SEARCH_PORT))); } - public ClusterHealth getClusterHealth() { - ClusterHealth health = new ClusterHealth(); - ClusterStatsResponse clusterStatsResponse = this.prepareClusterStats().get(); - - // Cluster health - health.setClusterAvailable(clusterStatsResponse.getStatus() != ClusterHealthStatus.RED); - - // Number of nodes - health.setNumberOfNodes(clusterStatsResponse.getNodesStats().getCounts().getTotal()); - - return health; - } - private void initLogging() { ESLoggerFactory.setDefaultFactory(new Slf4jESLoggerFactory()); } @@ -117,26 +92,6 @@ public class SearchClient extends TransportClient implements Startable { return new ProxyRefreshRequestBuilder(this).setIndices(indices); } - public FlushRequestBuilder prepareFlush(String... indices) { - return new ProxyFlushRequestBuilder(this).setIndices(indices); - } - - public IndicesStatsRequestBuilder prepareStats(String... indices) { - return new ProxyIndicesStatsRequestBuilder(this).setIndices(indices); - } - - public NodesStatsRequestBuilder prepareNodesStats(String... nodesIds) { - return new ProxyNodesStatsRequestBuilder(this).setNodesIds(nodesIds); - } - - public ClusterStatsRequestBuilder prepareClusterStats() { - return new ProxyClusterStatsRequestBuilder(this); - } - - public ClusterStateRequestBuilder prepareState() { - return new ProxyClusterStateRequestBuilder(this); - } - public IndicesExistsRequestBuilder prepareIndicesExist(String... indices) { return new ProxyIndicesExistsRequestBuilder(this, indices); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/search/SearchHealth.java b/server/sonar-server/src/main/java/org/sonar/server/search/SearchHealth.java deleted file mode 100644 index fd03d6fc3e5..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/search/SearchHealth.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.search; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMap.Builder; -import com.google.common.collect.Maps; -import org.elasticsearch.action.admin.cluster.node.stats.NodeStats; -import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsRequestBuilder; -import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse; -import org.elasticsearch.action.admin.indices.stats.IndicesStatsRequestBuilder; -import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse; - -import java.util.Map; -import java.util.Map.Entry; - -public class SearchHealth { - - private SearchClient searchClient; - private IndexClient indexClient; - - public SearchHealth(SearchClient searchClient, IndexClient indexClient) { - this.searchClient = searchClient; - this.indexClient = indexClient; - } - - public ClusterHealth getClusterHealth() { - return searchClient.getClusterHealth(); - } - - public Map getIndexHealth() { - Builder builder = ImmutableMap.builder(); - for (Index index: indexClient.allIndices()) { - IndexStat indexStat = index.getIndexStat(); - IndexHealth newIndexHealth = new IndexHealth(); - newIndexHealth.name = index.getIndexName() + "/" + index.getIndexType(); - newIndexHealth.documentCount = indexStat.getDocumentCount(); - newIndexHealth.lastSync = indexStat.getLastUpdate(); - - IndicesStatsRequestBuilder statRequest = searchClient.prepareStats(index.getIndexName()) - .setTypes(index.getIndexType()); - IndicesStatsResponse indicesStatsResponse = statRequest.get(); - newIndexHealth.segmentCount = indicesStatsResponse.getTotal().getSegments().getCount(); - newIndexHealth.pendingDeletion = indicesStatsResponse.getTotal().getDocs().getDeleted(); - - builder.put(newIndexHealth.name, newIndexHealth); - } - return builder.build(); - } - - public Map getNodesHealth() { - NodesStatsRequestBuilder nodesStatsRequest = searchClient.prepareNodesStats().all(); - NodesStatsResponse nodesStats = nodesStatsRequest.get(); - - Map health = Maps.newHashMap(); - for (Entry nodeEntry: nodesStats.getNodesMap().entrySet()) { - health.put(nodeEntry.getKey(), new NodeHealth(nodeEntry.getValue())); - } - return ImmutableMap.copyOf(health); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/es/EsClientTest.java b/server/sonar-server/src/test/java/org/sonar/server/es/EsClientTest.java index bce0c2bd641..f65ab01b5b7 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/es/EsClientTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/es/EsClientTest.java @@ -52,7 +52,6 @@ public class EsClientTest { EsClient client = es.client(); client.start(); assertThat(client.nativeClient()).isNotNull(); - assertThat(client.getClusterHealth().isClusterAvailable()).isTrue(); assertThat(client.prepareBulk()).isInstanceOf(ProxyBulkRequestBuilder.class); assertThat(client.prepareClusterStats()).isInstanceOf(ProxyClusterStatsRequestBuilder.class); assertThat(client.prepareCount()).isInstanceOf(ProxyCountRequestBuilder.class); diff --git a/server/sonar-server/src/test/java/org/sonar/server/search/NodeHealthPerformanceTest.java b/server/sonar-server/src/test/java/org/sonar/server/search/NodeHealthPerformanceTest.java deleted file mode 100644 index 3245130257c..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/search/NodeHealthPerformanceTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.search; - -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public class NodeHealthPerformanceTest { - - @Test - public void OK_threshold() throws Exception { - NodeHealth.Performance OK = new NodeHealth.Performance("test") - .setWarnThreshold(Integer.MAX_VALUE) - .setErrorThreshold(Integer.MAX_VALUE) - .setValue(1); - assertThat(OK.getStatus()).isEqualTo(NodeHealth.Performance.Status.OK); - } - - @Test - public void WARN_threshold() throws Exception { - NodeHealth.Performance OK = new NodeHealth.Performance("test") - .setWarnThreshold(Integer.MIN_VALUE) - .setErrorThreshold(Integer.MAX_VALUE) - .setValue(1); - assertThat(OK.getStatus()).isEqualTo(NodeHealth.Performance.Status.WARN); - } - - @Test - public void ERROR_threshold() throws Exception { - NodeHealth.Performance OK = new NodeHealth.Performance("test") - .setWarnThreshold(Integer.MIN_VALUE) - .setErrorThreshold(Integer.MIN_VALUE) - .setValue(1); - assertThat(OK.getStatus()).isEqualTo(NodeHealth.Performance.Status.ERROR); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/search/SearchHealthMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/search/SearchHealthMediumTest.java deleted file mode 100644 index 9aee9fe7806..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/search/SearchHealthMediumTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.search; - -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.utils.System2; -import org.sonar.core.persistence.DbSession; -import org.sonar.server.db.DbClient; -import org.sonar.server.rule.RuleTesting; -import org.sonar.server.rule.db.RuleDao; -import org.sonar.server.tester.ServerTester; - -import java.util.Date; -import java.util.List; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; - -public class SearchHealthMediumTest { - - @ClassRule - public static ServerTester tester = new ServerTester(); - - DbSession dbSession; - - @Before - public void setUp() throws Exception { - dbSession = tester.get(DbClient.class).openSession(false); - } - - @After - public void tearDown() throws Exception { - dbSession.close(); - } - - @Test - public void get_search_health() { - tester.get(RuleDao.class).insert(dbSession, RuleTesting.newDto(RuleKey.of("javascript", "S001"))); - dbSession.commit(); - - SearchHealth health = tester.get(SearchHealth.class); - Date now = new Date(); - - ClusterHealth clusterHealth = health.getClusterHealth(); - assertThat(clusterHealth.isClusterAvailable()).isTrue(); - assertThat(clusterHealth.getNumberOfNodes()).isEqualTo(1); - - NodeHealth nodeHealth = health.getNodesHealth().values().iterator().next(); - assertThat(nodeHealth.isMaster()).isTrue(); - assertThat(nodeHealth.getAddress()).contains(":"); - assertThat(nodeHealth.getJvmHeapUsedPercent()).contains("%"); - assertThat(nodeHealth.getFsUsedPercent()).contains("%"); - assertThat(nodeHealth.getJvmThreads()).isGreaterThanOrEqualTo(0L); - assertThat(nodeHealth.getFieldCacheMemory()).isGreaterThanOrEqualTo(0L); - assertThat(nodeHealth.getFilterCacheMemory()).isGreaterThanOrEqualTo(0L); - assertThat(nodeHealth.getProcessCpuPercent()).contains("%"); - long openFiles = nodeHealth.getOpenFiles(); - if (!tester.get(System2.class).isOsWindows()) { - assertThat(openFiles).isGreaterThanOrEqualTo(0L); - } - assertThat(nodeHealth.getJvmUpSince().before(now)).isTrue(); - - List performances = nodeHealth.getPerformanceStats(); - assertThat(performances).hasSize(7); - for (NodeHealth.Performance performance : performances) { - assertThat(performance.getName()).isNotNull(); - assertThat(performance.getValue()).isNotNull(); - assertThat(performance.getMessage()).isNotNull(); - assertThat(performance.getStatus()).isNotNull(); - } - - Map indexHealth = health.getIndexHealth(); - assertThat(indexHealth).isNotEmpty(); - for (IndexHealth index : indexHealth.values()) { - assertThat(index.getDocumentCount()).isGreaterThanOrEqualTo(0L); - Date lastSync = index.getLastSynchronization(); - if (lastSync != null) { - assertThat(lastSync.before(now)).isTrue(); - } - assertThat(index.isOptimized()).isIn(true, false); - } - } - -} diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/system_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/system_controller.rb index aad178a17c9..929d1a6fcc9 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/system_controller.rb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/system_controller.rb @@ -27,8 +27,7 @@ class SystemController < ApplicationController Java::OrgSonarServerPlatform::Platform.component(Java::OrgSonarServerPlatformMonitoring::SonarQubeMonitor.java_class), Java::OrgSonarServerPlatform::Platform.component(Java::OrgSonarServerPlatformMonitoring::DatabaseMonitor.java_class), Java::OrgSonarServerPlatform::Platform.component(Java::OrgSonarServerPlatformMonitoring::SystemMonitor.java_class), - Java::OrgSonarServerPlatform::Platform.component(Java::OrgSonarServerPlatformMonitoring::EsClusterMonitor.java_class), - Java::OrgSonarServerPlatform::Platform.component(Java::OrgSonarServerPlatformMonitoring::EsNodesMonitor.java_class), + Java::OrgSonarServerPlatform::Platform.component(Java::OrgSonarServerPlatformMonitoring::EsMonitor.java_class), Java::OrgSonarServerPlatform::Platform.component(Java::OrgSonarServerPlatformMonitoring::JvmPropertiesMonitor.java_class) ] end diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/_monitor.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/_monitor.html.erb index 3765dfa9b2c..4d2c377723e 100644 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/_monitor.html.erb +++ b/server/sonar-web/src/main/webapp/WEB-INF/app/views/system/_monitor.html.erb @@ -5,11 +5,30 @@ - <% monitor.attributes().entrySet().each do |attribute| %> - - <%= h attribute.getKey() -%> - <%= h attribute.getValue() -%> - + <% monitor.attributes().to_hash.each do |attribute_key, attribute_value| %> + + <% if attribute_value.respond_to?(:to_hash) + attribute_value.to_hash.each do |group_key, group_value| + %> + + <%= h "#{attribute_key} - #{group_key}" -%> + + + <% group_value.to_hash.each do |group_attr_key, group_attr_value| %> + + <% end %> +
<%= h group_attr_key -%><%= h group_attr_value -%>
+ + + <% end %> + + <% else %> + + <%= h attribute_key -%> + <%= h attribute_value -%> + + <% end %> + <% end %> diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/JsonWriter.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/JsonWriter.java index 5450a63e22a..f8645826374 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/JsonWriter.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/text/JsonWriter.java @@ -203,6 +203,8 @@ public class JsonWriter { stream.value((Boolean) value); } else if (value instanceof Date) { valueDateTime((Date) value); + } else if (value instanceof Enum) { + stream.value(((Enum)value).name()); } else if (value instanceof Map) { stream.beginObject(); for (Map.Entry entry : ((Map) value).entrySet()) { diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/text/JsonWriterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/text/JsonWriterTest.java index 80c7fc65a2b..45280508abb 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/text/JsonWriterTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/text/JsonWriterTest.java @@ -130,9 +130,10 @@ public class JsonWriterTest { .name("aFloat").valueObject(3.14) .name("aLong").valueObject(42L) .name("aList").valueObject(Arrays.asList("one", 2, "three")) + .name("anEnum").valueObject(ColorEnum.GREEN) .name("aMap").valueObject(ImmutableMap.of("hello", "world", "good", "bye")) .endObject().close(); - expect("{\"aString\":\"stringValue\",\"aBoolean\":true,\"aInt\":42,\"aFloat\":3.14,\"aLong\":42,\"aList\":[\"one\",2,\"three\"],\"aMap\":{\"hello\":\"world\",\"good\":\"bye\"}}"); + expect("{\"aString\":\"stringValue\",\"aBoolean\":true,\"aInt\":42,\"aFloat\":3.14,\"aLong\":42,\"aList\":[\"one\",2,\"three\"],\"anEnum\":\"GREEN\",\"aMap\":{\"hello\":\"world\",\"good\":\"bye\"}}"); } @Test @@ -173,4 +174,8 @@ public class JsonWriterTest { new JsonWriter(gson).beginArray(); } + + private static enum ColorEnum { + RED, GREEN + } } -- 2.39.5