package act.metric;
/*-
* #%L
* ACT Framework
* %%
* Copyright (C) 2014 - 2017 ActFramework
* %%
* Licensed 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.
* #L%
*/
import act.Act;
import act.cli.CliContext;
import act.cli.Command;
import act.cli.Optional;
import act.util.PropertySpec;
import org.osgl.$;
import org.osgl.util.C;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;
/**
* Console app to access actframework metric data
*/
public class MetricAdmin {
@Command(name = "act.metric.sync")
public void updateMetricDataSync(
@Optional("pause sync") boolean pause,
CliContext context
) {
Act.metricPlugin().enableDataSync(!pause);
context.println(pause ? "metric data sync paused." : "metric data sync enabled");
}
@Command(name = "act.metric.counter.list", help = "list all counters")
@PropertySpec("name,count")
public Object getCounters(
@Optional("specify maximum items returned") Integer limit,
@Optional("display in tree view") boolean tree,
@Optional("specify depth of levels") Integer depth,
@Optional("specify search string") String q,
@Optional("including classloading metric") boolean classLoading
) {
List<MetricInfo> list = Act.metricPlugin().metricStore().timers();
if (!classLoading) {
list = withoutClassLoading(list);
}
return process(list, limit, q, tree, depth, MetricInfo.Comparator.COUNTER, MetricInfoTree.COUNTER);
}
@Command(name = "act.metric.timer.list", help = "list all timers")
@PropertySpec("name,accumulated,count,avg")
public Object getTimers(
@Optional("specify maximum items returned") Integer limit,
@Optional("display in tree view") boolean tree,
@Optional("specify depth of levels") Integer depth,
@Optional("specify search string") String q,
@Optional("including classloading metric") boolean classLoading
) {
List<MetricInfo> list = Act.metricPlugin().metricStore().timers();
if (!classLoading) {
list = withoutClassLoading(list);
}
return process(list, limit, q, tree, depth, MetricInfo.Comparator.TIMER, MetricInfoTree.TIMER);
}
private List<MetricInfo> withoutClassLoading(List<MetricInfo> list) {
return C.list(list).remove(new $.Predicate<MetricInfo>() {
@Override
public boolean test(MetricInfo metricInfo) {
return metricInfo.getName().startsWith(MetricInfo.CLASS_LOADING);
}
});
}
@Command(name = "act.metric.clear", help = "clear existing metric data")
public void clearMetricData() {
Act.metricPlugin().metricStore().clear();
}
private Object process(List<MetricInfo> list, Integer max, final String q,
boolean asTree, final Integer level, Comparator<MetricInfo> comp,
MetricInfoTree.NodeDecorator decorator) {
$.Predicate<String> filter = $.F.yes();
if (null != level) {
filter = (new $.Predicate<String>() {
@Override
public boolean test(String path) {
String[] sa = path.split(Metric.PATH_SEPARATOR);
return sa.length <= level;
}
});
}
if (null != q) {
final Pattern p = Pattern.compile(q);
filter = filter.and(new $.Predicate<String>() {
@Override
public boolean test(String path) {
return path.contains(q) || p.matcher(path).matches();
}
});
}
final $.Predicate<String> theFilter = filter;
if (!asTree) {
list = C.list(list).filter(new $.Predicate<MetricInfo>() {
@Override
public boolean test(MetricInfo metricInfo) {
return theFilter.test(metricInfo.getName());
}
});
if (null == max) {
return C.list(list).sorted(comp);
}
return C.list(list).take(max).sorted(comp);
} else {
MetricInfoTree tree = new MetricInfoTree(list, theFilter);
return tree.root(decorator);
}
}
}