@Override
    public Result search(Query query, Execution execution) {
        if (query.properties().getBoolean(IGNORE_QUERY,false)) {
            return execution.search(query);
        }

        Metric.Context metricContext = getChainMetricContext(execution.chain().getId().stringValue());

        incrQueryCount(metricContext);
        logQuery(query);
        // Timestamp when request was initially processed by Jetty
        long startMs = Optional.ofNullable(query.getHttpRequest())
                .map(r -> r.creationTime(TimeUnit.MILLISECONDS)).orElseGet(System::currentTimeMillis);
        qps(metricContext);
        metric.set(QUERY_TIMEOUT_METRIC, query.getTimeout(), metricContext);
        Result result;
        //handle exceptions thrown below in searchers
        try {
            result = execution.search(query); // Pass on down the chain
        } catch (Exception e) {
            incrErrorCount(null, metricContext);
            throw e;
        }

        long endMs = System.currentTimeMillis();
        long latencyMs = endMs - startMs;
        if (latencyMs >= 0) {
            addLatency(latencyMs, metricContext);
        } else {
            getLogger().log(Level.WARNING,
                            "Apparently negative latency measure, start: " + startMs
                            + ", end: " + endMs + ", for query: " + query + ". Could be caused by NTP adjustments.");
        }
        if (result.hits().getError() != null) {
            incrErrorCount(result, metricContext);
            incrementStatePageOnlyErrors(result);
        }
        Coverage queryCoverage = result.getCoverage(false);
        if (queryCoverage != null) {
            if (queryCoverage.isDegraded()) {
                Metric.Context degradedContext = getDegradedMetricContext(execution.chain().getId().stringValue(), queryCoverage);
                metric.add(DEGRADED_QUERIES_METRIC, 1, degradedContext);
            }
            metric.add(DOCS_COVERED_METRIC, queryCoverage.getDocs(), metricContext);
            metric.add(DOCS_TOTAL_METRIC, queryCoverage.getActive(), metricContext);
            metric.add(DOCS_TARGET_TOTAL_METRIC, queryCoverage.getTargetActive(), metricContext);
        }
        int hitCount = result.getConcreteHitCount();
        metric.set(HITS_PER_QUERY_METRIC, (double) hitCount, metricContext);

        long totalHitCount = result.getTotalHitCount();
        metric.set(TOTALHITS_PER_QUERY_METRIC, (double) totalHitCount, metricContext);
        metric.set(QUERY_HIT_OFFSET_METRIC, (double) (query.getHits() + query.getOffset()), metricContext);
        if (hitCount == 0) {
            metric.add(EMPTY_RESULTS_METRIC, 1, metricContext);
        }

        addRelevanceMetrics(query, execution, result);

        addItemCountMetric(query, metricContext);

        return result;
    }
Generate statistics for the query passing through this Searcher
1) Add 1 to total query count
2) Add response time to total response time (time from entry to return)
3) .....
container-search/src/main/java/com/yahoo/prelude/statistics/StatisticsSearcher.java