A lightweight log filtering mod designed to reduce spam in the console and log files, allowing developers and players to focus on critical errors and save disk space.
A lightweight log filtering mod designed to reduce spam in the console and log files, allowing developers and players to focus on critical errors and save disk space.
TRACE or DEBUG.
Block
INFOlogs? Of course! This way you will only see errors and warnings, suitable for debugging.
mods folder in your Minecraft installation directory.Or manually create a
logfilter-common.tomlfile, modify the configuration as needed, and then launch the game.
The configuration file is located at: config/logfilter-common.toml
Default configuration:
[General]
#Enable or disable log filtering
enableFilter = true
#Enable debug mode to see which logs are being filtered
debugMode = false
#Maximum size of filtered log cache (for duplicate detection)
#Range: 100 ~ 10000
maxCacheSize = 1000
[FilterRules]
#Regex patterns to filter log messages
filterRules = []
#Exact message strings to filter (case-sensitive)
exactMatches = []
#Logger names to completely filter (e.g., 'net.minecraft.server.MinecraftServer')
loggerNames = []
#Log levels to filter: TRACE, DEBUG, INFO, WARN, ERROR, FATAL
logLevels = ["TRACE", "DEBUG"]
#Regex patterns that will EXCLUDE logs from filtering (whitelist)
excludePatterns = []
| Option | Default | Description |
|---|---|---|
enableFilter |
true |
Whether to enable the log filtering function. |
debugMode |
false |
Enable debug mode to print filtered logs to the console, convenient for testing rules. |
maxCacheSize |
1000 |
The cache size for filtered logs, used for deduplication. |
filterRules (Regex)Use regex to match logs to be filtered.
filterRules = [
".*Exception.*", # Filter out all logs containing "Exception"
".*stack trace.*", # Filter out stack traces
".*Could not pass event.*"# Filter out specific event errors
]
exactMatches (Exact Match)Logs are filtered only when their content is exactly identical (case-sensitive).
exactMatches = [
"This message will be completely filtered out"
]
loggerNames (Logger Names)Filter based on the source of the log (class name or mod package name). Supports hierarchical filtering.
loggerNames = [
"net.minecraft.server.MinecraftServer", # Filter out logs from the main server
"com.some.noisy.mod" # Filter out all logs from a noisy mod
]
logLevels (Log Levels)Filter based on log level. Available values: TRACE, DEBUG, INFO, WARN, ERROR, FATAL.
logLevels = [
"TRACE",
"DEBUG"
]
excludePatterns (Whitelist/Exclusion Rules)Very Important. Logs matching rules here will not be filtered, even if other rules match them. Used to retain critical errors.
excludePatterns = [
".*CRITICAL ERROR.*", # Even if it matches Exception, if it is a CRITICAL ERROR, keep it
".*IMPORTANT.*"
]
The core idea of this mod is interception. It "hijacks" the data before Minecraft's log output reaches the console or files, deciding whether to let it pass or discard it.
Minecraft 1.20.1 uses the Log4j 2 logging framework.
LogEvent) -> Passes to Log4j's LoggerContext -> Passes to Appender (e.g., console appender, file writer) -> Finally displayed on the screen.Filter)" on Loggers or Appenders.Our mod performs the following operations via LogFilterManager.java when the game starts (FMLCommonSetupEvent):
Get Context:
LoggerContext loggerContext = LoggerContext.getContext(false);
We obtained Minecraft's current log environment context.
Get Root Configuration:
Configuration configuration = loggerContext.getConfiguration();
LoggerConfig rootLoggerConfig = configuration.getRootLogger();
We got the configuration of the "Root Logger". Since almost all logs eventually flow to the Root Logger, mounting a filter here can capture global logs.
Register Custom Filter:
log4jFilter = new FilteringLogFilter(); // Our custom filter class
log4jFilter.start();
rootLoggerConfig.addFilter(log4jFilter);
We inserted our custom FilteringLogFilter at the very front of the log processing chain.
Interception and Decision (FilteringLogFilter.filter method):
Whenever Minecraft attempts to output a line of log, Log4j calls our filter(LogEvent event) method. Here we perform the following judgment logic (priority from high to low):
LogEvent into our custom defined LogEntry object for easier processing.DENY immediately without subsequent calculation. This is for performance optimization, preventing CPU overload due to the same error spamming the screen.excludePatterns). If the log matches a whitelist regex, return NEUTRAL (neutral/pass). The whitelist has the highest priority and is used to protect important logs.loggerNames). If the log's source class name is in the blacklist, return DENY.logLevels). If the log level (e.g., DEBUG) is in the blacklist, return DENY.exactMatches). If the log message exactly matches a configured string, return DENY.filterRules). If the log message matches a configured regex, return DENY.Final Verdict:
Result.DENY. Upon receiving DENY, Log4j immediately discards the log, and it will not appear in the console or file.Result.NEUTRAL. Log4j considers the filter to have "no opinion" and continues to pass the log to the next processor, eventually displaying it normally.Let's look at this log:
[241... 00:32:22.574] [Render thread/WARN] [net.minecraft.client.renderer.ShaderInstance/]: Shader rendertype_entity_translucent_emissive could not find sampler named Sampler2 in the specified shader program.
We need to break down this log into several key parts:
| Log Fragment | Meaning | Corresponding Config Item | Note |
|---|---|---|---|
WARN |
Log Level | logLevels |
Indicates this is a warning, not an error or info. |
net.minecraft.client.renderer.ShaderInstance |
Logger Name | loggerNames |
The fully qualified name of the Java class that emitted this log. |
Shader ... program. |
Log Message | filterRules, exactMatches |
The specific error content. |
loggerNames.logLevels.exactMatches.filterRules.For this specific Shader error, we have four filtering strategies. Please choose according to your needs:
filterRules)The core feature of this log is "cannot find sampler". We can write a regular expression that covers all cases where a sampler is not found, without affecting other logs.
Applicable Scenario: You consider all warnings about missing shader samplers to be irrelevant and want to block them all.
Configuration Code:
# Explanation: .* means any character, matching all logs containing "could not find sampler named", regardless of what comes before or after.
filterRules = [".*could not find sampler named.*"]
exactMatches)If you only want to block the specific warning about Sampler2 not being found, but keep other Shader warnings.
Applicable Scenario: Extremely precise strike, no collateral damage.
Configuration Code:
# Must be exactly the same as the text in the log (usually excluding timestamp and thread name, only including the content after the colon)
exactMatches = ["Shader rendertype_entity_translucent_emissive could not find sampler named Sampler2 in the specified shader program."]
loggerNames)If the ShaderInstance class is very noisy and you don't want to see anything it outputs at all.
Applicable Scenario: Aggressive filtering. Warning: If this class outputs serious error logs later, you won't see them either.
Configuration Code:
# As long as the log source is net.minecraft.client.renderer.ShaderInstance, block everything.
loggerNames = ["net.minecraft.client.renderer.ShaderInstance"]
logLevels)Applicable Scenario: Not Recommended. This will block all warning messages, potentially causing you to miss potential issues that really need attention.
Configuration Code:
logLevels = ["WARN"]
Conversation