telling_logger 1.0.1 copy "telling_logger: ^1.0.1" to clipboard
telling_logger: ^1.0.1 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 ๐Ÿ“Š #

pub package License: MIT Flutter

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: '[email protected]',
);

// 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 to LogType.analytics)
  • level โ€“ Log level (defaults to LogLevel.info)
  • metadata โ€“ Additional context data
  • trackOnce โ€“ Track only first appearance (defaults to true)

Built-in Rate Limiting #

Telling includes intelligent rate limiting to prevent log flooding and protect your backend:

Automatically configured with optimal values:

  • Deduplication Window: 5 seconds โ€“ Identical logs (same message, level, stackTrace) are merged
  • Crash Throttle: 5 seconds โ€“ Only one crash with the same stackTrace per window
  • General Throttle: 1 second โ€“ Prevents rapid-fire duplicate logs
  • Rate Limit: 10 logs/second maximum

How it protects you:

  • Deduplication: Prevents accidental log spam from loops or rapid state changes
  • Crash Throttling: Stops crash storms from overwhelming your backend
  • Rate Limiting: Ensures your app doesn't exceed reasonable logging volume
  • Smart Throttling: Different limits for crashes vs general logs

No configuration needed โ€“ works out of the box! ๐ŸŽฏ

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": "[email protected]"
}

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 fatal errors
  • 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());
}

๐ŸŒ Backend Integration #

Using the Official Backend #

Deploy the open-source Telling backend with one click:

# Clone the backend
git clone https://github.com/ThatSaxyDev/telling.git
cd telling

# Deploy (supports Dart Frog, Globe.dev, etc.)
dart pub get
dart run bin/server.dart

Custom Backend #

Build your own backend that accepts logs via POST /api/v1/logs:

Request Headers:

Content-Type: application/json
x-api-key: YOUR_API_KEY

Request Body:

[
  {
    "id": "1700745600000",
    "type": "analytics",
    "level": "info",
    "message": "User logged in",
    "timestamp": "2024-11-23T10:30:00.000Z",
    "stackTrace": null,
    "metadata": {
      "screen": "Login",
      "method": "email"
    },
    "device": {
      "platform": "iOS",
      "osVersion": "17.0",
      "deviceModel": "iPhone 15 Pro",
      "appVersion": "1.2.0",
      "appBuildNumber": "42"
    },
    "userId": "user_123",
    "userName": "Jane Doe",
    "userEmail": "[email protected]",
    "sessionId": "user_123_1700745600000"
  }
]

Response:

  • 200 OK โ€“ Logs accepted
  • 403 Forbidden โ€“ Invalid API key
  • 4xx/5xx โ€“ Retry with exponential backoff

๐Ÿ“ฑ Platform Support #

Platform Status Notes
iOS โœ… Fully Supported iOS 11+
Android โœ… Fully Supported Android 5.0+ (API 21+)
Web โœ… Fully Supported All modern browsers
macOS โœ… Fully Supported macOS 10.14+
Windows โœ… Fully Supported Windows 10+
Linux โœ… Fully Supported Most distributions

โšก Performance #

Production Optimizations #

  • Zero Debug Overhead: Debug logs are tree-shaken from release builds
  • Asynchronous: All network operations run in background
  • Batched Sending: Logs are batched every 5 seconds
  • Smart Deduplication: Prevents duplicate logs from consuming bandwidth
  • Memory Efficient: Bounded buffer with automatic cleanup
  • Offline Resilient: Persists unsent logs to disk

Benchmarks #

  • Initialization: ~50ms (includes device metadata collection)
  • Log call overhead: <1ms (async, non-blocking)
  • Memory footprint: ~2MB (including buffer)
  • Battery impact: Negligible (<0.1% on mobile)

๐ŸŽ“ 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',
});

๐Ÿงช Testing #

Unit Testing #

Mock Telling in your tests:

// test/mocks.dart
import 'package:mocktail/mocktail.dart';
import 'package:telling_logger/telling_logger.dart';

class MockTelling extends Mock implements Telling {}

// test/my_test.dart
void main() {
  late MockTelling mockTelling;
  
  setUp(() {
    mockTelling = MockTelling();
  });
  
  test('logs event on button press', () async {
    when(() => mockTelling.event(any(), properties: any(named: 'properties')))
        .thenAnswer((_) async {});
    
    // Test your code
    
    verify(() => mockTelling.event('button_clicked', properties: any(named: 'properties')));
  });
}

Integration Testing #

void main() {
  testWidgets('tracks screen view', (tester) async {
    await Telling.instance.init('TEST_API_KEY');
    
    await tester.pumpWidget(MyApp());
    await tester.pumpAndSettle();
    
    // Verify screen tracking occurred
    // (check your test backend)
  });
}

๐Ÿ” Troubleshooting #

Logs Not Appearing #

  1. Check API Key: Ensure your API key is valid
  2. Check Network: Verify backend URL is reachable
  3. Check Initialization: Confirm Telling.instance.init() was called
  4. Check Rate Limiting: You may be hitting rate limits
// Enable debug mode to see what's happening
if (kDebugMode) {
  // Telling automatically prints debug info in debug mode
  // Check console for messages starting with "Telling:"
}

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"

  • Check rate limiting configuration
  • Reduce log volume or increase limits

๐Ÿค Contributing #

We welcome contributions! Please see our Contributing Guide.

Development Setup #

git clone https://github.com/ThatSaxyDev/telling-logger.git
cd telling-logger
flutter pub get
flutter test

๐Ÿ“„ License #

MIT License - see the LICENSE file for details.

๐Ÿ™‹ Support #

๐ŸŒŸ 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 the Telling team

Website โ€ข Twitter โ€ข GitHub

6
likes
0
points
465
downloads

Publisher

unverified uploader

Weekly Downloads

Comprehensive crash reporting, error tracking, and analytics SDK for Flutter applications. Track errors, monitor performance, and gain insights into your app's behavior.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

device_info_plus, flutter, http, package_info_plus, shared_preferences

More

Packages that depend on telling_logger