google_sheets_logger 1.0.0
google_sheets_logger: ^1.0.0 copied to clipboard
A lightweight, serverless error tracking system for Flutter Web that routes crashes and API failures directly into a Google Sheet using Google Apps Script.
Google Sheets Logger #
A Dart/Flutter package for logging messages directly to Google Sheets. Perfect for remote debugging, analytics, and monitoring applications in production without needing access to device logs.
Features #
- 📊 Log to Google Sheets - Send logs directly to a Google Spreadsheet
- 🔐 Service Account Authentication - Secure server-to-server authentication
- 📝 Structured Logging - Support for log levels (debug, info, warning, error)
- 🏷️ Custom Fields - Add custom metadata to each log entry
- ⚡ Batch Operations - Efficient batch writing to minimize API calls
- 🔄 Auto-retry - Automatic retry with exponential backoff on failures
- 📱 Cross-platform - Works on Flutter (iOS, Android, Web) and Dart VM
- 🎯 Logger Integration - Compatible with Dart's
loggingpackage
Getting Started #
Prerequisites #
- A Google Cloud Project with the Google Sheets API enabled
- A Service Account with access to your Google Sheet
- A Google Sheet shared with the service account email
Setup Google Cloud & Sheets #
- Go to Google Cloud Console
- Create a new project or select existing one
- Enable Google Sheets API (APIs & Services → Library → Google Sheets API)
- Create a Service Account (IAM & Admin → Service Accounts)
- Download the JSON key file
- Create a Google Sheet and share it with the service account email (Editor access)
- Copy the Spreadsheet ID from the URL:
https://docs.google.com/spreadsheets/d/{SPREADSHEET_ID}/edit
Installation #
Add to your pubspec.yaml:
dependencies:
google_sheets_logger: ^1.0.0
Then run:
dart pub get
# or
flutter pub get
Usage #
Basic Usage #
import 'package:google_sheets_logger/google_sheets_logger.dart';
import 'package:logging/logging.dart';
void main() async {
// Initialize the logger
final sheetsLogger = GoogleSheetsLogger(
credentialsPath: 'assets/credentials.json', // or use credentialsJson
spreadsheetId: 'YOUR_SPREADSHEET_ID',
sheetName: 'Logs', // optional, defaults to 'Logs'
);
// Initialize connection
await sheetsLogger.initialize();
// Log messages
sheetsLogger.info('Application started');
sheetsLogger.warning('Low memory detected');
sheetsLogger.severe('Failed to connect to server', error, stackTrace);
// Flush pending logs (optional, auto-flushes on interval)
await sheetsLogger.flush();
// Close when done
await sheetsLogger.close();
}
With Dart's logging Package #
import 'package:logging/logging.dart';
import 'package:google_sheets_logger/google_sheets_logger.dart';
void main() async {
// Setup Google Sheets logger
final sheetsLogger = GoogleSheetsLogger(
credentialsPath: 'assets/credentials.json',
spreadsheetId: 'YOUR_SPREADSHEET_ID',
);
await sheetsLogger.initialize();
// Attach to Dart's logging hierarchy
Logger.root.level = Level.ALL;
Logger.root.onRecord.listen(sheetsLogger.handler);
// Now use standard logging
final log = Logger('MyApp');
log.info('User logged in', {'userId': '123', 'method': 'oauth'});
log.warning('Rate limit approaching');
log.severe('Database connection failed', error, stackTrace);
}
Flutter Integration #
// main.dart
import 'package:flutter/material.dart';
import 'package:google_sheets_logger/google_sheets_logger.dart';
import 'package:logging/logging.dart';
late GoogleSheetsLogger sheetsLogger;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
sheetsLogger = GoogleSheetsLogger(
credentialsPath: 'assets/credentials.json',
spreadsheetId: const String.fromEnvironment('SHEETS_ID'),
sheetName: 'AppLogs',
batchSize: 10,
flushInterval: Duration(seconds: 30),
);
await sheetsLogger.initialize();
// Capture all Flutter errors
FlutterError.onError = (details) {
sheetsLogger.severe(details.exceptionAsString(), details.exception, details.stack);
};
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
home: const HomePage(),
);
}
}
Configuration Options #
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
credentialsPath |
String |
Yes* | - | Path to service account JSON file |
credentialsJson |
Map<String, dynamic> |
Yes* | - | Service account credentials as map |
spreadsheetId |
String |
Yes | - | Google Sheets spreadsheet ID |
sheetName |
String |
No | 'Logs' |
Name of the sheet tab |
batchSize |
int |
No | 10 |
Number of logs to batch before writing |
flushInterval |
Duration |
No | 30s |
Auto-flush interval |
maxRetries |
int |
No | 3 |
Max retry attempts on failure |
includeStackTrace |
bool |
No | true |
Include stack traces in logs |
*Either credentialsPath or credentialsJson is required.
Log Sheet Format #
The logger creates a sheet with these columns:
| Timestamp | Level | Logger | Message | Error | Stack Trace | Custom Fields |
|---|---|---|---|---|---|---|
| 2024-01-15 10:30:45 | INFO | MyApp | User logged in | {"userId":"123"} |
Additional Information #
Security Best Practices #
- Never commit credentials to version control
- Use environment variables or secure storage for credentials
- Restrict service account permissions to only the target spreadsheet
- Consider using a separate sheet per environment (dev/staging/prod)
Troubleshooting #
| Issue | Solution |
|---|---|
PERMISSION_DENIED |
Ensure sheet is shared with service account email |
SPREADSHEET_NOT_FOUND |
Verify spreadsheet ID is correct |
QUOTA_EXCEEDED |
Increase flushInterval or batchSize |
| Logs not appearing | Call flush() or wait for auto-flush interval |
Contributing #
Contributions are welcome! Please read our Contributing Guide first.
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
dart test - Submit a PR
Publishing to pub.dev #
# Dry run to verify package
dart pub publish --dry-run
# Publish to pub.dev
dart pub publish
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Support #
Made with ❤️ for the Dart & Flutter community