package edu.harvard.econcs.turkserver.logging; import java.io.IOException; import java.io.PrintStream; import com.google.common.collect.ObjectArrays; import edu.harvard.econcs.turkserver.api.ExperimentLog; import edu.harvard.econcs.turkserver.server.ExperimentScoped; import net.andrewmao.misc.Utils; @ExperimentScoped public class ExperimentLogImpl implements LogController, ExperimentLog { private static final String NOT_INIT_MSG = "Log not initialized! Make sure you call start() first!"; long startTime; volatile long roundStartTime; volatile int currentRound = 0; String expId = null; StringBuffer buffer = null; StringBuffer roundBuffer = null; ExperimentLogImpl() { buffer = new StringBuffer(); roundBuffer = new StringBuffer(); } public void initialize(long startTime, String expId) { if( this.expId != null ) throw new RuntimeException("initialize already called!"); this.expId = expId; this.startTime = startTime; print(expId + " started"); } public void startRound(int round) { // Clear SB and reset the reference time roundBuffer.setLength(0); currentRound = round; roundStartTime = System.currentTimeMillis(); printf(buffer, roundStartTime - startTime, "Round %d started", round); printf(roundBuffer, 0, "Round %d started", round); } public void finishRound() { long time = System.currentTimeMillis(); printf(roundBuffer, time - roundStartTime, "Round %d finished", currentRound); printf(buffer, time - startTime, "Round %d finished", currentRound); } @Override public String getRoundOutput() { return roundBuffer.toString(); } @Override public long print(String msg) { if( expId == null ) throw new RuntimeException(NOT_INIT_MSG); long start = currentRound > 0 ? roundStartTime: startTime; StringBuffer sb = currentRound > 0 ? roundBuffer : buffer; long time = System.currentTimeMillis(); print(sb, time - start, msg); return time; } private static void print(StringBuffer sb, long timeDiff, String msg) { sb.append( String.format("%s %s\n", Utils.clockStringMillis(timeDiff), msg) ); } @Override public long printf(String format, Object... args) { if( this.expId == null ) throw new RuntimeException(NOT_INIT_MSG); long start = currentRound > 0 ? roundStartTime: startTime; StringBuffer sb = currentRound > 0 ? roundBuffer : buffer; long time = System.currentTimeMillis(); printf(sb, time - start, format, args); return time; } private static void printf(StringBuffer sb, long timeDiff, String format, Object... args) { sb.append( String.format("%s " + format + "\n", ObjectArrays.concat( Utils.clockStringMillis(timeDiff), args) )); } @Override public long conclude() { long time = System.currentTimeMillis(); print(buffer, time - startTime, expId + " finished"); return time; } @Deprecated public void writeToFile(String file) throws IOException { // TODO: legacy method that should be moved elsewhere PrintStream ps = null; try { ps = new PrintStream(file); ps.print(buffer.toString()); } finally { if( ps != null ) ps.close(); } } @Override public String getOutput() { return buffer.toString(); } }