Skip to content
This repository has been archived by the owner on May 30, 2024. It is now read-only.

Commit

Permalink
prepare 5.10.0 release (#273)
Browse files Browse the repository at this point in the history
* misc fixes/tests

* use java-sdk-common 1.0.0

* use okhttp-eventsource 2.3.0

* use okhttp-eventsource 2.3.1 for thread fix

* fix flaky tests due to change in EventSource error reporting

* remove support for indirect put and indirect patch

* fix typo in javadoc example code

* clean up polling logic, fix status updating after an outage, don't reinit store unnecessarily (#256)

* slightly change semantics of boolean setters, improve tests, misc cleanup

* avoid NPEs if LDUser was deserialized by Gson (#257)

* avoid NPEs if LDUser was deserialized by Gson

* add test

* fix release metadata

* prepare 4.14.1 release (#200)

* Releasing version 4.14.1

* exclude Kotlin metadata from jar + fix misc Gradle problems

* update CI and Gradle to test with newer JDKs (#259)

* update okhttp to 3.14.9 (fixes incompatibility with OpenJDK 8.0.252)

* prepare 4.14.2 release (#205)

* Releasing version 4.14.2

* update okhttp to 4.8.1 (fixes incompatibility with OpenJDK 8.0.252)

* gitignore

* Bump SnakeYAML from 1.19 to 1.26 to address CVE-2017-18640

* prepare 4.14.3 release (#209)

* Releasing version 4.14.3

* comments

* only log initialization message once in polling mode

* [ch89935] Correct some logging call format strings (#264)

Also adds debug logs for full exception information in a couple locations.

* [ch90109] Remove outdated trackMetric comment from before service support. (#265)

* Fix compatibility with Java 7.

* Remove import that is no longer used.

* add Java 7 build (#267)

* prepare 4.14.4 release (#214)

* Releasing version 4.14.4

* add and use getSocketFactory

* alignment

* add socketFactory to builder

* test socket factory builder

* preserve dummy CI config file when pushing to gh-pages (#271)

* fix concatenation when base URI has a context path (#270)

* fix shaded jar builds to exclude Jackson classes and not modify Jackson return types (#268)

* add test httpClientCanUseCustomSocketFactory for DefaultFeatureRequestor

* add httpClientCanUseCustomSocketFactory() test for DefaultEventSenderTest

* add httpClientCanUseCustomSocketFactory() test to StreamProcessorTest

* pass URI to in customSocketFactory event test

* make test less ambiguous

* copy rules to new FlagBuilder instances (#273)

* Bump guava version (#274)

* Removed the guides link

* increment versions when loading file data, so FlagTracker will work (#275)

* increment versions when loading file data, so FlagTracker will work

* update doc comment about flag change events with file data

* add ability to ignore duplicate keys in file data (#276)

* add alias events (#278)

* add alias events and function
* update tests for new functionality
* update javadoc strings

* add validation of javadoc build to CI

* update commons-codec to 1.15 (#279)

* Add support for experiment rollouts

* add tests and use seed for allocating user to partition

* test serialization and add check for isExperiment

* fix PollingProcessorTest test race condition + other test issues (#282)

* use launchdarkly-java-sdk-common 1.1.0-alpha-expalloc.2

* Update src/test/java/com/launchdarkly/sdk/server/EvaluatorTest.java

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* Update src/test/java/com/launchdarkly/sdk/server/EvaluatorTest.java

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* Update src/test/java/com/launchdarkly/sdk/server/EvaluatorTest.java

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* Update src/test/java/com/launchdarkly/sdk/server/EvaluatorTest.java

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* changes per code review comments

* Please enter the commit message for your changes. Lines starting

* fix null pointer exception

* address code review comments

* address more comments

* missed a ! for isUntracked()

* fix default boolean for json

* make untracked FALSE by default

* refactoring of bucketing logic to remove the need for an extra result object (#283)

* add comment to enum

* various JSON fixes, update common-sdk (#284)

* simlpify the logic and make it match node/.Net sdks

* Update src/main/java/com/launchdarkly/sdk/server/EventFactory.java

Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>

* add the same comment as the Node SDK

* Remove outdated/meaningless doc comment. (#286)

* protect against NPEs if flag/segment JSON contains a null value

* use java-sdk-common 1.2.0

* fix Jackson-related build issues (again) (#288)

* update to okhttp-eventsource patch for stream retry bug, improve tests (#289)

* update to okhttp-eventsource patch for stream retry bug, improve test

* add test for appropriate stream retry

* add public builder for FeatureFlagsState (#290)

* add public builder for FeatureFlagsState

* javadoc fixes

* clarify FileData doc comment to say you shouldn't use offline mode (#291)

* improve validation of SDK key so we won't throw an exception that contains the key (#293)

* fix javadoc link in FileData comment (#294)

* fix PollingProcessor 401 behavior and use new HTTP test helpers (#292)

* re-fix metadata to remove Jackson dependencies, also remove Class-Path from manifest (#295)

* make FeatureFlagsState.Builder.build() public (#297)

* clean up tests using java-test-helpers 1.1.0 (#296)

* use Releaser v2 config + newer CI images (#298)

* [ch123129] Fix `PollingDataSourceBuilder` example. (#299)

* Updates docs URLs

* always use US locale when parsing HTTP dates

* use Gson 2.8.9

* don't try to send more diagnostic events after an unrecoverable HTTP error

* ensure module-info file isn't copied into our jars during build

* use Gradle 7

* update build for benchmarks

* more Gradle 7 compatibility changes for benchmark job

* test with Java 17 in CI (#307)

* test with Java 17 in CI

* also test in Java 17 for Windows

* fix choco install command

* do date comparisons as absolute times, regardless of time zone (#310)

* fix suppression of nulls in JSON representations (#311)

* fix suppression of nulls in JSON representations

* distinguish between situations where we do or do not want to suppress nulls

* fix identify/track null user key check, also don't create index event for alias

* use latest java-sdk-common

* fix setting of trackEvents/trackReason in allFlagsState data when there's an experiment

* implement contract tests (#314)

* Merge Big Segments feature branch for 5.7.0 release (#316)

Includes Big Segments implementation and contract test support for the new behavior.

* Fix for pom including SDK common library as a dependency. (#317)

* use new logging API

* update readme notes about logging

* set base logger name for SDK per test

* comment

* javadoc fixes

* revert accidental commit

* Upload JUnit XML to CircleCI on failure (#320)

Fix a bug in the CircleCI config that was only uploading JUnit XML on _success_, not failure.

* Add application tag support (#319)

* Enforce 64 character limit on application tag values (#323)

* fix "wrong type" logic in evaluations when default value is null

* Rename master to main in .ldrelease/config.yml (#325)

* Simpler way of setting base URIs in Java (#322)

Now supports the `ServiceEndpoints` config for setting custom URIs for endpoints in a single place

* update logging info in readme

* use 1.0.0 release of logging package

* misc cleanup

* remove unnecessary extra interfaces, just use default methods instead

* make BigSegmentStoreWrapper.pollingDetectsStaleStatus test less timing-sensitive

* make LDEndToEndClientTest.test____SpecialHttpConfigurations less timing-sensitive

* make data source status tests less timing-sensitive

* use streaming JSON parsing for incoming LD data

* fix tests

* rm unused

* rm unused

* use okhttp-eventsource 2.6.0

* update eventsource to 2.6.1 to fix pom/manifest problem

* increase efficiency of summary event data structures (#335)

* make reusable EvaluationDetail instances as part of flag preprocessing (#336)

* make evaluator result object immutable and reuse instances

* comment

* avoid creating List iterators during evaluations

* remove unnecessary copy

* fix allFlagsState to not generate prereq eval events

* add "...ForAll" TestData methods to replace "...ForAllUsers"

* bump okhttp & okhttp-eventsource dependencies

* update comment to clarify that level() doesn't apply to SLF4J

* update readme to mention different logging examples in hello-java

* switch to use snapshot build of java-logging, pending next release

* level setting does not apply to SLF4J and JUL

* use java-logging 1.1.0 release

* make sure META-INF files are never mistaken for classes and relocated

* update shared data store test logic to pass ClientContext with logger

* enable external javadoc links for com.launchdarkly.logging types

* use variable for dependency version

Co-authored-by: Eli Bishop <eli@launchdarkly.com>
Co-authored-by: LaunchDarklyCI <dev@launchdarkly.com>
Co-authored-by: LaunchDarklyCI <LaunchDarklyCI@users.noreply.github.com>
Co-authored-by: Gavin Whelan <gwhelan@launchdarkly.com>
Co-authored-by: ssrm <ssrm@users.noreply.github.com>
Co-authored-by: Harpo Roeder <hroeder@launchdarkly.com>
Co-authored-by: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com>
Co-authored-by: Elliot <35050275+Apache-HB@users.noreply.github.com>
Co-authored-by: Robert J. Neal <rneal@launchdarkly.com>
Co-authored-by: Robert J. Neal <robertjneal@users.noreply.github.com>
Co-authored-by: Sam Stokes <sstokes@launchdarkly.com>
Co-authored-by: LaunchDarklyReleaseBot <launchdarklyreleasebot@launchdarkly.com>
Co-authored-by: Ember Stevens <ember.stevens@launchdarkly.com>
Co-authored-by: ember-stevens <79482775+ember-stevens@users.noreply.github.com>
Co-authored-by: Alex Engelberg <alex.benjamin.engelberg@gmail.com>
Co-authored-by: Alex Engelberg <aengelberg@launchdarkly.com>
  • Loading branch information
17 people committed Jul 29, 2022
1 parent 9364f98 commit 2bc0371
Show file tree
Hide file tree
Showing 76 changed files with 1,158 additions and 565 deletions.
8 changes: 5 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,15 @@ The project in the `benchmarks` subdirectory uses [JMH](https://openjdk.java.net

### Logging

Currently the SDK uses SLF4J for all log output. Here some things to keep in mind for good logging behavior:
The SDK uses a LaunchDarkly logging facade, [`com.launchdarkly.logging`](https://github.com/launchdarkly/java-logging). By default, this facade sends output to SLF4J.

Here some things to keep in mind for good logging behavior:

1. Stick to the standardized logger name scheme defined in `Loggers.java`, preferably for all log output, but definitely for all log output above `DEBUG` level. Logger names can be useful for filtering log output, so it is desirable for users to be able to reference a clear, stable logger name like `com.launchdarkly.sdk.server.LDClient.Events` rather than a class name like `com.launchdarkly.sdk.server.EventSummarizer` which is an implementation detail. The text of a log message should be distinctive enough that we can easily find which class generated the message.

2. Use parameterized messages (`Logger.MAIN.info("The value is {}", someValue)`) rather than string concatenation (`Logger.MAIN.info("The value is " + someValue)`). This avoids the overhead of string concatenation if the logger is not enabled for that level. If computing the value is an expensive operation, and it is _only_ relevant for logging, consider implementing that computation via a custom `toString()` method on some wrapper type so that it will be done lazily only if the log level is enabled.
2. Use parameterized messages (`logger.info("The value is {}", someValue)`) rather than string concatenation (`logger.info("The value is " + someValue)`). This avoids the overhead of string concatenation if the logger is not enabled for that level. If computing the value is an expensive operation, and it is _only_ relevant for logging, consider implementing that computation via a custom `toString()` method on some wrapper type so that it will be done lazily only if the log level is enabled.

3. Exception stacktraces should only be logged at debug level. For instance: `Logger.MAIN.warn("An error happened: {}", ex.toString()); Logger.MAIN.debug(ex.toString(), ex)`. Also, consider whether the stacktrace would be at all meaningful in this particular context; for instance, in a `try` block around a network I/O operation, the stacktrace would only tell us (a) some internal location in Java standard libraries and (b) the location in our own code where we tried to do the operation; (a) is very unlikely to tell us anything that the exception's type and message doesn't already tell us, and (b) could be more clearly communicated by just writing a specific log message.
3. There is a standard pattern for logging exceptions, using the `com.launchdarkly.logging.LogValues` helpers. First, log the basic description of the exception at whatever level is appropriate (`WARN` or `ERROR`): `logger.warn("An error happened: {}", LogValues.exceptionSummary(ex))`. Then, log a stack at debug level: `logger.debug(LogValues.exceptionTrace(ex))`. The `exceptionTrace` helper is lazily evaluated so that the stacktrace will only be computed if debug logging is actually enabled. However, consider whether the stacktrace would be at all meaningful in this particular context; for instance, in a `try` block around a network I/O operation, the stacktrace would only tell us (a) some internal location in Java standard libraries and (b) the location in our own code where we tried to do the operation; (a) is very unlikely to tell us anything that the exception's type and message doesn't already tell us, and (b) could be more clearly communicated by just writing a specific log message.

### Code coverage

Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,13 @@ Refer to the [SDK reference guide](https://docs.launchdarkly.com/sdk/server-side

## Logging

The LaunchDarkly SDK uses [SLF4J](https://www.slf4j.org/). All loggers are namespaced under `com.launchdarkly`. For an example configuration check out the [hello-java](https://github.com/launchdarkly/hello-java) project.
By default, the LaunchDarkly SDK uses [SLF4J](https://www.slf4j.org/). SLF4J has its own configuration mechanisms for determining where output will go, and filtering by level and/or logger name.

The SDK can also be configured to use other adapters from the [com.launchdarkly.logging](https://github.com/launchdarkly/java-logging) facade instead of SLF4J. See `LoggingConfigurationBuilder`. This allows the logging behavior to be completely determined by the application, rather than by external SLF4J configuration.

For an example of using the default SLF4J behavior with a simple console logging configuration, check out the [`slf4j-logging` branch](https://github.com/launchdarkly/hello-java/tree/slf4j-logging) of the [`hello-java`](https://github.com/launchdarkly/hello-java) project. The [main branch](https://github.com/launchdarkly/hello-java) of `hello-java` uses console logging that is programmatically configured without SLF4J.

All loggers are namespaced under `com.launchdarkly`, if you are using name-based filtering.

Be aware of two considerations when enabling the DEBUG log level:
1. Debug-level logs can be very verbose. It is not recommended that you turn on debug logging in high-volume environments.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public BenchmarkInputs() {
.dataStore(specificDataStore(dataStore))
.events(Components.noEvents())
.dataSource(Components.externalUpdatesOnly())
.logging(Components.noLogging())
.build();
client = new LDClient(SDK_KEY, config);

Expand Down
10 changes: 10 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ ext.versions = [
"guava": "30.1-jre",
"jackson": "2.11.2",
"launchdarklyJavaSdkCommon": "1.3.0",
"launchdarklyLogging": "1.1.0",
"okhttp": "4.9.3", // specify this for the SDK build instead of relying on the transitive dependency from okhttp-eventsource
"okhttpEventsource": "2.6.2",
"slf4j": "1.7.21",
Expand Down Expand Up @@ -131,6 +132,7 @@ libraries.internal = [
// also as package exports (i.e. it provides them if a newer version is not available
// from an import).
libraries.external = [
"com.launchdarkly:launchdarkly-logging:${versions.launchdarklyLogging}",
"org.slf4j:slf4j-api:${versions.slf4j}"
]

Expand Down Expand Up @@ -322,6 +324,14 @@ javadoc {
// Use test classpath so Javadoc won't complain about java-sdk-common classes that internally
// reference stuff we don't use directly, like Jackson
classpath = sourceSets.test.compileClasspath

// The following should allow hyperlinks to com.launchdarkly.logging classes to go to
// the correct external URLs
if (options instanceof StandardJavadocDocletOptions) {
(options as StandardJavadocDocletOptions).links(
"https://javadoc.io/doc/com.launchdarkly/launchdarkly-logging/${versions.launchdarklyLogging}"
)
}
}

// Force the Javadoc build to fail if there are any Javadoc warnings. See: https://discuss.gradle.org/t/javadoc-fail-on-warning/18141/3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public SdkClientEntity(TestService owner, CreateInstanceParams params) {
this.logger = LoggerFactory.getLogger(params.tag);
logger.info("Starting SDK client");

LDConfig config = buildSdkConfig(params.configuration);
LDConfig config = buildSdkConfig(params.configuration, params.tag);
this.client = new LDClient(params.configuration.credential, config);
if (!client.isInitialized() && !params.configuration.initCanFail) {
throw new RuntimeException("client initialization failed or timed out");
Expand Down Expand Up @@ -184,9 +184,11 @@ public void close() {
logger.info("Test ended");
}

private LDConfig buildSdkConfig(SdkConfigParams params) {
private LDConfig buildSdkConfig(SdkConfigParams params, String tag) {
LDConfig.Builder builder = new LDConfig.Builder();

builder.logging(Components.logging().baseLoggerName(tag + ".sdk"));

if (params.startWaitTimeMs != null) {
builder.startWait(Duration.ofMillis(params.startWaitTimeMs.longValue()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.launchdarkly.logging.LDLogger;
import com.launchdarkly.sdk.EvaluationReason.BigSegmentsStatus;
import com.launchdarkly.sdk.server.interfaces.BigSegmentStore;
import com.launchdarkly.sdk.server.interfaces.BigSegmentStoreStatusProvider.Status;
Expand All @@ -15,7 +16,6 @@

import org.apache.commons.codec.digest.DigestUtils;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.slf4j.Logger;

import java.io.Closeable;
import java.io.IOException;
Expand All @@ -27,23 +27,23 @@
import java.util.concurrent.TimeUnit;

class BigSegmentStoreWrapper implements Closeable {
private static final Logger logger = Loggers.BIG_SEGMENTS;

private final BigSegmentStore store;
private final Duration staleAfter;
private final ScheduledFuture<?> pollFuture;
private final LoadingCache<String, Membership> cache;
private final EventBroadcasterImpl<StatusListener, Status> statusProvider;

private final LDLogger logger;
private final Object statusLock = new Object();
private Status lastStatus;

BigSegmentStoreWrapper(BigSegmentsConfiguration config,
EventBroadcasterImpl<StatusListener, Status> statusProvider,
ScheduledExecutorService sharedExecutor) {
ScheduledExecutorService sharedExecutor,
LDLogger logger) {
this.store = config.getStore();
this.staleAfter = config.getStaleAfter();
this.statusProvider = statusProvider;
this.logger = logger;

CacheLoader<String, Membership> loader = new CacheLoader<String, Membership>() {
@Override
Expand Down
33 changes: 29 additions & 4 deletions src/main/java/com/launchdarkly/sdk/server/ClientContextImpl.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.launchdarkly.sdk.server;

import com.launchdarkly.sdk.server.interfaces.ApplicationInfo;
import com.launchdarkly.logging.LDLogger;
import com.launchdarkly.logging.Logs;
import com.launchdarkly.sdk.server.interfaces.BasicConfiguration;
import com.launchdarkly.sdk.server.interfaces.ClientContext;
import com.launchdarkly.sdk.server.interfaces.HttpConfiguration;
Expand Down Expand Up @@ -52,11 +53,35 @@ private ClientContextImpl(
ScheduledExecutorService sharedExecutor,
DiagnosticAccumulator diagnosticAccumulator
) {
this.basicConfiguration = new BasicConfiguration(sdkKey, configuration.offline, configuration.threadPriority, configuration.applicationInfo, configuration.serviceEndpoints);
// There is some temporarily over-elaborate logic here because the component factory interfaces can't
// be updated to make the dependencies more sensible till the next major version.
BasicConfiguration tempBasic = new BasicConfiguration(sdkKey, configuration.offline, configuration.threadPriority,
configuration.applicationInfo, configuration.serviceEndpoints, LDLogger.none());
this.loggingConfiguration = configuration.loggingConfigFactory.createLoggingConfiguration(tempBasic);
LDLogger baseLogger = LDLogger.withAdapter(
loggingConfiguration.getLogAdapter() == null ? Logs.none() : loggingConfiguration.getLogAdapter(),
loggingConfiguration.getBaseLoggerName() == null ? Loggers.BASE_LOGGER_NAME :
loggingConfiguration.getBaseLoggerName()
);

this.basicConfiguration = new BasicConfiguration(
sdkKey,
configuration.offline,
configuration.threadPriority,
configuration.applicationInfo,
configuration.serviceEndpoints,
baseLogger
);

this.httpConfiguration = configuration.httpConfigFactory.createHttpConfiguration(basicConfiguration);
this.loggingConfiguration = configuration.loggingConfigFactory.createLoggingConfiguration(basicConfiguration);



if (this.httpConfiguration.getProxy() != null) {
baseLogger.info("Using proxy: {} {} authentication.",
this.httpConfiguration.getProxy(),
this.httpConfiguration.getProxyAuthentication() == null ? "without" : "with");
}

this.sharedExecutor = sharedExecutor;

if (!configuration.diagnosticOptOut && diagnosticAccumulator != null) {
Expand Down
53 changes: 52 additions & 1 deletion src/main/java/com/launchdarkly/sdk/server/Components.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import static com.launchdarkly.sdk.server.ComponentsImpl.NULL_EVENT_PROCESSOR_FACTORY;

import com.launchdarkly.logging.LDLogAdapter;
import com.launchdarkly.logging.Logs;
import com.launchdarkly.sdk.server.ComponentsImpl.EventProcessorBuilderImpl;
import com.launchdarkly.sdk.server.ComponentsImpl.HttpBasicAuthentication;
import com.launchdarkly.sdk.server.ComponentsImpl.HttpConfigurationBuilderImpl;
Expand Down Expand Up @@ -316,14 +318,63 @@ public static HttpAuthentication httpBasicAuthentication(String username, String
* .build();
* </code></pre>
*
* @return a factory object
* @return a configuration builder
* @since 5.0.0
* @see LDConfig.Builder#logging(com.launchdarkly.sdk.server.interfaces.LoggingConfigurationFactory)
*/
public static LoggingConfigurationBuilder logging() {
return new LoggingConfigurationBuilderImpl();
}

/**
* Returns a configuration builder for the SDK's logging configuration, specifying the
* implementation of logging to use.
* <p>
* This is a shortcut for <code>Components.logging().adapter(logAdapter)</code>. The
* <a href="https://github.com/launchdarkly/java-logging"><code>com.launchdarkly.logging</code></a>
* API defines the {@link LDLogAdapter} interface to specify where log output should be sent. By default,
* it is set to {@link com.launchdarkly.logging.LDSLF4J#adapter()}, meaning that output will be sent to
* <a href="https://www.slf4j.org/">SLF4J</a> and controlled by the SLF4J configuration. You may use
* the {@link com.launchdarkly.logging.Logs} factory methods, or a custom implementation, to handle log
* output differently. For instance, you may specify {@link com.launchdarkly.logging.Logs#basic()} for
* simple console output, or {@link com.launchdarkly.logging.Logs#toJavaUtilLogging()} to use the
* <code>java.util.logging</code> framework.
* <p>
* Passing this to {@link LDConfig.Builder#logging(com.launchdarkly.sdk.server.interfaces.LoggingConfigurationFactory)},
* after setting any desired properties on the builder, applies this configuration to the SDK.
* <pre><code>
* LDConfig config = new LDConfig.Builder()
* .logging(
* Components.logging(Logs.basic())
* )
* .build();
* </code></pre>
*
* @param logAdapter the log adapter
* @return a configuration builder
* @since 5.10.0
* @see LDConfig.Builder#logging(com.launchdarkly.sdk.server.interfaces.LoggingConfigurationFactory)
* @see LoggingConfigurationBuilder#adapter(LDLogAdapter)
*/
public static LoggingConfigurationBuilder logging(LDLogAdapter logAdapter) {
return logging().adapter(logAdapter);
}

/**
* Returns a configuration builder that turns off SDK logging.
* <p>
* Passing this to {@link LDConfig.Builder#logging(com.launchdarkly.sdk.server.interfaces.LoggingConfigurationFactory)}
* applies this configuration to the SDK.
* <p>
* It is equivalent to <code>Components.logging(com.launchdarkly.logging.Logs.none())</code>.
*
* @return a configuration builder
* @since 5.10.0
*/
public static LoggingConfigurationBuilder noLogging() {
return logging().adapter(Logs.none());
}

/**
* Returns a configuration builder for the SDK's application metadata.
* <p>
Expand Down
Loading

0 comments on commit 2bc0371

Please sign in to comment.