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); } } }