telling_logger 1.0.2
telling_logger: ^1.0.2 copied to clipboard
Comprehensive crash reporting, error tracking, and analytics SDK for Flutter applications. Track errors, monitor performance, and gain insights into your app's behavior.
Telling Logger π #
A production-ready crash reporting, error tracking, and analytics SDK for Flutter applications. Monitor your app's health, track user behavior, and gain actionable insights with minimal setup.
β¨ Features #
Core Capabilities #
- π Automatic Crash Reporting β Captures unhandled Flutter framework and platform errors
- π Event Analytics β Track custom events, user actions, and business metrics
- π± Rich Device Context β Auto-collects platform, OS version, device model, and app info
- π Session Management β Automatic session tracking with app lifecycle hooks
- π Screen Tracking β Built-in NavigatorObserver for automatic screen view analytics
- π€ User Context β Associate logs with user IDs, names, and emails
- π― Widget-Level Tracking β
.nowTelling()extension for effortless view tracking - β‘ Smart Batching β Efficient log deduplication and batching to minimize network overhead
- οΏ½ Offline Support β Persists logs when offline, auto-sends when connection is restored
- π‘οΈ Rate Limiting β Built-in deduplication, throttling, and flood protection
- π Cross-Platform β Works on iOS, Android, Web, macOS, Windows, and Linux
Developer Experience #
- π 5-Minute Setup β Initialize with a single line of code
- π Production-Safe Logging β Debug logs automatically stripped from release builds
- π Backend Agnostic β Use our backend or build your own
- π¨ Flexible API β Multiple log levels, types, and metadata support
- π Type-Safe β Fully typed with comprehensive IntelliSense
π¦ Installation #
Add telling_logger to your pubspec.yaml:
dependencies:
telling_logger: ^1.0.0
Then install:
flutter pub get
π Quick Start #
1. Initialize the SDK #
In your main.dart, initialize Telling before running your app:
import 'package:flutter/material.dart';
import 'package:telling_logger/telling_logger.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize Telling SDK
await Telling.instance.init(
'YOUR_API_KEY',
);
// Enable automatic crash reporting
Telling.instance.enableCrashReporting();
runApp(MyApp());
}
2. Log Events #
// Simple info log
Telling.instance.log('User completed onboarding');
// Log with metadata
Telling.instance.log(
'Payment processed',
level: LogLevel.info,
metadata: {
'amount': 29.99,
'currency': 'USD',
'payment_method': 'stripe',
},
);
// Error logging
try {
await processPayment();
} catch (e, stack) {
Telling.instance.log(
'Payment failed',
level: LogLevel.error,
error: e,
stackTrace: stack,
);
}
3. Track Analytics #
// Track custom events
Telling.instance.event(
'button_clicked',
properties: {
'button_name': 'Sign Up',
'screen': 'Landing Page',
'user_segment': 'free_trial',
},
);
π Core Concepts #
Log Levels #
Control the severity and visibility of your logs:
| Level | Use Case | Severity |
|---|---|---|
LogLevel.trace |
Extremely detailed debugging | 0 |
LogLevel.debug |
Detailed diagnostic information | 1 |
LogLevel.info |
General informational messages | 2 |
LogLevel.warning |
Potentially harmful situations | 3 |
LogLevel.error |
Runtime errors that allow continuation | 4 |
LogLevel.fatal |
Critical errors causing termination | 5 |
Log Types #
Categorize logs for better filtering and analytics:
| Type | Purpose |
|---|---|
LogType.general |
Standard application logs |
LogType.analytics |
User behavior and event tracking |
LogType.event |
Custom business events |
LogType.performance |
Performance metrics and benchmarks |
LogType.network |
API calls and network activity |
LogType.security |
Security-related events |
LogType.exception |
Handled exceptions |
LogType.crash |
Application crashes and fatal errors |
LogType.custom |
Custom log categories |
π― Advanced Features #
User Context Tracking #
Associate logs with specific users for better debugging and analytics:
// Set user context after login
Telling.instance.setUser(
userId: 'user_12345',
userName: 'Jane Doe',
userEmail: 'jane@example.com',
);
// Clear user context after logout
Telling.instance.clearUser();
All subsequent logs will automatically include user information until cleared.
Automatic Screen Tracking #
With MaterialApp
MaterialApp(
navigatorObservers: [
Telling.instance.screenTracker,
],
home: HomeScreen(),
)
With go_router
final router = GoRouter(
observers: [
Telling.instance.goRouterScreenTracker,
],
routes: [...],
);
MaterialApp.router(
routerConfig: router,
)
Screen views are automatically logged with:
- Screen name
- Previous screen
- Time spent on previous screen
- Session context
Widget-Level Tracking #
Use the .nowTelling() extension to track any widget's visibility:
import 'package:telling_logger/telling_logger.dart';
// Basic usage - tracks when widget appears
Column(
children: [
Text('Welcome!'),
],
).nowTelling()
// With custom name
ProductCard(product: item).nowTelling(
name: 'Product Card Impression',
)
// With metadata for context
PremiumFeature().nowTelling(
name: 'Premium Feature Shown',
metadata: {
'feature_id': 'dark_mode',
'user_tier': 'free',
},
)
// Track every appearance (not just once)
AdBanner().nowTelling(
name: 'Banner Ad Impression',
trackOnce: false,
metadata: {'ad_id': 'banner_123'},
)
// Custom log type and level
CriticalAlert().nowTelling(
name: 'Security Alert Displayed',
type: LogType.security,
level: LogLevel.warning,
)
Parameters:
nameβ Custom name (defaults to widget's runtimeType)typeβ Log type (defaults toLogType.analytics)levelβ Log level (defaults toLogLevel.info)metadataβ Additional context datatrackOnceβ Track only first appearance (defaults totrue)
Session Management #
Sessions are automatically managed based on app lifecycle:
- Session Start: When app launches or returns from background
- Session End: When app goes to background or terminates
- Session Data: Duration, user context, device info
// Session data is automatically included in all logs
{
"sessionId": "user_123_1700745600000",
"userId": "user_123",
"userName": "Jane Doe",
"userEmail": "jane@example.com"
}
Crash Reporting #
Enable automatic crash capture for both Flutter and platform errors:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Telling.instance.init('YOUR_API_KEY');
// Captures:
// - Flutter framework errors (FlutterError.onError)
// - Platform dispatcher errors (PlatformDispatcher.onError)
// - Render issues (marked as warnings)
Telling.instance.enableCrashReporting();
runApp(MyApp());
}
Crash Intelligence:
- Render/layout issues are logged as
warnings - Actual crashes are logged as
fatalerrors - Full stack traces included
- Automatic retry with exponential backoff
π§ Configuration Options #
Initialization Parameters #
await Telling.instance.init(
String apiKey, // Required: Your API key
{
String? userId, // Initial user ID
String? userName, // Initial user name
String? userEmail, // Initial user email
}
);
Environment-Specific Setup #
void main() async {
WidgetsFlutterBinding.ensureInitialized();
const isProduction = bool.fromEnvironment('dart.vm.product');
await Telling.instance.init(
isProduction ? 'PROD_API_KEY' : 'DEV_API_KEY',
);
runApp(MyApp());
}
π Best Practices #
1. Initialize Early #
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize BEFORE runApp
await Telling.instance.init('API_KEY');
Telling.instance.enableCrashReporting();
runApp(MyApp());
}
2. Use Appropriate Log Levels #
// β
Good
Telling.instance.log('User login successful', level: LogLevel.info);
Telling.instance.log('Database query slow', level: LogLevel.warning);
Telling.instance.log('Payment failed', level: LogLevel.error);
// β Avoid
Telling.instance.log('Button clicked', level: LogLevel.fatal); // Wrong severity
3. Add Context with Metadata #
// β
Good - rich context
Telling.instance.event('purchase_completed', properties: {
'product_id': 'premium_monthly',
'price': 9.99,
'currency': 'USD',
'payment_method': 'stripe',
'user_segment': 'trial_converted',
});
// β Poor - no context
Telling.instance.event('purchase');
4. Track User Context #
// Set user context after authentication
await signIn(email, password);
Telling.instance.setUser(
userId: user.id,
userName: user.name,
userEmail: user.email,
);
// Clear on logout
await signOut();
Telling.instance.clearUser();
5. Use Widget Tracking Wisely #
// β
Good - track important screens/components
HomeScreen().nowTelling(name: 'Home Screen');
PremiumPaywall().nowTelling(name: 'Paywall Viewed');
// β Avoid - don't track every tiny widget
Text('Hello').nowTelling(); // Too granular
Container().nowTelling(); // Not meaningful
6. Handle Sensitive Data #
// β Don't log PII or sensitive data
Telling.instance.event('login', properties: {
'password': '123456', // NEVER
'credit_card': '4111...', // NEVER
});
// β
Hash or omit sensitive fields
Telling.instance.event('login', properties: {
'email_hash': hashEmail(user.email),
'login_method': 'email',
});
Common Errors #
"Telling SDK not initialized"
- Call
await Telling.instance.init()before using the SDK
"Invalid API Key" (403)
- Verify your API key is correct
- Check backend is running and accessible
"Logs being dropped"
- Reduce log volume or increase limits
π License #
MIT License - see the LICENSE file for details.
π Support #
- οΏ½ Documentation
- π Report Issues
- οΏ½ Discussions
- π§ Email: kiishidart@gmail.com
π Show Your Support #
If Telling Logger helped you build better apps, please:
- β Star this repo
- π¦ Share on Twitter
- π Write a blog post
- π¬ Tell your friends
Made with π by Kiishi