Skip to content

Logging

Every mod has access to a built-in logger via getLogger(). Hytale uses Google Flogger for logging.

import java.util.logging.Level;
// in your mod class
getLogger().atInfo().log("Server started");
getLogger().atWarning().log("Something might be wrong");
getLogger().atSevere().log("Critical error occurred");
getLogger().at(Level.FINE).log("Debug info"); // explicit level syntax
LevelUse For
Level.SEVEREErrors and failures
Level.WARNINGPotential problems
Level.INFOGeneral information
Level.CONFIGConfiguration and setup messages
Level.FINEDebug information (hidden by default)
Level.FINERDetailed debug (hidden by default)
Level.FINESTTrace-level debug (hidden by default)

Convenience methods: atSevere(), atWarning(), atInfo(), atConfig(), atFine(), atFiner(), atFinest().

Use %s placeholders for formatting (printf-style):

String playerName = "Steve";
int count = 42;
getLogger().atInfo().log("Player %s joined", playerName);
getLogger().atInfo().log("Loaded %d items", count);
getLogger().atInfo().log("Player %s has %d coins", playerName, count);

Use withCause() to attach an exception:

try {
loadConfig();
} catch (Exception e) {
getLogger().atSevere().withCause(e).log("Failed to load configuration");
}

This logs both the message and the full stack trace.

Avoid log spam with built-in rate limiting:

import java.util.concurrent.TimeUnit;
// log only every 100th occurrence
getLogger().atWarning().every(100).log("Frequent event occurred");
// log at most once every 5 seconds
getLogger().atWarning().atMostEvery(5, TimeUnit.SECONDS).log("Rate-limited message");

Include a stack trace for debugging (without an exception):

import com.google.common.flogger.StackSize;
getLogger().atWarning().withStackTrace(StackSize.MEDIUM).log("How did we get here?");

Stack sizes: SMALL (10 frames), MEDIUM (20), LARGE (50), FULL (all).

For expensive operations, check if the level is enabled first:

if (getLogger().at(Level.FINE).isEnabled()) {
String expensiveDebugInfo = computeDebugState();
getLogger().at(Level.FINE).log("Debug state: %s", expensiveDebugInfo);
}

Enable debug logging dynamically:

getLogger().setLevel(Level.FINE); // enable FINE and above
getLogger().setLevel(Level.INFO); // back to normal

For utility classes without mod context, use HytaleLogger:

import com.hypixel.hytale.logger.HytaleLogger;
// per-class logger (recommended)
private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
LOGGER.atInfo().log("Processing data");
// sub-logger for subsystems
HytaleLogger dbLogger = LOGGER.getSubLogger("database");
dbLogger.atInfo().log("Connected"); // logged as "[MyClass][database]"
// global logger
HytaleLogger.getLogger().atWarning().log("Something happened");