astute_logger 2.0.2
astute_logger: ^2.0.2 copied to clipboard
A simple and powerful logger for Flutter apps with support for color-coding, JSON pretty-printing, and performance tracking.
Astute Logger #
A lightweight yet powerful logging utility designed specifically for Flutter applications. Astute Logger provides beautiful console output, persistent file logging, remote log forwarding, and sensitive data redactionβall with a simple, intuitive API.
β¨ Features #
- π¨ Color-Coded Console Logs - Beautiful, level-based color formatting for easy debugging
- π Persistent File Logging - Save logs to disk for later analysis
- π Remote Logging - Forward logs to your backend/monitoring service
- π Automatic Sensitive Data Redaction - Hide passwords, tokens, and sensitive fields
- β‘ Async Log Queue - Non-blocking logging that won't slow down your app
- π Caller Location Tracking - See exactly where each log originated
- π§ͺ Test-Friendly - Override console output for deterministic unit tests
- π Advanced Log Analysis - Search, paginate, and filter logs
- π€ Share Logs - Export log files via native share dialogs
- π― Zero Dependencies in Release Mode - Logging automatically disabled
π¦ Installation #
Add to your pubspec.yaml:
dependencies:
astute_logger: ^1.0.0
path_provider: ^2.0.0 # Required for file logging
share_plus: ^12.0.0 # Required for log sharing
Then run:
flutter pub get
π Quick Start #
Basic Usage #
import 'package:astute_logger/astute_logger.dart';
// Create a logger instance
final logger = AstuteLogger('MyApp');
// Log at different levels
logger.debug('Verbose debugging information');
logger.info('General application flow');
logger.warning('Something unexpected happened');
logger.error('Critical error occurred');
With File Logging #
final logger = AstuteLogger(
'MyApp',
enableFileLogging: true,
fileNamePrefix: 'app_logs',
);
// Initialize file logging
await logger.initFileLogging();
// Now all logs are saved to disk AND printed to console
logger.info('This will be saved to file');
With Custom Directory #
final logger = AstuteLogger(
'MyApp',
enableFileLogging: true,
);
// Use a custom directory
await logger.initFileLogging(
directoryPath: '/path/to/custom/logs',
);
π Advanced Features #
Remote Logging #
Forward logs to your backend or monitoring service:
final logger = AstuteLogger(
'MyApp',
enableRemote: true,
remoteSender: (message, level, tag) async {
await http.post(
Uri.parse('https://api.example.com/logs'),
body: jsonEncode({
'message': message,
'level': level.toString(),
'tag': tag,
'timestamp': DateTime.now().toIso8601String(),
}),
);
},
);
logger.info('This will be sent to your server');
Pretty-Print JSON #
final user = {'name': 'John', 'age': 30, 'email': 'john@example.com'};
logger.logJson(user);
// Output:
// {
// "name": "John",
// "age": 30,
// "email": "john@example.com"
// }
Measure Execution Time #
final result = logger.logExecutionTime('Database Query', () {
return database.query('SELECT * FROM users');
});
// Output: Database Query executed in 45 ms
Search Logs #
// Search for specific keywords
await logger.searchLogs(
keywords: ['error', 'network'],
reverse: true, // Show newest first
);
Paginated Log Viewing #
// Print logs in chunks (prevents UI freeze)
await logger.printLogsPaginated(
chunkSize: 200,
reverse: true,
);
Share Log Files #
// Share logs via native dialogs (email, messaging, etc.)
final success = await logger.shareLogFile(
subject: 'App Debug Logs',
text: 'Please find the attached log file',
);
π Sensitive Data Redaction #
Astute Logger automatically redacts sensitive information from your logs:
logger.info('User login: {"password": "secret123", "token": "abc-xyz"}');
// Output: User login: {"password": "***", "token": "***"}
Default patterns redact:
passwordtokenaccess_token/accessTokenrefresh_token/refreshToken
Custom Redaction Patterns #
AstuteLogger.globalRedactionPatterns.add(
RegExp(r'("api_key"\s*:\s*")[^"]+(")', caseSensitive: false),
);
π§ͺ Testing Support #
Capture logs during unit tests without depending on dart:developer:
test('should log error on failure', () {
final logBuffer = <String>[];
// Override console output
AstuteLogger.consoleOverride = (msg) => logBuffer.add(msg);
final logger = AstuteLogger('Test');
logger.error('Test error');
expect(logBuffer, contains(contains('Test error')));
// Clean up
AstuteLogger.consoleOverride = null;
});
Mock File System for Tests #
test('file logging in tests', () async {
final tempDir = Directory.systemTemp.createTempSync();
AstuteLogger.debugDirectoryProvider = () async => tempDir;
final logger = AstuteLogger(
'Test',
enableFileLogging: true,
);
await logger.initFileLogging();
logger.info('Test message');
await logger.dispose();
final logFile = File('${tempDir.path}/log.log');
final content = await logFile.readAsString();
expect(content, contains('Test message'));
});
π¨ Log Output Format #
Logs include comprehensive metadata for easy debugging:
[2024-12-10 14:32:15] [INFO] [myFunction @ main.dart:42] User logged in successfully
Each log shows:
- Timestamp - Local time when log was created
- Level - DEBUG, INFO, WARNING, or ERROR
- Caller - Function name, file, and line number
- Message - Your log content
π§ Configuration #
Log Levels #
enum LogLevel {
debug, // Verbose development logs
info, // General application flow
warning, // Unexpected but non-fatal scenarios
error, // Failures, exceptions, or critical issues
off, // Disable logging entirely
}
Color Coding #
Logs are automatically color-coded in the console:
- π΅ DEBUG - Blue
- π’ INFO - Green
- π‘ WARNING - Yellow
- π΄ ERROR - Red
Colors are automatically stripped from file and remote logs.
π API Reference #
Core Methods #
| Method | Description |
|---|---|
debug(message, {tag}) |
Log debug information |
info(message, {tag}) |
Log general information |
warning(message, {tag}) |
Log warnings |
error(message, {tag}) |
Log errors |
write(message, level, tag) |
Low-level logging method |
Utility Methods #
| Method | Description |
|---|---|
logJson(jsonObject, {level}) |
Pretty-print JSON |
logPrettyList(list, {label, level}) |
Pretty-print lists |
logExecutionTime(label, fn) |
Measure execution time |
logWithColor(message, {color, tag}) |
Custom color logging |
File Management #
| Method | Description |
|---|---|
initFileLogging({directoryPath}) |
Initialize file logging |
shareLogFile({subject, text}) |
Share via native dialogs |
printAllLogsToConsole() |
Print entire log file |
printLogsPaginated({chunkSize, reverse}) |
Paginated log viewing |
searchLogs({keywords, chunkSize, reverse}) |
Search log contents |
Lifecycle #
| Method | Description |
|---|---|
dispose() |
Close file handles and clean up resources |
Properties #
| Property | Type | Description |
|---|---|---|
logFilePath |
String? |
Current log file path |
logFile |
File? |
Log file object |
enableFileLogging |
bool |
Enable/disable file logging |
enableRemote |
bool |
Enable/disable remote forwarding |
β οΈ Important Notes #
- Release Mode: All logging is automatically disabled in release mode to avoid performance impact
- Async Queue: Logs are processed asynchronously to prevent blocking your app
- Disposal: Always call
dispose()during app shutdown to ensure all logs are flushed - File Permissions: Ensure your app has appropriate permissions for file logging on Android/iOS
π± Platform Support #
| Platform | Console Logging | File Logging | Remote Logging | Share Logs |
|---|---|---|---|---|
| Android | β | β | β | β |
| iOS | β | β | β | β |
| Web | β | β | β | β |
| macOS | β | β | β | β |
| Windows | β | β | β | β |
| Linux | β | β | β | β |
π€ Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
π License #
This project is licensed under the MIT License - see the LICENSE file for details.
π Acknowledgments #
Built with β€οΈ for the Flutter community.
π Support #
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Made with Flutter π