package com.netflix.staash.rest.util;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Simple class that encapsulates a ThreadLocal of a map of context.
* This context can be used by various classes that service the request and
* can store vital info that can be used for debugging.
*
* @author poberai
*
*/
public class StaashRequestContext {
private static final Logger Logger = LoggerFactory.getLogger(StaashRequestContext.class);
private static final DateTimeFormatter dateFormat = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS z");
private static final ThreadLocal<StaashRequestContext> requestContext = new ThreadLocal<StaashRequestContext>() {
@Override
protected StaashRequestContext initialValue() {
return new StaashRequestContext();
}
};
public static void resetRequestContext() {
requestContext.set(new StaashRequestContext());
}
public static void flushRequestContext() {
Logger.info(requestContext.get().getMapContents());
}
public static void addContext(String key, String value) {
requestContext.get().addContextToMap(key, value);
}
public static void logDate() {
requestContext.get().addDateToMap();
}
public static void recordRequestStart() {
requestContext.get().startTime.set(System.currentTimeMillis());
}
public static void recordRequestEnd() {
Long begin = requestContext.get().startTime.get();
Long now = System.currentTimeMillis();
requestContext.get().addContextToMap("Duration", String.valueOf(now - begin));
}
public static String getRequestId() {
return requestContext.get().requestId;
}
private final ConcurrentHashMap<String, String> map = new ConcurrentHashMap<String, String>();
private final AtomicLong startTime = new AtomicLong(0L);
private final String requestId = UUID.randomUUID().toString();
private StaashRequestContext() {
map.put("request-id", requestId);
}
private void addContextToMap(String key, String value) {
map.put(key, value);
}
private void addDateToMap() {
DateTime dt = new DateTime();
map.put("Date", dateFormat.print(dt));
}
private String getMapContents() {
if (map == null) {
return null;
}
StringBuilder sb = new StringBuilder("\n========================STAASH REQUEST CONTEXT===========================================");
for (String key : map.keySet()) {
sb.append("\n").append(key).append(":").append(map.get(key));
}
sb.append("\n======================================================================================");
return sb.toString();
}
}