Skip to main content

log_tracking 0.5.0 copy "log_tracking: ^0.5.0" to clipboard
log_tracking: ^0.5.0 copied to clipboard

Flutter logger with readable console output, callbacks for Crashlytics or Sentry, and offline storage that uploads logs to your own server.

log_tracking #

A small logger for Flutter apps. It prints readable logs to the console, forwards them to tools like Firebase Crashlytics or Sentry, and can store logs on the device and upload them to your own server, even after the app was offline.

Console output of log_tracking

Features #

  • Four log levels: Log.i, Log.w, Log.e and Log.d.
  • Readable console output: each log shows its level, time, class and method in a colored box.
  • Callbacks for each level: send logs to Crashlytics, Sentry or anything else.
  • Offline storage: logs are saved on the device and uploaded when there is a connection.
  • Safe: logging never throws and never crashes your app.

Installation #

dependencies:
  log_tracking: ^0.5.0

Quick start #

Call Log.init once, before runApp:

import 'package:log_tracking/log_tracking.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Log.init(
    onError: (log) => debugPrint('Error: ${log.error}'),
  );

  runApp(const MyApp());
}

Then log from anywhere:

Log.i('Booking form opened');
Log.w('Slot 14:30 is almost full');
Log.d('Selected service id: 42');

try {
  await saveBooking();
} catch (e, stack) {
  Log.e(e, stack: stack, message: 'Could not save booking');
}

Log levels #

Method Use for Console (debug builds) Saved on device Uploaded to your server
Log.i(text) Normal events ✓ ✓ ✓
Log.w(text) Something unexpected but not an error ✓ ✓ ✓
Log.e(error) Exceptions and errors ✓ ✓ ✓ (starts the upload)
Log.d(text) Development details ✓ – –

"Saved" and "uploaded" only apply when you turn them on (see below). In release builds nothing is printed to the console; the callbacks still run.

Sending logs to Crashlytics or Sentry #

Every level has its own callback. Each one receives a LogInfo with the text, error, stack trace, class and method name.

await Log.init(
  onInfo: (log) {
    FirebaseCrashlytics.instance.log('INFO: ${log.text}');
  },
  onWarning: (log) {
    FirebaseCrashlytics.instance.recordError('WARNING: ${log.text}', log.stackTrace);
  },
  onError: (log) {
    FirebaseCrashlytics.instance.recordError(log.error, log.stackTrace, fatal: true);
  },
);

Uploading logs to your own server #

Set saveToLocal: true and pass onSendToServer. Return true when your server accepted the logs.

await Log.init(
  saveToLocal: true,
  onError: (log) {},
  onSendToServer: (LogInfoRequest request) async {
    final response = await dio.post('https://example.com/logs', data: request.toJson());
    return response.statusCode == 200;
  },
);

When are logs sent?

  • Right after Log.e is called.
  • When the app starts with an internet connection.
  • When the device comes back online.

What is sent? Every log that has not been sent yet, in batches of up to 500. Only one upload runs at a time. If you return false or throw, the logs stay on the device and are sent next time.

What does the request contain? Device information and the list of logs:

{
  "deviceType": "IOS",
  "model": "iPad",
  "brand": "ipad",
  "versionSdkInt": "18.1",
  "deviceId": "48FFBBAC-B260-47C2-9B5F-BDB2EEF1D1A8",
  "appVersion": "1.2.10",
  "isPhysicalDevice": true,
  "logList": [
    {
      "logType": "ERROR",
      "text": "Could not save booking",
      "errorString": "SocketException: Connection timed out",
      "stacktraceString": "#1 BookingRepo.save (...)",
      "className": "BookingScreen",
      "methodName": "saveBooking",
      "dateTime": "2026-10-22T14:32:07.412",
      "timeZone": "+03",
      "version": "1.2.10",
      "launchIndex": 12,
      "errorIndex": 3
    }
  ]
}

launchIndex counts app launches. errorIndex groups logs: every log up to and including an error has the same value.

deviceId is a persistent device identifier: identifierForVendor on iOS and the ID from flutter_udid on Android. Mention it in your privacy policy if you upload logs.

Local storage #

With saveToLocal: true, logs are written to the app's support directory (<application support>/log_tracking/). This directory is not visible to the user.

  • Logs older than 7 days are deleted.
  • Total size is limited to 5 MB; the oldest logs are deleted first.
  • Storage is not available on the web. There, saveToLocal is ignored and only the callbacks run.

Upgrading from 0.4.x #

No code changes are needed. On the first launch, 0.5.0 deletes the old logs folder from the documents directory and starts a new store. Logs from the old store are not uploaded.

License #

See LICENSE.

4
likes
140
points
194
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Flutter logger with readable console output, callbacks for Crashlytics or Sentry, and offline storage that uploads logs to your own server.

Repository (GitHub)
View/report issues

Topics

#logging #crashlytics #offline

License

MIT (license)

Dependencies

connectivity_plus, device_info_plus, flutter, flutter_udid, intl, json_annotation, package_info_plus, path, path_provider, synchronized

More

Packages that depend on log_tracking