Add script compilation stats

This commit adds basic support to track the number of times scripts are
compiled and compiled scripts are evicted from the script cache. These
statistics are tracked at the node level.

Closes #12673
This commit is contained in:
Jason Tedor 2015-08-07 14:48:49 -04:00
parent 7efc419041
commit 23b348040e
15 changed files with 269 additions and 11 deletions

View File

@ -33,6 +33,7 @@ import org.elasticsearch.monitor.fs.FsInfo;
import org.elasticsearch.monitor.jvm.JvmStats; import org.elasticsearch.monitor.jvm.JvmStats;
import org.elasticsearch.monitor.os.OsStats; import org.elasticsearch.monitor.os.OsStats;
import org.elasticsearch.monitor.process.ProcessStats; import org.elasticsearch.monitor.process.ProcessStats;
import org.elasticsearch.script.ScriptStats;
import org.elasticsearch.threadpool.ThreadPoolStats; import org.elasticsearch.threadpool.ThreadPoolStats;
import org.elasticsearch.transport.TransportStats; import org.elasticsearch.transport.TransportStats;
@ -73,13 +74,17 @@ public class NodeStats extends BaseNodeResponse implements ToXContent {
@Nullable @Nullable
private AllCircuitBreakerStats breaker; private AllCircuitBreakerStats breaker;
@Nullable
private ScriptStats scriptStats;
NodeStats() { NodeStats() {
} }
public NodeStats(DiscoveryNode node, long timestamp, @Nullable NodeIndicesStats indices, public NodeStats(DiscoveryNode node, long timestamp, @Nullable NodeIndicesStats indices,
@Nullable OsStats os, @Nullable ProcessStats process, @Nullable JvmStats jvm, @Nullable ThreadPoolStats threadPool, @Nullable OsStats os, @Nullable ProcessStats process, @Nullable JvmStats jvm, @Nullable ThreadPoolStats threadPool,
@Nullable FsInfo fs, @Nullable TransportStats transport, @Nullable HttpStats http, @Nullable FsInfo fs, @Nullable TransportStats transport, @Nullable HttpStats http,
@Nullable AllCircuitBreakerStats breaker) { @Nullable AllCircuitBreakerStats breaker,
@Nullable ScriptStats scriptStats) {
super(node); super(node);
this.timestamp = timestamp; this.timestamp = timestamp;
this.indices = indices; this.indices = indices;
@ -91,6 +96,7 @@ public class NodeStats extends BaseNodeResponse implements ToXContent {
this.transport = transport; this.transport = transport;
this.http = http; this.http = http;
this.breaker = breaker; this.breaker = breaker;
this.scriptStats = scriptStats;
} }
public long getTimestamp() { public long getTimestamp() {
@ -165,6 +171,11 @@ public class NodeStats extends BaseNodeResponse implements ToXContent {
return this.breaker; return this.breaker;
} }
@Nullable
public ScriptStats getScriptStats() {
return this.scriptStats;
}
public static NodeStats readNodeStats(StreamInput in) throws IOException { public static NodeStats readNodeStats(StreamInput in) throws IOException {
NodeStats nodeInfo = new NodeStats(); NodeStats nodeInfo = new NodeStats();
nodeInfo.readFrom(in); nodeInfo.readFrom(in);
@ -200,6 +211,7 @@ public class NodeStats extends BaseNodeResponse implements ToXContent {
http = HttpStats.readHttpStats(in); http = HttpStats.readHttpStats(in);
} }
breaker = AllCircuitBreakerStats.readOptionalAllCircuitBreakerStats(in); breaker = AllCircuitBreakerStats.readOptionalAllCircuitBreakerStats(in);
scriptStats = in.readOptionalStreamable(new ScriptStats());
} }
@ -256,6 +268,7 @@ public class NodeStats extends BaseNodeResponse implements ToXContent {
http.writeTo(out); http.writeTo(out);
} }
out.writeOptionalStreamable(breaker); out.writeOptionalStreamable(breaker);
out.writeOptionalStreamable(scriptStats);
} }
@Override @Override
@ -303,6 +316,9 @@ public class NodeStats extends BaseNodeResponse implements ToXContent {
if (getBreaker() != null) { if (getBreaker() != null) {
getBreaker().toXContent(builder, params); getBreaker().toXContent(builder, params);
} }
if (getScriptStats() != null) {
getScriptStats().toXContent(builder, params);
}
return builder; return builder;
} }

