Java tutorial
/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.ocsoft.olivia.logger; import java.io.IOException; import java.lang.Thread.UncaughtExceptionHandler; import java.text.SimpleDateFormat; import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; import java.util.logging.ConsoleHandler; import java.util.logging.FileHandler; import java.util.logging.Formatter; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; import javax.annotation.Nonnull; import org.frows.genericfile.v0_3_2.GenericFile; import org.ocsoft.olivia.DefaultValues; import org.ocsoft.olivia.observers.OliviaObservatories; import org.ocsoft.olivia.utils.JsonUtils; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; /** * OliviaLog???????. * @author tohhy */ public class LogStation { /** * ?. */ @Nonnull private static final Level DEFAULT_CONSOLE_LEVEL = Level.INFO; /** * ?. */ @Nonnull private static final Level DEFUALT_LOGFILE_LEVEL = Level.ALL; /** * ?. */ @Nonnull private final Logger logger = Logger.getLogger("org.ocsoft.olivia"); /** * ???.???. */ @Nonnull private Level consoleLevel = DEFAULT_CONSOLE_LEVEL; /** * ???.???. */ @Nonnull private Level logFileLevel = DEFUALT_LOGFILE_LEVEL; /** * ???. */ @Nonnull private final ConsoleHandler ch; /** * ???. */ @Nonnull private final FileHandler fh; /** * ???????????. */ @Nonnull private final UncaughtExceptionHandler uch; /** * . */ private static LogStation instance; /** * LogStation???. * @return */ public static LogStation getInstance() { if (instance == null) instance = new LogStation(); return instance; } /** * ????. */ private LogStation() { //?????????? try { setUpLogFile(); } catch (IOException e) { e.printStackTrace(); } //?? for (Handler h : logger.getHandlers()) { if (h instanceof ConsoleHandler) logger.removeHandler(h); } //??????? logger.setUseParentHandlers(false); //?? this.ch = createConsoleLogHandler(); logger.addHandler(ch); //? this.fh = createLogFileHandler(); logger.addHandler(fh); //???????? uch = new UncaughtExceptionHandler() { public void uncaughtException(Thread th, Throwable ex) { OliviaLogger.fatal("UNCAUGHT_EXCEPTION", "uncaught exception occured", new LogData() { { exception(ex); put("thread", th.getName()); } }); } }; Thread.currentThread().setUncaughtExceptionHandler(uch); //? logger.setLevel(Level.ALL); } /** * ??OliviaLog????. * @param log ? */ public void log(OliviaLog log) { logger.log(log.getLevel().toLoggerLevel(), log.getDataAsJsonString()); OliviaObservatories.getLog().logExecuted(log); } /** * ??. * @throws IOException */ private static void setUpLogFile() throws IOException { if (!DefaultValues.USER_LOG_FILE.exists()) { DefaultValues.USER_LOG_FILE.getParent().getHandler().createDirectories(); DefaultValues.USER_LOG_FILE.getHandler().createEmptyFile(); } else if (DefaultValues.USER_LOG_FILE.getFileSize() > 1024 * 1024) { //1MB???? DefaultValues.USER_LOG_FILE.getHandler().moveTo( new GenericFile(DefaultValues.USER_LOG_FILE.getParent(), new Date().toString() + ".log")); DefaultValues.USER_LOG_FILE.getHandler().createEmptyFile(); } } /** * ????. * @return ????? */ @Nonnull private ConsoleHandler createConsoleLogHandler() { ConsoleHandler ch = new ConsoleHandler(); //logger??JSON?? ch.setFormatter(new OliviaConsoleLogFormatter()); return ch; } /** * ???????. * @return ???????? */ @Nonnull private FileHandler createLogFileHandler() { try { FileHandler fh = new FileHandler(DefaultValues.USER_LOG_FILE.getAbsolutePathString(), true); //logger??JSON?? fh.setFormatter(new OliviaLogFileFormatter()); return fh; } catch (Exception e) { e.printStackTrace(); } return null; } /** * ?????.<br> * ?????. * @return ??? */ public Level getConsoleLevel() { return consoleLevel; } /** * * @param consoleLevel */ public void setConsoleLevel(Level consoleLevel) { if (consoleLevel == null) throw new IllegalArgumentException("consoleLevel must not be null"); this.consoleLevel = consoleLevel; ch.setLevel(consoleLevel); } /** * * @param consoleLevel */ public void setConsoleLevel(LogLevel consoleLevel) { setConsoleLevel(consoleLevel.toLoggerLevel()); } /** * */ public void resetConsoleLevel() { setConsoleLevel(DEFAULT_CONSOLE_LEVEL); } /** * * @return */ public Level getLogFileLevel() { return logFileLevel; } /** * * @param logFileLevel */ public void setLogFileLevel(Level logFileLevel) { if (logFileLevel == null) throw new IllegalArgumentException("logFileLevel must not be null"); this.logFileLevel = logFileLevel; fh.setLevel(logFileLevel); } /** * * @param logFileLevel */ public void setLogFileLevel(LogLevel logFileLevel) { setLogFileLevel(logFileLevel.toLoggerLevel()); } /** * */ public void resetLogFileLevel() { setLogFileLevel(DEFUALT_LOGFILE_LEVEL); } /** * ??. * @author tohhy */ private static class OliviaConsoleLogFormatter extends Formatter { /** * ??. */ private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); @Override public String format(LogRecord record) { try { Map<String, Object> log = new LinkedHashMap<>(); log.put("date", DATE_FORMAT.format(new Date(record.getMillis()))); log.put("level", record.getLevel().toString()); log.put("data", JsonUtils.readJsonString(record.getMessage(), new TypeReference<Map<String, String>>() { })); return JsonUtils.toJsonString(log) + "\n"; } catch (IOException e) { e.printStackTrace(); return null; } } } /** * ??. * @author tohhy */ private static class OliviaLogFileFormatter extends Formatter { /** * ??. */ private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); /** * ?????????mapper?? */ private final ObjectMapper mapper = new ObjectMapper(); @Override public String format(LogRecord record) { try { Map<String, Object> log = new LinkedHashMap<>(); log.put("date", DATE_FORMAT.format(new Date(record.getMillis()))); log.put("level", record.getLevel().toString()); log.put("data", JsonUtils.readJsonString(record.getMessage(), new TypeReference<Map<String, String>>() { })); return mapper.writeValueAsString(log) + "\n"; } catch (IOException e) { e.printStackTrace(); return null; } } } }