Skip to content

Instantly share code, notes, and snippets.

@loganmzz
Created October 8, 2015 22:09
Show Gist options
  • Save loganmzz/3cb8cd5caebc9aaeb5d0 to your computer and use it in GitHub Desktop.
Save loganmzz/3cb8cd5caebc9aaeb5d0 to your computer and use it in GitHub Desktop.
Simple monitoring API (Java 8 based)
public class BasicMonitor implements Monitor {
private Map<String, Stat> stats;
private Function<String, Stat> statBuilder;
public BasicMonitor(Collection<String> keys) {
Thread currentThread = Thread.currentThread();
long threadId = currentThread.getId();
String threadName = currentThread.getName();
statBuilder = name -> new Stat(threadId, threadName, name);
stats = new LinkedHashMap<>(keys.size(), 1.0f);
for (String key : keys) {
getStat(key);
}
}
private void addToStat(String name, long duration, long weight) {
getStat(name).add(duration, weight);
}
private Stat getStat(String name) {
return stats.computeIfAbsent(name, statBuilder);
}
@Override
public <T> T get(String name, Supplier<T> command, ToLongFunction<T> weigher) {
long start = System.nanoTime();
T t = command.get();
addToStat(name, System.nanoTime() - start, weigher.applyAsLong(t));
return t;
}
@Override
public void run(String name, Runnable command, LongSupplier weigher) {
long start = System.nanoTime();
command.run();
addToStat(name, System.nanoTime() - start, weigher.getAsLong());
}
}
class BasicMonitorCsvWriter {
private Writer writer;
public BasicMonitorCsvWriter(Writer writer) {
this.writer = writer;
}
public BasicMonitorCsvWriter append(CharSequence s) throws IOException {
writer.append(s).append(';');
return this;
}
public BasicMonitorCsvWriter append(long l) throws IOException {
return append(String.valueOf(l));
}
public BasicMonitorCsvWriter nl() throws IOException {
writer.append('\n');
return this;
}
public BasicMonitorCsvWriter appendHeaders() throws IOException {
return this
.append("processor_id")
.append("processor_name")
.append("task")
.append("times")
.append("duration")
.append("weight")
.nl();
}
public BasicMonitorCsvWriter appendMonitor(BasicMonitor monitor) throws IOException {
for (Stat stat : monitor.stats.values()) {
appendStat(stat);
}
return this;
}
public BasicMonitorCsvWriter appendStat(Stat stat) throws IOException {
return this
.append(stat.threadId)
.append(stat.threadName)
.append(stat.name)
.append(stat.times)
.append(stat.duration)
.append(stat.weight)
.nl();
}
public BasicMonitorCsvWriter appendMonitors(Collection<BasicMonitor> monitors) throws IOException {
for (BasicMonitor monitor : monitors) {
appendMonitor(monitor);
}
return this;
}
public BasicMonitorCsvWriter flush() throws IOException {
writer.flush();
return this;
}
}
public class BasicMonitorFactory implements Supplier<BasicMonitor> {
private ThreadLocal<BasicMonitor> monitors;
public BasicMonitorFactory(Collection<String> keys) {
monitors = ThreadLocal.withInitial(() -> new BasicMonitor(keys));
}
@Override
public BasicMonitor get() {
return monitors.get();
}
}
/**
* <p>Simple monitoring API.</p>
* <p>Usages:</p>
* <ul>
* <li>{@code List<Item> items = monitor.get("source.find", source::find, List::size)}</li>
* <li>{@code monitor.run("source.update", () -> source::update(item), () -> 1)}</li>
* </ul>
*/
public interface Monitor {
public <T> T get(String name, Supplier<T> command, ToLongFunction<T> weigher);
public void run(String name, Runnable command, LongSupplier weigher);
}
public class Stat {
private final long threadId;
private final String threadName;
private final String name;
private long times;
private long duration;
private long weight;
private Stat(long threadId, String threadName, String name) {
this.threadId = threadId;
this.threadName = threadName;
this.name = name;
}
public void add(long duration, long weight) {
this.times += 1;
this.duration += duration;
this.weight += weight;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment