Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jgroups.util.Metrics Maven / Gradle / Ivy
package org.jgroups.util;
import org.jgroups.JChannel;
import org.jgroups.annotations.ManagedAttribute;
import org.jgroups.annotations.Property;
import org.jgroups.jmx.ResourceDMBean;
import org.jgroups.stack.Protocol;
import javax.management.MBeanAttributeInfo;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.function.Predicate;
import java.util.function.Supplier;
import static org.jgroups.conf.AttributeType.BYTES;
import static org.jgroups.conf.AttributeType.SCALAR;
/**
* Extracts all attributes and methods annotated with {@link org.jgroups.annotations.ManagedAttribute} and returns them
* as a map of names associated with [getter-method/description tuples]. E.g. for an attribute called foo, a method
* foo() or getFoo() is searched for.
* @author Bela Ban
* @since 5.4, 5.3.6
*/
public class Metrics {
protected JChannel ch;
public static final Predicate IS_NUMBER=obj -> {
if(obj instanceof Field)
return isNumberAndScalar(obj, ((Field)obj).getType());
if(obj instanceof Method) {
Method m=(Method)obj;
return isNumberAndScalar(obj, m.getReturnType());
}
return false;
};
public static class Entry {
protected final AccessibleObject type; // Field or Method
protected final String description;
protected final Supplier supplier;
protected Entry(AccessibleObject type, String description, Supplier method) {
this.type=type;
this.description=description;
this.supplier=method;
}
public AccessibleObject type() {return type;}
public String description() {return description;}
public Supplier supplier() {return supplier;}
@Override
public String toString() {
return String.format(" %s [%s]", supplier.get(), description);
}
}
public static Map>> extract(JChannel ch) {
return extract(ch, null);
}
public static Map>> extract(JChannel ch, Predicate filter) {
Map>> map=new LinkedHashMap<>();
for(Protocol p: ch.stack().getProtocols())
map.put(p.getName(), extract(p, filter));
return map;
}
public static Map> extract(Protocol p) {
return extract(p, null);
}
public static Map> extract(Protocol p, Predicate filter) {
Map> map=new TreeMap<>();
ResourceDMBean dm=new ResourceDMBean(p, filter);
dm.forAllAttributes((k,v) -> {
MBeanAttributeInfo info=v.info();
String descr=info != null? info.getDescription() : "n/a";
Supplier getter=() -> {
try {
return v.getter() != null? v.getter().invoke(null) : null;
}
catch(Exception e) {
System.err.printf("failed getting value for %s\n", k);
return null;
}
};
map.put(k, new Entry<>(v.type(), descr, getter));
});
return map;
}
protected void start(boolean numeric) throws Exception {
ch=new JChannel().connect("bla").name("X");
Map>> m=extract(ch, numeric? IS_NUMBER : null);
if(numeric) {
Map>> map=convert(m);
print(map);
}
else
print(m);
Util.close(ch);
}
protected static void print(Map>> map) {
for(Map.Entry>> e: map.entrySet()) {
System.out.printf("\n%s:\n---------------\n", e.getKey());
for(Map.Entry> e2: e.getValue().entrySet()) {
Entry entry=e2.getValue();
Supplier s=entry.supplier();
if(s != null)
System.out.printf(" %s: %s\n", e2.getKey(), s.get());
}
}
}
public static Map>> convert(Map>> m) {
Map>> retval=new LinkedHashMap<>();
for(Map.Entry>> entry: m.entrySet()) {
Map> m1=entry.getValue();
Map> m2=convertProtocol(m1);
retval.put(entry.getKey(), m2);
}
return retval;
}
public static Map> convertProtocol(Map> m) {
Map> retval=new TreeMap<>();
for(Map.Entry> e: m.entrySet()) {
Entry en=e.getValue();
AccessibleObject type=en.type();
Class extends Object> cl=(type instanceof Field)? ((Field)type).getType() : ((Method)type).getReturnType();
if(Number.class.isAssignableFrom(cl)) {
Entry tmp=new Entry<>(en.type(), en.description(), () -> (Number)en.supplier().get());
retval.put(e.getKey(), tmp);
continue;
}
if(int.class.isAssignableFrom(cl)) {
Entry tmp=new Entry<>(en.type(), en.description(), () -> (Integer)en.supplier().get());
retval.put(e.getKey(), tmp);
continue;
}
if(long.class.isAssignableFrom(cl)) {
Entry tmp=new Entry<>(en.type(), en.description(), () -> (Long)en.supplier().get());
retval.put(e.getKey(), tmp);
continue;
}
if(double.class.isAssignableFrom(cl)) {
Entry tmp=new Entry<>(en.type(), en.description(), () -> (Double)en.supplier().get());
retval.put(e.getKey(), tmp);
continue;
}
if(float.class.isAssignableFrom(cl)) {
Entry tmp=new Entry<>(en.type(), en.description(), () -> (Float)en.supplier().get());
retval.put(e.getKey(), tmp);
continue;
}
if(AverageMinMax.class.isAssignableFrom(cl)) {
Entry tmp=new Entry<>(en.type(), en.description(), () -> ((AverageMinMax)en.supplier().get()).min());
retval.put(e.getKey() + ".min", tmp);
tmp=new Entry<>(en.type(), en.description(), () -> ((AverageMinMax)en.supplier().get()).average());
retval.put(e.getKey(), tmp);
tmp=new Entry<>(en.type(), en.description(), () -> ((AverageMinMax)en.supplier().get()).max());
retval.put(e.getKey() + ".max", tmp);
continue;
}
if(Average.class.isAssignableFrom(cl)) {
Entry tmp=new Entry<>(en.type(), en.description(), () -> ((Average)en.supplier()).average());
retval.put(e.getKey(), tmp);
}
}
return retval;
}
protected static boolean isNumberAndScalar(AccessibleObject obj, Class> cl) {
if(cl.equals(float.class) || cl.equals(Float.class) || cl.equals(double.class) || cl.equals(Double.class)
|| Average.class.isAssignableFrom(cl))
return true;
boolean is_number=cl.equals(int.class) || cl.equals(Integer.class) || cl.equals(long.class) || cl.equals(Long.class)
|| Number.class.isAssignableFrom(cl);
return is_number && isScalar(obj);
}
protected static boolean isScalar(AccessibleObject obj) {
ManagedAttribute annotation=obj.getAnnotation(ManagedAttribute.class);
if(annotation != null && (annotation.type() == SCALAR || annotation.type() == BYTES))
return true;
Property prop=obj.getAnnotation(Property.class);
return prop != null && (prop.type() == SCALAR || prop.type() == BYTES);
}
public static void main(String[] args) throws Throwable {
boolean numeric=args.length > 0 && Boolean.parseBoolean(args[0]);
new Metrics().start(numeric);
}
}