![JAR search and dependency download from the Maven repository](/logo.png)
org.xins.server.StatisticsInterceptor Maven / Gradle / Ivy
/*
* $Id: StatisticsInterceptor.java,v 1.2 2012/02/27 22:26:04 agoubard Exp $
*
* See the COPYRIGHT file for redistribution and use restrictions.
*/
package org.xins.server;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TimeZone;
import javax.servlet.http.HttpServletResponse;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xins.common.collections.InvalidPropertyValueException;
import org.xins.common.collections.MissingRequiredPropertyException;
import org.xins.common.manageable.BootstrapException;
import org.xins.common.spec.FunctionSpec;
import org.xins.common.spec.InvalidSpecificationException;
import org.xins.common.text.DateConverter;
/**
* Maintain the call statistics.
*
* @since xins 3.0
*
* @version $Revision: 1.2 $ $Date: 2012/02/27 22:26:04 $
* @author Anthony Goubard
*/
public class StatisticsInterceptor extends Interceptor {
protected Map statistics = new LinkedHashMap();
/**
* Last time the statistics were reset. Initially the startup timestamp.
*/
protected long _lastStatisticsReset;
@Override
protected void bootstrapImpl(Map properties)
throws MissingRequiredPropertyException,
InvalidPropertyValueException,
BootstrapException {
_lastStatisticsReset = getApi().getStartupTimestamp();
try {
Map functions = getApi().getAPISpecification().getFunctions();
for (String functionName: functions.keySet()) {
statistics.put(functionName, new FunctionStatistics());
}
} catch (InvalidSpecificationException ex) {
// TODO log
}
}
@Override
public FunctionResult afterFunctionCall(FunctionRequest functionRequest, FunctionResult xinsResult, HttpServletResponse httpResponse) {
String functionName = functionRequest.getFunctionName();
FunctionStatistics statistic = statistics.get(functionName);
if (statistic != null) {
long start = (Long) functionRequest.getBackpack().get(BackpackConstants.START);
String code = xinsResult.getErrorCode();
statistic.recordCall(start, code);
}
return xinsResult;
}
/**
* Returns the call statistics for all functions in this API.
*
* @param detailed
* If true
, the unsuccessful result will be returned sorted
* per error code. Otherwise the unsuccessful result won't be displayed
* by error code.
*
* @param functionName
* the name of the specific function to return the statistics for,
* if null
, then the stats for all functions are returned.
*
* @return
* the call result, never null
.
*/
protected FunctionResult getStatistics(boolean detailed, String functionName) {
// Initialize a builder
FunctionResult builder = new FunctionResult();
TimeZone timeZone = getApi().getTimeZone();
builder.param("startup", DateConverter.toDateString(timeZone, getApi().getStartupTimestamp()));
builder.param("lastReset", DateConverter.toDateString(timeZone, _lastStatisticsReset));
builder.param("now", DateConverter.toDateString(timeZone, System.currentTimeMillis()));
// Currently available processors
Runtime rt = Runtime.getRuntime();
builder.param("availableProcessors", String.valueOf(rt.availableProcessors()));
// Heap memory statistics
Element heap = builder.getDataElementBuilder().createElement("heap");
long free = rt.freeMemory();
long total = rt.totalMemory();
heap.setAttribute("used", String.valueOf(total - free));
heap.setAttribute("free", String.valueOf(free));
heap.setAttribute("total", String.valueOf(total));
long max = rt.maxMemory();
heap.setAttribute("max", String.valueOf(max));
double percentageUsed = (total - free) / (double) max;
heap.setAttribute("percentageUsed", String.valueOf((int) (percentageUsed * 100)));
builder.getDataElement().appendChild(heap);
// Function-specific statistics
for (Map.Entry stat : statistics.entrySet()) {
String statFunctionName = stat.getKey();
// Possibly only results for a specific function are to be returned
if (functionName != null && !functionName.equals(statFunctionName)) {
continue;
}
FunctionStatistics stats = stat.getValue();
Element functionElem = builder.getDataElementBuilder().createElement("function");
functionElem.setAttribute("name", statFunctionName);
// Successful
Document functionDoc = functionElem.getOwnerDocument();
Element successful = stats.getSuccessfulElement();
functionElem.appendChild(functionDoc.importNode(successful, true));
// Unsuccessful
Element[] unsuccessful = stats.getUnsuccessfulElement(detailed);
for(int j = 0; j < unsuccessful.length; j++) {
functionElem.appendChild(functionDoc.importNode(unsuccessful[j], true));
}
builder.getDataElement().appendChild(functionElem);
}
return builder;
}
/**
* Resets the statistics.
*
* @return
* the call result, never null
.
*/
protected FunctionResult resetStatistics() {
// Remember when we last reset the statistics
_lastStatisticsReset = System.currentTimeMillis();
// Function-specific statistics
for (FunctionStatistics stat : statistics.values()) {
stat.resetStatistics();
}
return API.SUCCESSFUL_RESULT;
}
public Map getStatistics() {
return statistics;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy