Skip to content

Commit 120c953

Browse files
committed
Refactor logging to log to console by default.
1 parent 543e8a9 commit 120c953

File tree

6 files changed

+74
-22
lines changed

6 files changed

+74
-22
lines changed

demos/supabase-todolist/lib/main.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import './widgets/signup_page.dart';
1313
import './widgets/status_app_bar.dart';
1414

1515
void main() async {
16-
// Log info from PowerSync
1716
Logger.root.level = Level.INFO;
1817
Logger.root.onRecord.listen((record) {
1918
if (kDebugMode) {

packages/powersync/lib/src/bucket_storage.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ class BucketStorage {
345345
SET last_applied_op = last_op
346346
WHERE last_applied_op != last_op""");
347347

348-
log.fine('Updated local database');
348+
isolateLogger.fine('Updated local database');
349349
return true;
350350
});
351351
}
@@ -407,7 +407,7 @@ class BucketStorage {
407407
final invalidBuckets = db.select(
408408
"SELECT name, target_op, last_op, last_applied_op FROM ps_buckets WHERE target_op > last_op AND (name = '\$local' OR pending_delete = 0)");
409409
if (invalidBuckets.isNotEmpty) {
410-
log.fine('Cannot update local database: $invalidBuckets');
410+
isolateLogger.fine('Cannot update local database: $invalidBuckets');
411411
return false;
412412
}
413413
// This is specifically relevant for when data is added to crud before another batch is completed.
@@ -505,7 +505,7 @@ class BucketStorage {
505505
BucketChecksum(bucket: checksum.bucket, checksum: 0, count: 0);
506506
// Note: Count is informational only.
507507
if (local.checksum != checksum.checksum) {
508-
log.warning(
508+
isolateLogger.warning(
509509
'Checksum mismatch for ${checksum.bucket}: local ${local.checksum} != remote ${checksum.checksum}');
510510
failedChecksums.add(checksum.bucket);
511511
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
import 'package:logging/logging.dart';
22

3-
final log = Logger('PowerSync');
3+
final isolateLogger = Logger.detached('PowerSync');

packages/powersync/lib/src/powersync_database.dart

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:async';
22
import 'dart:isolate';
33

4+
import 'package:flutter/foundation.dart';
45
import 'package:logging/logging.dart';
56
import 'package:sqlite_async/sqlite3.dart' as sqlite;
67
import 'package:sqlite_async/sqlite_async.dart';
@@ -68,6 +69,9 @@ class PowerSyncDatabase with SqliteQueries implements SqliteConnection {
6869
/// null when disconnected, present when connecting or connected
6970
AbortController? _disconnecter;
7071

72+
/// The Logger internally used by this PowerSyncDatabase
73+
late final Logger logger;
74+
7175
/// Open a [PowerSyncDatabase].
7276
///
7377
/// Only a single [PowerSyncDatabase] per [path] should be opened at a time.
@@ -84,12 +88,13 @@ class PowerSyncDatabase with SqliteQueries implements SqliteConnection {
8488
{required Schema schema,
8589
required String path,
8690
int maxReaders = SqliteDatabase.defaultMaxReaders,
91+
LogType log = LogType.auto,
8792
@Deprecated("Use [PowerSyncDatabase.withFactory] instead")
8893
// ignore: deprecated_member_use_from_same_package
8994
SqliteConnectionSetup? sqliteSetup}) {
9095
// ignore: deprecated_member_use_from_same_package
9196
var factory = PowerSyncOpenFactory(path: path, sqliteSetup: sqliteSetup);
92-
return PowerSyncDatabase.withFactory(factory, schema: schema);
97+
return PowerSyncDatabase.withFactory(factory, schema: schema, log: log);
9398
}
9499

95100
/// Open a [PowerSyncDatabase] with a [PowerSyncOpenFactory].
@@ -98,18 +103,54 @@ class PowerSyncDatabase with SqliteQueries implements SqliteConnection {
98103
/// additional logic to run inside the database isolate before or after opening.
99104
///
100105
/// Subclass [PowerSyncOpenFactory] to add custom logic to this process.
101-
factory PowerSyncDatabase.withFactory(PowerSyncOpenFactory openFactory,
102-
{required Schema schema,
103-
int maxReaders = SqliteDatabase.defaultMaxReaders}) {
106+
factory PowerSyncDatabase.withFactory(
107+
PowerSyncOpenFactory openFactory, {
108+
required Schema schema,
109+
int maxReaders = SqliteDatabase.defaultMaxReaders,
110+
LogType log = LogType.auto,
111+
}) {
104112
final db = SqliteDatabase.withFactory(openFactory, maxReaders: maxReaders);
105-
return PowerSyncDatabase.withDatabase(schema: schema, database: db);
113+
return PowerSyncDatabase.withDatabase(
114+
schema: schema, database: db, log: log);
106115
}
107116

108117
/// Open a PowerSyncDatabase on an existing [SqliteDatabase].
109118
///
110119
/// Migrations are run on the database when this constructor is called.
111-
PowerSyncDatabase.withDatabase(
112-
{required this.schema, required this.database}) {
120+
PowerSyncDatabase.withDatabase({
121+
required this.schema,
122+
required this.database,
123+
LogType log = LogType.auto,
124+
}) {
125+
if (log == LogType.debug || log == LogType.auto) {
126+
// Use a detached logger to log directly to the console
127+
logger = Logger.detached('PowerSync');
128+
final debug = log == LogType.debug || kDebugMode;
129+
if (debug) {
130+
logger.level = Level.FINE;
131+
logger.onRecord.listen((record) {
132+
print(
133+
'[${record.loggerName}] ${record.level.name}: ${record.time}: ${record.message}');
134+
135+
if (record.error != null) {
136+
print(record.error);
137+
}
138+
if (record.stackTrace != null) {
139+
print(record.stackTrace);
140+
}
141+
});
142+
} else {
143+
logger.level = Level.OFF;
144+
}
145+
} else if (log == LogType.logger) {
146+
// Standard logger. The app is responsible for adding an onRecord listener
147+
// on the root logger.
148+
logger = Logger('PowerSync');
149+
} else {
150+
// Should not happen
151+
logger = Logger.detached('PowerSync');
152+
}
153+
113154
updates = database.updates
114155
.map((update) =>
115156
PowerSyncUpdateNotification.fromUpdateNotification(update))
@@ -173,11 +214,11 @@ class PowerSyncDatabase with SqliteQueries implements SqliteConnection {
173214
if (action == "getCredentials") {
174215
await (data[1] as PortCompleter).handle(() async {
175216
final token = await connector.getCredentialsCached();
176-
log.fine('Credentials: $token');
217+
logger.fine('Credentials: $token');
177218
return token;
178219
});
179220
} else if (action == "invalidateCredentials") {
180-
log.fine('Refreshing credentials');
221+
logger.fine('Refreshing credentials');
181222
await (data[1] as PortCompleter).handle(() async {
182223
await connector.prefetchCredentials();
183224
});
@@ -205,7 +246,7 @@ class PowerSyncDatabase with SqliteQueries implements SqliteConnection {
205246
updateSubscription?.cancel();
206247
} else if (action == 'log') {
207248
LogRecord record = data[1];
208-
log.log(
249+
logger.log(
209250
record.level, record.message, record.error, record.stackTrace);
210251
}
211252
}
@@ -221,7 +262,7 @@ class PowerSyncDatabase with SqliteQueries implements SqliteConnection {
221262
// #3 _ForwardingStreamSubscription._handleError (dart:async/stream_pipe.dart:157:13)
222263
// #4 _HttpClientResponse.listen.<anonymous closure> (dart:_http/http_impl.dart:707:16)
223264
// ...
224-
log.severe('Sync Isolate error', message);
265+
logger.severe('Sync Isolate error', message);
225266

226267
// Reconnect
227268
connect(connector: connector);
@@ -237,7 +278,7 @@ class PowerSyncDatabase with SqliteQueries implements SqliteConnection {
237278

238279
var exitPort = ReceivePort();
239280
exitPort.listen((message) {
240-
log.fine('Sync Isolate exit');
281+
logger.fine('Sync Isolate exit');
241282
disconnected();
242283
});
243284

@@ -532,8 +573,8 @@ Future<void> _powerSyncDatabaseIsolate(
532573

533574
// Is there a way to avoid the overhead if logging is not enabled?
534575
// This only takes effect in this isolate.
535-
Logger.root.level = Level.ALL;
536-
log.onRecord.listen((record) {
576+
isolateLogger.level = Level.ALL;
577+
isolateLogger.onRecord.listen((record) {
537578
var copy = LogRecord(record.level, record.message, record.loggerName,
538579
record.error, record.stackTrace);
539580
sPort.send(["log", copy]);
@@ -602,3 +643,15 @@ Future<void> _powerSyncDatabaseIsolate(
602643
throw error;
603644
});
604645
}
646+
647+
enum LogType {
648+
/// Log to the console, with FINE level in debug mode, no logs in release mode
649+
auto,
650+
651+
/// Always log to the console with FINE level
652+
debug,
653+
654+
/// Uses a Logger instance.
655+
/// Use Logger.root.onRecord to handle log messages
656+
logger,
657+
}

packages/powersync/lib/src/streaming_sync.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class StreamingSyncImplementation {
6464
// Continue immediately
6565
} catch (e, stacktrace) {
6666
final message = _syncErrorMessage(e);
67-
log.warning('Sync error: $message', e, stacktrace);
67+
isolateLogger.warning('Sync error: $message', e, stacktrace);
6868
invalidCredentials = true;
6969

7070
_updateStatus(
@@ -96,7 +96,7 @@ class StreamingSyncImplementation {
9696
break;
9797
}
9898
} catch (e, stacktrace) {
99-
log.warning('Data upload error', e, stacktrace);
99+
isolateLogger.warning('Data upload error', e, stacktrace);
100100
_updateStatus(uploading: false, uploadError: e);
101101
await Future.delayed(retryDelay);
102102
}

packages/powersync/test/util.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class TestOpenFactory extends PowerSyncOpenFactory {
4242
Future<PowerSyncDatabase> setupPowerSync(
4343
{required String path, Schema? schema}) async {
4444
final db = PowerSyncDatabase.withFactory(TestOpenFactory(path: path),
45-
schema: schema ?? defaultSchema);
45+
schema: schema ?? defaultSchema, log: LogType.logger);
4646
return db;
4747
}
4848

0 commit comments

Comments
 (0)