Skip to content

Commit

Permalink
SONAR-9802 Add nodes to system info in cluster mode
Browse files Browse the repository at this point in the history
  • Loading branch information
gregaubert authored and Simon Brandhof committed Sep 26, 2017
1 parent d7df6d3 commit 74c8a8a
Show file tree
Hide file tree
Showing 78 changed files with 3,375 additions and 789 deletions.
Expand Up @@ -22,7 +22,7 @@
import org.sonar.ce.configuration.CeConfigurationImpl; import org.sonar.ce.configuration.CeConfigurationImpl;
import org.sonar.ce.log.CeLogging; import org.sonar.ce.log.CeLogging;
import org.sonar.core.platform.Module; import org.sonar.core.platform.Module;
import org.sonar.process.systeminfo.ProcessStateSystemInfo; import org.sonar.process.systeminfo.JvmStateSection;
import org.sonar.ce.monitoring.CeDatabaseMBeanImpl; import org.sonar.ce.monitoring.CeDatabaseMBeanImpl;


public class CeConfigurationModule extends Module { public class CeConfigurationModule extends Module {
Expand All @@ -32,6 +32,6 @@ protected void configureModule() {
CeConfigurationImpl.class, CeConfigurationImpl.class,
CeLogging.class, CeLogging.class,
CeDatabaseMBeanImpl.class, CeDatabaseMBeanImpl.class,
new ProcessStateSystemInfo("Compute Engine State")); new JvmStateSection("Compute Engine JVM State"));
} }
} }
Expand Up @@ -26,7 +26,7 @@
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import org.sonar.ce.httpd.HttpAction; import org.sonar.ce.httpd.HttpAction;
import org.sonar.process.systeminfo.ProcessStateSystemInfo; import org.sonar.process.systeminfo.JvmStateSection;
import org.sonar.process.systeminfo.SystemInfoSection; import org.sonar.process.systeminfo.SystemInfoSection;
import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo; import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;


Expand All @@ -44,8 +44,8 @@ public class SystemInfoHttpActionTest {
@Rule @Rule
public ExpectedException expectedException = ExpectedException.none(); public ExpectedException expectedException = ExpectedException.none();


private SystemInfoSection stateProvider1 = new ProcessStateSystemInfo("state1"); private SystemInfoSection stateProvider1 = new JvmStateSection("state1");
private SystemInfoSection stateProvider2 = new ProcessStateSystemInfo("state2"); private SystemInfoSection stateProvider2 = new JvmStateSection("state2");
private SystemInfoHttpAction underTest; private SystemInfoHttpAction underTest;


@Before @Before
Expand Down
Expand Up @@ -59,15 +59,15 @@ public Collection<Member> getMembers() {
return members; return members;
} }


void setAnswer(Member member, T answer) { public void setAnswer(Member member, T answer) {
this.answers.put(member, answer); this.answers.put(member, answer);
} }


void setTimedOut(Member member) { public void setTimedOut(Member member) {
this.timedOutMembers.add(member); this.timedOutMembers.add(member);
} }


void setFailed(Member member, Exception e) { public void setFailed(Member member, Exception e) {
failedMembers.put(member, e); failedMembers.put(member, e);
} }
} }
Expand Up @@ -17,24 +17,35 @@
* along with this program; if not, write to the Free Software Foundation, * along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
package org.sonar.server.platform.monitoring; package org.sonar.process.systeminfo;


import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.TreeMap; import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;


public class JvmPropsMonitor implements Monitor { import static org.sonar.process.systeminfo.SystemInfoUtils.setAttribute;
@Override
public String name() { /**
return "JvmProperties"; * Dumps {@link System#getProperties()}
*/
public class JvmPropertiesSection implements SystemInfoSection {

private final String name;

public JvmPropertiesSection(String name) {
this.name = name;
} }


@Override @Override
public Map<String, Object> attributes() { public ProtobufSystemInfo.Section toProtobuf() {
Map<String, Object> sortedProps = new TreeMap<>(); ProtobufSystemInfo.Section.Builder protobuf = ProtobufSystemInfo.Section.newBuilder();
protobuf.setName(name);

for (Map.Entry<Object, Object> systemProp : System.getProperties().entrySet()) { for (Map.Entry<Object, Object> systemProp : System.getProperties().entrySet()) {
sortedProps.put(Objects.toString(systemProp.getKey()), Objects.toString(systemProp.getValue())); if (systemProp.getValue() != null) {
setAttribute(protobuf, Objects.toString(systemProp.getKey()), Objects.toString(systemProp.getValue()));
}
} }
return sortedProps; return protobuf.build();
} }
} }
Expand Up @@ -25,11 +25,16 @@
import java.lang.management.ThreadMXBean; import java.lang.management.ThreadMXBean;
import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo; import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;


