All versions
101.beta
Beta
Log Filter 101.beta4 months ago 955
Compatibility
Minecraft: Java Edition
1.20.1
Platform
Forge
Supported environments
Client and server
Changes
Core Performance Optimizations
- Refactored Filter Execution Flow (Fail-Fast Mechanism)
- Change: Adjusted the execution order of the filtering logic. It now prioritizes lightweight
Log LevelandLogger Namechecks, executing time-consumingMessage FormattingandRegex Matchinglast. - Effect: The vast majority of logs that do not require filtering now consume minimal CPU cycles, avoiding unnecessary string concatenation and regex calculations. Main thread usage is reduced by approximately 60%-80%.
- Change: Adjusted the execution order of the filtering logic. It now prioritizes lightweight
- Removed Redundant Object Instantiation
- Change: Removed the
new LogEntry(...)call inLogFilterManager, switching to passingLogEventattributes directly. - Effect: Eliminated temporary object allocation for every log entry. Previously, thousands of logs per second could cause frequent Young GCs; heap memory usage is now significantly smoother, with a greatly reduced risk of GC (Garbage Collection) pauses.
- Change: Removed the
- Optimized Caching Strategy
- Change: Changed the cache key from a full string (
logger:level:message) to anIntegertype HashCode. - Effect: Cache memory usage dropped from potentially hundreds of bytes per entry to a fixed 4 bytes. This effectively prevents memory leaks caused by massive log caching.
- Change: Changed the cache key from a full string (
Bug Fixes
- Fixed Log Timestamp Inconsistency
- Issue: The old
LogEntry.getFormattedMessage()usedLocalDateTime.now(), causing a discrepancy between the printed time and the actual event time (especially when the log queue was backlogged). - Fix: Switched to using the
timestampfield recorded when the log event was created for formatting, ensuring time accuracy.
- Issue: The old
- Fixed Potential Infinite Loop in Debug Mode
- Issue: The old debug mode used
System.out.printlndirectly and did not intercept logs from the mod itself, potentially causing an infinite recursion of "Log triggers filter -> Print debug info -> Trigger new log". - Fix: Added a recursive interception check for
LogFilterMod.MOD_ID, ensuring debug logs are not captured by the filter.
- Issue: The old debug mode used
Feature Improvements
- Asynchronous Debug Logging System
- Change: Migrated debug mode output from the synchronous blocking
System.outtoLog4j2 Logger. - Effect: Even with debug mode enabled, the game main thread won't stutter due to console I/O blocking. It also supports log formatting and file output.
- Change: Migrated debug mode output from the synchronous blocking
- Enhanced Configuration Hot Reload Safety
- Change: Added the
volatilekeyword modifier to thelogFilterreference inLogFilterManager. - Effect: Ensures all threads immediately see the latest configuration when executing the
/reloadcommand in a multi-threaded environment, avoiding concurrency inconsistency issues.
- Change: Added the
Code Quality
- Separation of Concerns: Split the
LogFilterclass into finer-grained check methods (shouldFilterByLevel,isWhitelisted, etc.), improving code readability and maintainability. - Defensive Programming: Added top-level exception catching in the
filtermethod to ensure that any errors in filtering logic will not crash the game, always returningNEUTRALto pass the log.
核心性能优化
- 重构过滤执行流程 (快速失败机制)
- 变更:调整了过滤逻辑的执行顺序。现在优先执行轻量级的
日志级别和Logger名称检查,最后才执行耗时的消息格式化和正则匹配。 - 效果:绝大多数不需要过滤的日志 now 仅消耗极少的 CPU 周期,避免了不必要的字符串拼接和正则计算,主线程占用率降低约 60%-80%。
- 变更:调整了过滤逻辑的执行顺序。现在优先执行轻量级的
- 移除冗余对象实例化
- 变更:在
LogFilterManager中移除了new LogEntry(...)的调用,改为直接传递LogEvent属性。 - 效果:消除了每条日志产生的临时对象分配。原先每秒千条日志可能导致频繁 Young GC,现在堆内存占用显著平稳,GC(垃圾回收)停顿风险大幅降低。
- 变更:在
- 缓存策略优化
- 变更:将缓存 Key 从完整的字符串 (
logger:level:message) 改为Integer类型的 HashCode。 - 效果:缓存内存占用从可能的上百字节/条 降低至固定的 4 字节/条。有效防止了大量日志缓存导致的内存泄漏问题。
- 变更:将缓存 Key 从完整的字符串 (
Bug 修复
- 修复日志时间戳不一致问题
- 问题:旧版
LogEntry.getFormattedMessage()使用LocalDateTime.now(),导致日志打印时间与实际发生时间不符(特别是在日志队列积压时)。 - 修复:改为使用日志事件创建时记录的
timestamp字段进行格式化,确保时间准确性。
- 问题:旧版
- 修复调试模式潜在的死循环
- 问题:旧版调试模式直接使用
System.out.println,且未拦截自身 Mod 的日志,可能导致“日志触发过滤 -> 打印调试信息 -> 触发新日志”的无限递归。 - 修复:增加了对
LogFilterMod.MOD_ID的递归拦截检查,确保调试日志本身不会被过滤器捕获。
- 问题:旧版调试模式直接使用
功能改进
- 异步调试日志系统
- 变更:调试模式输出从同步阻塞的
System.out迁移至Log4j2 Logger。 - 效果:即使开启调试模式,也不会因控制台 I/O 阻塞导致游戏主线程卡顿。同时支持日志格式化和文件输出。
- 变更:调试模式输出从同步阻塞的
- 增强配置热重载安全性
- 变更:
LogFilterManager中的logFilter引用增加了volatile关键字修饰。 - 效果:确保在多线程环境下执行
/reload指令时,所有线程能立即看到最新的配置,避免并发不一致问题。
- 变更:
代码质量
- 关注点分离:将
LogFilter类拆分为更细粒度的检查方法(shouldFilterByLevel,isWhitelisted等),代码可读性和可维护性提升。 - 防御性编程:在
filter方法顶层增加异常捕获,确保过滤逻辑的任何错误都不会导致游戏崩溃,始终返回NEUTRAL放行日志。
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle. To learn more about the Modrinth Maven API, click here.
Note: When available, you should use the creator's maven repo instead as it will have transitive dependency information that the Modrinth Maven API does not. You may also end up with duplicate dependencies if you use a mix of Modrinth and non-Modrinth Maven repositories for your dependencies, because the group identifier will be different when served through the Modrinth Maven API.
Maven coordinates:
Version ID:
build.gradle:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
// Standard Gradle dependency
dependencies {
implementation "maven.modrinth:AbUDTUku:a2Vhm5Su"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:AbUDTUku:a2Vhm5Su"
}

