HomeGuidesAPI Reference
Submit Documentation FeedbackJoin Developer CommunityOptimizely GitHubOptimizely NuGetLog In
Hey! These docs are for version 2.1.0-full-stack, which is no longer officially supported. Click here for the latest version, 1.0!

Configure the logger

The logger logs information about your experiments to help you with debugging. You can customize where log information is sent and what kind of information is tracked.

In some SDKs, logging functionality is not enabled by default. See Default logging in each SDK below for a list of built-in logger support in each SDK.

To improve your experience setting up the SDK and configuring your production environment, we recommend that you pass in a logger for your Optimizely client. See the code examples below.

# android-logger.properties example (JSON)

# Java Core SDK
logger.com.optimizely.ab.Optimizely=DEBUG:Optly.core
logger.com.optimizely.ab.annotations=DEBUG:Optly.annotations
logger.com.optimizely.ab.bucketing=DEBUG:Optly.bucketing
logger.com.optimizely.ab.config=DEBUG:Optly.config
logger.com.optimizely.ab.error=DEBUG:Optly.error
logger.com.optimizely.ab.event=DEBUG:Optly.event
logger.com.optimizely.ab.internal=DEBUG:Optly.internal

# Android SDK
logger.com.optimizely.ab.android.sdk=DEBUG:Optly.androidSdk
logger.com.optimizely.ab.android.event_handler=DEBUG:Optly.eventHandler
logger.com.optimizely.ab.android.shared=DEBUG:Optly.shared
logger.com.optimizely.ab.android.user_profile=DEBUG:Optly.userProfile

# Disable most SDK logs by commenting all other lines and uncommenting below
# logger.com.optimizely.ab=ASSERT:Optly
using OptimizelySDK;
using OptimizelySDK.Logger;

ILogger logger = new DefaultLogger();
// Passing default logger
Optimizely optimizelyClient = new Optimizely(
    datafile: datafile,
    logger: logger
);
// Provide a SLF4j binding like logback or log4j

compile group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.25'
compile group: 'log4j', name: 'log4j', version: '1.2.17'

//For formatting: under slf4j.properties
  
# Root logger option
log4j.rootLogger=DEBUG, stdout

# Redirect log messages to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d

{yyyy-MM-dd HH:mm:ss}
%-5p %c

{1}
:%L - %m%n
const defaultLogger = require('@optimizely/optimizely-sdk/lib/plugins/logger');
const LOG_LEVEL = require('@optimizely/optimizely-sdk/lib/utils/enums').LOG_LEVEL;

/**
 * To set a log level choose one of the following:
 * 
 * NOTSET: LOG_LEVEL.NOTSET
 * DEBUG: LOG_LEVEL.DEBUG
 * INFO: LOG_LEVEL.INFO
 * WARNING: LOG_LEVEL.WARNING
 * ERROR: LOG_LEVEL.ERROR
 *
 * To define a minimum logging level pass it in during initialization.
 * The example below shows a minimum logging level of INFO.
 */
var optimizelyClientInstance = optimizely.createInstance({
  datafile,
  logger: defaultLogger.createLogger({
    logLevel: LOG_LEVEL.INFO
  }),
});
const defaultLogger = require("@optimizely/optimizely-sdk/lib/plugins/logger");
const LOG_LEVEL = require("@optimizely/optimizely-sdk/lib/utils/enums")
  .LOG_LEVEL;

/**
 * To set a log level choose one of the following:
 * 
 * NOTSET: LOG_LEVEL.NOTSET
 * DEBUG: LOG_LEVEL.DEBUG
 * INFO: LOG_LEVEL.INFO
 * WARNING: LOG_LEVEL.WARNING
 * ERROR: LOG_LEVEL.ERROR
 *
 * To define a minimum logging level pass it in during initialization.
 * The example below shows a minimum logging level of INFO.
 */
var optimizelyClient = optimizely.createInstance({
  datafile,
  logger: defaultLogger.createLogger({
    logLevel: LOG_LEVEL.INFO
  })
});
CustomLogger *customLogger = [[CustomLogger alloc] init];

OPTLYManager *manager = [[OPTLYManager alloc] initWithBuilder:[OPTLYManagerBuilder  builderWithBlock:^(OPTLYManagerBuilder * _Nullable builder) {
  builder.sdkKey = @"SDK_KEY_HERE";
  builder.logger = customLogger;
}]];

