flutter_remote_logger 0.3.1
flutter_remote_logger: ^0.3.1 copied to clipboard
A comprehensive remote logging and profiling package for Flutter. Captures sessions, device info, and uploads logs to Firebase or custom backends.
Flutter Remote Logger #
A robust Remote Logging and Profiling package for Flutter applications.
flutter_remote_logger captures logs, device metadata, and session information, buffers them locally, and uploads them to a remote target (Firebase or Supabase) entirely in the background logic. It solves the problem of "profiling sessions" where you need to trace user behavior or debug issues on specific devices, even linking anonymous sessions to authenticated users later.
Table of Contents #
Features #
- Session-based Logging: Every app launch creates a unique Session ID.
- Automatic Metadata: Captures OS, Version, Device Model, and more automatically.
- Persistent Device ID: Uses
android_idon Android and Keychain on iOS to ensure the ID persists across app reinstalls. - Nested Remote Paths: Supports uploading logs to custom nested folder structures (e.g.
project_name/v1.0/). - Local Buffering: Logs are written synchronously to secure local storage (
.jsonlfiles) ensuring no data loss on crashes. - Backend Agnostic: Comes with built-in uploaders for Firebase and Supabase, but you can implement your own.
- User Linking: Link an anonymous device session to a User ID at any point.
Getting Started #
Installation #
Add the package to your pubspec.yaml:
dependencies:
flutter_remote_logger:
git:
url: https://github.com/infodreams-software/flutter-remote-logger.git
# OR, if published:
# flutter_remote_logger: ^0.3.0
Configuration #
You need to choose a backend to store your logs.
Option A: Firebase
- Dependencies: Add
firebase_core,firebase_storage, andcloud_firestoreto your app. - Initialization: Initialize Firebase in your
main.dart. - Rules: Ensure your Firestore and Storage have appropriate write rules.
- Storage path:
logs/{deviceId}/{sessionId}.jsonl(default) or{remotePath}/{deviceId}/{sessionId}.jsonl - Firestore path:
sessions/{sessionId}
- Storage path:
Option B: Supabase
To use Supabase, you need to set up your project with the required tables and storage bucket.
-
Dependencies: Add
supabase_flutterto your app. -
Storage Bucket: Create a public bucket named
remote_logs. -
Database Tables: Run the following SQL in your Supabase SQL Editor: (See full SQL in Configuration section above)
-
RLS Policies: Ensure correct RLS policies for
remote_log_sessions(upsert) and storage objects (upload).
Usage #
Initialization #
Initialize RemoteLogger early in your app lifecycle. You must inject the appropriate LogUploader.
Example: Using Firebase
import 'package:flutter_remote_logger/flutter_remote_logger.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// Initialize with FirebaseUploader (default is null/noop if not provided?)
// Actually, you typically just let it rely on default imports or pass explicitly:
await RemoteLogger().initialize(
uploader: FirebaseLogUploader(),
// Optional: Upload logs every 5 minutes automatically
autoUploadFrequency: const Duration(minutes: 5),
// Optional: Organize logs in a specific remote folder
remotePath: 'my_project/v1.0',
);
runApp(MyApp());
}
Example: Using Supabase
import 'package:flutter_remote_logger/flutter_remote_logger.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Supabase.initialize(
url: 'YOUR_SUPABASE_URL',
anonKey: 'YOUR_SUPABASE_ANON_KEY',
);
await RemoteLogger().initialize(
uploader: SupabaseLogUploader(
supabaseClient: Supabase.instance.client,
// Optional: configuration
// bucketName: 'my_logs',
),
// Optional: Organize logs in a specific remote folder (e.g. project/version)
remotePath: 'my_app/production',
isEnabled: true,
);
// You can now access the stable Device ID used for sessions
print('Device ID: ${RemoteLogger().deviceId}');
runApp(MyApp());
}
Logging Events #
Log anywhere in your app. The API is similar to standard logging.
// Simple info log
RemoteLogger().log('App loaded successfully');
// Log with level and custom tag
RemoteLogger().log('Database connected', level: 'DEBUG', tag: 'DB');
// Log structured data (Payload)
try {
// ... risky code
} catch (e) {
RemoteLogger().log(
'Initialization failed',
level: 'ERROR',
payload: {
'error': e.toString(),
'retryCount': 3,
}
);
}
Linking User #
When a user authenticates, linking their User ID to the session allows you to find their logs later by User ID instead of just Device ID.
void onUserLogin(String userId) {
RemoteLogger().identifyUser(userId);
}
Force Upload #
Logs are locally buffered in files. You can trigger a manual upload of the current session file at any time (e.g. on important errors or app pause).
await RemoteLogger().uploadCurrentSession();
await RemoteLogger().uploadCurrentSession();
### Handling Errors and Events
You can listen to the `events` stream to receive real-time feedback about upload operations, including errors (e.g., network issues, permission denied) and successes.
```dart
RemoteLogger().events.listen((event) {
if (event is RemoteLoggerError) {
print('RemoteLogger Error: ${event.message} - ${event.error}');
} else if (event is RemoteLoggerSuccess) {
print('RemoteLogger Success: ${event.message}');
}
});
Architecture #
The package is designed to be modular.
- RemoteLogger: The singleton facade.
- LogStorage: Controls where logs are temporarily saved (Default:
FileLogStorage). - LogUploader: Controls where logs go (implementations:
FirebaseLogUploader,SupabaseLogUploader).
Contributing #
Contributions are welcome! Please submit a PR or open an issue.
License #
MIT License. See LICENSE file.