From b046d03874a50d2ac229737570479b231f64784f Mon Sep 17 00:00:00 2001 From: Poweruser Date: Wed, 25 May 2016 22:28:03 +0200 Subject: [PATCH] Add lag spike logger diff --git a/src/main/java/net/frozenorb/timings/ExtendedCustomTimingsHandler.java b/src/main/java/net/frozenorb/timings/ExtendedCustomTimingsHandler.java new file mode 100644 index 000000000..3d561ad33 --- /dev/null +++ b/src/main/java/net/frozenorb/timings/ExtendedCustomTimingsHandler.java @@ -0,0 +1,143 @@ +package net.frozenorb.timings; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Queue; +import java.util.Set; + +import net.frozenorb.ThreadingManager; +import net.frozenorb.ThreadingManager.TaskQueueWorker; +import net.minecraft.server.MinecraftServer; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.spigotmc.CustomTimingsHandler; +import org.spigotmc.SpigotConfig; + +public class ExtendedCustomTimingsHandler extends CustomTimingsHandler { + + private static File path = new File("LagSpikeLog"); + private static File file; + private static TaskQueueWorker taskQueue; + + public ExtendedCustomTimingsHandler(String name) + { + this( name, null ); + } + + public ExtendedCustomTimingsHandler(String name, CustomTimingsHandler parent) + { + super(name, parent); + } + + public static void tick() { + if(Bukkit.getPluginManager().useTimings() && SpigotConfig.lagSpikeLoggerEnabled) { + for(CustomTimingsHandler handler: HANDLERS) { + if(handler.getCurrentTickTotal() > SpigotConfig.lagSpikeLoggerTickLimitNanos) { + dumpTimings(HANDLERS); + break; + } + } + } + CustomTimingsHandler.tick(); + } + + private static void dumpTimings(Queue handlers) { + ArrayList list = new ArrayList(handlers.size()); + for(CustomTimingsHandler handler: handlers) { + if(handler.getCurrentTickTotal() > 1000000L) { // greater than 1ms + list.add(new LogEntry(handler)); + } + } + if(taskQueue == null) { + taskQueue = ThreadingManager.createTaskQueue(); + } + taskQueue.queueTask(new LogDump(list)); + } + + private static class LogEntry implements Comparable { + public String name; + public long total; + + public LogEntry(CustomTimingsHandler handler) { + this.name = handler.getName(); + this.total = handler.getCurrentTickTotal(); + } + + @Override + public int compareTo(LogEntry other) { + return (int) (other.total - this.total); + } + + public String getFormatedTotal() { + double a = (double) this.total / 1000000.0D; + return String.format("%.2f", a); + } + } + + private static class LogDump implements Runnable { + + private List list; + private long serverTick; + + public LogDump(List list) { + this.list = list; + this.serverTick = MinecraftServer.currentTick; + } + + @Override + public void run() { + if(list.isEmpty()) { + return; + } + Collections.sort(this.list); + if(!path.exists()) { + path.mkdirs(); + } + SimpleDateFormat df = new SimpleDateFormat ("yyyy-MM-dd_HH-mm-ss"); + String formatedDate = df.format(new Date()); + if(file == null) { + file = new File(path, "LagSpikeLog_" + formatedDate + ".txt"); + } + BufferedWriter writer = null; + try { + writer = new BufferedWriter(new FileWriter(file, true), 8 * 1024); + writer.newLine(); + writer.write("Time stamp: "); + writer.write(formatedDate); + writer.write(" Server tick: "); + writer.write(String.valueOf(this.serverTick)); + writer.newLine(); + writer.newLine(); + for(LogEntry e: list) { + writer.write(e.getFormatedTotal()); + writer.write(" -- "); + writer.write(e.name); + writer.newLine(); + } + writer.newLine(); + writer.write("============================================================"); + writer.newLine(); + writer.flush(); + } catch (IOException e) { + System.out.println("Failed to dump the timings of a lag spike: " + e.toString()); + e.printStackTrace(); + } finally { + if(writer != null) { + try { + writer.close(); + } catch (IOException e) {} + } + } + } + } +} diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 81d36ab27..74d3632e1 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -676,7 +676,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo SpigotTimings.serverTickTimer.stopTiming(); // Spigot this.lastTickTime = (System.nanoTime() - i) / 1000000F; ThreadingManager.cancelTimerTask(this.lastTickTime); // Poweruser - org.spigotmc.CustomTimingsHandler.tick(); // Spigot + net.frozenorb.timings.ExtendedCustomTimingsHandler.tick(); // Poweruser } public void v() { diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java index c2d272c5f..24b584880 100644 --- a/src/main/java/org/spigotmc/SpigotConfig.java +++ b/src/main/java/org/spigotmc/SpigotConfig.java @@ -445,5 +445,15 @@ public class SpigotConfig private static void autoSaveClearRegionFileCache() { autoSaveClearRegionFileCache = getBoolean ( "settings.autosave.clear-RegionFileCache", false); } + + public static boolean lagSpikeLoggerEnabled; + private static void lagSpikeLoggerEnabled() { + lagSpikeLoggerEnabled = getBoolean ( "settings.lagSpikeLogger.enabled", true); + } + + public static long lagSpikeLoggerTickLimitNanos; + private static void lagSpikeLoggerTickLimitNanos() { + lagSpikeLoggerTickLimitNanos = ((long) getInt( "settings.lagSpikeLogger.tickLimitInMilliseconds", 100)) * 1000000L; + } // Poweruser end } -- 2.13.3