/* * Licensed to Elasticsearch under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch licenses this file to you 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 org.elasticsearch.index.search.stats; import org.elasticsearch.action.support.ToXContentToBytes; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Streamable; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class SearchStats extends ToXContentToBytes implements Streamable { public static class Stats implements Streamable, ToXContent { private long queryCount; private long queryTimeInMillis; private long queryCurrent; private long fetchCount; private long fetchTimeInMillis; private long fetchCurrent; private long scrollCount; private long scrollTimeInMillis; private long scrollCurrent; private long suggestCount; private long suggestTimeInMillis; private long suggestCurrent; Stats() { } public Stats( long queryCount, long queryTimeInMillis, long queryCurrent, long fetchCount, long fetchTimeInMillis, long fetchCurrent, long scrollCount, long scrollTimeInMillis, long scrollCurrent, long suggestCount, long suggestTimeInMillis, long suggestCurrent ) { this.queryCount = queryCount; this.queryTimeInMillis = queryTimeInMillis; this.queryCurrent = queryCurrent; this.fetchCount = fetchCount; this.fetchTimeInMillis = fetchTimeInMillis; this.fetchCurrent = fetchCurrent; this.scrollCount = scrollCount; this.scrollTimeInMillis = scrollTimeInMillis; this.scrollCurrent = scrollCurrent; this.suggestCount = suggestCount; this.suggestTimeInMillis = suggestTimeInMillis; this.suggestCurrent = suggestCurrent; } public Stats(Stats stats) { this( stats.queryCount, stats.queryTimeInMillis, stats.queryCurrent, stats.fetchCount, stats.fetchTimeInMillis, stats.fetchCurrent, stats.scrollCount, stats.scrollTimeInMillis, stats.scrollCurrent, stats.suggestCount, stats.suggestTimeInMillis, stats.suggestCurrent ); } public void add(Stats stats) { queryCount += stats.queryCount; queryTimeInMillis += stats.queryTimeInMillis; queryCurrent += stats.queryCurrent; fetchCount += stats.fetchCount; fetchTimeInMillis += stats.fetchTimeInMillis; fetchCurrent += stats.fetchCurrent; scrollCount += stats.scrollCount; scrollTimeInMillis += stats.scrollTimeInMillis; scrollCurrent += stats.scrollCurrent; suggestCount += stats.suggestCount; suggestTimeInMillis += stats.suggestTimeInMillis; suggestCurrent += stats.suggestCurrent; } public long getQueryCount() { return queryCount; } public TimeValue getQueryTime() { return new TimeValue(queryTimeInMillis); } public long getQueryTimeInMillis() { return queryTimeInMillis; } public long getQueryCurrent() { return queryCurrent; } public long getFetchCount() { return fetchCount; } public TimeValue getFetchTime() { return new TimeValue(fetchTimeInMillis); } public long getFetchTimeInMillis() { return fetchTimeInMillis; } public long getFetchCurrent() { return fetchCurrent; } public long getScrollCount() { return scrollCount; } public TimeValue getScrollTime() { return new TimeValue(scrollTimeInMillis); } public long getScrollTimeInMillis() { return scrollTimeInMillis; } public long getScrollCurrent() { return scrollCurrent; } public long getSuggestCount() { return suggestCount; } public long getSuggestTimeInMillis() { return suggestTimeInMillis; } public TimeValue getSuggestTime() { return new TimeValue(suggestTimeInMillis); } public long getSuggestCurrent() { return suggestCurrent; } public static Stats readStats(StreamInput in) throws IOException { Stats stats = new Stats(); stats.readFrom(in); return stats; } @Override public void readFrom(StreamInput in) throws IOException { queryCount = in.readVLong(); queryTimeInMillis = in.readVLong(); queryCurrent = in.readVLong(); fetchCount = in.readVLong(); fetchTimeInMillis = in.readVLong(); fetchCurrent = in.readVLong(); scrollCount = in.readVLong(); scrollTimeInMillis = in.readVLong(); scrollCurrent = in.readVLong(); suggestCount = in.readVLong(); suggestTimeInMillis = in.readVLong(); suggestCurrent = in.readVLong(); } @Override public void writeTo(StreamOutput out) throws IOException { out.writeVLong(queryCount); out.writeVLong(queryTimeInMillis); out.writeVLong(queryCurrent); out.writeVLong(fetchCount); out.writeVLong(fetchTimeInMillis); out.writeVLong(fetchCurrent); out.writeVLong(scrollCount); out.writeVLong(scrollTimeInMillis); out.writeVLong(scrollCurrent); out.writeVLong(suggestCount); out.writeVLong(suggestTimeInMillis); out.writeVLong(suggestCurrent); } @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.field(Fields.QUERY_TOTAL, queryCount); builder.timeValueField(Fields.QUERY_TIME_IN_MILLIS, Fields.QUERY_TIME, queryTimeInMillis); builder.field(Fields.QUERY_CURRENT, queryCurrent); builder.field(Fields.FETCH_TOTAL, fetchCount); builder.timeValueField(Fields.FETCH_TIME_IN_MILLIS, Fields.FETCH_TIME, fetchTimeInMillis); builder.field(Fields.FETCH_CURRENT, fetchCurrent); builder.field(Fields.SCROLL_TOTAL, scrollCount); builder.timeValueField(Fields.SCROLL_TIME_IN_MILLIS, Fields.SCROLL_TIME, scrollTimeInMillis); builder.field(Fields.SCROLL_CURRENT, scrollCurrent); builder.field(Fields.SUGGEST_TOTAL, suggestCount); builder.timeValueField(Fields.SUGGEST_TIME_IN_MILLIS, Fields.SUGGEST_TIME, suggestTimeInMillis); builder.field(Fields.SUGGEST_CURRENT, suggestCurrent); return builder; } } Stats totalStats; long openContexts; @Nullable Map<String, Stats> groupStats; public SearchStats() { totalStats = new Stats(); } public SearchStats(Stats totalStats, long openContexts, @Nullable Map<String, Stats> groupStats) { this.totalStats = totalStats; this.openContexts = openContexts; this.groupStats = groupStats; } public void add(SearchStats searchStats) { add(searchStats, true); } public void add(SearchStats searchStats, boolean includeTypes) { if (searchStats == null) { return; } addTotals(searchStats); openContexts += searchStats.openContexts; if (includeTypes && searchStats.groupStats != null && !searchStats.groupStats.isEmpty()) { if (groupStats == null) { groupStats = new HashMap<>(searchStats.groupStats.size()); } for (Map.Entry<String, Stats> entry : searchStats.groupStats.entrySet()) { Stats stats = groupStats.get(entry.getKey()); if (stats == null) { groupStats.put(entry.getKey(), new Stats(entry.getValue())); } else { stats.add(entry.getValue()); } } } } public void addTotals(SearchStats searchStats) { if (searchStats == null) { return; } totalStats.add(searchStats.totalStats); } public Stats getTotal() { return this.totalStats; } public long getOpenContexts() { return this.openContexts; } @Nullable public Map<String, Stats> getGroupStats() { return this.groupStats; } @Override public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException { builder.startObject(Fields.SEARCH); builder.field(Fields.OPEN_CONTEXTS, openContexts); totalStats.toXContent(builder, params); if (groupStats != null && !groupStats.isEmpty()) { builder.startObject(Fields.GROUPS); for (Map.Entry<String, Stats> entry : groupStats.entrySet()) { builder.startObject(entry.getKey()); entry.getValue().toXContent(builder, params); builder.endObject(); } builder.endObject(); } builder.endObject(); return builder; } static final class Fields { static final String SEARCH = "search"; static final String OPEN_CONTEXTS = "open_contexts"; static final String GROUPS = "groups"; static final String QUERY_TOTAL = "query_total"; static final String QUERY_TIME = "query_time"; static final String QUERY_TIME_IN_MILLIS = "query_time_in_millis"; static final String QUERY_CURRENT = "query_current"; static final String FETCH_TOTAL = "fetch_total"; static final String FETCH_TIME = "fetch_time"; static final String FETCH_TIME_IN_MILLIS = "fetch_time_in_millis"; static final String FETCH_CURRENT = "fetch_current"; static final String SCROLL_TOTAL = "scroll_total"; static final String SCROLL_TIME = "scroll_time"; static final String SCROLL_TIME_IN_MILLIS = "scroll_time_in_millis"; static final String SCROLL_CURRENT = "scroll_current"; static final String SUGGEST_TOTAL = "suggest_total"; static final String SUGGEST_TIME = "suggest_time"; static final String SUGGEST_TIME_IN_MILLIS = "suggest_time_in_millis"; static final String SUGGEST_CURRENT = "suggest_current"; } @Override public void readFrom(StreamInput in) throws IOException { totalStats = Stats.readStats(in); openContexts = in.readVLong(); if (in.readBoolean()) { groupStats = in.readMap(StreamInput::readString, Stats::readStats); } } @Override public void writeTo(StreamOutput out) throws IOException { totalStats.writeTo(out); out.writeVLong(openContexts); if (groupStats == null || groupStats.isEmpty()) { out.writeBoolean(false); } else { out.writeBoolean(true); out.writeMap(groupStats, StreamOutput::writeString, (stream, stats) -> stats.writeTo(stream)); } } }