View File

@ -41,6 +41,7 @@ public class NodesStatsRequest extends BaseNodesRequest<NodesStatsRequest> {
private boolean transport; private boolean transport;
private boolean http; private boolean http;
private boolean breaker; private boolean breaker;
private boolean script;
protected NodesStatsRequest() { protected NodesStatsRequest() {
} }
@ -67,6 +68,7 @@ public class NodesStatsRequest extends BaseNodesRequest<NodesStatsRequest> {
this.transport = true; this.transport = true;
this.http = true; this.http = true;
this.breaker = true; this.breaker = true;
this.script = true;
return this; return this;
} }
@ -84,6 +86,7 @@ public class NodesStatsRequest extends BaseNodesRequest<NodesStatsRequest> {
this.transport = false; this.transport = false;
this.http = false; this.http = false;
this.breaker = false; this.breaker = false;
this.script = false;
return this; return this;
} }
@ -240,6 +243,15 @@ public class NodesStatsRequest extends BaseNodesRequest<NodesStatsRequest> {
return this; return this;
} }
public boolean script() {
return script;
}
public NodesStatsRequest script(boolean script) {
this.script = script;
return this;
}
@Override @Override
public void readFrom(StreamInput in) throws IOException { public void readFrom(StreamInput in) throws IOException {
super.readFrom(in); super.readFrom(in);
@ -253,6 +265,7 @@ public class NodesStatsRequest extends BaseNodesRequest<NodesStatsRequest> {
transport = in.readBoolean(); transport = in.readBoolean();
http = in.readBoolean(); http = in.readBoolean();
breaker = in.readBoolean(); breaker = in.readBoolean();
script = in.readBoolean();
} }
@Override @Override
@ -268,6 +281,7 @@ public class NodesStatsRequest extends BaseNodesRequest<NodesStatsRequest> {
out.writeBoolean(transport); out.writeBoolean(transport);
out.writeBoolean(http); out.writeBoolean(http);
out.writeBoolean(breaker); out.writeBoolean(breaker);
out.writeBoolean(script);
} }
} }

View File

@ -62,6 +62,11 @@ public class NodesStatsRequestBuilder extends NodesOperationRequestBuilder<Nodes
return this; return this;
} }
public NodesStatsRequestBuilder setScript(boolean script) {
request.script(script);
return this;
}
/** /**
* Should the node indices stats be returned. * Should the node indices stats be returned.
*/ */

View File

@ -80,7 +80,7 @@ public class TransportNodesStatsAction extends TransportNodesAction<NodesStatsRe
protected NodeStats nodeOperation(NodeStatsRequest nodeStatsRequest) { protected NodeStats nodeOperation(NodeStatsRequest nodeStatsRequest) {
NodesStatsRequest request = nodeStatsRequest.request; NodesStatsRequest request = nodeStatsRequest.request;
return nodeService.stats(request.indices(), request.os(), request.process(), request.jvm(), request.threadPool(), request.network(), return nodeService.stats(request.indices(), request.os(), request.process(), request.jvm(), request.threadPool(), request.network(),
request.fs(), request.transport(), request.http(), request.breaker()); request.fs(), request.transport(), request.http(), request.breaker(), request.script());
} }
@Override @Override

View File

