From 53f534b3c69e6705913876a37391ae97679b4aa9 Mon Sep 17 00:00:00 2001 From: asofold Date: Fri, 28 Apr 2017 21:35:00 +0200 Subject: [PATCH] Split off logOnce to StaticLog. --- .../nocheatplus/logging/StaticLog.java | 60 ++++++++++++++++++- .../nocheatplus/utilities/CheckUtils.java | 52 +++++----------- 2 files changed, 73 insertions(+), 39 deletions(-) diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/logging/StaticLog.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/logging/StaticLog.java index 44d2153e..2a7b48ae 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/logging/StaticLog.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/logging/StaticLog.java @@ -14,7 +14,10 @@ */ package fr.neatmonster.nocheatplus.logging; +import java.util.Collections; import java.util.Date; +import java.util.HashSet; +import java.util.Set; import java.util.logging.Level; import fr.neatmonster.nocheatplus.NCPAPIProvider; @@ -28,13 +31,18 @@ import fr.neatmonster.nocheatplus.utilities.StringUtil; * */ public class StaticLog { - + // TODO: Remove this class, instead use an implementation of LogManager for testing. private static boolean useLogManager = false; - + private static StreamID streamID = Streams.INIT; + /** The Constant logOnce. */ + // TODO: Quick and dirty - should probably use an access ordered LinkedHashSet, to expire the eldest half :p. + private static final Set logOnce = Collections.synchronizedSet(new HashSet()); + + /** * Now needs to be set, in order to log to the INIT stream instead of the console. * @param useLogManager @@ -42,7 +50,7 @@ public class StaticLog { public static void setUseLogManager(boolean useLogManager) { StaticLog.useLogManager = useLogManager; } - + public static void setStreamID(StreamID streamID) { if (streamID == null) { throw new NullPointerException("StreamID must not be null, use setUseLogManager(false) instead."); @@ -75,6 +83,17 @@ public class StaticLog { } public static void log(final Level level, final String msg) { + log(StaticLog.streamID, level, msg); + } + + /** + * + * @param streamID + * May get ignored if only the console is available. + * @param level + * @param msg + */ + public static void log(final StreamID streamID, final Level level, final String msg) { if (useLogManager) { NCPAPIProvider.getNoCheatPlusAPI().getLogManager().log(streamID, level, msg); } else { @@ -83,4 +102,39 @@ public class StaticLog { } } + /** + * Not really once: Always log the header with an id: create a hash of to be + * logged parts and keep the hash in memory, log it with the header - only + * log the longMessage once per hash. Once the id tracking storage has + * reached a certain size, many/all are removed. The hash involves both the + * header and longMessage strings as well as their lengths. No distinction + * is made for log level. This is intended for long messages like stack + * traces. + * + * @param level + * @param message + */ + public static void logOnce(final StreamID stream, final Level level, + final String header, final String longMessage) { + // TODO: LogOnce should be in static log ? + final int ref = header.hashCode() ^ longMessage.hashCode() ^ new Integer(header.length()).hashCode() + ^ new Integer(longMessage.length()).hashCode(); + final String extra; + final boolean details = logOnce.add(ref); + if (details) { + // Not already contained. + extra = " -> log once id="; + } else { + extra = " See earlier in this log, search for -> log once id="; + } + log(stream, level, header + extra + ref); + if (details) { + log(stream, level, longMessage); + if (logOnce.size() > 10000) { + logOnce.clear(); + log(stream, level, "Cleared log once ids, due to exceeding the maximum number of stored ids."); + } + } + } + } diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/CheckUtils.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/CheckUtils.java index 5b14c3c5..da218151 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/CheckUtils.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/CheckUtils.java @@ -15,10 +15,8 @@ package fr.neatmonster.nocheatplus.utilities; import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; import java.util.Random; -import java.util.Set; +import java.util.logging.Level; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -38,15 +36,25 @@ import fr.neatmonster.nocheatplus.logging.StaticLog; import fr.neatmonster.nocheatplus.logging.Streams; import fr.neatmonster.nocheatplus.utilities.ds.count.ActionFrequency; -// TODO: Auto-generated Javadoc + /** - * Random auxiliary gear, some might have general quality. Contents are likely to get moved to other classes. + * Random auxiliary gear, some might have general quality. Contents are likely + * to get moved to other classes. All that is in here should be set up with + * checks and not be related to early setup stages of the plugin. */ public class CheckUtils { - /** The Constant logOnce. */ - // TODO: Quick and dirty -> other methods elsewhere. - private static final Set logOnce = Collections.synchronizedSet(new HashSet()); + /** + * Improper API access. + * + * @param checkType + * the check type + */ + private static void improperAPIAccess(final CheckType checkType) { + // TODO: Log once + examine stack (which plugins/things are involved). + final String trace = Arrays.toString(Thread.currentThread().getStackTrace()); + StaticLog.logOnce(Streams.STATUS, Level.SEVERE, "Off primary thread call to hasByPass for " + checkType, trace); + } /** * Kick and log. @@ -191,34 +199,6 @@ public class CheckUtils { return NCPExemptionManager.isExempted(player, checkType, isPrimaryThread); } - /** - * Improper api access. - * - * @param checkType - * the check type - */ - private static void improperAPIAccess(final CheckType checkType) { - // TODO: Log once + examine stack (which plugins/things are involved). - final String trace = Arrays.toString(Thread.currentThread().getStackTrace()); - final int ref = trace.hashCode() ^ new Integer(trace.length()).hashCode(); - final String extra; - final boolean details = logOnce.add(ref); - if (details) { - // Not already contained. - extra = " (id=" + ref + ")"; - } else { - extra = " (see earlier log with id=" + ref + ")"; - } - NCPAPIProvider.getNoCheatPlusAPI().getLogManager().severe(Streams.STATUS, "Off primary thread call to hasByPass for " + checkType + extra + "."); - if (details) { - NCPAPIProvider.getNoCheatPlusAPI().getLogManager().severe(Streams.STATUS, trace); - if (logOnce.size() > 10000) { - logOnce.clear(); - NCPAPIProvider.getNoCheatPlusAPI().getLogManager().severe(Streams.STATUS, "Cleared log-once ids, due to exceeding the maximum number of stored ids."); - } - } - } - /** * Static relay for the check-specific convenience methods, logging with * standard format ([check_type] [player_name] ...).