OPTLYLoggerDefault *optlyLogger = [[OPTLYLoggerDefault alloc] initWithLogLevel:OptimizelyLogLevelAll];
OPTLYManager *manager = [[OPTLYManager alloc] initWithBuilder:[OPTLYManagerBuilder  builderWithBlock:^(OPTLYManagerBuilder * _Nullable builder) {
  builder.sdkKey = @"SDK_KEY_HERE";
  builder.logger = optlyLogger;
}]];
use Monolog\Logger;
use Optimizely\Logger\DefaultLogger;

$optimizelyClient = new Optimizely($datafile, null, new DefaultLogger());

/**
 * To set a log level choose one of the following:
 * 
 * DEBUG: Logger.DEBUG
 * INFO: Logger.INFO
 * WARNING: Logger.WARNING
 * ERROR: Logger.ERROR
 * CRITICAL: Logger.CRITICAL
 *
 * To define a different minimum logging level pass it in during initialization
 * The example below shows a minimum logging level of WARNING and outputs
 * to standard out
 */

$optimizelyClient = new Optimizely($datafile, null, new
DefaultLogger(Logger::WARNING, "stdout"));
import logging
from optimizely import logger

optimizely_client = optimizely.Optimizely(
  datafile,
  logger=logger.SimpleLogger()
)

# To set a log level choose one of the following:
# NOTSET: logging.NOTSET
# DEBUG: logging.DEBUG
# INFO: logging.INFO
# WARNING: logging.WARNING
# ERROR: logging.ERROR
# CRITICAL: logging.CRITICAL

# To define a different minimum logging level pass it in during initialization
# The example below shows a minimum logging level of WARNING

optimizely_client = optimizely.Optimizely(
  datafile,
  logger=logger.SimpleLogger(min_level=logging.WARNING)
)
optimizely_client = Optimizely::Project.new(
  datafile,
  nil, # don't override the EventDispatcher
  Optimizely::SimpleLogger.new
)
let customLogger: CustomLogger? = CustomLogger()

let manager = OPTLYManager(builder: OPTLYManagerBuilder(block: { (builder) in
  builder?.sdkKey = "SDK_KEY_HERE"
  builder?.logger = customLogger
}))

let optlyLogger: OPTLYLoggerDefault? = OPTLYLoggerDefault(logLevel: OptimizelyLogLevel.all)

let manager = OPTLYManager(builder: OPTLYManagerBuilder(block: { (builder) in
  builder?.sdkKey = "SDK_KEY_HERE"
  builder?.logger = optlyLogger
}))

Log levels

The log levels vary slightly among SDKs but are generally as follows:

Log LevelExplanation
CRITICALEvents that cause the app to crash are logged.
ERROREvents that prevent experiments from functioning correctly (for example, invalid datafile in initialization and invalid experiment keys or event keys) are logged. The user can take action to correct.
WARNINGEvents that don't prevent experiments from functioning correctly, but can have unexpected outcomes (for example, future API deprecation, logger or error handler are not set properly, and nil values from getters) are logged.
DEBUGAny information related to errors that can help us debug the issue (for example, experiment is not running, user is not in experiment, and the bucket value generated by our helper method) are logged.
INFOEvents of significance (for example, activate started, activate succeeded, tracking started, and tracking succeeded) are logged. This is helpful in showing the lifecycle of an API call.

Default logging in each SDK

  • Android: For the Android SDK, you can use our Android SLF4J logger. Logging verbosity can be controlled via the android-logger.properties file. This file can be placed in src/main/resources. You can also include a copy in src/release/resources with different settings for the build you release to the Play Store. Read about advanced configuration options.
  • iOS: You can use our default logger and configure OptimizelyLogLevelInfo. You can initialize it with any log level and pass it in when creating an Optimizely instance. You can also implement your own logger and pass it in the builder when creating an Optimizely instance.
  • Java: In the Java SDK, logging functionality is not enabled by default. To improve your experience setting up the SDK and configuring your production environment, we recommend that you include a SLF4J implementation in your dependencies. For the Java SDK, we require the use of an SLF4J implementation.
  • JavaScript: By default, the JavaScript SDK uses our Logger implementation. You can also implement your own logger and pass it into the builder when creating an Optimizely instance. It's also possible to configure the log level threshold of the default logger without implementing your own logger. You can do so by passing the constructor an integer logLevel, and these are the possible levels.
  • PHP: You can use our Logger implementation out of the box, available here.
  • Python: You can use our SimpleLogger implementation out of the box, available here.
  • Ruby: You can use our SimpleLogger implementation out of the box, available here.