package teamcomm.net.logging; import common.Log; import data.GameControlData; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.Serializable; import java.text.SimpleDateFormat; import java.util.Date; import teamcomm.net.SPLStandardMessagePackage; /** * Singleton class for logging received messages. * * @author Felix Thielke */ public class Logger { private static final String LOG_DIRECTORY = "logs_teamcomm"; private static final Logger instance = new Logger(); private File logFile; private ObjectOutputStream logger; private long beginTimestamp; private Logger() { createLogfile(); } /** * Returns the only instance of the logger. * * @return instance */ public static Logger getInstance() { return instance; } /** * Creates a new log file to store received messages in. */ public final void createLogfile() { createLogfile(null); } /** * Creates a new log file to store received messages in. * * @param name string appended to the name of the new log file */ public final void createLogfile(final String name) { if (!LogReplayer.getInstance().isReplaying()) { // Close current log file closeLogfile(); // Determine file name final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss-S"); final String fileName = "teamcomm_" + df.format(new Date(System.currentTimeMillis())) + (name == null || name.isEmpty() ? "" : ("_" + name)) + ".log"; // Determine file path final File logDir = new File(LOG_DIRECTORY); synchronized (this) { if (!logDir.exists() && !logDir.mkdirs()) { logFile = new File(fileName); } else { logFile = new File(logDir, fileName); } } } } /** * Closes the currently used log file. */ public void closeLogfile() { if (!LogReplayer.getInstance().isReplaying()) { synchronized (this) { if (logger != null) { try { logger.close(); } catch (IOException e) { Log.error("something went wrong while closing logfile: " + e.getMessage()); } logger = null; } if (logFile != null) { if (logFile.exists() && logFile.length() <= 4) { logFile.delete(); } logFile = null; } } } } /** * Logs the given SPLStandardMessage package. * * @param p package */ public void log(final SPLStandardMessagePackage p) { log(SPLStandardMessagePackage.class, p); } /** * Logs the given message from the GameController. * * @param p game control data */ public void log(final GameControlData p) { log(GameControlData.class, p); } /** * Logs the given package. * * @param <T> type of the package * @param cls class of the package * @param p package */ public <T extends Serializable> void log(final Class<T> cls, final T p) { if (!LogReplayer.getInstance().isReplaying()) { boolean error = false; synchronized (this) { if (logFile != null) { // Open stream if needed if (logger == null) { try { logger = new ObjectOutputStream(new FileOutputStream(logFile)); } catch (IOException ex) { Log.error("error while opening logfile: " + ex.getMessage()); error = true; } beginTimestamp = System.currentTimeMillis(); } // Log object try { logger.writeLong(System.currentTimeMillis() - beginTimestamp); logger.writeBoolean(p != null); if (p == null) { logger.writeInt(getIDForClass(cls)); } else { logger.writeObject(p); } } catch (IOException ex) { Log.error("error while writing to logfile: " + ex.getMessage()); error = true; } } } if (error) { closeLogfile(); } } } /** * Returns the unique log ID for the given class. * * @param cls Class * @return id */ public static int getIDForClass(final Class<?> cls) { if (cls.equals(GameControlData.class)) { return 1; } return -1; } }