diff --git a/src/main/java/com/launchdarkly/client/Clause.java b/src/main/java/com/launchdarkly/client/Clause.java
index 53c315bb5..22897ed35 100644
--- a/src/main/java/com/launchdarkly/client/Clause.java
+++ b/src/main/java/com/launchdarkly/client/Clause.java
@@ -4,7 +4,6 @@
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.util.List;
diff --git a/src/main/java/com/launchdarkly/client/DefaultLoggerFactoryImpl.java b/src/main/java/com/launchdarkly/client/DefaultLoggerFactoryImpl.java
new file mode 100644
index 000000000..d3c3d87d9
--- /dev/null
+++ b/src/main/java/com/launchdarkly/client/DefaultLoggerFactoryImpl.java
@@ -0,0 +1,10 @@
+package com.launchdarkly.client;
+
+import org.slf4j.LoggerFactory;
+
+
+public class DefaultLoggerFactoryImpl implements ILoggerFactory {
+ public Logger getLogger(Class> classType) {
+ return LoggerFactory.getLogger(classType);
+ }
+}
diff --git a/src/main/java/com/launchdarkly/client/EventProcessor.java b/src/main/java/com/launchdarkly/client/EventProcessor.java
index a578e771c..62c3c82a2 100644
--- a/src/main/java/com/launchdarkly/client/EventProcessor.java
+++ b/src/main/java/com/launchdarkly/client/EventProcessor.java
@@ -9,7 +9,6 @@
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.io.Closeable;
import java.io.IOException;
diff --git a/src/main/java/com/launchdarkly/client/FeatureFlag.java b/src/main/java/com/launchdarkly/client/FeatureFlag.java
index 7dbaa0810..9040e0f3b 100644
--- a/src/main/java/com/launchdarkly/client/FeatureFlag.java
+++ b/src/main/java/com/launchdarkly/client/FeatureFlag.java
@@ -4,7 +4,6 @@
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.lang.reflect.Type;
import java.util.ArrayList;
diff --git a/src/main/java/com/launchdarkly/client/FeatureRequestor.java b/src/main/java/com/launchdarkly/client/FeatureRequestor.java
index 543c93b91..404f0133b 100644
--- a/src/main/java/com/launchdarkly/client/FeatureRequestor.java
+++ b/src/main/java/com/launchdarkly/client/FeatureRequestor.java
@@ -11,7 +11,6 @@
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Map;
diff --git a/src/main/java/com/launchdarkly/client/ILoggerFactory.java b/src/main/java/com/launchdarkly/client/ILoggerFactory.java
new file mode 100644
index 000000000..0e839ce99
--- /dev/null
+++ b/src/main/java/com/launchdarkly/client/ILoggerFactory.java
@@ -0,0 +1,8 @@
+package com.launchdarkly.client;
+
+import org.slf4j.Logger;
+
+public interface ILoggerFactory {
+ Logger getLogger(Class> className);
+}
+
diff --git a/src/main/java/com/launchdarkly/client/InMemoryFeatureStore.java b/src/main/java/com/launchdarkly/client/InMemoryFeatureStore.java
index 3dd3aa32b..b746ecc74 100644
--- a/src/main/java/com/launchdarkly/client/InMemoryFeatureStore.java
+++ b/src/main/java/com/launchdarkly/client/InMemoryFeatureStore.java
@@ -1,7 +1,6 @@
package com.launchdarkly.client;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.HashMap;
diff --git a/src/main/java/com/launchdarkly/client/LDClient.java b/src/main/java/com/launchdarkly/client/LDClient.java
index 50fc98628..f0ccb13ad 100644
--- a/src/main/java/com/launchdarkly/client/LDClient.java
+++ b/src/main/java/com/launchdarkly/client/LDClient.java
@@ -7,7 +7,6 @@
import org.apache.commons.codec.binary.Hex;
import org.apache.http.annotation.ThreadSafe;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
@@ -30,7 +29,7 @@
*/
@ThreadSafe
public class LDClient implements LDClientInterface {
- private static final Logger logger = LoggerFactory.getLogger(LDClient.class);
+ private final Logger logger;
private static final String HMAC_ALGORITHM = "HmacSHA256";
protected static final String CLIENT_VERSION = getClientVersion();
@@ -58,6 +57,7 @@ public LDClient(String sdkKey) {
* @param config a client configuration object
*/
public LDClient(String sdkKey, LDConfig config) {
+ this.logger = config.getLogger(LDClient.class);
this.config = config;
this.sdkKey = sdkKey;
this.requestor = createFeatureRequestor(sdkKey, config);
@@ -344,7 +344,7 @@ private JsonElement evaluate(String featureKey, LDUser user, JsonElement default
try {
FeatureFlag featureFlag = config.featureStore.get(featureKey);
if (featureFlag == null) {
- logger.warn("Unknown feature flag " + featureKey + "; returning default value");
+ logger.debug("Unknown feature flag " + featureKey + "; returning default value");
sendFlagRequestEvent(featureKey, user, defaultValue, defaultValue, null);
return defaultValue;
}
diff --git a/src/main/java/com/launchdarkly/client/LDConfig.java b/src/main/java/com/launchdarkly/client/LDConfig.java
index ad7ab7837..1749c8924 100644
--- a/src/main/java/com/launchdarkly/client/LDConfig.java
+++ b/src/main/java/com/launchdarkly/client/LDConfig.java
@@ -5,7 +5,6 @@
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.net.URI;
@@ -13,7 +12,7 @@
* This class exposes advanced configuration options for the {@link LDClient}. Instances of this class must be constructed with a {@link com.launchdarkly.client.LDConfig.Builder}.
*
*/
-public final class LDConfig {
+public final class LDConfig implements ILoggerFactory{
private static final URI DEFAULT_BASE_URI = URI.create("https://app.launchdarkly.com");
private static final URI DEFAULT_EVENTS_URI = URI.create("https://events.launchdarkly.com");
private static final URI DEFAULT_STREAM_URI = URI.create("https://stream.launchdarkly.com");
@@ -25,7 +24,8 @@ public final class LDConfig {
private static final long DEFAULT_START_WAIT_MILLIS = 5000L;
private static final int DEFAULT_SAMPLING_INTERVAL = 0;
private static final long DEFAULT_RECONNECT_TIME_MILLIS = 1000;
- private static final Logger logger = LoggerFactory.getLogger(LDConfig.class);
+ private final ILoggerFactory loggerFactory;
+ private final Logger logger;
protected static final LDConfig DEFAULT = new Builder().build();
@@ -47,6 +47,9 @@ public final class LDConfig {
final long reconnectTimeMs;
protected LDConfig(Builder builder) {
+ this.loggerFactory = new PerClassLoggerFactory(builder.loggerFactory);
+ this.logger = this.loggerFactory.getLogger(LDConfig.class);
+
this.baseURI = builder.baseURI;
this.eventsURI = builder.eventsURI;
this.capacity = builder.capacity;
@@ -69,6 +72,10 @@ protected LDConfig(Builder builder) {
this.reconnectTimeMs = builder.reconnectTimeMs;
}
+ public Logger getLogger(Class> klass) {
+ return this.getLogger(klass);
+ }
+
/**
* A builder that helps construct {@link com.launchdarkly.client.LDConfig} objects. Builder
* calls can be chained, enabling the following pattern:
@@ -99,6 +106,7 @@ public static class Builder {
private long startWaitMillis = DEFAULT_START_WAIT_MILLIS;
private int samplingInterval = DEFAULT_SAMPLING_INTERVAL;
private long reconnectTimeMs = DEFAULT_RECONNECT_TIME_MILLIS;
+ private ILoggerFactory loggerFactory = LoggerFactory.
/**
* Creates a builder with all configuration parameters set to the default
diff --git a/src/main/java/com/launchdarkly/client/LDUser.java b/src/main/java/com/launchdarkly/client/LDUser.java
index 270d9a978..fb21736d7 100644
--- a/src/main/java/com/launchdarkly/client/LDUser.java
+++ b/src/main/java/com/launchdarkly/client/LDUser.java
@@ -4,7 +4,6 @@
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.List;
diff --git a/src/main/java/com/launchdarkly/client/LoggerFactory.java b/src/main/java/com/launchdarkly/client/LoggerFactory.java
new file mode 100644
index 000000000..f01f94c0f
--- /dev/null
+++ b/src/main/java/com/launchdarkly/client/LoggerFactory.java
@@ -0,0 +1,23 @@
+package com.launchdarkly.client;
+
+import java.util.concurrent.atomic.AtomicReference;
+import org.slf4j.Logger;
+
+public class LoggerFactory {
+
+ private static AtomicReference factory = new AtomicReference<>();
+
+ public static void install(ILoggerFactory factory) {
+ LoggerFactory.factory.set(factory);
+ }
+
+ public static ILoggerFactory instance() {
+ LoggerFactory.factory.compareAndSet(null, new DefaultLoggerFactoryImpl());
+ return LoggerFactory.factory.get();
+ }
+
+ public static Logger getLogger(Class> className) {
+ LoggerFactory.factory.compareAndSet(null, new DefaultLoggerFactoryImpl());
+ return LoggerFactory.factory.get().getLogger(className);
+ }
+}
diff --git a/src/main/java/com/launchdarkly/client/NewRelicReflector.java b/src/main/java/com/launchdarkly/client/NewRelicReflector.java
index f01832d6f..7b11b2838 100644
--- a/src/main/java/com/launchdarkly/client/NewRelicReflector.java
+++ b/src/main/java/com/launchdarkly/client/NewRelicReflector.java
@@ -1,7 +1,6 @@
package com.launchdarkly.client;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
diff --git a/src/main/java/com/launchdarkly/client/PerClassLoggerFactory.java b/src/main/java/com/launchdarkly/client/PerClassLoggerFactory.java
new file mode 100644
index 000000000..b197f212b
--- /dev/null
+++ b/src/main/java/com/launchdarkly/client/PerClassLoggerFactory.java
@@ -0,0 +1,18 @@
+package com.launchdarkly.client;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import org.slf4j.Logger;
+
+public class PerClassLoggerFactory implements ILoggerFactory {
+ private final ILoggerFactory factory;
+ private final ConcurrentMap, Logger> staticLoggers;
+ public PerClassLoggerFactory(ILoggerFactory factory) {
+ this.factory = factory;
+ this.staticLoggers = new ConcurrentHashMap<>();
+ }
+
+ public Logger getLogger(Class> klass){
+ return staticLoggers.computeIfAbsent(klass, factory::getLogger);
+ }
+}
diff --git a/src/main/java/com/launchdarkly/client/PollingProcessor.java b/src/main/java/com/launchdarkly/client/PollingProcessor.java
index 134f955d7..288d67537 100644
--- a/src/main/java/com/launchdarkly/client/PollingProcessor.java
+++ b/src/main/java/com/launchdarkly/client/PollingProcessor.java
@@ -2,14 +2,13 @@
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
public class PollingProcessor implements UpdateProcessor {
- private static final Logger logger = LoggerFactory.getLogger(PollingProcessor.class);
+ private final Logger logger;
private final FeatureRequestor requestor;
private final LDConfig config;
@@ -20,6 +19,7 @@ public class PollingProcessor implements UpdateProcessor {
PollingProcessor(LDConfig config, FeatureRequestor requestor) {
this.requestor = requestor;
this.config = config;
+ this.logger = config.getLogger(PollingProcessor.class);
this.store = config.featureStore;
}
diff --git a/src/main/java/com/launchdarkly/client/RedisFeatureStore.java b/src/main/java/com/launchdarkly/client/RedisFeatureStore.java
index 8694d403d..e6cc9e75d 100644
--- a/src/main/java/com/launchdarkly/client/RedisFeatureStore.java
+++ b/src/main/java/com/launchdarkly/client/RedisFeatureStore.java
@@ -11,7 +11,6 @@
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
diff --git a/src/main/java/com/launchdarkly/client/RedisFeatureStoreBuilder.java b/src/main/java/com/launchdarkly/client/RedisFeatureStoreBuilder.java
index 6eeb85de7..cc87db184 100644
--- a/src/main/java/com/launchdarkly/client/RedisFeatureStoreBuilder.java
+++ b/src/main/java/com/launchdarkly/client/RedisFeatureStoreBuilder.java
@@ -2,7 +2,6 @@
import org.apache.http.client.utils.URIBuilder;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Protocol;
diff --git a/src/main/java/com/launchdarkly/client/StreamProcessor.java b/src/main/java/com/launchdarkly/client/StreamProcessor.java
index a27d444db..4e5ccd1ca 100644
--- a/src/main/java/com/launchdarkly/client/StreamProcessor.java
+++ b/src/main/java/com/launchdarkly/client/StreamProcessor.java
@@ -11,7 +11,6 @@
import org.apache.http.HttpHost;
import org.joda.time.DateTime;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.URI;
@@ -24,7 +23,7 @@ class StreamProcessor implements UpdateProcessor {
private static final String DELETE = "delete";
private static final String INDIRECT_PUT = "indirect/put";
private static final String INDIRECT_PATCH = "indirect/patch";
- private static final Logger logger = LoggerFactory.getLogger(StreamProcessor.class);
+ private final Logger logger;
private static final int DEAD_CONNECTION_INTERVAL_SECONDS = 300;
private final FeatureStore store;
@@ -40,6 +39,7 @@ class StreamProcessor implements UpdateProcessor {
StreamProcessor(String sdkKey, LDConfig config, FeatureRequestor requestor) {
this.store = config.featureStore;
this.config = config;
+ this.logger = config.getLogger(StreamProcessor.class);
this.sdkKey = sdkKey;
this.requestor = requestor;
ThreadFactory threadFactory = new ThreadFactoryBuilder()