blob: 356e865427dfca6e9a3bbcc23e1af0b4c954a298 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.apache.solr.handler.admin;
import java.util.Map;
import com.codahale.metrics.Counter;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.response.SolrQueryResponse;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* Test for {@link MetricsHandler}
*/
public class MetricsHandlerTest extends SolrTestCaseJ4 {
@BeforeClass
public static void beforeClass() throws Exception {
initCore("solrconfig-minimal.xml", "schema.xml");
h.getCoreContainer().waitForLoadingCoresToFinish(30000);
// manually register & seed some metrics in solr.jvm and solr.jetty for testing via handler
// (use "solrtest_" prefix just in case the jvm or jetty ads a "foo" metric at some point)
Counter c = h.getCoreContainer().getMetricManager().counter(null, "solr.jvm", "solrtest_foo");
c.inc();
c = h.getCoreContainer().getMetricManager().counter(null, "solr.jetty", "solrtest_foo");
c.inc(2);
// test escapes
c = h.getCoreContainer().getMetricManager().counter(null, "solr.jetty", "solrtest_foo:bar");
c.inc(3);
}
@AfterClass
public static void cleanupMetrics() throws Exception {
if (null != h) {
h.getCoreContainer().getMetricManager().registry("solr.jvm").remove("solrtest_foo");
h.getCoreContainer().getMetricManager().registry("solr.jetty").remove("solrtest_foo");
h.getCoreContainer().getMetricManager().registry("solr.jetty").remove("solrtest_foo:bar");
}
}
@Test
public void test() throws Exception {
MetricsHandler handler = new MetricsHandler(h.getCoreContainer());
SolrQueryResponse resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", MetricsHandler.COMPACT_PARAM, "false", CommonParams.WT, "json"), resp);
NamedList values = resp.getValues();
assertNotNull(values.get("metrics"));
values = (NamedList) values.get("metrics");
NamedList nl = (NamedList) values.get("solr.core.collection1");
assertNotNull(nl);
Object o = nl.get("SEARCHER.new.errors");
assertNotNull(o); // counter type
assertTrue(o instanceof Map);
// response wasn't serialized so we get here whatever MetricUtils produced instead of NamedList
assertNotNull(((Map) o).get("count"));
assertEquals(0L, ((Map) nl.get("SEARCHER.new.errors")).get("count"));
nl = (NamedList) values.get("solr.node");
assertNotNull(nl.get("CONTAINER.cores.loaded")); // int gauge
assertEquals(1, ((Map) nl.get("CONTAINER.cores.loaded")).get("value"));
assertNotNull(nl.get("ADMIN./admin/authorization.clientErrors")); // timer type
assertEquals(5, ((Map) nl.get("ADMIN./admin/authorization.clientErrors")).size());
resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", MetricsHandler.COMPACT_PARAM, "false", CommonParams.WT, "json", "group", "jvm,jetty"), resp);
values = resp.getValues();
assertNotNull(values.get("metrics"));
values = (NamedList) values.get("metrics");
assertEquals(2, values.size());
assertNotNull(values.get("solr.jetty"));
assertNotNull(values.get("solr.jvm"));
resp = new SolrQueryResponse();
// "collection" works too, because it's a prefix for "collection1"
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", MetricsHandler.COMPACT_PARAM, "false", CommonParams.WT, "json", "registry", "solr.core.collection,solr.jvm"), resp);
values = resp.getValues();
assertNotNull(values.get("metrics"));
values = (NamedList) values.get("metrics");
assertEquals(2, values.size());
assertNotNull(values.get("solr.core.collection1"));
assertNotNull(values.get("solr.jvm"));
resp = new SolrQueryResponse();
// "collection" works too, because it's a prefix for "collection1"
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", MetricsHandler.COMPACT_PARAM, "false", CommonParams.WT, "json", "registry", "solr.core.collection", "registry", "solr.jvm"), resp);
values = resp.getValues();
assertNotNull(values.get("metrics"));
values = (NamedList) values.get("metrics");
assertEquals(2, values.size());
assertNotNull(values.get("solr.core.collection1"));
assertNotNull(values.get("solr.jvm"));
resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", MetricsHandler.COMPACT_PARAM, "false", CommonParams.WT, "json", "group", "jvm,jetty"), resp);
values = resp.getValues();
assertNotNull(values.get("metrics"));
values = (NamedList) values.get("metrics");
assertEquals(2, values.size());
assertNotNull(values.get("solr.jetty"));
assertNotNull(values.get("solr.jvm"));
resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", MetricsHandler.COMPACT_PARAM, "false", CommonParams.WT, "json", "group", "jvm", "group", "jetty"), resp);
values = resp.getValues();
assertNotNull(values.get("metrics"));
values = (NamedList) values.get("metrics");
assertEquals(2, values.size());
assertNotNull(values.get("solr.jetty"));
assertNotNull(values.get("solr.jvm"));
resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", MetricsHandler.COMPACT_PARAM, "false", CommonParams.WT, "json", "group", "node", "type", "counter"), resp);
values = resp.getValues();
assertNotNull(values.get("metrics"));
values = (NamedList) values.get("metrics");
assertEquals(1, values.size());
values = (NamedList) values.get("solr.node");
assertNotNull(values);
assertNull(values.get("ADMIN./admin/authorization.errors")); // this is a timer node
resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", MetricsHandler.COMPACT_PARAM, "false", CommonParams.WT, "json", "prefix", "CONTAINER.cores,CONTAINER.threadPool"), resp);
values = resp.getValues();
assertNotNull(values.get("metrics"));
values = (NamedList) values.get("metrics");
assertEquals(1, values.size());
assertEquals(13, ((NamedList) values.get("solr.node")).size());
assertNotNull(values.get("solr.node"));
values = (NamedList) values.get("solr.node");
assertNotNull(values.get("CONTAINER.cores.lazy")); // this is a gauge node
assertNotNull(values.get("CONTAINER.threadPool.coreContainerWorkExecutor.completed"));
assertNotNull(values.get("CONTAINER.threadPool.coreLoadExecutor.completed"));
resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", MetricsHandler.COMPACT_PARAM, "false", CommonParams.WT, "json", "prefix", "CONTAINER.cores", "regex", "C.*thread.*completed"), resp);
values = resp.getValues();
assertNotNull(values.get("metrics"));
values = (NamedList) values.get("metrics");
assertNotNull(values.get("solr.node"));
values = (NamedList) values.get("solr.node");
assertEquals(5, values.size());
assertNotNull(values.get("CONTAINER.threadPool.coreContainerWorkExecutor.completed"));
assertNotNull(values.get("CONTAINER.threadPool.coreLoadExecutor.completed"));
resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json", "prefix", "CACHE.core.fieldCache", "property", "entries_count", MetricsHandler.COMPACT_PARAM, "true"), resp);
values = resp.getValues();
assertNotNull(values.get("metrics"));
values = (NamedList) values.get("metrics");
assertNotNull(values.get("solr.core.collection1"));
values = (NamedList) values.get("solr.core.collection1");
assertEquals(1, values.size());
Map m = (Map) values.get("CACHE.core.fieldCache");
assertNotNull(m);
assertNotNull(m.get("entries_count"));
resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", MetricsHandler.COMPACT_PARAM, "false", CommonParams.WT, "json", "group", "jvm", "prefix", "CONTAINER.cores"), resp);
values = resp.getValues();
assertNotNull(values.get("metrics"));
values = (NamedList) values.get("metrics");
assertEquals(0, values.size());
resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", MetricsHandler.COMPACT_PARAM, "false", CommonParams.WT, "json", "group", "node", "type", "timer", "prefix", "CONTAINER.cores"), resp);
values = resp.getValues();
assertNotNull(values.get("metrics"));
SimpleOrderedMap map = (SimpleOrderedMap) values.get("metrics");
assertEquals(0, map.size());
}
@Test
public void testCompact() throws Exception {
MetricsHandler handler = new MetricsHandler(h.getCoreContainer());
SolrQueryResponse resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json", MetricsHandler.COMPACT_PARAM, "true"), resp);
NamedList values = resp.getValues();
assertNotNull(values.get("metrics"));
values = (NamedList) values.get("metrics");
NamedList nl = (NamedList) values.get("solr.core.collection1");
assertNotNull(nl);
Object o = nl.get("SEARCHER.new.errors");
assertNotNull(o); // counter type
assertTrue(o instanceof Number);
}
@Test
public void testPropertyFilter() throws Exception {
assertQ(req("*:*"), "//result[@numFound='0']");
MetricsHandler handler = new MetricsHandler(h.getCoreContainer());
SolrQueryResponse resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json",
MetricsHandler.COMPACT_PARAM, "true", "group", "core", "prefix", "CACHE.searcher"), resp);
NamedList values = resp.getValues();
assertNotNull(values.get("metrics"));
values = (NamedList) values.get("metrics");
NamedList nl = (NamedList) values.get("solr.core.collection1");
assertNotNull(nl);
assertTrue(nl.size() > 0);
nl.forEach((k, v) -> {
assertTrue(v instanceof Map);
Map map = (Map) v;
assertTrue(map.size() > 2);
});
resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json",
MetricsHandler.COMPACT_PARAM, "true", "group", "core", "prefix", "CACHE.searcher",
"property", "inserts", "property", "size"), resp);
values = resp.getValues();
values = (NamedList) values.get("metrics");
nl = (NamedList) values.get("solr.core.collection1");
assertNotNull(nl);
assertTrue(nl.size() > 0);
nl.forEach((k, v) -> {
assertTrue(v instanceof Map);
Map map = (Map) v;
assertEquals(2, map.size());
assertNotNull(map.get("inserts"));
assertNotNull(map.get("size"));
});
}
@Test
public void testKeyMetrics() throws Exception {
MetricsHandler handler = new MetricsHandler(h.getCoreContainer());
String key1 = "solr.core.collection1:CACHE.core.fieldCache";
SolrQueryResponse resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json",
MetricsHandler.KEY_PARAM, key1), resp);
NamedList values = resp.getValues();
Object val = values.findRecursive("metrics", key1);
assertNotNull(val);
assertTrue(val instanceof Map);
assertTrue(((Map) val).size() >= 2);
String key2 = "solr.core.collection1:CACHE.core.fieldCache:entries_count";
resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json",
MetricsHandler.KEY_PARAM, key2), resp);
values = resp.getValues();
val = values.findRecursive("metrics", key2);
assertNotNull(val);
assertTrue(val instanceof Number);
String key3 = "solr.jetty:solrtest_foo\\:bar";
resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json",
MetricsHandler.KEY_PARAM, key3), resp);
values = resp.getValues();
val = values.findRecursive("metrics", key3);
assertNotNull(val);
assertTrue(val instanceof Number);
assertEquals(3, ((Number) val).intValue());
// test multiple keys
resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json",
MetricsHandler.KEY_PARAM, key1, MetricsHandler.KEY_PARAM, key2, MetricsHandler.KEY_PARAM, key3), resp);
values = resp.getValues();
val = values.findRecursive("metrics", key1);
assertNotNull(val);
val = values.findRecursive("metrics", key2);
assertNotNull(val);
val = values.findRecursive("metrics", key3);
assertNotNull(val);
String key4 = "solr.core.collection1:QUERY./select.requestTimes:1minRate";
resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json",
MetricsHandler.KEY_PARAM, key4), resp);
values = resp.getValues();
val = values.findRecursive("metrics", key4);
assertNotNull(val);
assertTrue(val instanceof Number);
// test errors
// invalid keys
resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json",
MetricsHandler.KEY_PARAM, "foo", MetricsHandler.KEY_PARAM, "foo:bar:baz:xyz"), resp);
values = resp.getValues();
NamedList metrics = (NamedList) values.get("metrics");
assertEquals(0, metrics.size());
assertNotNull(values.findRecursive("errors", "foo"));
assertNotNull(values.findRecursive("errors", "foo:bar:baz:xyz"));
// unknown registry
resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json",
MetricsHandler.KEY_PARAM, "foo:bar:baz"), resp);
values = resp.getValues();
metrics = (NamedList) values.get("metrics");
assertEquals(0, metrics.size());
assertNotNull(values.findRecursive("errors", "foo:bar:baz"));
// unknown metric
resp = new SolrQueryResponse();
handler.handleRequestBody(req(CommonParams.QT, "/admin/metrics", CommonParams.WT, "json",
MetricsHandler.KEY_PARAM, "solr.jetty:unknown:baz"), resp);
values = resp.getValues();
metrics = (NamedList) values.get("metrics");
assertEquals(0, metrics.size());
assertNotNull(values.findRecursive("errors", "solr.jetty:unknown:baz"));
}
}