From 546b5a91f01add743cc99490e0090b92b6f999c2 Mon Sep 17 00:00:00 2001 From: Edward Knight Date: Tue, 2 Feb 2016 21:38:08 +0000 Subject: [PATCH] Refactored logging framework --- src/main/java/chat/haver/server/Logger.java | 100 ++++++++++++-------- src/main/java/chat/haver/server/Main.java | 32 ++----- src/main/java/chat/haver/server/Room.java | 2 +- src/main/java/chat/haver/server/Router.java | 3 +- 4 files changed, 71 insertions(+), 66 deletions(-) diff --git a/src/main/java/chat/haver/server/Logger.java b/src/main/java/chat/haver/server/Logger.java index bdb8581..c0a3801 100644 --- a/src/main/java/chat/haver/server/Logger.java +++ b/src/main/java/chat/haver/server/Logger.java @@ -1,72 +1,98 @@ package chat.haver.server; -import java.io.PrintWriter; -import java.io.StringWriter; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.logging.Level; /** * Basic logging class */ public class Logger { - private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - private static final StringWriter STRING_WRITER = new StringWriter(); - private static final PrintWriter PRINT_WRITER = new PrintWriter(STRING_WRITER); - public static void printStackTrace(Exception e) { - e.printStackTrace(PRINT_WRITER); - for (String line : STRING_WRITER.toString().split("\\r?\\n")) { - severe(line); - } - STRING_WRITER.flush(); + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + /** + * Logs a {@link Level}.INFO level message. + * + * @param message to be logged + */ + public static void info(final String message) { + out(format(message, Level.INFO)); } - public static void info(String message) { - out(format(message, "info")); + /** + * Logs a {@link Level}.WARNING level message. + * + * @param message to be logged + */ + public static void warning(final String message) { + err(format(message, Level.WARNING)); } - public static void warning(String message) { - err(format(message, "warning")); + /** + * Logs a {@link Level}.SEVERE level message. + * + * @param e the exception to log + */ + public static void severe(final Exception e) { + err(format(formatStackTrace(e), Level.SEVERE)); } - public static void severe(String message) { - err(format(message, "severe")); + /** + * Helper method to format a stack trace for logging + * + * @param e the exception to extract the stack trace from + * @return a stack trace formatted identically to {@link Exception#printStackTrace()} + */ + private static String formatStackTrace(final Exception e) { + StringBuilder sb = new StringBuilder(e.getClass().getCanonicalName() + ": " + e.getMessage()); + for(StackTraceElement ste : e.getStackTrace()) { + sb.append("\n\tat ").append(ste.toString()); + } + return sb.toString(); } /** * Formats the message to be printed to log - * @param message To be logged - * @param type The type of message: info, warning, or severe - * @return Formatted message + * + * @param message to be logged + * @param level the logging level + * @return formatted message */ - private static String format(String message, String type) { - Date date = new Date(); - StackTraceElement ste = Thread.currentThread().getStackTrace()[3]; - String[] arr = ste.getClassName().split("\\."); - String classDetails = arr[arr.length - 1] + ":" + ste.getMethodName(); - String dateString = dateFormat.format(date); - if (type.equalsIgnoreCase("info")) { - return "[" + dateString + "] " + type.toUpperCase() + " " + message; - } else { - return "[" + dateString + "] " + type.toUpperCase() + " (" + classDetails + ") " + message; - } + private static String format(final String message, final Level level) { + return '[' + DATE_FORMAT.format(new Date()) + "] " + level + ' ' + message; } /** - * Prints to standard out - * TODO: Use ENVIRONMENT to determine whether to print + * Prints to standard out and logs. + * * @param message to output */ - private static void out(String message) { + private static void out(final String message) { System.out.println(message); + if(Main.ENVIRONMENT == Main.Environment.PRODUCTION) { + log(message); + } } /** - * Prints to standard error - * TODO: Use ENVIRONMENT to determine whether to print + * Prints to standard error and logs. + * * @param message to output */ - private static void err(String message) { + private static void err(final String message) { System.err.println(message); + if(Main.ENVIRONMENT == Main.Environment.PRODUCTION) { + log(message); + } + } + + /** + * Helper method to log messages to a logfile. + * + * @param message to be logged + */ + private static void log(final String message) { + // TODO implement log file } } diff --git a/src/main/java/chat/haver/server/Main.java b/src/main/java/chat/haver/server/Main.java index b66dadc..e8dd591 100644 --- a/src/main/java/chat/haver/server/Main.java +++ b/src/main/java/chat/haver/server/Main.java @@ -1,31 +1,12 @@ package chat.haver.server; -import java.net.UnknownHostException; - public class Main { - @Deprecated - public static final boolean DEBUG = true; // To be removed and replaced with Environment enum public static final Environment ENVIRONMENT = Environment.DEVELOPMENT; private static String host = "127.0.0.1"; private static int port = 8080; - public enum Environment { - DEVELOPMENT("development"), - TESTING("testing"), - PRODUCTION("production"); - - public final String env; - - Environment(final String env) { - this.env = env; - } - - @Override - public String toString() { - return env; - } - } + public enum Environment {PRODUCTION, DEVELOPMENT} /** * Empty private constructor to prevent creation of Main. @@ -39,13 +20,12 @@ private Main() { * @param args Command line arguments. */ public static void main(final String[] args) { - parseArgs(args); try { - Router router = new Router(host, port); - router.start(); - Logger.info("Hosting new server on: " + router.getAddress()); - } catch (UnknownHostException e) { - Logger.severe("Invalid host: " + host + ':' + port); + parseArgs(args); + new Router(host, port).start(); + Logger.info("Hosting new server on: " + host + ':' + port); + } catch (Exception e) { + Logger.severe(e); } } diff --git a/src/main/java/chat/haver/server/Room.java b/src/main/java/chat/haver/server/Room.java index 17ad74d..5faa474 100644 --- a/src/main/java/chat/haver/server/Room.java +++ b/src/main/java/chat/haver/server/Room.java @@ -66,7 +66,7 @@ public void addClient(final WebSocket conn, final Client client) { */ private String generateName() { if(freeNames.size() == 0) { // TODO Actually handle this situation somehow - Logger.severe("ROOM IS OVER MAXIMUM LIMIT, RIP IN KILL"); + Logger.severe(new Exception("ROOM IS OVER MAXIMUM LIMIT, RIP IN KILL")); System.exit(-2011); } int index = RANDOM.nextInt(freeNames.size()); diff --git a/src/main/java/chat/haver/server/Router.java b/src/main/java/chat/haver/server/Router.java index e7d3f80..04f4e6b 100644 --- a/src/main/java/chat/haver/server/Router.java +++ b/src/main/java/chat/haver/server/Router.java @@ -52,8 +52,7 @@ public void onClose(final WebSocket conn, final int code, final String reason, f @Override public void onError(final WebSocket conn, final Exception ex) { - Logger.severe("Websocket error: " + ex.getMessage()); - Logger.printStackTrace(ex); + Logger.severe(ex); if (conn != null) { // some errors like port binding failed may not be assignable to a specific websocket conn.close();