diff --git a/packages/realm_dart/lib/src/app.dart b/packages/realm_dart/lib/src/app.dart index 5cd0a2d3b..e908657bd 100644 --- a/packages/realm_dart/lib/src/app.dart +++ b/packages/realm_dart/lib/src/app.dart @@ -154,7 +154,7 @@ class App implements Finalizable { // background isolates. This check will log a warning if the isolate name is != 'main' and doesn't start with 'test/' since dart test will // construct a new isolate per file and we don't want to log excessively in unit test projects. if (Isolate.current.debugName != 'main' && Isolate.current.debugName?.startsWith('test/') == false) { - Realm.logger.log(RealmLogLevel.warn, + Realm.logger.log(LogLevel.warn, "App constructor called on Isolate ${Isolate.current.debugName} which doesn't appear to be the main isolate. If you need an app instance on a background isolate use App.getById after constructing the App on the main isolate."); } } diff --git a/packages/realm_dart/lib/src/configuration.dart b/packages/realm_dart/lib/src/configuration.dart index 995fcd482..714acebf9 100644 --- a/packages/realm_dart/lib/src/configuration.dart +++ b/packages/realm_dart/lib/src/configuration.dart @@ -305,12 +305,12 @@ enum SessionStopPolicy { typedef SyncErrorHandler = void Function(SyncError); void defaultSyncErrorHandler(SyncError e) { - Realm.logger.log(RealmLogLevel.error, e); + Realm.logger.log(LogLevel.error, e); } void _defaultClientResetHandler(ClientResetError e) { Realm.logger.log( - RealmLogLevel.error, + LogLevel.error, "A client reset error occurred but no handler was supplied. " "Synchronization is now paused and will resume automatically once the app is restarted and " "the server data is re-downloaded. Any un-synchronized changes the client has made or will " diff --git a/packages/realm_dart/lib/src/logging.dart b/packages/realm_dart/lib/src/logging.dart index cf7cb7134..466dd8043 100644 --- a/packages/realm_dart/lib/src/logging.dart +++ b/packages/realm_dart/lib/src/logging.dart @@ -8,7 +8,7 @@ import 'package:logging/logging.dart'; import 'native/realm_core.dart'; // Using classes to make a fancy hierarchical enum -sealed class RealmLogCategory { +sealed class LogCategory { /// All possible log categories. static final values = [ realm, @@ -32,12 +32,12 @@ sealed class RealmLogCategory { static final realm = _RealmLogCategory(); final String _name; - final RealmLogCategory? _parent; + final LogCategory? _parent; - RealmLogCategory._(this._name, this._parent); + LogCategory._(this._name, this._parent); /// Returns `true` if this category contains the given [category]. - bool _contains(RealmLogCategory category) { + bool _contains(LogCategory category) { var current = category; while (current != this) { final isRoot = current == realm; @@ -54,18 +54,18 @@ sealed class RealmLogCategory { @override String toString() => _toString; - static final _map = {for (final category in RealmLogCategory.values) category.toString(): category}; + static final _map = {for (final category in LogCategory.values) category.toString(): category}; - /// Returns the [RealmLogCategory] for the given [category] string. + /// Returns the [LogCategory] for the given [category] string. /// Will throw if the category is not recognized. - factory RealmLogCategory.fromString(String category) => _map[category]!; + factory LogCategory.fromString(String category) => _map[category]!; } -class _LeafLogCategory extends RealmLogCategory { - _LeafLogCategory(super.name, RealmLogCategory super.parent) : super._(); +class _LeafLogCategory extends LogCategory { + _LeafLogCategory(super.name, LogCategory super.parent) : super._(); } -class _RealmLogCategory extends RealmLogCategory { +class _RealmLogCategory extends LogCategory { _RealmLogCategory() : super._('Realm', null); late final app = _LeafLogCategory('App', this); @@ -74,15 +74,15 @@ class _RealmLogCategory extends RealmLogCategory { late final sync = _SyncLogCategory(this); } -class _SyncLogCategory extends RealmLogCategory { - _SyncLogCategory(RealmLogCategory parent) : super._('Sync', parent); +class _SyncLogCategory extends LogCategory { + _SyncLogCategory(LogCategory parent) : super._('Sync', parent); late final client = _ClientLogCategory(this); late final server = _LeafLogCategory('Server', this); } -class _ClientLogCategory extends RealmLogCategory { - _ClientLogCategory(RealmLogCategory parent) : super._('Client', parent); +class _ClientLogCategory extends LogCategory { + _ClientLogCategory(LogCategory parent) : super._('Client', parent); late final changeset = _LeafLogCategory('Changeset', this); late final network = _LeafLogCategory('Network', this); @@ -90,8 +90,8 @@ class _ClientLogCategory extends RealmLogCategory { late final session = _LeafLogCategory('Session', this); } -class _StorageLogCategory extends RealmLogCategory { - _StorageLogCategory(RealmLogCategory parent) : super._('Storage', parent); +class _StorageLogCategory extends LogCategory { + _StorageLogCategory(LogCategory parent) : super._('Storage', parent); late final notification = _LeafLogCategory('Notification', this); late final object = _LeafLogCategory('Object', this); @@ -102,7 +102,7 @@ class _StorageLogCategory extends RealmLogCategory { /// Specifies the criticality level above which messages will be logged /// by the default sync client logger. /// {@category Realm} -enum RealmLogLevel { +enum LogLevel { /// Log everything. This will seriously harm the performance of the /// sync client and should never be used in production scenarios. all(Level.ALL), @@ -136,14 +136,14 @@ enum RealmLogLevel { ; /// The [Level] from package [logging](https://pub.dev/packages/logging) that - /// corresponds to this [RealmLogLevel]. + /// corresponds to this [LogLevel]. final Level level; - const RealmLogLevel(this.level); + const LogLevel(this.level); } /// A record of a log message from the Realm SDK. -typedef RealmLogRecord = ({RealmLogCategory category, RealmLogLevel level, String message}); +typedef LogRecord = ({LogCategory category, LogLevel level, String message}); /// A logger that logs messages from the Realm SDK. /// @@ -163,7 +163,7 @@ typedef RealmLogRecord = ({RealmLogCategory category, RealmLogLevel level, Strin /// If no listeners are attached to [onRecord] in any isolate, the trace will go /// to stdout. class RealmLogger { - static final _controller = StreamController.broadcast( + static final _controller = StreamController.broadcast( onListen: () => realmCore.loggerAttach(), onCancel: () => realmCore.loggerDetach(), ); @@ -172,9 +172,9 @@ class RealmLogger { /// Set the log [level] for the given [category]. /// - /// If [category] is not provided, the log level will be set [RealmLogCategory.realm]. - void setLogLevel(RealmLogLevel level, {RealmLogCategory? category}) { - category ??= RealmLogCategory.realm; + /// If [category] is not provided, the log level will be set [LogCategory.realm]. + void setLogLevel(LogLevel level, {LogCategory? category}) { + category ??= LogCategory.realm; realmCore.setLogLevel(level, category: category); } @@ -182,23 +182,23 @@ class RealmLogger { /// /// This is a broadcast stream. It is safe to listen to it multiple times. /// If no listeners are attached in any isolate, the trace will go to stdout. - Stream get onRecord => _controller.stream; + Stream get onRecord => _controller.stream; - void _raise(RealmLogRecord record) { + void _raise(LogRecord record) { _controller.add(record); } - void _log(RealmLogLevel level, Object message, {RealmLogCategory? category}) { - category ??= RealmLogCategory.realm.sdk; - realmCore.logMessage(RealmLogCategory.realm.sdk, level, message.toString()); + void _log(LogLevel level, Object message, {LogCategory? category}) { + category ??= LogCategory.realm.sdk; + realmCore.logMessage(LogCategory.realm.sdk, level, message.toString()); } } extension RealmLoggerInternal on RealmLogger { - void raise(RealmLogRecord record) => _raise(record); - void log(RealmLogLevel level, Object message, {RealmLogCategory? category}) => _log(level, message, category: category); + void raise(LogRecord record) => _raise(record); + void log(LogLevel level, Object message, {LogCategory? category}) => _log(level, message, category: category); } -extension RealmLogCategoryInternal on RealmLogCategory { - bool contains(RealmLogCategory category) => _contains(category); +extension RealmLogCategoryInternal on LogCategory { + bool contains(LogCategory category) => _contains(category); } diff --git a/packages/realm_dart/lib/src/native/realm_core.dart b/packages/realm_dart/lib/src/native/realm_core.dart index 1c21c76de..9534d663c 100644 --- a/packages/realm_dart/lib/src/native/realm_core.dart +++ b/packages/realm_dart/lib/src/native/realm_core.dart @@ -1766,7 +1766,7 @@ class _RealmCore { try { realm.updateSchema(); } catch (e) { - Realm.logger.log(RealmLogLevel.error, 'Failed to update Realm schema: $e'); + Realm.logger.log(LogLevel.error, 'Failed to update Realm schema: $e'); } } @@ -2026,7 +2026,7 @@ class _RealmCore { request.add(utf8.encode(body)); } - Realm.logger.log(RealmLogLevel.debug, "HTTP Transport: Executing ${method.name} $url"); + Realm.logger.log(LogLevel.debug, "HTTP Transport: Executing ${method.name} $url"); final stopwatch = Stopwatch()..start(); @@ -2034,7 +2034,7 @@ class _RealmCore { final response = await request.close(); stopwatch.stop(); - Realm.logger.log(RealmLogLevel.debug, "HTTP Transport: Executed ${method.name} $url: ${response.statusCode} in ${stopwatch.elapsedMilliseconds} ms"); + Realm.logger.log(LogLevel.debug, "HTTP Transport: Executed ${method.name} $url: ${response.statusCode} in ${stopwatch.elapsedMilliseconds} ms"); final responseBody = await response.fold>([], (acc, l) => acc..addAll(l)); // gather response @@ -2063,13 +2063,13 @@ class _RealmCore { responseRef.custom_status_code = _CustomErrorCode.noError.code; } on SocketException catch (socketEx) { - Realm.logger.log(RealmLogLevel.warn, "HTTP Transport: SocketException executing ${method.name} $url: $socketEx"); + Realm.logger.log(LogLevel.warn, "HTTP Transport: SocketException executing ${method.name} $url: $socketEx"); responseRef.custom_status_code = _CustomErrorCode.timeout.code; } on HttpException catch (httpEx) { - Realm.logger.log(RealmLogLevel.warn, "HTTP Transport: HttpException executing ${method.name} $url: $httpEx"); + Realm.logger.log(LogLevel.warn, "HTTP Transport: HttpException executing ${method.name} $url: $httpEx"); responseRef.custom_status_code = _CustomErrorCode.unknownHttp.code; } catch (ex) { - Realm.logger.log(RealmLogLevel.error, "HTTP Transport: Exception executing ${method.name} $url: $ex"); + Realm.logger.log(LogLevel.error, "HTTP Transport: Exception executing ${method.name} $url: $ex"); responseRef.custom_status_code = _CustomErrorCode.unknown.code; } finally { _realmLib.realm_http_transport_complete_request(request_context, response_pointer); @@ -2077,7 +2077,7 @@ class _RealmCore { }); } - void logMessage(RealmLogCategory category, RealmLogLevel logLevel, String message) { + void logMessage(LogCategory category, LogLevel logLevel, String message) { return using((arena) { _realmLib.realm_dart_log(logLevel.index, category.toString().toCharPtr(arena), message.toCharPtr(arena)); }); @@ -3065,7 +3065,7 @@ class _RealmCore { } } - void setLogLevel(RealmLogLevel level, {required RealmLogCategory category}) { + void setLogLevel(LogLevel level, {required LogCategory category}) { using((arena) { _realmLib.realm_set_log_level_category(category.toString().toCharPtr(arena), level.index); }); @@ -3102,7 +3102,7 @@ class LastError { const _enableFinalizerTrace = false; // Level used for finalization trace, if enabled. -const _finalizerTraceLevel = RealmLogLevel.trace; +const _finalizerTraceLevel = LogLevel.trace; void _traceFinalization(Object o) { Realm.logger.log(_finalizerTraceLevel, 'Finalizing: $o'); diff --git a/packages/realm_dart/lib/src/realm_class.dart b/packages/realm_dart/lib/src/realm_class.dart index ce0dbd326..179ce3c49 100644 --- a/packages/realm_dart/lib/src/realm_class.dart +++ b/packages/realm_dart/lib/src/realm_class.dart @@ -516,7 +516,7 @@ class Realm implements Finalizable { /// /// If no isolate subscribes to the stream, the trace messages will go to stdout. /// - /// The default log level is [RealmLogLevel.info]. + /// The default log level is [LogLevel.info]. static const logger = RealmLogger(); /// Used to shutdown Realm and allow the process to correctly release native resources and exit. diff --git a/packages/realm_dart/lib/src/scheduler.dart b/packages/realm_dart/lib/src/scheduler.dart index 7bdc58e44..d737a48cf 100644 --- a/packages/realm_dart/lib/src/scheduler.dart +++ b/packages/realm_dart/lib/src/scheduler.dart @@ -24,14 +24,14 @@ class Scheduler { _receivePort.handler = (dynamic message) { if (message is List) { // currently the only `message as List` is from the logger. - final category = RealmLogCategory.fromString(message[0] as String); - final level = RealmLogLevel.values[message[1] as int]; + final category = LogCategory.fromString(message[0] as String); + final level = LogLevel.values[message[1] as int]; final text = message[2] as String; Realm.logger.raise((category: category, level: level, message: text)); } else if (message is int) { realmCore.invokeScheduler(message); } else { - Realm.logger.log(RealmLogLevel.error, 'Unexpected Scheduler message type: ${message.runtimeType} - $message'); + Realm.logger.log(LogLevel.error, 'Unexpected Scheduler message type: ${message.runtimeType} - $message'); } }; diff --git a/packages/realm_dart/test/app_test.dart b/packages/realm_dart/test/app_test.dart index d98be0d57..27635bb77 100644 --- a/packages/realm_dart/test/app_test.dart +++ b/packages/realm_dart/test/app_test.dart @@ -358,7 +358,7 @@ void main() { }); baasTest('App(AppConfiguration) on background isolate logs warning', (appConfig) async { - Realm.logger.setLogLevel(RealmLogLevel.warn); + Realm.logger.setLogLevel(LogLevel.warn); final sb = StringBuffer(); Realm.logger.onRecord.listen((event) { diff --git a/packages/realm_dart/test/realm_logger_test.dart b/packages/realm_dart/test/realm_logger_test.dart index 62d63ddac..b50cda9b1 100644 --- a/packages/realm_dart/test/realm_logger_test.dart +++ b/packages/realm_dart/test/realm_logger_test.dart @@ -3,28 +3,31 @@ import 'dart:async'; import 'dart:isolate'; -import 'package:logging/logging.dart'; +import 'package:logging/logging.dart' hide LogRecord; +import 'package:logging/logging.dart' as logging show LogRecord; import 'package:realm_dart/src/logging.dart'; import 'package:realm_dart/src/native/realm_core.dart'; import 'package:test/test.dart' hide test, throws; import 'package:realm_dart/realm.dart'; import 'test.dart'; -final logToValues = RealmLogLevel.values.where((l) => ![RealmLogLevel.all, RealmLogLevel.off].contains(l)); +typedef DartLogRecord = logging.LogRecord; + +final logToValues = LogLevel.values.where((l) => ![LogLevel.all, LogLevel.off].contains(l)); void main() { setupTests(); group('All levels', () { - for (var level in RealmLogLevel.values) { + for (var level in LogLevel.values) { test('Realm.logger supports log level $level', () { - Realm.logger.setLogLevel(RealmLogLevel.off); - Realm.logger.setLogLevel(RealmLogLevel.all, category: RealmLogCategory.realm.sdk); + Realm.logger.setLogLevel(LogLevel.off); + Realm.logger.setLogLevel(LogLevel.all, category: LogCategory.realm.sdk); final tag = Uuid.v4(); expectLater( Realm.logger.onRecord, - emits((category: RealmLogCategory.realm.sdk, level: level, message: '$level $tag')), + emits((category: LogCategory.realm.sdk, level: level, message: '$level $tag')), ); Realm.logger.log(level, '$level $tag'); }); @@ -32,13 +35,13 @@ void main() { }); group('Match levels', () { - for (var level in RealmLogLevel.values) { + for (var level in LogLevel.values) { final expectedLevels = logToValues.where((l) => l.index >= level.index); test('$level matches $expectedLevels', () { - Realm.logger.setLogLevel(RealmLogLevel.off); - Realm.logger.setLogLevel(level, category: RealmLogCategory.realm.sdk); + Realm.logger.setLogLevel(LogLevel.off); + Realm.logger.setLogLevel(level, category: LogCategory.realm.sdk); - expectLater(Realm.logger.onRecord, emitsInOrder(expectedLevels.map((l) => isA().having((r) => r.level, '$l', l)))); + expectLater(Realm.logger.onRecord, emitsInOrder(expectedLevels.map((l) => isA().having((r) => r.level, '$l', l)))); for (var sendLevel in logToValues) { Realm.logger.log(sendLevel, '$sendLevel'); } @@ -46,9 +49,9 @@ void main() { } }); - group('RealmLogCategory.contains', () { - for (final outer in RealmLogCategory.values) { - for (final inner in RealmLogCategory.values) { + group('LogCategory.contains', () { + for (final outer in LogCategory.values) { + for (final inner in LogCategory.values) { test('$outer contains $inner', () { expect(outer.contains(inner), inner.toString().startsWith(outer.toString())); }); @@ -57,44 +60,44 @@ void main() { }); test('Trace in subisolate seen in parent', () { - Realm.logger.setLogLevel(RealmLogLevel.off); - Realm.logger.setLogLevel(RealmLogLevel.all, category: RealmLogCategory.realm.sdk); + Realm.logger.setLogLevel(LogLevel.off); + Realm.logger.setLogLevel(LogLevel.all, category: LogCategory.realm.sdk); - expectLater(Realm.logger.onRecord, emits(isA().having((r) => r.message, 'message', 'Hey'))); + expectLater(Realm.logger.onRecord, emits(isA().having((r) => r.message, 'message', 'Hey'))); Isolate.run(() { - Realm.logger.log(RealmLogLevel.trace, 'Hey'); + Realm.logger.log(LogLevel.trace, 'Hey'); }); }); test('Trace in root isolate seen in subisolate', () async { - Realm.logger.setLogLevel(RealmLogLevel.off); - Realm.logger.setLogLevel(RealmLogLevel.all, category: RealmLogCategory.realm.sdk); + Realm.logger.setLogLevel(LogLevel.off); + Realm.logger.setLogLevel(LogLevel.all, category: LogCategory.realm.sdk); final trace = Isolate.run(() async { return (await Realm.logger.onRecord.first).message; }); await Future.delayed(const Duration(milliseconds: 100)); // yield expectLater(trace, completion('Hey')); - Realm.logger.log(RealmLogLevel.trace, 'Hey'); + Realm.logger.log(LogLevel.trace, 'Hey'); }); test('RealmLogger hookup logging', () async { - Realm.logger.setLogLevel(RealmLogLevel.off); - Realm.logger.setLogLevel(RealmLogLevel.all, category: RealmLogCategory.realm.sdk); + Realm.logger.setLogLevel(LogLevel.off); + Realm.logger.setLogLevel(LogLevel.all, category: LogCategory.realm.sdk); final logger = Logger.detached('Test'); final sub = Realm.logger.onRecord.listen((r) => logger.log(r.level.level, r.message)); logger.level = Level.ALL; - expectLater(logger.onRecord, emits(isA().having((r) => r.level, 'level', Level.SEVERE).having((r) => r.message, 'message', 'error'))) + expectLater(logger.onRecord, emits(isA().having((r) => r.level, 'level', Level.SEVERE).having((r) => r.message, 'message', 'error'))) .whenComplete(sub.cancel); - Realm.logger.log(RealmLogLevel.error, 'error'); + Realm.logger.log(LogLevel.error, 'error'); }); test('RealmLogger hookup hierarchical logging', () async { - Realm.logger.setLogLevel(RealmLogLevel.off); - Realm.logger.setLogLevel(RealmLogLevel.all, category: RealmLogCategory.realm.sdk); + Realm.logger.setLogLevel(LogLevel.off); + Realm.logger.setLogLevel(LogLevel.all, category: LogCategory.realm.sdk); final old = hierarchicalLoggingEnabled; hierarchicalLoggingEnabled = true; @@ -102,10 +105,11 @@ void main() { final sub = Realm.logger.onRecord.listen((r) => Logger(r.category.toString()).log(r.level.level, r.message)); Logger.root.level = Level.ALL; - expectLater(Logger('Realm').onRecord, emits(isA().having((r) => r.level, 'level', Level.SEVERE).having((r) => r.message, 'message', 'error'))); + expectLater( + Logger('Realm').onRecord, emits(isA().having((r) => r.level, 'level', Level.SEVERE).having((r) => r.message, 'message', 'error'))); expectLater( Logger('Realm.SDK').onRecord, - emits(isA().having((r) => r.level, 'level', Level.SEVERE).having( + emits(isA().having((r) => r.level, 'level', Level.SEVERE).having( (r) => r.message, 'message', 'error', @@ -115,20 +119,20 @@ void main() { hierarchicalLoggingEnabled = old; }); - Realm.logger.log(RealmLogLevel.error, 'error', category: RealmLogCategory.realm.sdk); + Realm.logger.log(LogLevel.error, 'error', category: LogCategory.realm.sdk); }); group('Category mapping', () { final nativeCategoryNames = realmCore.getAllCategoryNames(); for (final name in nativeCategoryNames) { test('$name can parse', () { - expect(() => RealmLogCategory.fromString(name), returnsNormally); - final category = RealmLogCategory.fromString(name); - expect(category, isA().having((c) => c.toString(), 'toString()', name)); + expect(() => LogCategory.fromString(name), returnsNormally); + final category = LogCategory.fromString(name); + expect(category, isA().having((c) => c.toString(), 'toString()', name)); }); } - for (final category in RealmLogCategory.values) { + for (final category in LogCategory.values) { test('$category known by native', () { expect(nativeCategoryNames, contains(category.toString())); }); @@ -144,20 +148,20 @@ void main() { }); test('Changing levels works', () { - Realm.logger.setLogLevel(RealmLogLevel.off); - Realm.logger.setLogLevel(RealmLogLevel.all, category: RealmLogCategory.realm.sdk); + Realm.logger.setLogLevel(LogLevel.off); + Realm.logger.setLogLevel(LogLevel.all, category: LogCategory.realm.sdk); expectLater( Realm.logger.onRecord, emitsInOrder([ - isA().having((r) => r.level, 'level', RealmLogLevel.trace).having((r) => r.message, 'message', 'trace'), + isA().having((r) => r.level, 'level', LogLevel.trace).having((r) => r.message, 'message', 'trace'), // note second trace is not seen - isA().having((r) => r.level, 'level', RealmLogLevel.warn).having((r) => r.message, 'message', 'warn'), + isA().having((r) => r.level, 'level', LogLevel.warn).having((r) => r.message, 'message', 'warn'), ])); - Realm.logger.log(RealmLogLevel.trace, 'trace'); - Realm.logger.setLogLevel(RealmLogLevel.warn, category: RealmLogCategory.realm.sdk); - Realm.logger.log(RealmLogLevel.trace, 'trace'); // <-- not seen - Realm.logger.log(RealmLogLevel.warn, 'warn'); + Realm.logger.log(LogLevel.trace, 'trace'); + Realm.logger.setLogLevel(LogLevel.warn, category: LogCategory.realm.sdk); + Realm.logger.log(LogLevel.trace, 'trace'); // <-- not seen + Realm.logger.log(LogLevel.warn, 'warn'); }); } diff --git a/packages/realm_dart/test/test.dart b/packages/realm_dart/test/test.dart index 18ede4cf0..d06689008 100644 --- a/packages/realm_dart/test/test.dart +++ b/packages/realm_dart/test/test.dart @@ -416,7 +416,7 @@ void setupTests() { setUpAll(() async { baasHelper = await BaasHelper.setupBaas(); - Realm.logger.setLogLevel(RealmLogLevel.detail); + Realm.logger.setLogLevel(LogLevel.detail); Realm.logger.onRecord.listen((record) { testing.printOnFailure('${record.category} ${record.level.name}: ${record.message}'); }); @@ -553,7 +553,7 @@ Future tryDeleteRealm(String path) async { return; } catch (e) { - Realm.logger.log(RealmLogLevel.info, 'Failed to delete realm at path $path. Trying again in ${duration.inMilliseconds}ms'); + Realm.logger.log(LogLevel.info, 'Failed to delete realm at path $path. Trying again in ${duration.inMilliseconds}ms'); await Future.delayed(duration); } }