用途
hytale-logging 技能用于在开发 Hytale 服务端插件时添加日志功能。Hytale 提供 HytaleLogger 作为日志 API,它基于 Google Flogger(com.google.common.flogger.AbstractLogger),日志会写入服务器的日志文件,路径为 {Hytale install}/UserData/Saves/{World}/logs。
主要能力
- 日志器创建:使用 HytaleLogger.forEnclosingClass() 创建与当前类绑定的日志器,或使用 HytaleLogger.get("MyPluginName") 创建带自定义名称的日志器,名称会显示在日志消息之前以便识别。
- 日志级别:atInfo() 用于正常行为、启动和状态变化等信息;atWarning() 用于可能引发错误的情况;atSevere() 用于阻止正常运行的严重错误。默认配置下只有 Info、Warning、Severe 三个级别会输出。
- 模板参数:采用 printf 风格格式说明符,支持 %s(字符串)、%d(整数)、%f(浮点/双精度)、%b(布尔)、%c(字符)。参数在格式字符串之后传入,不使用字符串拼接。
- 异常记录:通过 .withCause(exception) 附加异常,保留完整堆栈信息,可与参数链式组合使用。
- 后端组件:HytaleLoggerBackend 负责管理日志级别与输出目标(sinks);HytaleFileHandler 负责文件输出;HytaleLogManager 负责日志管理器集成。HytaleLogger.init() 在服务器启动时初始化日志后端,HytaleLogger.replaceStd() 将 System.out / System.err 重定向到日志流。
使用方式
创建日志器并声明为 public static final 字段,便于在插件内及其他类中复用:
import com.hypixel.hytale.logger.HytaleLogger;
public class ExamplePlugin extends JavaPlugin {
public static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
@Override
protected void setup() {
LOGGER.atInfo().log("ExamplePlugin loaded");
}
}
在其他类中通过主插件类的静态日志器引用:
ExamplePlugin.LOGGER.atInfo().log("hello world");
使用 printf 风格参数:
final String name = "World";
LOGGER.atInfo().log("Hello %s", name);
// prints: Hello World
int count = 5;
LOGGER.atInfo().log("Found %d items for player %s", count, playerName);
附加异常:
try {
// risky operation
} catch (IOException e) {
LOGGER.atSevere().withCause(e).log("Failed to load configuration file");
}
与参数链式组合:
try {
loadResource(path);
} catch (Exception e) {
LOGGER.atSevere().withCause(e).log("Failed to load resource: %s", path);
}
完整示例:
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.server.pluginframework.JavaPlugin;
public class MyPlugin extends JavaPlugin {
public static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
@Override
protected void setup() {
LOGGER.atInfo().log("MyPlugin setup starting");
try {
initializeSystems();
LOGGER.atInfo().log("MyPlugin setup complete — %d systems initialized", systemCount);
} catch (Exception e) {
LOGGER.atSevere().withCause(e).log("MyPlugin setup failed");
}
}
@Override
protected void start() {
LOGGER.atInfo().log("MyPlugin started");
}
private void onPlayerAction(String playerName, String action) {
LOGGER.atInfo().log("Player %s performed action: %s", playerName, action);
}
}
适用场景
- 在 Hytale 插件中添加日志语句。
- 配置与选择日志级别。
- 格式化日志消息并传入动态参数。
- 记录异常并保留堆栈信息。
最佳实践
- 使用 forEnclosingClass():自动将日志器限定到当前类,重构时无需手动修改名称。
- 正常流程优先使用 atInfo(),将 atWarning() 和 atSevere() 保留给实际问题。
- 使用 printf 风格参数,不要在日志调用中拼接字符串;参数仅在日志级别激活时才会被求值。
- 始终附加异常:使用 .withCause(e) 而非记录 e.getMessage(),以保留堆栈信息。
- 将日志器声明为 public static final,便于插件内及其他类复用。
- 避免过度记录:在 tick 循环中大量使用 atInfo() 会淹没日志文件并影响性能。
限制
资料未提供关于日志级别自定义配置、日志文件轮转、输出目标(sink)自定义等更详细配置的说明;也未提供收费、价格或平台相关信息。