Flutter Native Crash Log

A Flutter plugin to capture native Android crashes, log non-fatal errors, and view or share them within the app.

Features

  • Capture Native Crashes: Automatically catches uncaught exceptions in the Android native layer.
  • Persistent Logs: Logs are saved locally using SharedPreferences.
  • Log Viewer: Built-in UI to view crash details (Timestamp, Error, Stack Trace).
  • Share Logs: Export logs as a JSON file using the system share sheet.
  • Non-Fatal Error Logging: Log "soft crashes" or handled exceptions without killing the app.
  • Force Crash: Test the crash reporting by forcing a native crash.

Installation

Add the following to your pubspec.yaml:

dependencies:
  flutter_native_crash_log:
    path: ./ # Or git url

Usage

1. Initialize

Initialize the plugin in your main.dart, preferably after the first frame ensures the context is available for the overlay.

import 'package:flutter_native_crash_log/flutter_native_crash_log.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});
  
  // ...
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    // Initialize after build
    WidgetsBinding.instance.addPostFrameCallback((_) {
      // trackLog: true enables the native handler and shows the floating debug button
      FlutterNativeCrashLog.initialize(context, trackLog: true);
    });
  }
}

2. Force a Crash (For Testing)

To verify that native crashes are being caught, you can force a crash:

ElevatedButton(
  onPressed: () {
    FlutterNativeCrashLog.forceCrash(); // App will close
  },
  child: const Text('Force Native Crash'),
),

3. Log a Non-Fatal Error

To log an important event or error without crashing the app:

try {
  // critical operation
} catch (e, stack) {
  FlutterNativeCrashLog.logNonFatalError(e.toString(), stackTrace: stack.toString());
}

4. API Logging (Automatic 🕵️‍♂️)

The plugin can automatically capture all API requests and responses made via HttpClient (this includes most packages like http and dio).

Simply enable trackApi: true during initialization:

await FlutterNativeCrashLog.initialize(
  context, 
  trackLog: true, 
  trackApi: true, // Enables zero-code automatic tracking
);

Once enabled, any network call in your app will be captured behind the scenes and displayed in the API tab of the log viewer.

Manual Logging (Optional):

If you want to log a specific event manually:

await FlutterNativeCrashLog.logApi(
  url: 'https://api.example.com/v1/users',
  method: 'POST',
  statusCode: 201,
  requestHeaders: {'Content-Type': 'application/json'},
  requestBody: {'name': 'John Doe'},
  responseHeaders: {'Content-Type': 'application/json'},
  responseBody: {'id': 1},
);

Features in API Tab:

  • Separate Sections: View Request Headers, Request Body, Response Headers, and Response Body individually.
  • Pretty Formatting: Bodies are automatically pretty-printed if they are JSON.
  • Clean cURL Generation: Use the "Copy cURL" button to get a command ready for Postman. It automatically filters out unnecessary infrastructure headers (like host, content-length, user-agent) for a clean import.

5. Log General Info/Errors

Dart print() statements and FlutterError (e.g., framework crashes) are automatically captured and categorized.

6. Share Logs

The built-in log viewer has a share button to export all logs as a JSON file.

Viewing Logs

  1. If trackLog: true is passed, a floating bug icon appears.
  2. Tap to open the App Logs screen.
  3. Tabs:
    • Native: View low-level Android process crashes (Red).
    • Flutter: View Dart exceptions, framework errors, and print logs (Orange/Blue).
    • API: View network requests captured automatically or manually (Green).
  4. API Details: Expand an API log to view Headers/Body and use the Copy cURL button.