cdc.perfs.api.RuntimeManager Maven / Gradle / Ivy
package cdc.perfs.api;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.function.Supplier;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import cdc.util.lang.InstallationException;
import cdc.util.lang.Procedure;
/**
* Main API used to create sources, probes and measures.
*
* @author Damien Carbonne
*
*/
public final class RuntimeManager {
private static final Logger LOGGER = LogManager.getLogger(RuntimeManager.class);
private static RuntimeService service;
private RuntimeManager() {
}
private static RuntimeService getRuntimeService() {
if (service == null) {
try {
@SuppressWarnings("unchecked")
final Class extends RuntimeService> cls = (Class extends RuntimeService>) Class.forName("cdc.perfs.core.runtime.RuntimeEnvironment");
final Method m = cls.getMethod("getInstance");
service = (RuntimeService) m.invoke(null);
} catch (final ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
LOGGER.catching(e);
throw new InstallationException("Failed to retrieve RuntimeService implementation", e);
}
}
return service;
}
/**
* Returns the shared source that has a given name.
*
* If a source with that name already exists, then it returns it.
* Otherwise, creates a new Source and returns it.
*
* @param name Name of the source.
* @return The shared source that is named name.
*/
public static Source getSource(String name) {
return getRuntimeService().getSource(name);
}
/**
* Returns the source associated to a class.
*
* Equivalent to getSource(klass.getCanonicalName())
*
* @param cls The class whose name will be associated to source.
* @return getSource(cls.getCanonicalName())
*/
public static Source getSource(Class> cls) {
return getRuntimeService().getSource(cls);
}
/**
* Creates a probe that can be used to create measures at a given level and
* associated to a source.
*
* @param source The source for which a probe must be created.
* @param level The level of generated measures.
* @return An appropriate probe (matching source and level).
*/
public static RuntimeProbe createProbe(Source source,
MeasureLevel level) {
return getRuntimeService().createProbe(source, level);
}
/**
* Creates a probe at the MINOR level.
*
* @param source The source for which a probe must be created.
* @return An appropriate probe (matching source and MINOR level).
*/
public static RuntimeProbe createProbe(Source source) {
return getRuntimeService().createProbe(source);
}
public static T wrap(Supplier supplier,
String details,
Source source,
MeasureLevel level) {
final RuntimeProbe local = createProbe(source, level);
local.start(details);
try {
return supplier.get();
} finally {
local.stop();
}
}
public static T wrap(Supplier supplier,
String details,
Source source) {
return wrap(supplier, details, source, MeasureLevel.MINOR);
}
public static void wrap(Procedure procedure,
String details,
Source source,
MeasureLevel level) {
final RuntimeProbe local = createProbe(source, level);
local.start(details);
try {
procedure.invoke();
} finally {
local.stop();
}
}
public static void wrap(Procedure procedure,
String details,
Source source) {
wrap(procedure, details, source, MeasureLevel.MINOR);
}
private static String truncate(String s,
int max) {
if (s == null || s.length() < max) {
return s;
} else {
return s.substring(0, max - 3) + "...";
}
}
private static void begin(StringBuilder builder,
String caller) {
builder.append(caller);
builder.append('(');
}
private static void arg(StringBuilder builder,
Object arg,
boolean first) {
if (!first) {
builder.append(", ");
}
builder.append(truncate(String.valueOf(arg), 40));
}
private static void end(StringBuilder builder) {
builder.append(')');
}
public static String format(String caller) {
final StringBuilder builder = new StringBuilder();
begin(builder, caller);
end(builder);
return builder.toString();
}
public static String format(String caller,
Object arg0) {
final StringBuilder builder = new StringBuilder();
begin(builder, caller);
arg(builder, arg0, true);
end(builder);
return builder.toString();
}
public static String format(String caller,
Object arg0,
Object arg1) {
final StringBuilder builder = new StringBuilder();
begin(builder, caller);
arg(builder, arg0, true);
arg(builder, arg1, false);
end(builder);
return builder.toString();
}
public static String format(String caller,
Object arg0,
Object arg1,
Object arg2) {
final StringBuilder builder = new StringBuilder();
begin(builder, caller);
arg(builder, arg0, true);
arg(builder, arg1, false);
arg(builder, arg2, false);
end(builder);
return builder.toString();
}
public static String format(String caller,
Object arg0,
Object arg1,
Object arg2,
Object arg3) {
final StringBuilder builder = new StringBuilder();
begin(builder, caller);
arg(builder, arg0, true);
arg(builder, arg1, false);
arg(builder, arg2, false);
arg(builder, arg3, false);
end(builder);
return builder.toString();
}
public static String format(String caller,
Object... args) {
final StringBuilder builder = new StringBuilder();
begin(builder, caller);
for (int index = 0; index < args.length; index++) {
arg(builder, args[index], index == 0);
}
end(builder);
return builder.toString();
}
public static interface RuntimeService {
/**
* Returns the shared source that has a given name.
*
* If a source with that name already exists, then it returns it.
* Otherwise, creates a new Source and returns it.
*
* @param name Name of the source.
* @return The shared source that is named name.
*/
public Source getSource(String name);
/**
* Returns the source associated to a class.
*
* Equivalent to getSource(klass.getCanonicalName())
*
* @param cls The class whose name will be associated to source.
* @return getSource(cls.getCanonicalName())
*/
public default Source getSource(Class> cls) {
return getSource(cls.getCanonicalName());
}
/**
* Creates a probe that can be used to create measures at a given level and
* associated to a source.
*
* @param source The source for which a probe must be created.
* @param level The level of generated measures.
* @return An appropriate probe (matching source and level).
*/
public RuntimeProbe createProbe(Source source,
MeasureLevel level);
/**
* Creates a probe at the MINOR level.
*
* @param source The source for which a probe must be created.
* @return An appropriate probe (matching source and MINOR level).
*/
public RuntimeProbe createProbe(Source source);
}
}