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.log.CeLogging;
import org.sonar.core.platform.Module;
import org.sonar.process.systeminfo.ProcessStateSystemInfo;
import org.sonar.process.systeminfo.JvmStateSection;
import org.sonar.ce.monitoring.CeDatabaseMBeanImpl;

public class CeConfigurationModule extends Module {
Expand All @@ -32,6 +32,6 @@ protected void configureModule() {
CeConfigurationImpl.class,
CeLogging.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.rules.ExpectedException;
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.protobuf.ProtobufSystemInfo;

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

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

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

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

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

void setFailed(Member member, Exception e) {
public void setFailed(Member member, Exception e) {
failedMembers.put(member, e);
}
}
Expand Up @@ -17,24 +17,35 @@
* 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;
package org.sonar.process.systeminfo;

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

public class JvmPropsMonitor implements Monitor {
@Override
public String name() {
return "JvmProperties";
import static org.sonar.process.systeminfo.SystemInfoUtils.setAttribute;

/**
* Dumps {@link System#getProperties()}
*/
public class JvmPropertiesSection implements SystemInfoSection {

private final String name;

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

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

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 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 final String name;

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

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

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

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) {
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,
* 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.sonar.core.platform.ComponentContainer;
import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;

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 {
@Test
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
public class JvmPropertiesSectionTest {

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.when;

public class ProcessStateSystemInfoTest {
public class JvmStateSectionTest {

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

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

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);
when(memoryBean.getHeapMemoryUsage().getCommitted()).thenReturn(-1L);

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

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

import org.picocontainer.Startable;
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
*/
public abstract class BaseMonitorMBean implements Monitor, Startable {
public abstract class BaseSectionMBean implements SystemInfoSection, Startable {

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

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

0 comments on commit 74c8a8a

Please sign in to comment.