public class ProcessStateSystemInfo implements SystemInfoSection { import static org.sonar.process.systeminfo.SystemInfoUtils.setAttribute;

/**
* Dumps state of JVM (memory, threads)
*/
public class JvmStateSection implements SystemInfoSection {
private static final long MEGABYTE = 1024L * 1024L; private static final long MEGABYTE = 1024L * 1024L;
private final String name; private final String name;


public ProcessStateSystemInfo(String name) { public JvmStateSection(String name) {
this.name = name; this.name = name;
} }


Expand All @@ -40,26 +45,27 @@ public ProtobufSystemInfo.Section toProtobuf() {


// Visible for testing // Visible for testing
ProtobufSystemInfo.Section toProtobuf(MemoryMXBean memoryBean) { ProtobufSystemInfo.Section toProtobuf(MemoryMXBean memoryBean) {
ProtobufSystemInfo.Section.Builder builder = ProtobufSystemInfo.Section.newBuilder(); ProtobufSystemInfo.Section.Builder protobuf = ProtobufSystemInfo.Section.newBuilder();
builder.setName(name); protobuf.setName(name);
MemoryUsage heap = memoryBean.getHeapMemoryUsage(); MemoryUsage heap = memoryBean.getHeapMemoryUsage();
addAttributeInMb(builder, "Heap Committed (MB)", heap.getCommitted()); addAttributeInMb(protobuf, "Heap Committed (MB)", heap.getCommitted());
addAttributeInMb(builder, "Heap Init (MB)", heap.getInit()); addAttributeInMb(protobuf, "Heap Init (MB)", heap.getInit());
addAttributeInMb(builder, "Heap Max (MB)", heap.getMax()); addAttributeInMb(protobuf, "Heap Max (MB)", heap.getMax());
addAttributeInMb(builder, "Heap Used (MB)", heap.getUsed()); addAttributeInMb(protobuf, "Heap Used (MB)", heap.getUsed());
MemoryUsage nonHeap = memoryBean.getNonHeapMemoryUsage(); MemoryUsage nonHeap = memoryBean.getNonHeapMemoryUsage();
addAttributeInMb(builder, "Non Heap Committed (MB)", nonHeap.getCommitted()); addAttributeInMb(protobuf, "Non Heap Committed (MB)", nonHeap.getCommitted());
addAttributeInMb(builder, "Non Heap Init (MB)", nonHeap.getInit()); addAttributeInMb(protobuf, "Non Heap Init (MB)", nonHeap.getInit());
addAttributeInMb(builder, "Non Heap Max (MB)", nonHeap.getMax()); addAttributeInMb(protobuf, "Non Heap Max (MB)", nonHeap.getMax());
addAttributeInMb(builder, "Non Heap Used (MB)", nonHeap.getUsed()); addAttributeInMb(protobuf, "Non Heap Used (MB)", nonHeap.getUsed());
ThreadMXBean thread = ManagementFactory.getThreadMXBean(); ThreadMXBean thread = ManagementFactory.getThreadMXBean();
builder.addAttributesBuilder().setKey("Thread Count").setLongValue(thread.getThreadCount()).build(); setAttribute(protobuf, "Thread Count", thread.getThreadCount());
return builder.build();
return protobuf.build();
} }


private static void addAttributeInMb(ProtobufSystemInfo.Section.Builder builder, String key, long valueInBytes) { private static void addAttributeInMb(ProtobufSystemInfo.Section.Builder protobuf, String key, long valueInBytes) {
if (valueInBytes >= 0L) { if (valueInBytes >= 0L) {
builder.addAttributesBuilder().setKey(key).setLongValue(valueInBytes / MEGABYTE).build(); setAttribute(protobuf, key, valueInBytes / MEGABYTE);
} }
} }
} }
@@ -0,0 +1,64 @@
/*
* SonarQube
* Copyright (C) 2009-2017 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program 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.
*
* This program 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.process.systeminfo;

import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;

public class SystemInfoUtils {

private SystemInfoUtils() {
// prevent instantiation
}

public static void setAttribute(ProtobufSystemInfo.Section.Builder section, String key, @Nullable String value) {
if (value != null) {
section.addAttributesBuilder()
.setKey(key)
.setStringValue(value)
.build();
}
}

public static void setAttribute(ProtobufSystemInfo.Section.Builder section, String key, boolean value) {
section.addAttributesBuilder()
.setKey(key)
.setBooleanValue(value)
.build();
}

public static void setAttribute(ProtobufSystemInfo.Section.Builder section, String key, long value) {
section.addAttributesBuilder()
.setKey(key)
.setLongValue(value)
.build();
}

@CheckForNull
public static ProtobufSystemInfo.Attribute attribute(ProtobufSystemInfo.Section section, String key) {
for (ProtobufSystemInfo.Attribute attribute : section.getAttributesList()) {
if (attribute.getKey().equals(key)) {
return attribute;
}
}
return null;
}
}
Expand Up @@ -17,22 +17,29 @@
* along with this program; if not, write to the Free Software Foundation, * along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
package org.sonar.server.platform.ws; package org.sonar.process.systeminfo;


import org.assertj.core.api.Assertions;
import org.junit.Test; import org.junit.Test;
import org.sonar.core.platform.ComponentContainer; import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;


import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.core.platform.ComponentContainer.COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER; import static org.sonar.process.systeminfo.SystemInfoUtils.attribute;


public class InfoActionModuleTest { public class JvmPropertiesSectionTest {
@Test
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();


new InfoActionModule().configure(container); private JvmPropertiesSection underTest = new JvmPropertiesSection("Web JVM Properties");


assertThat(container.size()).isEqualTo(4 + COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER); @Test
public void name_is_not_empty() {
assertThat(underTest.toProtobuf().getName()).isEqualTo("Web JVM Properties");
} }


@Test
public void test_toProtobuf() {
ProtobufSystemInfo.Section section = underTest.toProtobuf();

Assertions.assertThat(attribute(section, "java.vm.vendor").getStringValue()).isNotEmpty();
Assertions.assertThat(attribute(section, "os.name").getStringValue()).isNotEmpty();
}
} }
Expand Up @@ -28,13 +28,13 @@
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;


public class ProcessStateSystemInfoTest { public class JvmStateSectionTest {


public static final String PROCESS_NAME = "the process name"; public static final String PROCESS_NAME = "the process name";


@Test @Test
public void toSystemInfoSection() { public void toSystemInfoSection() {
ProcessStateSystemInfo underTest = new ProcessStateSystemInfo(PROCESS_NAME); JvmStateSection underTest = new JvmStateSection(PROCESS_NAME);
ProtobufSystemInfo.Section section = underTest.toProtobuf(); ProtobufSystemInfo.Section section = underTest.toProtobuf();


assertThat(section.getName()).isEqualTo(PROCESS_NAME); assertThat(section.getName()).isEqualTo(PROCESS_NAME);
Expand All @@ -47,7 +47,7 @@ public void should_hide_attributes_without_values() {
MemoryMXBean memoryBean = mock(MemoryMXBean.class, Mockito.RETURNS_DEEP_STUBS); MemoryMXBean memoryBean = mock(MemoryMXBean.class, Mockito.RETURNS_DEEP_STUBS);
when(memoryBean.getHeapMemoryUsage().getCommitted()).thenReturn(-1L); when(memoryBean.getHeapMemoryUsage().getCommitted()).thenReturn(-1L);


ProcessStateSystemInfo underTest = new ProcessStateSystemInfo(PROCESS_NAME); JvmStateSection underTest = new JvmStateSection(PROCESS_NAME);
ProtobufSystemInfo.Section section = underTest.toProtobuf(memoryBean); ProtobufSystemInfo.Section section = underTest.toProtobuf(memoryBean);


assertThat(section.getAttributesList()).extracting("key").doesNotContain("Heap Committed (MB)"); assertThat(section.getAttributesList()).extracting("key").doesNotContain("Heap Committed (MB)");
Expand Down
Expand Up @@ -21,12 +21,13 @@


import org.picocontainer.Startable; import org.picocontainer.Startable;
import org.sonar.process.Jmx; import org.sonar.process.Jmx;
import org.sonar.process.systeminfo.SystemInfoSection;


/** /**
* Base implementation of a {@link org.sonar.server.platform.monitoring.Monitor} * Base implementation of a {@link SystemInfoSection}
* that is exported as a JMX bean * that is exported as a JMX bean
*/ */
public abstract class BaseMonitorMBean implements Monitor, Startable { public abstract class BaseSectionMBean implements SystemInfoSection, Startable {


/** /**
* Auto-registers to MBean server * Auto-registers to MBean server
Expand All @@ -47,4 +48,9 @@ public void stop() {
String objectName() { String objectName() {
return "SonarQube:name=" + name(); return "SonarQube:name=" + name();
} }

/**
* Name of section in System Info page
*/
abstract String name();
} }

0 comments on commit 74c8a8a

Please sign in to comment.