com.groupbyinc.common.blip.BlipTimer Maven / Gradle / Ivy
package com.groupbyinc.common.blip;
import org.apache.commons.lang3.StringUtils;
import java.time.Clock;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Stream;
import static java.util.Collections.emptyMap;
public class BlipTimer {
private static final String TOTAL = "millis";
private static final Clock systemClock = Clock.systemUTC();
public static final BlipTimer DUMMY = new BlipTimer(StringUtils.EMPTY) {
@Override
public Map getMetadata() {
return emptyMap();
}
};
private Clock clock;
private long startTime;
private Map metadata = new ConcurrentHashMap<>();
private Map timers = new ConcurrentHashMap<>();
public BlipTimer(String eventType) {
this(systemClock, eventType);
}
public BlipTimer(Clock clock, String eventType) {
this.clock = clock;
startTime = clock.millis();
metadata.put("eventType", eventType);
}
protected void setClock(Clock clock) {
this.clock = clock;
}
public void addMetaData(String key, String value) {
if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(value)) {
metadata.put(key, value);
}
}
private void addDelta(String identifier, long delta) {
addDelta(metadata, identifier, delta);
}
private void addDelta(Map metadata, String identifier, long delta) {
metadata.put("duration" + StringUtils.capitalize(identifier), Long.toString(delta));
}
public Map getMetadata() {
Map map = new HashMap<>(metadata);
new HashMap<>(timers).forEach((name, time) -> addDelta(map, name, time.get()));
addDelta(map, TOTAL, getTotal());
return map;
}
public long getTotal() {
return getTime() - startTime;
}
public long getTime() {
return clock.millis();
}
public class Delta implements AutoCloseable {
private long startTime = getTime();
private String[] names;
private Delta(String... names) {
this.names = names;
}
@Override
public void close() {
long totalTime = getTime() - startTime;
Stream.of(names).forEach(name -> increment(name, totalTime));
}
}
public Delta delta(String... timer) {
return new Delta(timer);
}
public void increment(String timer, long totalTime) {
timers.computeIfAbsent(timer, key -> new AtomicLong(0)).addAndGet(totalTime);
}
}