Skip to content

Instantly share code, notes, and snippets.

@LrWm3
Last active September 6, 2024 13:45
Show Gist options
  • Save LrWm3/6a1cd21c7c50de6663f943da9ef574a6 to your computer and use it in GitHub Desktop.
Save LrWm3/6a1cd21c7c50de6663f943da9ef574a6 to your computer and use it in GitHub Desktop.
Log4j2 debounce filter example (untested)
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
// Register the plugin to allow it to be used later
@Plugin(name = "DebounceFilter", category = "Core", elementType = "filter", printObject = true)
public class DebounceFilterPlugin extends DebounceFilter {
// Factory method for creating the filter from configuration
@PluginFactory
public static DebounceFilter createFilter(@PluginAttribute("debounceTimeMs") long debounceTimeMs) {
return new DebounceFilter(debounceTimeMs);
}
}
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<!-- Root logger without the debounce filter -->
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
<!-- Logger specifically for classes which may log a high level of warn messages -->
<Logger name="com.myorg.myproduct.MySpecificClass" level="warn" additivity="false">
<AppenderRef ref="Console"/>
<Filters>
<!-- Debounce filter applied only to this logger -->
<Filter type="DebounceFilter" debounceTimeMs="60000" onMatch="NEUTRAL" onMismatch="DENY"/>
</Filters>
</Logger>
</Loggers>
</Configuration>
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.filter.AbstractFilter;
import org.apache.logging.log4j.core.filter.Filter.Result;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class DebounceFilter extends AbstractFilter {
// Class to hold details about a log message's debouncing status
private static class LogEntry {
long firstLoggedTime; // First time the message was logged
long lastLoggedTime; // Last time the message was logged
int debounceCount; // Number of times the message was suppressed
}
// Map to store log messages and their debouncing information
private final Map<String, LogEntry> messageLogEntries = new ConcurrentHashMap<>();
// Time window for debounce in milliseconds (e.g., 1 minute = 60000 ms)
private final long debounceTimeMs;
// Constructor to set debounce time
public DebounceFilter(long debounceTimeMs) {
this.debounceTimeMs = debounceTimeMs;
}
@Override
public Result filter(LogEvent event) {
// Get the log message
String message = event.getMessage().getFormattedMessage();
long currentTime = System.currentTimeMillis();
// Get or create a LogEntry for this message
LogEntry logEntry = messageLogEntries.computeIfAbsent(message, k -> new LogEntry());
// If this is the first time the message is being logged, initialize the entry
if (logEntry.firstLoggedTime == 0) {
logEntry.firstLoggedTime = currentTime;
logEntry.lastLoggedTime = currentTime;
logEntry.debounceCount = 0;
return Result.NEUTRAL; // Log the message
}
// Check if enough time has passed since the last time the message was logged
if ((currentTime - logEntry.lastLoggedTime) > debounceTimeMs) {
// Log the original message along with the debounce count and duration
if (logEntry.debounceCount > 0) {
String debounceInfo = String.format(
"[%d suppressed occurrences over %d ms]",
logEntry.debounceCount,
currentTime - logEntry.firstLoggedTime
);
// Log the message with debounce info (you can decide how to log this, like appending to the original message)
System.out.println(message + " " + debounceInfo);
}
// Reset the debounce state for the message
logEntry.firstLoggedTime = currentTime;
logEntry.lastLoggedTime = currentTime;
logEntry.debounceCount = 0;
return Result.NEUTRAL; // Log the message
} else {
// Debounce the message: update the last logged time and increment the debounce count
logEntry.lastLoggedTime = currentTime;
logEntry.debounceCount++;
return Result.DENY; // Suppress the message
}
}
// Factory method for the filter configuration (optional, can be customized)
public static DebounceFilter createFilter(long debounceTimeMs) {
return new DebounceFilter(debounceTimeMs);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment