/** * BetonQuest - advanced quests for Bukkit * Copyright (C) 2016 Jakub "Co0sh" Sapalski * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pl.betoncraft.betonquest.utils; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.logging.Logger; import org.bukkit.Bukkit; import org.bukkit.scheduler.BukkitRunnable; import pl.betoncraft.betonquest.BetonQuest; /** * Handels error logging and debugging. * * @author Jakub Sapalski */ public class Debug { private static boolean debugging = false; private static Debug instance; private Logger logger = BetonQuest.getInstance().getLogger(); private File debug; private File error; public Debug() { instance = this; // if debug option isn't set (yet), then assume it's off String configDebug = BetonQuest.getInstance().getConfig().getString("debug"); if (configDebug == null) { configDebug = "true"; } // create logs folder if it doesn't already exist File logFolder = new File(BetonQuest.getInstance().getDataFolder(), "logs"); if (!logFolder.isDirectory()) { logFolder.mkdirs(); } // if debugging is set to true then initialize debugger if (configDebug.equals("true")) { debugging = true; debug = new File(logFolder, "debug.log"); try { debug.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } else { debugging = false; } // initialize error log error = new File(logFolder, "error.log"); try { error.createNewFile(); } catch (IOException e) { e.printStackTrace(); } if (debugging) { if (debug == null) { return; } try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(debug, true)))) { out.println("--------------------[New debug session]--------------------"); } catch (IOException e) { e.printStackTrace(); } } // display a message in the console if (debugging) BetonQuest.getInstance().getLogger().info("Debugging is turned on!"); } private enum LogType { DEBUG, ERROR, BROAD } /** * Checks if the debugging is turned on. * * @return true if it is turned on */ public static boolean debugging() { return debugging; } /** * Logs a debug message to "debug.log" file. Only works if "config.debug" is * true. Can be called from an async thread. * * @param message * message to log into the file */ public static void info(String message) { if (debugging) instance.log(message, LogType.DEBUG); } /** * Logs an error message to "error.log" (and "debug.log" if debugging is * turned on). Can be called from an async thread. * * @param message * error to log into the file */ public static void error(String message) { instance.log(message, LogType.ERROR); } /** * Sends a message to the console and logs it to "debug.log" if debugging is * turned on * * @param message * message to broadcast */ public static void broadcast(String message) { instance.log(message, LogType.BROAD); } private void log(String message, LogType type) { // errors should be displayed in the console at severe level and logged // into error.log file if (type == LogType.ERROR) { logger.severe(message); save(message, error, LogType.ERROR); } // broadcast should only be displayed in the console if (type == LogType.BROAD) logger.info(message); // addictionally everything should be logged to debug.log if debugging // is turned on if (debugging) save(message, debug, type); } private void save(final String message, final File file, final LogType type) { // if the thread isn't primary then it's unsafe to access the file. // schedule it to be done on next tick if (Bukkit.isPrimaryThread()) { sync(message, file, type); } else { new BukkitRunnable() { @Override public void run() { sync(message, file, type); } }.runTask(BetonQuest.getInstance()); } } private void sync(String message, File file, LogType type) { // log it to the file String date = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date()); try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(file, true)))) { out.println("[" + date + "] " + type + ": " + message); } catch (IOException e) { e.printStackTrace(); } } }