FilePickUpPlaceHealthCheck.java
package emissary.core;
import emissary.pickup.file.FilePickUpPlace;
import com.codahale.metrics.health.HealthCheck;
import org.apache.commons.io.filefilter.HiddenFileFilter;
import java.io.File;
import java.io.FileFilter;
import java.lang.reflect.Field;
/**
* A health check that warns if the input data queue is larger than a given threshold or if the aggregate file size is
* larger than a given threshold. This only applies to FilePickUpPlace.
*/
public class FilePickUpPlaceHealthCheck extends HealthCheck {
/**
* How many files to allow in the queue before we deem the situation unhealthy
*/
protected int maxFileCountBeforeUnhealthy = Integer.MAX_VALUE; // default is unbounded
/**
* How large we let the aggregate file size to get before we deem the situation unhealthy
*/
protected long maxAggregateFileSizeBeforeUnhealthy = Long.MAX_VALUE; // default is unbounded
public FilePickUpPlaceHealthCheck(final int maxFileCountBeforeUnhealthy, final long maxAggregateFileSizeBeforeUnhealthy) {
this.maxFileCountBeforeUnhealthy = maxFileCountBeforeUnhealthy;
this.maxAggregateFileSizeBeforeUnhealthy = maxAggregateFileSizeBeforeUnhealthy;
}
@Override
protected Result check() throws Exception {
int aggregateFileCount = 0; // how many things we think are in the queue
long aggregateFileSize = 0; // aggregate file size across all files
try {
final FilePickUpPlace pup = (FilePickUpPlace) Namespace.lookup("FilePickUpPlace"); // if no exception, will
// not be
// null
// Get the inputDirs by reflection, result should be a String[]
final Field inputDirField = pup.getClass().getDeclaredField("inputDataDirs");
inputDirField.setAccessible(true); // make it so we can read it
if (inputDirField.getType().isArray()) {
// This better be a String[], but we are not checking for the String part
final String[] inputDirs = (String[]) inputDirField.get(pup);
if (inputDirs != null) {
for (int dirIdx = 0; dirIdx < inputDirs.length; dirIdx++) {
final File inputDir = new File(inputDirs[dirIdx]);
if ((inputDir != null) && inputDir.isDirectory()) {
final File[] files = inputDir.listFiles((FileFilter) HiddenFileFilter.VISIBLE);
aggregateFileCount += files.length;
if (files != null) {
for (int fileIdx = 0; fileIdx < files.length; fileIdx++) {
aggregateFileSize += files[fileIdx].length();
}
}
}
}
}
}
// Check either condition
if (aggregateFileCount > this.maxFileCountBeforeUnhealthy) {
return Result.unhealthy("Large number of files backed up for FilePickUpPlace = " + aggregateFileCount);
} else if (aggregateFileSize > this.maxAggregateFileSizeBeforeUnhealthy) {
return Result.unhealthy("Large aggregate file size backed up for FilePickUpPlace = " + aggregateFileSize);
}
} catch (NamespaceException ignored) {
// This gets throw if can't find FilePickUpPlace, assume it is not configured
// and things are healthy
} catch (NoSuchFieldException ignored) {
// Possibly thrown by getDeclaredField, assume FilePickUpPlace implementation has changed
} catch (SecurityException ignored) {
// Possibly thrown by getDeclaredField - would prevent our access to the field
} catch (NullPointerException ignored) {
// A variety of methods throw NPEs
} catch (IllegalArgumentException ignored) {
// Thrown by get()
} catch (IllegalAccessException ignored) {
// Also thrown by get()
} catch (ExceptionInInitializerError ignored) {
// Also thrown by get()
}
// If we get here, we assume things are OK
return Result.healthy("FilePickUpPlace appears to be healthy");
}
}