@ -100,7 +100,7 @@ public class TransportClusterStatsAction extends TransportNodesAction<ClusterSta
@Override @Override
protected ClusterStatsNodeResponse nodeOperation(ClusterStatsNodeRequest nodeRequest) { protected ClusterStatsNodeResponse nodeOperation(ClusterStatsNodeRequest nodeRequest) {
NodeInfo nodeInfo = nodeService.info(false, true, false, true, false, false, true, false, true); NodeInfo nodeInfo = nodeService.info(false, true, false, true, false, false, true, false, true);
NodeStats nodeStats = nodeService.stats(CommonStatsFlags.NONE, false, true, true, false, false, true, false, false, false); NodeStats nodeStats = nodeService.stats(CommonStatsFlags.NONE, false, true, true, false, false, true, false, false, false, false);
List<ShardStats> shardsStats = new ArrayList<>(); List<ShardStats> shardsStats = new ArrayList<>();
for (IndexService indexService : indicesService) { for (IndexService indexService : indicesService) {
for (IndexShard indexShard : indexService) { for (IndexShard indexShard : indexService) {

View File

@ -36,6 +36,7 @@ import org.elasticsearch.indices.IndicesService;
import org.elasticsearch.indices.breaker.CircuitBreakerService; import org.elasticsearch.indices.breaker.CircuitBreakerService;
import org.elasticsearch.monitor.MonitorService; import org.elasticsearch.monitor.MonitorService;
import org.elasticsearch.plugins.PluginsService; import org.elasticsearch.plugins.PluginsService;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService; import org.elasticsearch.transport.TransportService;
@ -51,6 +52,8 @@ public class NodeService extends AbstractComponent {
private final IndicesService indicesService; private final IndicesService indicesService;
private final PluginsService pluginService; private final PluginsService pluginService;
private final CircuitBreakerService circuitBreakerService; private final CircuitBreakerService circuitBreakerService;
private ScriptService scriptService;
@Nullable @Nullable
private HttpServer httpServer; private HttpServer httpServer;
@ -63,7 +66,8 @@ public class NodeService extends AbstractComponent {
@Inject @Inject
public NodeService(Settings settings, ThreadPool threadPool, MonitorService monitorService, Discovery discovery, public NodeService(Settings settings, ThreadPool threadPool, MonitorService monitorService, Discovery discovery,
TransportService transportService, IndicesService indicesService, TransportService transportService, IndicesService indicesService,
PluginsService pluginService, CircuitBreakerService circuitBreakerService, Version version) { PluginsService pluginService, CircuitBreakerService circuitBreakerService,
Version version) {
super(settings); super(settings);
this.threadPool = threadPool; this.threadPool = threadPool;
this.monitorService = monitorService; this.monitorService = monitorService;
@ -76,6 +80,12 @@ public class NodeService extends AbstractComponent {
this.circuitBreakerService = circuitBreakerService; this.circuitBreakerService = circuitBreakerService;
} }
// can not use constructor injection or there will be a circular dependency
@Inject(optional = true)
public void setScriptService(ScriptService scriptService) {
this.scriptService = scriptService;
}
public void setHttpServer(@Nullable HttpServer httpServer) { public void setHttpServer(@Nullable HttpServer httpServer) {
this.httpServer = httpServer; this.httpServer = httpServer;
} }
@ -134,12 +144,14 @@ public class NodeService extends AbstractComponent {
monitorService.fsService().stats(), monitorService.fsService().stats(),
transportService.stats(), transportService.stats(),
httpServer == null ? null : httpServer.stats(), httpServer == null ? null : httpServer.stats(),
circuitBreakerService.stats() circuitBreakerService.stats(),
scriptService.stats()
); );
} }
public NodeStats stats(CommonStatsFlags indices, boolean os, boolean process, boolean jvm, boolean threadPool, boolean network, public NodeStats stats(CommonStatsFlags indices, boolean os, boolean process, boolean jvm, boolean threadPool, boolean network,
boolean fs, boolean transport, boolean http, boolean circuitBreaker) { boolean fs, boolean transport, boolean http, boolean circuitBreaker,
boolean script) {
// for indices stats we want to include previous allocated shards stats as well (it will // for indices stats we want to include previous allocated shards stats as well (it will
// only be applied to the sensible ones to use, like refresh/merge/flush/indexing stats) // only be applied to the sensible ones to use, like refresh/merge/flush/indexing stats)
return new NodeStats(discovery.localNode(), System.currentTimeMillis(), return new NodeStats(discovery.localNode(), System.currentTimeMillis(),
@ -151,7 +163,8 @@ public class NodeService extends AbstractComponent {
fs ? monitorService.fsService().stats() : null, fs ? monitorService.fsService().stats() : null,
transport ? transportService.stats() : null, transport ? transportService.stats() : null,
http ? (httpServer == null ? null : httpServer.stats()) : null, http ? (httpServer == null ? null : httpServer.stats()) : null,
circuitBreaker ? circuitBreakerService.stats() : null circuitBreaker ? circuitBreakerService.stats() : null,
script ? scriptService.stats() : null
); );
} }
} }

View File

@ -76,6 +76,7 @@ public class RestNodesStatsAction extends BaseRestHandler {
nodesStatsRequest.indices(metrics.contains("indices")); nodesStatsRequest.indices(metrics.contains("indices"));
nodesStatsRequest.process(metrics.contains("process")); nodesStatsRequest.process(metrics.contains("process"));
nodesStatsRequest.breaker(metrics.contains("breaker")); nodesStatsRequest.breaker(metrics.contains("breaker"));
nodesStatsRequest.script(metrics.contains("script"));
// check for index specific metrics // check for index specific metrics
if (metrics.contains("indices")) { if (metrics.contains("indices")) {

View File

@ -57,6 +57,7 @@ import org.elasticsearch.rest.*;
import org.elasticsearch.rest.action.support.RestActionListener; import org.elasticsearch.rest.action.support.RestActionListener;
import org.elasticsearch.rest.action.support.RestResponseListener; import org.elasticsearch.rest.action.support.RestResponseListener;
import org.elasticsearch.rest.action.support.RestTable; import org.elasticsearch.rest.action.support.RestTable;
import org.elasticsearch.script.ScriptStats;
import org.elasticsearch.search.suggest.completion.CompletionStats; import org.elasticsearch.search.suggest.completion.CompletionStats;
import java.util.Locale; import java.util.Locale;
@ -92,7 +93,7 @@ public class RestNodesAction extends AbstractCatAction {
@Override @Override
public void processResponse(final NodesInfoResponse nodesInfoResponse) { public void processResponse(final NodesInfoResponse nodesInfoResponse) {
NodesStatsRequest nodesStatsRequest = new NodesStatsRequest(); NodesStatsRequest nodesStatsRequest = new NodesStatsRequest();
nodesStatsRequest.clear().jvm(true).os(true).fs(true).indices(true).process(true); nodesStatsRequest.clear().jvm(true).os(true).fs(true).indices(true).process(true).script(true);
client.admin().cluster().nodesStats(nodesStatsRequest, new RestResponseListener<NodesStatsResponse>(channel) { client.admin().cluster().nodesStats(nodesStatsRequest, new RestResponseListener<NodesStatsResponse>(channel) {
@Override @Override
public RestResponse buildResponse(NodesStatsResponse nodesStatsResponse) throws Exception { public RestResponse buildResponse(NodesStatsResponse nodesStatsResponse) throws Exception {
@ -183,6 +184,9 @@ public class RestNodesAction extends AbstractCatAction {
table.addCell("refresh.total", "alias:rto,refreshTotal;default:false;text-align:right;desc:total refreshes"); table.addCell("refresh.total", "alias:rto,refreshTotal;default:false;text-align:right;desc:total refreshes");
table.addCell("refresh.time", "alias:rti,refreshTime;default:false;text-align:right;desc:time spent in refreshes"); table.addCell("refresh.time", "alias:rti,refreshTime;default:false;text-align:right;desc:time spent in refreshes");
table.addCell("script.compilations", "alias:scrcc,scriptCompilations;default:false;text-align:right;desc:script compilations");
table.addCell("script.cache_evictions", "alias:scrce,scriptCacheEvictions;default:false;text-align:right;desc:script cache evictions");
table.addCell("search.fetch_current", "alias:sfc,searchFetchCurrent;default:false;text-align:right;desc:current fetch phase ops"); table.addCell("search.fetch_current", "alias:sfc,searchFetchCurrent;default:false;text-align:right;desc:current fetch phase ops");
table.addCell("search.fetch_time", "alias:sfti,searchFetchTime;default:false;text-align:right;desc:time spent in fetch phase"); table.addCell("search.fetch_time", "alias:sfti,searchFetchTime;default:false;text-align:right;desc:time spent in fetch phase");
table.addCell("search.fetch_total", "alias:sfto,searchFetchTotal;default:false;text-align:right;desc:total fetch ops"); table.addCell("search.fetch_total", "alias:sfto,searchFetchTotal;default:false;text-align:right;desc:total fetch ops");
@ -317,6 +321,10 @@ public class RestNodesAction extends AbstractCatAction {
table.addCell(refreshStats == null ? null : refreshStats.getTotal()); table.addCell(refreshStats == null ? null : refreshStats.getTotal());
table.addCell(refreshStats == null ? null : refreshStats.getTotalTime()); table.addCell(refreshStats == null ? null : refreshStats.getTotalTime());
ScriptStats scriptStats = stats == null ? null : stats.getScriptStats();
table.addCell(scriptStats == null ? null : scriptStats.getCompilations());
table.addCell(scriptStats == null ? null : scriptStats.getCacheEvictions());
SearchStats searchStats = indicesStats == null ? null : indicesStats.getSearch(); SearchStats searchStats = indicesStats == null ? null : indicesStats.getSearch();
table.addCell(searchStats == null ? null : searchStats.getTotal().getFetchCurrent()); table.addCell(searchStats == null ? null : searchStats.getTotal().getFetchCurrent());
table.addCell(searchStats == null ? null : searchStats.getTotal().getFetchTime()); table.addCell(searchStats == null ? null : searchStats.getTotal().getFetchTime());

View File

@ -0,0 +1,39 @@
/*
* 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.script;
import org.elasticsearch.common.metrics.CounterMetric;
public class ScriptMetrics {
final CounterMetric compilationsMetric = new CounterMetric();
final CounterMetric cacheEvictionsMetric = new CounterMetric();
public ScriptStats stats() {
return new ScriptStats(compilationsMetric.count(), cacheEvictionsMetric.count());
}
public void onCompilation() {
compilationsMetric.inc();
}
public void onCacheEviction() {
cacheEvictionsMetric.inc();
}
}

View File

@ -84,6 +84,7 @@ public class ScriptService extends AbstractComponent implements Closeable {
public static final String DEFAULT_SCRIPTING_LANGUAGE_SETTING = "script.default_lang"; public static final String DEFAULT_SCRIPTING_LANGUAGE_SETTING = "script.default_lang";
public static final String SCRIPT_CACHE_SIZE_SETTING = "script.cache.max_size"; public static final String SCRIPT_CACHE_SIZE_SETTING = "script.cache.max_size";
public static final int SCRIPT_CACHE_SIZE_DEFAULT = 100;
public static final String SCRIPT_CACHE_EXPIRE_SETTING = "script.cache.expire"; public static final String SCRIPT_CACHE_EXPIRE_SETTING = "script.cache.expire";
public static final String SCRIPT_INDEX = ".scripts"; public static final String SCRIPT_INDEX = ".scripts";
public static final String DEFAULT_LANG = GroovyScriptEngineService.NAME; public static final String DEFAULT_LANG = GroovyScriptEngineService.NAME;
@ -107,6 +108,8 @@ public class ScriptService extends AbstractComponent implements Closeable {
private Client client = null; private Client client = null;
private final ScriptMetrics scriptMetrics = new ScriptMetrics();
/** /**
* @deprecated Use {@link org.elasticsearch.script.Script.ScriptField} instead. This should be removed in * @deprecated Use {@link org.elasticsearch.script.Script.ScriptField} instead. This should be removed in
* 2.0 * 2.0
@ -140,7 +143,7 @@ public class ScriptService extends AbstractComponent implements Closeable {
this.scriptEngines = scriptEngines; this.scriptEngines = scriptEngines;
this.scriptContextRegistry = scriptContextRegistry; this.scriptContextRegistry = scriptContextRegistry;
int cacheMaxSize = settings.getAsInt(SCRIPT_CACHE_SIZE_SETTING, 100); int cacheMaxSize = settings.getAsInt(SCRIPT_CACHE_SIZE_SETTING, SCRIPT_CACHE_SIZE_DEFAULT);
TimeValue cacheExpire = settings.getAsTime(SCRIPT_CACHE_EXPIRE_SETTING, null); TimeValue cacheExpire = settings.getAsTime(SCRIPT_CACHE_EXPIRE_SETTING, null);
logger.debug("using script cache with max_size [{}], expire [{}]", cacheMaxSize, cacheExpire); logger.debug("using script cache with max_size [{}], expire [{}]", cacheMaxSize, cacheExpire);
@ -306,6 +309,7 @@ public class ScriptService extends AbstractComponent implements Closeable {
//Since the cache key is the script content itself we don't need to //Since the cache key is the script content itself we don't need to
//invalidate/check the cache if an indexed script changes. //invalidate/check the cache if an indexed script changes.
scriptMetrics.onCompilation();
cache.put(cacheKey, compiledScript); cache.put(cacheKey, compiledScript);
} }
@ -474,6 +478,10 @@ public class ScriptService extends AbstractComponent implements Closeable {
} }
} }
public ScriptStats stats() {
return scriptMetrics.stats();
}
/** /**
* A small listener for the script cache that calls each * A small listener for the script cache that calls each
* {@code ScriptEngineService}'s {@code scriptRemoved} method when the * {@code ScriptEngineService}'s {@code scriptRemoved} method when the
@ -486,6 +494,7 @@ public class ScriptService extends AbstractComponent implements Closeable {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("notifying script services of script removal due to: [{}]", notification.getCause()); logger.debug("notifying script services of script removal due to: [{}]", notification.getCause());
} }
scriptMetrics.onCacheEviction();
for (ScriptEngineService service : scriptEngines) { for (ScriptEngineService service : scriptEngines) {
try { try {
service.scriptRemoved(notification.getValue()); service.scriptRemoved(notification.getValue());
@ -532,6 +541,7 @@ public class ScriptService extends AbstractComponent implements Closeable {
String script = Streams.copyToString(reader); String script = Streams.copyToString(reader);
String cacheKey = getCacheKey(engineService, scriptNameExt.v1(), null); String cacheKey = getCacheKey(engineService, scriptNameExt.v1(), null);
staticCache.put(cacheKey, new CompiledScript(ScriptType.FILE, scriptNameExt.v1(), engineService.types()[0], engineService.compile(script))); staticCache.put(cacheKey, new CompiledScript(ScriptType.FILE, scriptNameExt.v1(), engineService.types()[0], engineService.compile(script)));
scriptMetrics.onCompilation();
} }
} else { } else {
logger.warn("skipping compile of script file [{}] as all scripted operations are disabled for file scripts", file.toAbsolutePath()); logger.warn("skipping compile of script file [{}] as all scripted operations are disabled for file scripts", file.toAbsolutePath());

View File

@ -0,0 +1,82 @@
/*
* 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.script;
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.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentBuilderString;
import java.io.IOException;
public class ScriptStats implements Streamable, ToXContent {
private long compilations;
private long cacheEvictions;
public ScriptStats() {
}
public ScriptStats(long compilations, long cacheEvictions) {
this.compilations = compilations;
this.cacheEvictions = cacheEvictions;
}
public void add(ScriptStats stats) {
this.compilations += stats.compilations;
this.cacheEvictions += stats.cacheEvictions;
}
public long getCompilations() {
return compilations;
}
public long getCacheEvictions() {
return cacheEvictions;
}
@Override
public void readFrom(StreamInput in) throws IOException {
compilations = in.readVLong();
cacheEvictions = in.readVLong();
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVLong(compilations);
out.writeVLong(cacheEvictions);
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(Fields.SCRIPT_STATS);
builder.field(Fields.COMPILATIONS, getCompilations());
builder.field(Fields.CACHE_EVICTIONS, getCacheEvictions());
builder.endObject();
return builder;
}
static final class Fields {
static final XContentBuilderString SCRIPT_STATS = new XContentBuilderString("script");
static final XContentBuilderString COMPILATIONS = new XContentBuilderString("compilations");
static final XContentBuilderString CACHE_EVICTIONS = new XContentBuilderString("cache_evictions");
}
}

View File

@ -179,7 +179,8 @@ public class MockDiskUsagesIT extends ESIntegTestCase {
System.currentTimeMillis(), System.currentTimeMillis(),
null, null, null, null, null, null, null, null, null, null,
fsInfo, fsInfo,
null, null, null); null, null, null,
null);
} }
/** /**

View File

@ -387,6 +387,73 @@ public class ScriptServiceTests extends ESTestCase {
} }
} }
@Test
public void testCompileCountedInCompilationStats() throws IOException {
buildScriptService(Settings.EMPTY);
scriptService.compile(new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts));
assertEquals(1L, scriptService.stats().getCompilations());
}
@Test
public void testExecutableCountedInCompilationStats() throws IOException {
buildScriptService(Settings.EMPTY);
scriptService.executable(new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts));
assertEquals(1L, scriptService.stats().getCompilations());
}
@Test
public void testSearchCountedInCompilationStats() throws IOException {
buildScriptService(Settings.EMPTY);
scriptService.search(null, new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts));
assertEquals(1L, scriptService.stats().getCompilations());
}
@Test
public void testMultipleCompilationsCountedInCompilationStats() throws IOException {
buildScriptService(Settings.EMPTY);
int numberOfCompilations = randomIntBetween(1, 1024);
for (int i = 0; i < numberOfCompilations; i++) {
scriptService.compile(new Script(String.format("%d+%d", i, i), ScriptType.INLINE, "test", null), randomFrom(scriptContexts));
}
assertEquals(numberOfCompilations, scriptService.stats().getCompilations());
}
@Test
public void testCompilationStatsOnCacheHit() throws IOException {
Settings.Builder builder = Settings.builder();
builder.put(ScriptService.SCRIPT_CACHE_SIZE_SETTING, 1);
buildScriptService(builder.build());
scriptService.executable(new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts));
scriptService.executable(new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts));
assertEquals(1L, scriptService.stats().getCompilations());
}
@Test
public void testFileScriptCountedInCompilationStats() throws IOException {
buildScriptService(Settings.EMPTY);
createFileScripts("test");
scriptService.compile(new Script("file_script", ScriptType.FILE, "test", null), randomFrom(scriptContexts));
assertEquals(1L, scriptService.stats().getCompilations());
}
@Test
public void testIndexedScriptCountedInCompilationStats() throws IOException {
buildScriptService(Settings.EMPTY);
scriptService.compile(new Script("script", ScriptType.INDEXED, "test", null), randomFrom(scriptContexts));
assertEquals(1L, scriptService.stats().getCompilations());
}
@Test
public void testCacheEvictionCountedInCacheEvictionsStats() throws IOException {
Settings.Builder builder = Settings.builder();
builder.put(ScriptService.SCRIPT_CACHE_SIZE_SETTING, 1);
buildScriptService(builder.build());
scriptService.executable(new Script("1+1", ScriptType.INLINE, "test", null), randomFrom(scriptContexts));
scriptService.executable(new Script("2+2", ScriptType.INLINE, "test", null), randomFrom(scriptContexts));
assertEquals(2L, scriptService.stats().getCompilations());
assertEquals(1L, scriptService.stats().getCacheEvictions());
}
private void createFileScripts(String... langs) throws IOException { private void createFileScripts(String... langs) throws IOException {
for (String lang : langs) { for (String lang : langs) {
Path scriptPath = scriptsFilePath.resolve("file_script." + lang); Path scriptPath = scriptsFilePath.resolve("file_script." + lang);

View File

@ -1855,7 +1855,7 @@ public final class InternalTestCluster extends TestCluster {
} }
NodeService nodeService = getInstanceFromNode(NodeService.class, nodeAndClient.node); NodeService nodeService = getInstanceFromNode(NodeService.class, nodeAndClient.node);
NodeStats stats = nodeService.stats(CommonStatsFlags.ALL, false, false, false, false, false, false, false, false, false); NodeStats stats = nodeService.stats(CommonStatsFlags.ALL, false, false, false, false, false, false, false, false, false, false);
assertThat("Fielddata size must be 0 on node: " + stats.getNode(), stats.getIndices().getFieldData().getMemorySizeInBytes(), equalTo(0l)); assertThat("Fielddata size must be 0 on node: " + stats.getNode(), stats.getIndices().getFieldData().getMemorySizeInBytes(), equalTo(0l));
assertThat("Query cache size must be 0 on node: " + stats.getNode(), stats.getIndices().getQueryCache().getMemorySizeInBytes(), equalTo(0l)); assertThat("Query cache size must be 0 on node: " + stats.getNode(), stats.getIndices().getQueryCache().getMemorySizeInBytes(), equalTo(0l));
assertThat("FixedBitSet cache size must be 0 on node: " + stats.getNode(), stats.getIndices().getSegments().getBitsetMemoryInBytes(), equalTo(0l)); assertThat("FixedBitSet cache size must be 0 on node: " + stats.getNode(), stats.getIndices().getSegments().getBitsetMemoryInBytes(), equalTo(0l));

View File

@ -168,6 +168,8 @@ percolating |0s
|`percolate.total` |`pto`, `percolateTotal` |No |Total percolations |0 |`percolate.total` |`pto`, `percolateTotal` |No |Total percolations |0
|`refresh.total` |`rto`, `refreshTotal` |No |Number of refreshes |16 |`refresh.total` |`rto`, `refreshTotal` |No |Number of refreshes |16
|`refresh.time` |`rti`, `refreshTime` |No |Time spent in refreshes |91ms |`refresh.time` |`rti`, `refreshTime` |No |Time spent in refreshes |91ms
|`script.compilations` |`scrcc`, `scriptCompilations` |No |Total script compilations |17
|`script.cache_evictions` |`scrce`, `scriptCacheEvictions` |No |Total compiled scripts evicted from cache |6
|`search.fetch_current` |`sfc`, `searchFetchCurrent` |No |Current fetch |`search.fetch_current` |`sfc`, `searchFetchCurrent` |No |Current fetch
phase operations |0 phase operations |0
|`search.fetch_time` |`sfti`, `searchFetchTime` |No |Time spent in fetch |`search.fetch_time` |`sfti`, `searchFetchTime` |No |Time spent in fetch