package io.github.lucaseasedup.logit.logging; import io.github.lucaseasedup.logit.LogItCore; import io.github.lucaseasedup.logit.common.Disposable; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.logging.Level; import org.bukkit.ChatColor; public final class LogItCoreLogger implements Disposable { public LogItCoreLogger(LogItCore core) { if (core == null) throw new IllegalArgumentException(); this.core = core; } @Override public void dispose() { } public synchronized void open() { openLogFile( core.getConfig("config.yml").getString("logging.file.filename") ); } public synchronized void close() { if (logFileWriter != null) { try { logFileWriter.close(); } catch (IOException ex) { log(Level.WARNING, "Could not close log file.", ex); } finally { logFileWriter = null; } } } /** * Logs a message in the name of LogIt. * * <p> The message will be saved to the log file if it's been enabled * in the config. * * @param level the message level. * @param message the message to be logged. * * @throws IllegalArgumentException if {@code level} or {@code message} * is {@code null}. * * @see #log(Level, String, Throwable) */ public synchronized void log(Level level, String message) { if (level == null || message == null) throw new IllegalArgumentException(); if (core.getConfig("config.yml") != null && core.getConfig("config.yml").isLoaded()) { boolean fileLogEnabled = core.getConfig("config.yml") .getBoolean("logging.file.enabled"); int fileLogLevel = core.getConfig("config.yml") .getInt("logging.file.level"); if (fileLogEnabled && level.intValue() >= fileLogLevel) { try { getLogFileWriter().write(LOG_DATE_FORMAT.format(new Date())); getLogFileWriter().write(" ["); getLogFileWriter().write(level.getName()); getLogFileWriter().write("] "); getLogFileWriter().write(ChatColor.stripColor(message)); getLogFileWriter().write("\n"); getLogFileWriter().flush(); } catch (IOException ex) { core.getPlugin().getLogger().log(Level.WARNING, "Could not log to file", ex); } } if (core.getConfig("config.yml").getBoolean("logging.verboseConsole")) { System.out.println("[" + level + "] " + ChatColor.stripColor(message)); return; } } core.getPlugin().getLogger().log(level, ChatColor.stripColor(message)); } /** * Logs a message with a {@code Throwable} in the name of LogIt. * * <p> The message will be saved to the log file if it's been enabled * in the config. * * @param level the message level. * @param message the message to be logged. * @param throwable the throwable whose stack trace should be appended * to the log. * * @see #log(Level, String) */ public synchronized void log( Level level, String message, Throwable throwable ) { StringWriter sw = new StringWriter(); try (PrintWriter pw = new PrintWriter(sw)) { throwable.printStackTrace(pw); } log(level, message + " [Exception stack trace:\n" + sw + "]"); } /** * Logs a {@code Throwable} in the name of LogIt. * * <p> The message will be saved to the log file if it's been enabled * in the config. * * @param level the logging level. * @param throwable the throwable to be logged. * * @see #log(Level, String, Throwable) */ public synchronized void log(Level level, Throwable throwable) { StringWriter sw = new StringWriter(); try (PrintWriter pw = new PrintWriter(sw)) { throwable.printStackTrace(pw); } log(level, "Caught exception:\n" + sw); } private void openLogFile(String filename) { File logFile = core.getDataFile(filename); if (logFile.length() > 300000) { int suffix = 0; File nextLogFile; do { suffix++; nextLogFile = core.getDataFile(filename + "." + suffix); } while (nextLogFile.exists()); logFile.renameTo(nextLogFile); } try { logFileWriter = new FileWriter(logFile, true); } catch (IOException ex) { core.getPlugin().getLogger().log(Level.WARNING, "Could not open log file for writing.", ex); } } private FileWriter getLogFileWriter() { if (logFileWriter == null) throw new IllegalStateException("Log file not opened"); return logFileWriter; } private static final DateFormat LOG_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private final LogItCore core; private FileWriter logFileWriter; }