Skip to content
This repository was archived by the owner on May 30, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/main/java/com/launchdarkly/client/Clause.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
1 change: 0 additions & 1 deletion src/main/java/com/launchdarkly/client/EventProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion src/main/java/com/launchdarkly/client/FeatureFlag.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/com/launchdarkly/client/ILoggerFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.launchdarkly.client;

import org.slf4j.Logger;

public interface ILoggerFactory {
Logger getLogger(Class<?> className);
}

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.launchdarkly.client;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.HashMap;
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/com/launchdarkly/client/LDClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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();

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with this change-- we've seen enough cases where an unknown FF is expected (e.g. test scenarios), so debug does feel appropriate to me.

sendFlagRequestEvent(featureKey, user, defaultValue, defaultValue, null);
return defaultValue;
}
Expand Down
14 changes: 11 additions & 3 deletions src/main/java/com/launchdarkly/client/LDConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
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;

/**
* 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");
Expand All @@ -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();

Expand All @@ -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;
Expand All @@ -69,6 +72,10 @@ protected LDConfig(Builder builder) {
this.reconnectTimeMs = builder.reconnectTimeMs;
}

public Logger getLogger(Class<?> klass) {
return this.getLogger(klass);
}

/**
* A <a href="http://en.wikipedia.org/wiki/Builder_pattern">builder</a> that helps construct {@link com.launchdarkly.client.LDConfig} objects. Builder
* calls can be chained, enabling the following pattern:
Expand Down Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion src/main/java/com/launchdarkly/client/LDUser.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
23 changes: 23 additions & 0 deletions src/main/java/com/launchdarkly/client/LoggerFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.launchdarkly.client;

import java.util.concurrent.atomic.AtomicReference;
import org.slf4j.Logger;

public class LoggerFactory {

private static AtomicReference<ILoggerFactory> factory = new AtomicReference<>();

public static void install(ILoggerFactory factory) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@keynan What do you think about making the LoggerFactory part of the config? Then this method doesn't need to be public, and it makes configuring the Logger consistent with the rest of the LDClient setup.
If there's a reason you need this to be configurable after the client has been created, then I'm curious..
(Depending on your logging framework, log levels can be changed at runtime outside of any code changes to this library)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh! I would much rather have this be part of a constructor somewhere. This way was about expediency to start the conversation. I can amend the PR on Monday. How long, do you think, before we'd see it in a release?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In many cases loggers where instantiated in classes that did not refrence the config so I've left them as is. Where possible it now goes to the LDConfig to get a logger instance.

I couldn't get gradle to build locally so you should double check this all works before merging :/ sorry for the hassle

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);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.launchdarkly.client;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;

Expand Down
18 changes: 18 additions & 0 deletions src/main/java/com/launchdarkly/client/PerClassLoggerFactory.java
Original file line number Diff line number Diff line change
@@ -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<Class<?>, Logger> staticLoggers;
public PerClassLoggerFactory(ILoggerFactory factory) {
this.factory = factory;
this.staticLoggers = new ConcurrentHashMap<>();
}

public Logger getLogger(Class<?> klass){
return staticLoggers.computeIfAbsent(klass, factory::getLogger);
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/launchdarkly/client/PollingProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/launchdarkly/client/StreamProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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()
Expand Down