tekartik / sqflite

SQLite flutter plugin
BSD 2-Clause "Simplified" License
2.86k stars 521 forks source link

Execution callback for tracing support #928

Open marandaneto opened 1 year ago

marandaneto commented 1 year ago

Hi, first of all, thanks for the great work.

It'd be awesome if this lib would add support for APM/error monitoring.

Today this is possible if you manually do it for each of your DB calls, eg.

startTrace()
await db.execute(...);
endTrace();

This would be a lot of boilerplate in your App, and much harder to migrate in case something changes.

Imagine that you are able to automatically start/finish tracing all of your execution statements (CRUD) using a callback of sort.

For example, OpenDatabaseOptions takes an optional onExecute callback in its configuration.

typedef OnExecuteFn = FutureOr<void> Function(
  Database db,
  String sql, {
  List<Object?>? arguments,
  required DateTime startTime,
  required DateTime endTime,
});

And the methods responsible for performing such operations would do something similar to:

  @override
  Future<SqfliteQueryCursor> txnRawQueryCursor(SqfliteTransaction? txn,
      String sql, List<Object?>? arguments, int pageSize) {
    return txnSynchronized(txn, (_) async {
      // start
      final start = DateTime.now();
      var methodArguments = _txnGetSqlMethodArguments(txn, sql, arguments);
      methodArguments[paramCursorPageSize] = pageSize;
      dynamic result =
          await safeInvokeMethod<dynamic>(methodQuery, methodArguments);

      var cursorId = queryResultCursorId(result);
      var resultList = queryResultToList(result);
      final sqfliteQueryCursor =
          SqfliteQueryCursor(this, txn, cursorId, resultList);
      // end
      final end = DateTime.now();
      // call callback for monitoring
      await options?.onExecute?.call(
        db,
        sql,
        arguments: arguments,
        startTime: start,
        endTime: end,
      );

      return sqfliteQueryCursor;
    });
  }

So APM tools such as sentry.io could provide builtinOnExecuteFn for automatic monitoring.

This is just an example, I don't know the sqflite well so don't take this example as a recommendation, maybe there are better ways to hook up into the execution pipeline, etc.

Thanks!

alextekartik commented 1 year ago

Thanks for explaining your need. Currently logging is done the native side mainly for debugging (and batch are executed only on the native without calling back the dart side). But I'm looking for a solution likely a wrapper presented as a factory that will wrap each call like you suggest.

marandaneto commented 1 year ago

@alextekartik Thanks, a wrapper works but its more cumbersome IMO, so I'd be looking for something similar to https://square.github.io/okhttp/features/interceptors/ You could do that before & after calling the Native channels (calling native), it'd be pretty much the same. I'll go for a wrapper solution for now but I'd love to help on this in the future.