mirror of https://github.com/apache/lucene.git
SOLR-1972: Add extra query stats to RequestHandler
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1403555 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7e65097905
commit
03ed8213cb
|
@ -55,6 +55,10 @@ New Features
|
|||
* SOLR-3911: Make Directory and DirectoryFactory first class so that the majority
|
||||
of Solr's features work with any custom implementations. (Mark Miller)
|
||||
|
||||
* SOLR-1972: Add extra statistics to RequestHandlers - 5 & 15-minute reqs/sec
|
||||
rolling averages; median, 75th, 95th, 99th, 99.9th percentile request times
|
||||
(Alan Woodward)
|
||||
|
||||
Optimizations
|
||||
----------------------
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
<dependency org="org.easymock" name="easymock" rev="2.2" transitive="false"/>
|
||||
<dependency org="com.spatial4j" name="spatial4j" rev="0.3" transitive="false"/>
|
||||
<dependency org="javax.servlet" name="javax.servlet-api" rev="3.0.1" transitive="false"/>
|
||||
<dependency org="com.yammer.metrics" name="metrics-core" rev="2.1.2" transitive="false"/>
|
||||
<exclude org="*" ext="*" matcher="regexp" type="${ivy.exclude.types}"/>
|
||||
</dependencies>
|
||||
</ivy-module>
|
||||
|
|
|
@ -17,6 +17,11 @@
|
|||
|
||||
package org.apache.solr.handler;
|
||||
|
||||
import com.yammer.metrics.Metrics;
|
||||
import com.yammer.metrics.core.Counter;
|
||||
import com.yammer.metrics.core.Timer;
|
||||
import com.yammer.metrics.core.TimerContext;
|
||||
import com.yammer.metrics.stats.Snapshot;
|
||||
import org.apache.lucene.queryparser.classic.ParseException;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.common.params.SolrParams;
|
||||
|
@ -30,26 +35,34 @@ import org.apache.solr.response.SolrQueryResponse;
|
|||
import org.apache.solr.util.SolrPluginUtils;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfoMBean {
|
||||
|
||||
// statistics
|
||||
// TODO: should we bother synchronizing these, or is an off-by-one error
|
||||
// acceptable every million requests or so?
|
||||
volatile long numRequests;
|
||||
volatile long numErrors;
|
||||
volatile long numTimeouts;
|
||||
protected NamedList initArgs = null;
|
||||
protected SolrParams defaults;
|
||||
protected SolrParams appends;
|
||||
protected SolrParams invariants;
|
||||
volatile long totalTime = 0;
|
||||
long handlerStart = System.currentTimeMillis();
|
||||
protected boolean httpCaching = true;
|
||||
|
||||
// Statistics
|
||||
private static final AtomicLong handlerNumber = new AtomicLong();
|
||||
private final Counter numRequests;
|
||||
private final Counter numErrors;
|
||||
private final Counter numTimeouts;
|
||||
private final Timer requestTimes;
|
||||
long handlerStart = System.currentTimeMillis();
|
||||
|
||||
public RequestHandlerBase() {
|
||||
String scope = new String("metrics-scope-" + handlerNumber.getAndIncrement());
|
||||
numRequests = Metrics.newCounter(RequestHandlerBase.class, "numRequests", scope);
|
||||
numErrors = Metrics.newCounter(RequestHandlerBase.class, "numErrors", scope);
|
||||
numTimeouts = Metrics.newCounter(RequestHandlerBase.class, "numTimeouts", scope);
|
||||
requestTimes = Metrics.newTimer(RequestHandlerBase.class, "requestTimes", scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the {@link org.apache.solr.request.SolrRequestHandler} by creating three {@link org.apache.solr.common.params.SolrParams} named.
|
||||
|
@ -93,7 +106,7 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo
|
|||
public void init(NamedList args) {
|
||||
initArgs = args;
|
||||
|
||||
// Copied from StandardRequestHandler
|
||||
// Copied from StandardRequestHandler
|
||||
if( args != null ) {
|
||||
Object o = args.get("defaults");
|
||||
if (o != null && o instanceof NamedList) {
|
||||
|
@ -113,6 +126,7 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo
|
|||
Object caching = initArgs.get("httpCaching");
|
||||
httpCaching = caching != null ? Boolean.parseBoolean(caching.toString()) : true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public NamedList getInitArgs() {
|
||||
|
@ -122,7 +136,8 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo
|
|||
public abstract void handleRequestBody( SolrQueryRequest req, SolrQueryResponse rsp ) throws Exception;
|
||||
|
||||
public void handleRequest(SolrQueryRequest req, SolrQueryResponse rsp) {
|
||||
numRequests++;
|
||||
numRequests.inc();
|
||||
TimerContext timer = requestTimes.time();
|
||||
try {
|
||||
SolrPluginUtils.setDefaults(req,defaults,appends,invariants);
|
||||
rsp.setHttpCaching(httpCaching);
|
||||
|
@ -133,7 +148,7 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo
|
|||
Object partialResults = header.get("partialResults");
|
||||
boolean timedOut = partialResults == null ? false : (Boolean)partialResults;
|
||||
if( timedOut ) {
|
||||
numTimeouts++;
|
||||
numTimeouts.inc();
|
||||
rsp.setHttpCaching(false);
|
||||
}
|
||||
}
|
||||
|
@ -154,11 +169,12 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo
|
|||
}
|
||||
|
||||
rsp.setException(e);
|
||||
numErrors++;
|
||||
numErrors.inc();
|
||||
}
|
||||
finally {
|
||||
timer.stop();
|
||||
}
|
||||
totalTime += rsp.getEndTime() - req.getStartTime();
|
||||
}
|
||||
|
||||
|
||||
//////////////////////// SolrInfoMBeans methods //////////////////////
|
||||
|
||||
|
@ -184,12 +200,20 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo
|
|||
public NamedList<Object> getStatistics() {
|
||||
NamedList<Object> lst = new SimpleOrderedMap<Object>();
|
||||
lst.add("handlerStart",handlerStart);
|
||||
lst.add("requests", numRequests);
|
||||
lst.add("errors", numErrors);
|
||||
lst.add("timeouts", numTimeouts);
|
||||
lst.add("totalTime",totalTime);
|
||||
lst.add("avgTimePerRequest", (float) totalTime / (float) this.numRequests);
|
||||
lst.add("avgRequestsPerSecond", (float) numRequests*1000 / (float)(System.currentTimeMillis()-handlerStart));
|
||||
lst.add("requests", numRequests.count());
|
||||
lst.add("errors", numErrors.count());
|
||||
lst.add("timeouts", numTimeouts.count());
|
||||
lst.add("totalTime",requestTimes.sum());
|
||||
lst.add("avgRequestsPerSecond", requestTimes.meanRate());
|
||||
lst.add("5minRateReqsPerSecond", requestTimes.fiveMinuteRate());
|
||||
lst.add("15minRateReqsPerSecond", requestTimes.fifteenMinuteRate());
|
||||
lst.add("avgTimePerRequest", requestTimes.mean());
|
||||
Snapshot snapshot = requestTimes.getSnapshot();
|
||||
lst.add("medianRequestTime", snapshot.getMedian());
|
||||
lst.add("75thPcRequestTime", snapshot.get75thPercentile());
|
||||
lst.add("95thPcRequestTime", snapshot.get95thPercentile());
|
||||
lst.add("99thPcRequestTime", snapshot.get99thPercentile());
|
||||
lst.add("999thPcRequestTime", snapshot.get999thPercentile());
|
||||
return lst;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package org.apache.solr.core;
|
||||
|
||||
import org.apache.solr.SolrTestCaseJ4;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.solr.handler.StandardRequestHandler;
|
||||
import org.apache.solr.request.SolrRequestHandler;
|
||||
import org.junit.BeforeClass;
|
||||
|
@ -87,4 +88,23 @@ public class RequestHandlersTest extends SolrTestCaseJ4 {
|
|||
|
||||
assertNull( core.getRequestHandler("/update/asdgadsgas" ) ); // prefix
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatistics() {
|
||||
SolrCore core = h.getCore();
|
||||
SolrRequestHandler updateHandler = core.getRequestHandler("/update");
|
||||
SolrRequestHandler termHandler = core.getRequestHandler("/terms");
|
||||
|
||||
assertU(adoc("id", "47",
|
||||
"text", "line up and fly directly at the enemy death cannons, clogging them with wreckage!"));
|
||||
assertU(commit());
|
||||
|
||||
NamedList updateStats = updateHandler.getStatistics();
|
||||
NamedList termStats = termHandler.getStatistics();
|
||||
|
||||
Double updateTime = (Double) updateStats.get("totalTime");
|
||||
Double termTime = (Double) termStats.get("totalTime");
|
||||
|
||||
assertFalse("RequestHandlers should not share statistics!", updateTime.equals(termTime));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,8 @@ public class SolrIgnoredThreadsFilter implements ThreadFilter {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (threadName.startsWith("facetExecutor-") ||
|
||||
if (threadName.startsWith("facetExecutor-") ||
|
||||
threadName.startsWith("metrics-") ||
|
||||
threadName.startsWith("cmdDistribExecutor-") ||
|
||||
threadName.startsWith("httpShardExecutor-")) {
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue