Skip to content

Commit be95ef5

Browse files
build: add Optimizely SDK logger classes
- Add FlutterOptimizelyLogger class implementing OPTLogger protocol - Add constants for customLogger and loggerChannel - Implement FlutterMethodChannel for invoking log method - Add logger field to OptimizelyFlutterSdk constructor - Initialize custom logger in OptimizelyClientWrapper - Create LoggerBridge to handle log method calls - Implement OptimizelyLogger interface and DefaultOptimizelyLogger class
1 parent bbb4790 commit be95ef5

File tree

8 files changed

+134
-15
lines changed

8 files changed

+134
-15
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import Flutter
2+
import Optimizely
3+
4+
public class FlutterOptimizelyLogger: NSObject, OPTLogger {
5+
public static var logLevel: OptimizelyLogLevel = .info
6+
7+
private static let loggerChannel = FlutterMethodChannel(
8+
name: "optimizely_flutter_sdk_logger",
9+
binaryMessenger: SwiftOptimizelyFlutterSdkPlugin.registrar?.messenger() ?? FlutterEngine().binaryMessenger
10+
)
11+
12+
public required override init() {
13+
super.init()
14+
}
15+
16+
public func log(level: OptimizelyLogLevel, message: String) {
17+
// Ensure we're on the main thread when calling Flutter
18+
DispatchQueue.main.async {
19+
Self.loggerChannel.invokeMethod("log", arguments: [
20+
"level": level.rawValue,
21+
"message": message
22+
])
23+
}
24+
}
25+
}

