Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
4 changes: 2 additions & 2 deletions android/src/main/assets/logback.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<configuration
<!-- <configuration
xmlns="https://tony19.github.io/logback-android/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://tony19.github.io/logback-android/xml https://cdn.jsdelivr.net/gh/tony19/logback-android/logback.xsd"
Expand All @@ -15,4 +15,4 @@
<root level="DEBUG">
<appender-ref ref="logcat" />
</root>
</configuration>
</configuration> -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.optimizely.optimizely_flutter_sdk;
import com.optimizely.optimizely_flutter_sdk.helper_classes.Constants;

import android.os.Handler;
import android.os.Looper;

import java.util.HashMap;
import java.util.Map;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import io.flutter.plugin.common.MethodChannel;

public class FlutterLogbackAppender extends AppenderBase<ILoggingEvent> {

public static final String CHANNEL_NAME = "optimizely_flutter_sdk_logger";
public static MethodChannel channel;
private static final Handler mainThreadHandler = new Handler(Looper.getMainLooper());

public static void setChannel(MethodChannel channel) {
FlutterLogbackAppender.channel = channel;
}

@Override
protected void append(ILoggingEvent event) {
if (channel == null) {
return;
}

String message = event.getFormattedMessage();
String level = event.getLevel().toString();
int logLevel = convertLogLevel(level);
Map<String, Object> logData = new HashMap<>();
logData.put("level", logLevel);
logData.put("message", message);

mainThreadHandler.post(() -> {
if (channel != null) {
channel.invokeMethod("log", logData);
}
});
}

int convertLogLevel(String logLevel) {
if (logLevel == null || logLevel.isEmpty()) {
return 3;
}

switch (logLevel.toUpperCase()) {
case "ERROR":
return 1;
case "WARN":
return 2;
case "INFO":
return 3;
case "DEBUG":
return 4;
default:
return 3;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,19 @@

import io.flutter.embedding.engine.plugins.activity.ActivityAware;

import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;


/** OptimizelyFlutterSdkPlugin */
public class OptimizelyFlutterSdkPlugin extends OptimizelyFlutterClient implements FlutterPlugin, ActivityAware, MethodCallHandler {

public static MethodChannel channel;
private Appender<ILoggingEvent> flutterLogbackAppender;

@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
Expand Down Expand Up @@ -157,11 +166,32 @@ public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
channel = new MethodChannel(binding.getBinaryMessenger(), "optimizely_flutter_sdk");
channel.setMethodCallHandler(this);
context = binding.getApplicationContext();

MethodChannel loggerChannel = new MethodChannel(binding.getBinaryMessenger(), FlutterLogbackAppender.CHANNEL_NAME);
FlutterLogbackAppender.setChannel(loggerChannel);

// Add appender to logback
flutterLogbackAppender = new FlutterLogbackAppender();
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
flutterLogbackAppender.setContext(lc);
flutterLogbackAppender.start();
Logger rootLogger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
rootLogger.setLevel(ch.qos.logback.classic.Level.ALL);
rootLogger.addAppender(flutterLogbackAppender);
}

@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
channel.setMethodCallHandler(null);
// Stop and detach the appender
if (flutterLogbackAppender != null) {
Logger rootLogger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
rootLogger.detachAppender(flutterLogbackAppender);
flutterLogbackAppender.stop();
flutterLogbackAppender = null;
}
// Clean up the channel
FlutterLogbackAppender.setChannel(null);
}

@Override
Expand Down
1 change: 0 additions & 1 deletion ios/Classes/HelperClasses/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ struct RequestParameterKey {
static let reasons = "reasons"
static let decideOptions = "optimizelyDecideOption"
static let defaultLogLevel = "defaultLogLevel"
static let useCustomLogger = "useCustomLogger"
static let eventBatchSize = "eventBatchSize"
static let eventTimeInterval = "eventTimeInterval"
static let eventMaxQueueSize = "eventMaxQueueSize"
Expand Down
13 changes: 4 additions & 9 deletions ios/Classes/SwiftOptimizelyFlutterSdkPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,10 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin {
notificationIdsTracker.removeValue(forKey: sdkKey)
optimizelyClientsTracker.removeValue(forKey: sdkKey)

// Check if custom logger is requested
var logger: OPTLogger?
if let useCustomLogger = parameters[RequestParameterKey.useCustomLogger] as? Bool, useCustomLogger {
// OptimizelyFlutterLogger bridges iOS logs to Flutter via Method Channel
// When useCustomLogger = true:
// iOS SDK log → OptimizelyFlutterLogger → Flutter Method Channel → Flutter console
logger = OptimizelyFlutterLogger()
}

// OptimizelyFlutterLogger bridges iOS logs to Flutter via Method Channel
// iOS SDK log → OptimizelyFlutterLogger → Flutter Method Channel → Flutter console
var logger: OPTLogger = OptimizelyFlutterLogger()

// Creating new instance
let optimizelyInstance = OptimizelyClient(
sdkKey:sdkKey,
Expand Down
12 changes: 2 additions & 10 deletions lib/optimizely_flutter_sdk.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,6 @@ class OptimizelyFlutterSdk {
final OptimizelyLogLevel _defaultLogLevel;
final SDKSettings _sdkSettings;
static OptimizelyLogger? _customLogger;
/// Set a custom logger for the SDK
static void setLogger(OptimizelyLogger logger) {
_customLogger = logger;
LoggerBridge.initialize(logger);
}
/// Get the current logger
static OptimizelyLogger? get logger {
return _customLogger;
Expand All @@ -97,11 +92,8 @@ class OptimizelyFlutterSdk {
_defaultLogLevel = defaultLogLevel,
_sdkSettings = sdkSettings {
// Set the logger if provided
if (logger != null) {
setLogger(logger);
} else {
logWarning("Logger not provided.");
}
_customLogger = logger ?? DefaultOptimizelyLogger();
LoggerBridge.initialize(_customLogger);
}

/// Starts Optimizely SDK (Synchronous) with provided sdkKey.
Expand Down
5 changes: 4 additions & 1 deletion lib/src/logger/flutter_logger.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:flutter/foundation.dart';
import 'package:optimizely_flutter_sdk/src/data_objects/log_level.dart';

abstract class OptimizelyLogger {
Expand All @@ -8,7 +9,9 @@ abstract class OptimizelyLogger {
class DefaultOptimizelyLogger implements OptimizelyLogger {
@override
void log(OptimizelyLogLevel level, String message) {
print('[OPTIMIZELY] [${level.name.toUpperCase()}]: $message');
if (kDebugMode) {
print('[OPTIMIZELY] [${level.name.toUpperCase()}]: $message');
}
}
}

Expand Down
1 change: 0 additions & 1 deletion lib/src/optimizely_client_wrapper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ class OptimizelyClientWrapper {
Constants.eventBatchSize: eventOptions.batchSize,
Constants.eventTimeInterval: eventOptions.timeInterval,
Constants.eventMaxQueueSize: eventOptions.maxQueueSize,
Constants.useCustomLogger: logger != null,
};

// Odp Request params
Expand Down
1 change: 0 additions & 1 deletion lib/src/utils/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ class Constants {
static const String optimizelyDecideOption = "optimizelyDecideOption";
static const String optimizelySegmentOption = "optimizelySegmentOption";
static const String optimizelySdkSettings = "optimizelySdkSettings";
static const String useCustomLogger = 'useCustomLogger';
static const String defaultLogLevel = "defaultLogLevel";
static const String payload = "payload";
static const String value = "value";
Expand Down