com.arpnetworking.metrics.jvm.JvmMetricsRunnable Maven / Gradle / Ivy
/**
* Copyright 2015 Groupon.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arpnetworking.metrics.jvm;
import com.arpnetworking.metrics.Metrics;
import com.arpnetworking.metrics.MetricsFactory;
import com.arpnetworking.metrics.jvm.collectors.BufferPoolMetricsCollector;
import com.arpnetworking.metrics.jvm.collectors.FileDescriptorMetricsCollector;
import com.arpnetworking.metrics.jvm.collectors.GarbageCollectionMetricsCollector;
import com.arpnetworking.metrics.jvm.collectors.HeapMemoryMetricsCollector;
import com.arpnetworking.metrics.jvm.collectors.JvmMetricsCollector;
import com.arpnetworking.metrics.jvm.collectors.NonHeapMemoryMetricsCollector;
import com.arpnetworking.metrics.jvm.collectors.ThreadMetricsCollector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.management.BufferPoolMXBean;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.ThreadMXBean;
import java.util.ArrayList;
import java.util.List;
/**
* An implementation of Runnable
that collects all JVM metrics each time its run.
*
* @author Deepika Misra (deepika at groupon dot com)
*/
// CHECKSTYLE.OFF: FinalClass - Allow clients to inherit from this.
public class JvmMetricsRunnable implements Runnable {
// CHECKSTYLE.ON: FinalClass
/**
* {@inheritDoc}
*/
@Override
public void run() {
Metrics metrics = null;
try {
metrics = _metricsFactory.create();
for (final JvmMetricsCollector collector : _collectorsEnabled) {
collector.collect(metrics, _managementFactory);
}
// CHECKSTYLE.OFF: IllegalCatch - No checked exceptions here
} catch (final Exception e) {
// CHECKSTYLE.ON: IllegalCatch
handleException(e);
} finally {
try {
metrics.close();
// CHECKSTYLE.OFF: IllegalCatch - No checked exceptions here
} catch (final Exception e) {
// CHECKSTYLE.ON: IllegalCatch
handleException(e);
}
}
}
/**
* Handles exceptions based on a boolean flag. If the flag is true, it logs and swallows the exception, else it will
* throw.
*
* @param e An instance of RuntimeException
.
*/
protected void handleException(final Exception e) {
if (_swallowException) {
LOGGER.warn("JVM metrics collection failed.", e);
} else {
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else {
throw new RuntimeException(e);
}
}
}
private JvmMetricsRunnable(final Builder builder) {
_metricsFactory = builder._metricsFactory;
_managementFactory = builder._managementFactory;
_swallowException = builder._swallowException;
if (builder._collectGarbageCollectionMetrics) {
_collectorsEnabled.add(builder._garbageCollectionMetricsCollector);
}
if (builder._collectHeapMemoryMetrics) {
_collectorsEnabled.add(builder._heapMemoryMetricsCollector);
}
if (builder._collectNonHeapMemoryMetrics) {
_collectorsEnabled.add(builder._nonHeapMemoryMetricsCollector);
}
if (builder._collectThreadMetrics) {
_collectorsEnabled.add(builder._threadMetricsCollector);
}
if (builder._collectBufferPoolMetrics) {
_collectorsEnabled.add(builder._bufferPoolMetricsCollector);
}
if (builder._collectFileDescriptorMetrics) {
_collectorsEnabled.add(builder._fileDescriptorMetricsCollector);
}
}
private final MetricsFactory _metricsFactory;
private final ManagementFactory _managementFactory;
private final boolean _swallowException;
private final List _collectorsEnabled = new ArrayList<>();
private static final Logger LOGGER = LoggerFactory.getLogger(JvmMetricsRunnable.class);
/**
* Builder for JvmMetricsRunnable
.
*
* @author Deepika Misra (deepika at groupon dot com)
*/
// CHECKSTYLE.OFF: FinalClass - Allow clients to inherit from this.
public static class Builder {
// CHECKSTYLE.ON: FinalClass
/**
* Builds an instance of JvmMetricsRunnable
.
*
* @return An instance of JvmMetricsRunnable
.
*/
public JvmMetricsRunnable build() {
if (_metricsFactory == null) {
throw new IllegalArgumentException("MetricsFactory cannot be null.");
}
if (_managementFactory == null) {
throw new IllegalArgumentException("ManagementFactory cannot be null.");
}
if (_swallowException == null) {
throw new IllegalArgumentException("SwallowException cannot be null.");
}
if (_collectNonHeapMemoryMetrics == null) {
throw new IllegalArgumentException("CollectNonHeapMemoryMetrics cannot be null.");
}
if (_collectHeapMemoryMetrics == null) {
throw new IllegalArgumentException("CollectHeapMemoryMetrics cannot be null.");
}
if (_collectThreadMetrics == null) {
throw new IllegalArgumentException("CollectThreadMetrics cannot be null.");
}
if (_collectGarbageCollectionMetrics == null) {
throw new IllegalArgumentException("CollectGarbageCollectionMetrics cannot be null.");
}
if (_collectBufferPoolMetrics == null) {
throw new IllegalArgumentException("CollectBufferPoolMetrics cannot be null.");
}
if (_collectFileDescriptorMetrics == null) {
throw new IllegalArgumentException("CollectFileDescriptorMetrics cannot be null.");
}
if (_nonHeapMemoryMetricsCollector == null) {
throw new IllegalArgumentException("NonHeapMemoryMetricsCollector cannot be null.");
}
if (_heapMemoryMetricsCollector == null) {
throw new IllegalArgumentException("HeapMemoryMetricsCollector cannot be null.");
}
if (_threadMetricsCollector == null) {
throw new IllegalArgumentException("ThreadMetricsCollector cannot be null.");
}
if (_garbageCollectionMetricsCollector == null) {
throw new IllegalArgumentException("GarbageCollectionMetricsCollector cannot be null.");
}
if (_bufferPoolMetricsCollector == null) {
throw new IllegalArgumentException("BufferPoolMetricsCollector cannot be null.");
}
if (_fileDescriptorMetricsCollector == null) {
throw new IllegalArgumentException("FileDescriptorMetricsCollector cannot be null.");
}
return new JvmMetricsRunnable(this);
}
/**
* Set the MetricsFactory
instance. Required. Cannot be null.
*
* @param value The value for the MetricsFactory
instance.
* @return This Builder
instance.
*/
public Builder setMetricsFactory(final MetricsFactory value) {
_metricsFactory = value;
return this;
}
/**
* Set the flag indicating if any exception caught during the process of metrics collection should be logged and
* swallowed. Optional. Defaults to true. True indicates that the exception will be logged and swallowed.
*
* @param value The value for the Boolean
instance.
* @return This Builder
instance.
*/
public Builder setSwallowException(final Boolean value) {
_swallowException = value;
return this;
}
/**
* Set the flag indicating if Heap Memory metrics should be collected. A true value indicates that these
* metrics need to be collected. Optional. Defaults to true.
*
* @param value A Boolean
value.
* @return This Builder
instance.
*/
public Builder setCollectHeapMemoryMetrics(final Boolean value) {
_collectHeapMemoryMetrics = value;
return this;
}
/**
* Set the flag indicating if Non-Heap Memory metrics should be collected. A true value indicates that these
* metrics need to be collected. Optional. Defaults to true.
*
* @param value A Boolean
value.
* @return This Builder
instance.
*/
public Builder setCollectNonHeapMemoryMetrics(final Boolean value) {
_collectNonHeapMemoryMetrics = value;
return this;
}
/**
* Set the flag indicating if Thread metrics should be collected. A true value indicates that these metrics
* need to be collected. Optional. Defaults to true.
*
* @param value A Boolean
value.
* @return This Builder
instance.
*/
public Builder setCollectThreadMetrics(final Boolean value) {
_collectThreadMetrics = value;
return this;
}
/**
* Set the flag indicating if Garbage Collection metrics should be collected. A true value indicates that these
* metrics need to be collected. Optional. Defaults to true.
*
* @param value A Boolean
value.
* @return This Builder
instance.
*/
public Builder setCollectGarbageCollectionMetrics(final Boolean value) {
_collectGarbageCollectionMetrics = value;
return this;
}
/**
* Set the flag indicating if Buffer Pool metrics should be collected. A true value indicates that these
* metrics need to be collected. Optional. Defaults to true.
*
* @param value A Boolean
value.
* @return This Builder
instance.
*/
public Builder setCollectBufferPoolMetrics(final Boolean value) {
_collectBufferPoolMetrics = value;
return this;
}
/**
* Set the flag indicating if File Descriptor metrics should be collected. A true value indicates that these
* metrics need to be collected. Optional. Defaults to true.
*
* @param value A Boolean
value.
* @return This Builder
instance.
*/
public Builder setCollectFileDescriptorMetrics(final Boolean value) {
_collectFileDescriptorMetrics = value;
return this;
}
/**
* Set the ManagementFactory
instance. Defaults to an instance of
* ManagementFactoryDefault
. This is for testing purposes only and should never be used by clients.
*
* @param value The value for the ManagementFactory
instance.
* @return This Builder
instance.
*/
/* package private */ Builder setManagementFactory(final ManagementFactory value) {
_managementFactory = value;
return this;
}
/**
* Set the HeapMemoryMetricsCollector
. Defaults to an instance of
* HeapMemoryMetricsCollector
. This is for testing purposes only and should never be used by
* clients.
*
* @param value A HeapMemoryMetricsCollector
instance.
* @return This Builder
instance.
*/
/* package private */ Builder setHeapMemoryMetricsCollector(final JvmMetricsCollector value) {
_heapMemoryMetricsCollector = value;
return this;
}
/**
* Set the NonHeapMemoryMetricsCollector
. Defaults to an instance of
* NonHeapMemoryMetricsCollector
. This is for testing purposes only and should never be used by
* clients.
*
* @param value A NonHeapMemoryMetricsCollector
instance.
* @return This Builder
instance.
*/
/* package private */ Builder setNonHeapMemoryMetricsCollector(final JvmMetricsCollector value) {
_nonHeapMemoryMetricsCollector = value;
return this;
}
/**
* Set the ThreadMetricsCollector
. Defaults to an instance of
* ThreadMetricsCollector
. This is for testing purposes only and should never be used by clients.
*
* @param value A ThreadMetricsCollector
instance.
* @return This Builder
instance.
*/
/* package private */ Builder setThreadMetricsCollector(final JvmMetricsCollector value) {
_threadMetricsCollector = value;
return this;
}
/**
* Set the GarbageCollectionMetricsCollector
. Defaults to an instance of
* GarbageCollectionMetricsCollector
. This is for testing purposes only and should never be used
* by clients.
*
* @param value A GarbageCollectionMetricsCollector
instance.
* @return This Builder
instance.
*/
/* package private */ Builder setGarbageCollectionMetricsCollector(final JvmMetricsCollector value) {
_garbageCollectionMetricsCollector = value;
return this;
}
/**
* Set the BufferPoolMetricsCollector
. Defaults to an instance of
* BufferPoolMetricsCollector
. This is for testing purposes only and should never be used
* by clients.
*
* @param value A BufferPoolMetricsCollector
instance.
* @return This Builder
instance.
*/
/* package private */ Builder setBufferPoolMetricsCollector(final JvmMetricsCollector value) {
_bufferPoolMetricsCollector = value;
return this;
}
/**
* Set the FileDescriptorMetricsCollector
. Defaults to an instance of
* FileDescriptorMetricsCollector
. This is for testing purposes only and should never be used
* by clients.
*
* @param value A FileDescriptorMetricsCollector
instance.
* @return This Builder
instance.
*/
/* package private */ Builder setFileDescriptorMetricsCollector(final JvmMetricsCollector value) {
_fileDescriptorMetricsCollector = value;
return this;
}
private MetricsFactory _metricsFactory;
private ManagementFactory _managementFactory = MANAGEMENT_FACTORY_DEFAULT;
private Boolean _swallowException = true;
private Boolean _collectNonHeapMemoryMetrics = true;
private Boolean _collectHeapMemoryMetrics = true;
private Boolean _collectThreadMetrics = true;
private Boolean _collectGarbageCollectionMetrics = true;
private Boolean _collectBufferPoolMetrics = true;
private Boolean _collectFileDescriptorMetrics = true;
private JvmMetricsCollector _nonHeapMemoryMetricsCollector = NonHeapMemoryMetricsCollector.newInstance();
private JvmMetricsCollector _heapMemoryMetricsCollector = HeapMemoryMetricsCollector.newInstance();
private JvmMetricsCollector _threadMetricsCollector = ThreadMetricsCollector.newInstance();
private JvmMetricsCollector _garbageCollectionMetricsCollector = GarbageCollectionMetricsCollector.newInstance();
private JvmMetricsCollector _bufferPoolMetricsCollector = BufferPoolMetricsCollector.newInstance();
private JvmMetricsCollector _fileDescriptorMetricsCollector = FileDescriptorMetricsCollector.newInstance();
private static final ManagementFactory MANAGEMENT_FACTORY_DEFAULT = ManagementFactoryDefault.newInstance();
}
/**
* An implementation class of ManagementFactory
that is to be used for getting the actual values for jvm
* metrics from the java management API. This class exists to facilitate testing only and the clients should never
* have to explicitly instantiate this.
*
* @author Deepika Misra (deepika at groupon dot com)
*/
/* package private */ static final class ManagementFactoryDefault implements ManagementFactory {
/**
* Creates a new instance of ManagementFactoryDefault
.
*
* @return An instance of ManagementFactoryDefault
*/
/* package private */ static ManagementFactory newInstance() {
return new ManagementFactoryDefault();
}
/**
* {@inheritDoc}
*/
@Override
public List getGarbageCollectorMXBeans() {
return java.lang.management.ManagementFactory.getGarbageCollectorMXBeans();
}
/**
* {@inheritDoc}
*/
@Override
public MemoryMXBean getMemoryMXBean() {
return java.lang.management.ManagementFactory.getMemoryMXBean();
}
/**
* {@inheritDoc}
*/
@Override
public List getMemoryPoolMXBeans() {
return java.lang.management.ManagementFactory.getMemoryPoolMXBeans();
}
/**
* {@inheritDoc}
*/
@Override
public ThreadMXBean getThreadMXBean() {
return java.lang.management.ManagementFactory.getThreadMXBean();
}
/**
* {@inheritDoc}
*/
@Override
public List getBufferPoolMXBeans() {
return java.lang.management.ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);
}
/**
* {@inheritDoc}
*/
@Override
public OperatingSystemMXBean getOperatingSystemMXBean() {
return java.lang.management.ManagementFactory.getOperatingSystemMXBean();
}
private ManagementFactoryDefault() {}
}
}