ios/Classes/HelperClasses/Constants.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ struct RequestParameterKey {
9191
static let reasons = "reasons"
9292
static let decideOptions = "optimizelyDecideOption"
9393
static let defaultLogLevel = "defaultLogLevel"
94+
static let customLogger = "customLogger"
9495
static let eventBatchSize = "eventBatchSize"
9596
static let eventTimeInterval = "eventTimeInterval"
9697
static let eventMaxQueueSize = "eventMaxQueueSize"

ios/Classes/SwiftOptimizelyFlutterSdkPlugin.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin {
3636
return UUID().uuidString
3737
}
3838

39+
static var registrar: FlutterPluginRegistrar?
3940
/// Registers optimizely_flutter_sdk channel to communicate with the flutter sdk to receive requests and send responses
4041
public static func register(with registrar: FlutterPluginRegistrar) {
42+
self.registrar = registrar
4143
channel = FlutterMethodChannel(name: "optimizely_flutter_sdk", binaryMessenger: registrar.messenger())
4244
let instance = SwiftOptimizelyFlutterSdkPlugin()
4345
registrar.addMethodCallDelegate(instance, channel: channel)
@@ -163,9 +165,16 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin {
163165
notificationIdsTracker.removeValue(forKey: sdkKey)
164166
optimizelyClientsTracker.removeValue(forKey: sdkKey)
165167

168+
// Check if custom logger is requested
169+
var logger: OPTLogger?
170+
if let useCustomLogger = parameters[RequestParameterKey.customLogger] as? Bool, useCustomLogger {
171+
logger = FlutterOptimizelyLogger()
172+
}
173+
166174
// Creating new instance
167175
let optimizelyInstance = OptimizelyClient(
168176
sdkKey:sdkKey,
177+
logger:logger,
169178
eventDispatcher: eventDispatcher,
170179
datafileHandler: datafileHandler,
171180
periodicDownloadInterval: datafilePeriodicDownloadInterval,

lib/optimizely_flutter_sdk.dart

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import 'package:optimizely_flutter_sdk/src/data_objects/optimizely_config_respon
2828
import 'package:optimizely_flutter_sdk/src/optimizely_client_wrapper.dart';
2929
import 'package:optimizely_flutter_sdk/src/user_context/optimizely_user_context.dart';
3030
import 'package:optimizely_flutter_sdk/src/data_objects/log_level.dart';
31+
import 'package:optimizely_flutter_sdk/src/logger/OptimizelyLogger.dart';
32+
import 'package:optimizely_flutter_sdk/src/logger/LoggerBridge.dart';
3133

3234
export 'package:optimizely_flutter_sdk/src/optimizely_client_wrapper.dart'
3335
show ClientPlatform, ListenerType;
@@ -68,20 +70,37 @@ class OptimizelyFlutterSdk {
6870
final Set<OptimizelyDecideOption> _defaultDecideOptions;
6971
final OptimizelyLogLevel _defaultLogLevel;
7072
final SDKSettings _sdkSettings;
73+
final OptimizelyLogger? _logger; // Add logger field
74+
static OptimizelyLogger? _customLogger;
75+
/// Set a custom logger for the SDK
76+
static void setLogger(OptimizelyLogger logger) {
77+
_customLogger = logger;
78+
LoggerBridge.initialize();
79+
}
80+
/// Get the current logger
81+
static OptimizelyLogger? get logger {
82+
return _customLogger;
83+
}
7184
OptimizelyFlutterSdk(this._sdkKey,
72-
{EventOptions eventOptions = const EventOptions(),
73-
int datafilePeriodicDownloadInterval =
74-
10 * 60, // Default time interval in seconds
75-
Map<ClientPlatform, DatafileHostOptions> datafileHostOptions = const {},
76-
Set<OptimizelyDecideOption> defaultDecideOptions = const {},
77-
OptimizelyLogLevel defaultLogLevel = OptimizelyLogLevel.info,
78-
SDKSettings sdkSettings = const SDKSettings()})
79-
: _eventOptions = eventOptions,
80-
_datafilePeriodicDownloadInterval = datafilePeriodicDownloadInterval,
81-
_datafileHostOptions = datafileHostOptions,
82-
_defaultDecideOptions = defaultDecideOptions,
83-
_defaultLogLevel = defaultLogLevel,
84-
_sdkSettings = sdkSettings;
85+
{EventOptions eventOptions = const EventOptions(),
86+
int datafilePeriodicDownloadInterval = 10 * 60,
87+
Map<ClientPlatform, DatafileHostOptions> datafileHostOptions = const {},
88+
Set<OptimizelyDecideOption> defaultDecideOptions = const {},
89+
OptimizelyLogLevel defaultLogLevel = OptimizelyLogLevel.info,
90+
SDKSettings sdkSettings = const SDKSettings(),
91+
OptimizelyLogger? logger}) // Add logger parameter
92+
: _eventOptions = eventOptions,
93+
_datafilePeriodicDownloadInterval = datafilePeriodicDownloadInterval,
94+
_datafileHostOptions = datafileHostOptions,
95+
_defaultDecideOptions = defaultDecideOptions,
96+
_defaultLogLevel = defaultLogLevel,
97+
_sdkSettings = sdkSettings,
98+
_logger = logger {
99+
// Set the logger if provided
100+
if (logger != null) {
101+
setLogger(logger);
102+
}
103+
}
85104

86105
/// Starts Optimizely SDK (Synchronous) with provided sdkKey.
87106
Future<BaseResponse> initializeClient() async {
@@ -92,7 +111,9 @@ class OptimizelyFlutterSdk {
92111
_datafileHostOptions,
93112
_defaultDecideOptions,
94113
_defaultLogLevel,
95-
_sdkSettings);
114+
_sdkSettings,
115+
_logger
116+
);
96117
}
97118

98119
/// Use the activate method to start an experiment.

lib/src/logger/LoggerBridge.dart

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import 'dart:async';
2+
import 'package:flutter/services.dart';
3+
import 'package:optimizely_flutter_sdk/src/data_objects/log_level.dart';
4+
5+
import 'package:optimizely_flutter_sdk/optimizely_flutter_sdk.dart';
6+
7+
class LoggerBridge {
8+
static const MethodChannel _loggerChannel =
9+
MethodChannel('optimizely_flutter_sdk_logger');
10+
11+
static void initialize() {
12+
_loggerChannel.setMethodCallHandler(_handleMethodCall);
13+
}
14+
15+
static Future<void> _handleMethodCall(MethodCall call) async {
16+
switch (call.method) {
17+
case 'log':
18+
final args = call.arguments as Map<String, dynamic>;
19+
final level = OptimizelyLogLevel.values[args['level'] as int];
20+
final message = args['message'] as String;
21+
22+
OptimizelyFlutterSdk.logger?.log(level, message);
23+
break;
24+
}
25+
}
26+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import 'package:optimizely_flutter_sdk/src/data_objects/log_level.dart';
2+
3+
abstract class OptimizelyLogger {
4+
/// The log level for the logger
5+
OptimizelyLogLevel get logLevel;
6+
set logLevel(OptimizelyLogLevel level);
7+
8+
/// Log a message at a certain level
9+
void log(OptimizelyLogLevel level, String message);
10+
}
11+
12+
// enum OptimizelyLogLevel { error, warning, info, debug }
13+
14+
class DefaultOptimizelyLogger implements OptimizelyLogger {
15+
@override
16+
OptimizelyLogLevel logLevel = OptimizelyLogLevel.info;
17+
18+
@override
19+
void log(OptimizelyLogLevel level, String message) {
20+
if (_shouldLog(level)) {
21+
print('[Optimizely ${level.name.toUpperCase()}] $message');
22+
}
23+
}
24+
25+
bool _shouldLog(OptimizelyLogLevel messageLevel) {
26+
return messageLevel.index <= logLevel.index;
27+
}
28+
}

lib/src/optimizely_client_wrapper.dart

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import 'package:optimizely_flutter_sdk/src/data_objects/get_vuid_response.dart';
2727
import 'package:optimizely_flutter_sdk/src/data_objects/optimizely_config_response.dart';
2828
import 'package:optimizely_flutter_sdk/src/utils/constants.dart';
2929
import 'package:optimizely_flutter_sdk/src/utils/utils.dart';
30+
import 'package:optimizely_flutter_sdk/src/logger/OptimizelyLogger.dart';
31+
import 'package:optimizely_flutter_sdk/src/logger/LoggerBridge.dart';
3032

3133
enum ListenerType { activate, track, decision, logEvent, projectConfigUpdate }
3234

@@ -63,8 +65,13 @@ class OptimizelyClientWrapper {
6365
Map<ClientPlatform, DatafileHostOptions> datafileHostOptions,
6466
Set<OptimizelyDecideOption> defaultDecideOptions,
6567
OptimizelyLogLevel defaultLogLevel,
66-
SDKSettings sdkSettings) async {
68+
SDKSettings sdkSettings,
69+
OptimizelyLogger? logger) async {
6770
_channel.setMethodCallHandler(methodCallHandler);
71+
// Initialize logger bridge if custom logger is provided
72+
if (logger != null) {
73+
LoggerBridge.initialize();
74+
}
6875
final convertedOptions = Utils.convertDecideOptions(defaultDecideOptions);
6976
final convertedLogLevel = Utils.convertLogLevel(defaultLogLevel);
7077
const sdkVersion = PackageInfo.version;
@@ -79,6 +86,7 @@ class OptimizelyClientWrapper {
7986
Constants.eventBatchSize: eventOptions.batchSize,
8087
Constants.eventTimeInterval: eventOptions.timeInterval,
8188
Constants.eventMaxQueueSize: eventOptions.maxQueueSize,
89+
Constants.customLogger: logger != null,
8290
};
8391

8492
// Odp Request params

lib/src/utils/constants.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class Constants {
8686
static const String optimizelyDecideOption = "optimizelyDecideOption";
8787
static const String optimizelySegmentOption = "optimizelySegmentOption";
8888
static const String optimizelySdkSettings = "optimizelySdkSettings";
89+
static const String customLogger = 'customLogger';
8990
static const String defaultLogLevel = "defaultLogLevel";
9091
static const String payload = "payload";
9192
static const String value = "value";

0 commit comments

Comments
 (0)