diff --git a/gradle.properties b/gradle.properties index 8a06ad3..d2ead2d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -version=9.2.0 +version=9.3.0 diff --git a/src/main/java/com/configcat/ConfigCatClient.java b/src/main/java/com/configcat/ConfigCatClient.java index 261fcea..ac32a1e 100644 --- a/src/main/java/com/configcat/ConfigCatClient.java +++ b/src/main/java/com/configcat/ConfigCatClient.java @@ -28,7 +28,7 @@ public final class ConfigCatClient implements ConfigurationProvider { private final LogLevel clientLogLevel; private ConfigCatClient(String sdkKey, Options options) { - this.logger = new ConfigCatLogger(LoggerFactory.getLogger(ConfigCatClient.class), options.logLevel, options.configCatHooks); + this.logger = new ConfigCatLogger(LoggerFactory.getLogger(ConfigCatClient.class), options.logLevel, options.configCatHooks, options.logFilter); this.clientLogLevel = options.logLevel; this.sdkKey = sdkKey; @@ -707,6 +707,7 @@ public static class Options { private User defaultUser; private boolean offline = false; private final ConfigCatHooks configCatHooks = new ConfigCatHooks(); + private LogFilterFunction logFilter; /** @@ -813,6 +814,13 @@ public ConfigCatHooks hooks() { return configCatHooks; } + /** + * Set the client's log filter callback function. When logFilterFunction returns false, the ConfigCatLogger skips the log event. + */ + public void logFilter(LogFilterFunction logFilter) { + this.logFilter = logFilter; + } + private boolean isBaseURLCustom() { return this.baseUrl != null && !this.baseUrl.isEmpty(); } diff --git a/src/main/java/com/configcat/ConfigCatLogger.java b/src/main/java/com/configcat/ConfigCatLogger.java index 4b09b0e..bd76edc 100644 --- a/src/main/java/com/configcat/ConfigCatLogger.java +++ b/src/main/java/com/configcat/ConfigCatLogger.java @@ -6,15 +6,17 @@ class ConfigCatLogger { private final Logger logger; private final LogLevel logLevel; private final ConfigCatHooks configCatHooks; + private final LogFilterFunction filterFunction ; - public ConfigCatLogger(Logger logger, LogLevel logLevel, ConfigCatHooks configCatHooks) { + public ConfigCatLogger(Logger logger, LogLevel logLevel, ConfigCatHooks configCatHooks, LogFilterFunction filterFunction ) { this.logger = logger; this.logLevel = logLevel; this.configCatHooks = configCatHooks; + this.filterFunction = filterFunction ; } public ConfigCatLogger(Logger logger, LogLevel logLevel) { - this(logger, logLevel, null); + this(logger, logLevel, null, null); } public ConfigCatLogger(Logger logger) { @@ -22,34 +24,38 @@ public ConfigCatLogger(Logger logger) { } public void warn(int eventId, String message) { - if (this.logLevel.ordinal() <= LogLevel.WARNING.ordinal()) { + if (filter(eventId, LogLevel.WARNING, message, null)) { this.logger.warn("[{}] {}", eventId, message); } } public void error(int eventId, String message, Exception exception) { if (this.configCatHooks != null) this.configCatHooks.invokeOnError(message); - if (this.logLevel.ordinal() <= LogLevel.ERROR.ordinal()) { + if (filter(eventId, LogLevel.ERROR, message, exception)) { this.logger.error("[{}] {}", eventId, message, exception); } } public void error(int eventId, String message) { if (this.configCatHooks != null) this.configCatHooks.invokeOnError(message); - if (this.logLevel.ordinal() <= LogLevel.ERROR.ordinal()) { + if (filter(eventId, LogLevel.ERROR, message, null)) { this.logger.error("[{}] {}", eventId, message); } } public void info(int eventId, String message) { - if (this.logLevel.ordinal() <= LogLevel.INFO.ordinal()) { + if (filter(eventId, LogLevel.INFO, message, null)) { this.logger.info("[{}] {}", eventId, message); } } public void debug(String message) { - if (this.logLevel.ordinal() <= LogLevel.DEBUG.ordinal()) { + if (filter(0, LogLevel.DEBUG, message, null)) { this.logger.debug("[{}] {}", 0, message); } } + + private boolean filter(int eventId, LogLevel logLevel, String message, Exception exception) { + return this.logLevel.ordinal() <= logLevel.ordinal() && (this.filterFunction == null || this.filterFunction.apply(logLevel, eventId, message, exception)); + } } diff --git a/src/main/java/com/configcat/Constants.java b/src/main/java/com/configcat/Constants.java index 07d39ed..a51b5b3 100644 --- a/src/main/java/com/configcat/Constants.java +++ b/src/main/java/com/configcat/Constants.java @@ -7,7 +7,7 @@ private Constants() { /* prevent from instantiation*/ } static final long DISTANT_PAST = 0; static final String CONFIG_JSON_NAME = "config_v6.json"; static final String SERIALIZATION_FORMAT_VERSION = "v2"; - static final String VERSION = "9.2.0"; + static final String VERSION = "9.3.0"; static final String SDK_KEY_PROXY_PREFIX = "configcat-proxy/"; static final String SDK_KEY_PREFIX = "configcat-sdk-1"; diff --git a/src/main/java/com/configcat/LogFilterFunction.java b/src/main/java/com/configcat/LogFilterFunction.java new file mode 100644 index 0000000..4c10e19 --- /dev/null +++ b/src/main/java/com/configcat/LogFilterFunction.java @@ -0,0 +1,19 @@ +package com.configcat; + +/** + * The Log Filter Functional Interface provides a custom filter option for the ConfigCat Logger. + */ +@FunctionalInterface +public interface LogFilterFunction { + + /** + * Apply the custom filter option to the ConfigCatLogger. + * + * @param logLevel Event severity level. + * @param eventId Event identifier. + * @param message Message. + * @param exception The exception object related to the message (if any). + * @return True to log the event, false will leave out the log. + */ + boolean apply(LogLevel logLevel, int eventId, String message, Throwable exception); +} diff --git a/src/test/java/com/configcat/LoggerTests.java b/src/test/java/com/configcat/LoggerTests.java index c7c5950..0812ffd 100644 --- a/src/test/java/com/configcat/LoggerTests.java +++ b/src/test/java/com/configcat/LoggerTests.java @@ -87,4 +87,29 @@ public void noLog() { verify(mockLogger, never()).warn(anyString(), eq(3000), eq("warn")); verify(mockLogger, never()).error(anyString(), eq(1000), eq("error"), any(Exception.class)); } + + @Test + public void excludeLogEvents() { + Logger mockLogger = mock(Logger.class); + + LogFilterFunction filterLogFunction = ( LogLevel logLevel, int eventId, String message, Throwable exception) -> eventId != 1001 && eventId != 3001 && eventId != 5001; + + ConfigCatLogger logger = new ConfigCatLogger(mockLogger, LogLevel.INFO, null, filterLogFunction); + + logger.debug("[0] debug"); + logger.info(5000, "info"); + logger.warn(3000, "warn"); + logger.error(1000, "error", new Exception()); + logger.info(5001, "info"); + logger.warn(3001, "warn"); + logger.error(1001, "error", new Exception()); + + verify(mockLogger, never()).debug(anyString(), eq(0), eq("debug")); + verify(mockLogger, times(1)).info(anyString(), eq(5000), eq("info")); + verify(mockLogger, times(1)).warn(anyString(), eq(3000), eq("warn")); + verify(mockLogger, times(1)).error(anyString(), eq(1000), eq("error"), any(Exception.class)); + verify(mockLogger, never()).info(anyString(), eq(5001), eq("info")); + verify(mockLogger, never()).warn(anyString(), eq(3001), eq("warn")); + verify(mockLogger, never()).error(anyString(), eq(1001), eq("error"), any(Exception.class)); + } }