这是indexloc提供的服务,不要输入任何密码

engine_tracking 1.5.1 copy "engine_tracking: ^1.5.1" to clipboard
engine_tracking: ^1.5.1 copied to clipboard

Plugin Flutter para tracking, analytics, crashlytics e logs do Engine Framework

Engine Tracking #

Engine Tracking Logo

pub.dev License: MIT Flutter Dart

A comprehensive Flutter library for analytics tracking and bug reporting with unified integration across multiple services including Firebase Analytics, Firebase Crashlytics, Microsoft Clarity, Grafana Faro, Splunk, and Google Cloud Logging.

Supported Platforms: iOS • Android

Quick Start #

Add to your pubspec.yaml:

dependencies:
  engine_tracking: ^1.5.0

Initialize the library:

import 'package:engine_tracking/engine_tracking.dart';

// Initialize both analytics and bug tracking
await EngineTrackingInitialize.initWithModels(
  analyticsModel: EngineAnalyticsModel(
    firebaseAnalyticsConfig: const EngineFirebaseAnalyticsConfig(enabled: true),
    // Configure other services as needed
  ),
  bugTrackingModel: EngineBugTrackingModel(
    crashlyticsConfig: const EngineCrashlyticsConfig(enabled: true),
    // Configure other services as needed
  ),
);

// Start tracking events
await EngineAnalytics.logEvent('app_opened');

Features #

Analytics Integration

  • Firebase Analytics for comprehensive user behavior tracking
  • Microsoft Clarity with dual integration (adapter + widget) for session recordings, heatmaps, and custom events
  • Grafana Faro for observability and monitoring
  • Splunk for enterprise logging and analytics
  • Google Cloud Logging for centralized log management

Bug Tracking & Monitoring

  • Firebase Crashlytics for crash reporting
  • Automatic Flutter error handling
  • Custom error tracking with context
  • Structured logging with multiple severity levels

Developer Experience

  • Type-safe implementation with full null safety
  • Automatic session ID correlation across all services
  • Flexible service configuration (enable/disable individually)
  • Custom widgets with built-in tracking capabilities
  • HTTP request monitoring
  • Single import entry point

Architecture #

Engine Tracking uses an adapter pattern to provide unified interfaces for multiple analytics and bug tracking services. Each service can be enabled or disabled independently through configuration.

Session Management #

graph LR
    A[App Start] --> B[Generate UUID]
    B --> C[Session ID]
    C --> D[Analytics Events]
    C --> E[Bug Reports]
    C --> F[Log Entries]

All tracking events automatically include a unique session ID for correlation across services.

Analytics Flow #

graph TD
    A[Your App] --> B[EngineAnalytics]
    B --> C[Adapters]
    C --> D[Firebase Analytics]
    C --> E[Microsoft Clarity]
    C --> F[Grafana Faro]
    C --> G[Splunk]
    C --> H[Google Cloud Logging]

Bug Tracking Flow #

graph TD
    A[Flutter Errors] --> B[EngineBugTracking]
    A2[Custom Errors] --> B
    B --> C[Adapters]
    C --> D[Firebase Crashlytics]
    C --> E[Grafana Faro]
    C --> F[Google Cloud Logging]

EngineLog - Unified Logging System #

EngineLog is the central logging system that automatically abstracts and unifies calls to both Analytics and Bug Tracking services. It's the recommended way to log events as it handles service routing automatically.

graph TD
    A[Your App] --> B[EngineLog]
    B --> C{Log Level}
    C -->|debug/info| D[Developer Console]
    C -->|warning/error/fatal| E[Developer Console + Services]
    E --> F[EngineAnalytics]
    E --> G[EngineBugTracking]
    F --> H[All Analytics Services]
    G --> I[All Bug Tracking Services]

Key Benefits:

  • Single API: One method call routes to multiple services
  • Automatic Service Detection: Only calls enabled services
  • Level-based Routing: Different log levels go to appropriate services
  • Context Preservation: Maintains session ID and metadata across all services
  • Performance Optimized: No-op when services are disabled

Widget Tracking System #

Engine Tracking provides custom widgets that automatically track user interactions and screen lifecycle events.

graph TD
    A[EngineStatelessWidget] --> B[buildWithTracking]
    C[EngineStatefulWidget] --> D[buildWithTracking]
    B --> E[Automatic Screen Tracking]
    D --> E
    E --> F[screen_initialized]
    E --> G[screen_viewed]
    E --> H[screen_disposed]
    
    I[User Actions] --> J[logUserAction]
    K[State Changes] --> L[logStateChange]
    M[Custom Events] --> N[logCustomEvent]
    
    J --> O[EngineLog]
    L --> O
    N --> O

Automatic navigation tracking with EngineNavigationObserver:

graph LR
    A[Navigator] --> B[EngineNavigationObserver]
    B --> C[Route Changes]
    C --> D[EngineAnalytics.setPage]
    D --> E[All Analytics Services]

HTTP Tracking System #

Engine Tracking provides comprehensive HTTP request/response logging through EngineHttpOverride and EngineHttpTracking.

graph TD
    A[HTTP Requests] --> B[EngineHttpOverride]
    B --> C[Request Logging]
    B --> D[Response Logging]
    B --> E[Error Logging]
    C --> F[EngineLog.debug]
    D --> F
    E --> G[EngineLog.error]
    F --> H[All Tracking Services]
    G --> H

Key Features:

  • Automatic HTTP Logging: Intercepts all HTTP requests/responses
  • Configurable Logging: Control what gets logged (headers, body, timing)
  • Error Tracking: Automatic error logging for failed requests
  • Performance Metrics: Request timing and performance data
  • Chain-friendly: Works with existing HttpOverrides (like FaroHttpOverrides)
  • Multiple Configurations: Development, production, and error-only presets

Configuration Options:

// Development configuration (verbose logging)
const EngineHttpTrackingConfig(
  enabled: true,
  enableRequestLogging: true,
  enableResponseLogging: true,
  enableTimingLogging: true,
  enableHeaderLogging: true,
  enableBodyLogging: true,
  maxBodyLogLength: 2000,
  logName: 'HTTP_TRACKING_DEV',
)

// Production configuration (minimal logging)
const EngineHttpTrackingConfig(
  enabled: true,
  enableRequestLogging: true,
  enableResponseLogging: true,
  enableTimingLogging: true,
  enableHeaderLogging: false, // Be careful with sensitive data
  enableBodyLogging: false,   // Be careful with sensitive data
  maxBodyLogLength: 500,
  logName: 'HTTP_TRACKING_PROD',
)

// Error-only configuration (only log failures)
const EngineHttpTrackingConfig(
  enabled: true,
  enableRequestLogging: false,
  enableResponseLogging: true,
  enableTimingLogging: true,
  enableHeaderLogging: false,
  enableBodyLogging: false,
  maxBodyLogLength: 0,
  logName: 'HTTP_ERRORS',
)

// Custom configuration
const EngineHttpTrackingConfig(
  enabled: true,
  enableRequestLogging: true,
  enableResponseLogging: true,
  enableTimingLogging: true,
  enableHeaderLogging: false, // Be careful with sensitive data
  enableBodyLogging: false,   // Be careful with sensitive data
  maxBodyLogLength: 1000,
  logName: 'CUSTOM_HTTP',
)

Installation #

Add to your pubspec.yaml:

dependencies:
  engine_tracking: ^1.5.0

Run:

flutter pub get

Usage Examples #

Complete Examples #

The package includes complete examples demonstrating all functionality:

cd example && flutter run

Available examples:

  • Main Example: Initialization, event tracking, user properties, and navigation
  • HTTP Tracking: Requests with PokéAPI and JSONPlaceholder
  • View Tracking: Automatic screen tracking system

Use EngineTrackingInitialize to initialize both Analytics and Bug Tracking:

import 'package:engine_tracking/engine_tracking.dart';

// Both services
await EngineTrackingInitialize.initWithModels(
  analyticsModel: EngineAnalyticsModel(/* configs */),
  bugTrackingModel: EngineBugTrackingModel(/* configs */),
);

// Analytics only
await EngineTrackingInitialize.initWithModels(
  analyticsModel: EngineAnalyticsModel(/* configs */),
  bugTrackingModel: null,
);

// Bug tracking only
await EngineTrackingInitialize.initWithModels(
  analyticsModel: null,
  bugTrackingModel: EngineBugTrackingModel(/* configs */),
);

// With adapters (granular control)
await EngineTrackingInitialize.initWithAdapters(
  analyticsAdapters: [EngineFirebaseAnalyticsAdapter(/* config */)],
  bugTrackingAdapters: null, // Skip bug tracking
);

// Quick initialization (both disabled)
await EngineTrackingInitialize.initWithDefaults();

// Status
bool bothReady = EngineTrackingInitialize.isInitialized;
bool anyEnabled = EngineTrackingInitialize.isEnabled;

// Cleanup
await EngineTrackingInitialize.dispose();

Microsoft Clarity Integration #

Engine Tracking provides two ways to integrate with Microsoft Clarity:

The EngineClarityAdapter integrates Clarity into the unified analytics system:

final analyticsModel = EngineAnalyticsModel(
  clarityConfig: const EngineClarityConfig(
    enabled: true,
    projectId: 'your-clarity-project-id',
  ),
  // ... other configs
);

await EngineAnalytics.initWithModel(analyticsModel);

// All analytics calls now include Clarity
await EngineAnalytics.logEvent('user_action');
await EngineAnalytics.setUserId('user_123');
await EngineAnalytics.setPage('home_screen');

2. Widget-based Integration (For Session Recordings)

Use EngineWidget to automatically enable session recordings and heatmaps. The widget automatically detects if Clarity has been initialized through the analytics system - no manual configuration required:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Initialize analytics with Clarity configuration
  final analyticsModel = EngineAnalyticsModel(
    clarityConfig: EngineClarityConfig(
      enabled: true,
      projectId: 'your-clarity-project-id',
    ),
    // ... other configurations
  );
  
  await EngineAnalytics.initWithModel(analyticsModel);
  
  // EngineWidget automatically detects and uses Clarity configuration
  // No need to pass clarityConfig manually!
  runApp(EngineWidget(app: MyApp()));
}

Combined Usage (Best Practice)

For complete Clarity integration, initialize analytics and use EngineWidget:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  final clarityConfig = EngineClarityConfig(
    enabled: true,
    projectId: 'your-clarity-project-id',
  );
  
  // Initialize analytics with Clarity adapter
  await EngineAnalytics.initWithModel(
    EngineAnalyticsModel(
      clarityConfig: clarityConfig,
      // ... other configs
    ),
  );
  
  // EngineWidget automatically detects Clarity configuration
  // No manual configuration needed!
  runApp(EngineWidget(app: MyApp()));
}

Individual Service Configuration #

import 'package:engine_tracking/engine_tracking.dart';

Future<void> setupTracking() async {
  final analyticsModel = EngineAnalyticsModel(
    firebaseAnalyticsConfig: const EngineFirebaseAnalyticsConfig(enabled: true),
    clarityConfig: const EngineClarityConfig(
      enabled: true,
      projectId: 'your-clarity-project-id',
    ),
    faroConfig: const EngineFaroConfig(
      enabled: true,
      endpoint: 'https://faro-collector.grafana.net/collect',
      appName: 'YourApp',
      appVersion: '1.0.0',
      environment: 'production',
      apiKey: 'your-faro-api-key',
    ),
    googleLoggingConfig: const EngineGoogleLoggingConfig(
      enabled: true,
      projectId: 'your-gcp-project',
      logName: 'engine-tracking',
      credentials: {
        "type": "service_account",
        "project_id": "your-gcp-project",
        "private_key_id": "...",
        "private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
        "client_email": "your-service-account@your-gcp-project.iam.gserviceaccount.com",
        // ... rest of credentials
      },
      resource: {
        'type': 'global',
        'labels': {'project_id': 'your-gcp-project'},
      },
    ),
    splunkConfig: const EngineSplunkConfig(enabled: false),
  );

  final bugTrackingModel = EngineBugTrackingModel(
    crashlyticsConfig: const EngineCrashlyticsConfig(enabled: true),
    faroConfig: const EngineFaroConfig(
      enabled: true,
      endpoint: 'https://faro-collector.grafana.net/collect',
      appName: 'YourApp',
      appVersion: '1.0.0',
      environment: 'production',
      apiKey: 'your-faro-api-key',
    ),
    googleLoggingConfig: const EngineGoogleLoggingConfig(enabled: true, /* configs */),
  );

  await EngineAnalytics.initWithModel(analyticsModel);
  await EngineBugTracking.initWithModel(bugTrackingModel);
}

Event Tracking #

// Simple event (Session ID included automatically)
await EngineAnalytics.logEvent('button_clicked');

// Event with parameters
await EngineAnalytics.logEvent('purchase_completed', {
  'item_id': 'premium_plan',
  'value': 29.99,
  'currency': 'USD',
  'category': 'subscription',
});

// App open event
await EngineAnalytics.logAppOpen();

User Management #

// Set user ID
await EngineAnalytics.setUserId('user_12345');

// With complete information (for Faro/Clarity)
await EngineAnalytics.setUserId(
  'user_12345',
  'user@example.com',
  'John Doe',
);

// User properties
await EngineAnalytics.setUserProperty('user_type', 'premium');
await EngineAnalytics.setUserProperty('plan', 'monthly');

Screen Navigation #

// Simple screen
await EngineAnalytics.setPage('HomeScreen');

// With complete context
await EngineAnalytics.setPage(
  'ProductScreen',      // Current screen
  'HomeScreen',        // Previous screen
  'ECommerceApp',      // Screen class
);

Bug Tracking #

// Structured logging
await EngineBugTracking.log('User completed purchase', {
  'user_id': '12345',
  'product_id': 'abc-123',
  'amount': 29.99,
});

// Capture errors
try {
  // code that might fail
} catch (error, stackTrace) {
  await EngineBugTracking.recordError(
    error,
    stackTrace,
    reason: 'Payment processing failure',
  );
}

// Set user context
await EngineBugTracking.setUserIdentifier('user_12345', 'user@example.com', 'John Doe');
await EngineBugTracking.setCustomKey('subscription_plan', 'premium');

Logging System #

// Different log levels
await EngineLog.debug('Debug information');
await EngineLog.info('Informational message');
await EngineLog.warning('Warning message');
await EngineLog.error('Error occurred');
await EngineLog.fatal('Fatal error');

// With additional data
await EngineLog.info('User action', data: {
  'action': 'button_click',
  'screen': 'home',
  'user_id': '12345',
});

// Custom log name and include in analytics
await EngineLog.warning('Important warning', 
  logName: 'USER_ACTION',
  includeInAnalytics: true,
);

// Error logging with exception and stack trace
try {
  // risky operation
} catch (error, stackTrace) {
  await EngineLog.error('Operation failed',
    error: error,
    stackTrace: stackTrace,
    data: {'operation': 'user_registration'},
  );
}

// Fatal error with complete context
await EngineLog.fatal('Critical system failure',
  logName: 'SYSTEM',
  error: exception,
  stackTrace: stackTrace,
  data: {
    'component': 'payment_processor',
    'user_id': 'user_123',
    'transaction_id': 'tx_456',
  },
);

View Tracking with Widgets #

class HomePage extends EngineStatelessWidget {
  HomePage({super.key});

  @override
  String get screenName => 'home';

  @override
  Map<String, dynamic>? get screenParameters => {
    'user_type': 'premium',
    'version': '1.0.0',
  };

  @override
  Widget buildWithTracking(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Home')),
      body: ElevatedButton(
        onPressed: () {
          logUserAction('cta_clicked', parameters: {
            'button_type': 'primary',
            'location': 'header',
          });
        },
        child: const Text('Click Me'),
      ),
    );
  }
}
class ShoppingCartPage extends StatefulWidget {
  final List<Product> initialProducts;
  
  const ShoppingCartPage({super.key, required this.initialProducts});

  @override
  State<ShoppingCartPage> createState() => _ShoppingCartPageState();
}

class _ShoppingCartPageState extends EngineStatefulWidgetState<ShoppingCartPage> {
  
  late List<Product> _products;
  
  @override
  void initState() {
    super.initState();
    _products = List.from(widget.initialProducts);
  }
  
  @override
  String get screenName => 'shopping_cart';

  @override
  Map<String, dynamic>? get screenParameters => {
    'initial_product_count': widget.initialProducts.length,
    'cart_value': _calculateTotal(),
  };

  @override
  Widget buildWithTracking(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Shopping Cart')),
      body: ListView.builder(
        itemCount: _products.length,
        itemBuilder: (context, index) {
          final product = _products[index];
          return ListTile(
            title: Text(product.name),
            trailing: IconButton(
              icon: const Icon(Icons.remove_circle),
              onPressed: () {
                setState(() {
                  _products.removeAt(index);
                });
                
                logUserAction('product_removed', parameters: {
                  'product_id': product.id,
                  'product_name': product.name,
                  'remaining_count': _products.length,
                });
                
                logStateChange('cart_updated', additionalData: {
                  'action': 'removal',
                  'new_total': _calculateTotal(),
                });
              },
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          logUserAction('checkout_initiated', parameters: {
            'product_count': _products.length,
            'total_value': _calculateTotal(),
          });
        },
        child: const Icon(Icons.shopping_cart_checkout),
      ),
    );
  }
  
  double _calculateTotal() {
    return _products.fold(0.0, (sum, product) => sum + product.price);
  }
}

Custom Widgets #

Engine Tracking provides several specialized widgets for enhanced tracking capabilities:

EngineWidget - Root App Wrapper

Automatically wraps your app to enable Microsoft Clarity session recordings when Clarity is initialized. The widget intelligently detects if Clarity has been configured through the analytics system and automatically enables session recordings without requiring manual configuration:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Initialize analytics with Clarity configuration
  await EngineAnalytics.initWithModel(
    EngineAnalyticsModel(
      clarityConfig: EngineClarityConfig(
        enabled: true,
        projectId: 'your-clarity-project-id',
      ),
      firebaseAnalyticsConfig: const EngineFirebaseAnalyticsConfig(enabled: true),
      // ... other configs
    ),
  );

  // EngineWidget automatically detects and enables Clarity session recordings
  // No manual clarityConfig parameter needed!
  runApp(EngineWidget(app: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
      navigatorObservers: [EngineNavigationObserver()],
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          ElevatedButton(
            onPressed: () async {
              // This event goes to all analytics services including Clarity
              await EngineAnalytics.logEvent('button_clicked', {
                'button_type': 'primary',
                'screen': 'home',
              });
            },
            child: Text('Track Event'),
          ),
          
          // Mask sensitive content in Clarity recordings
          EngineMaskWidget(
            child: Text('Sensitive user data'),
          ),
        ],
      ),
    );
  }
}

EngineMaskWidget - Privacy Protection

Masks sensitive content in session recordings:

class PaymentScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Text('Order Summary'),
          
          // Mask sensitive payment information
          EngineMaskWidget(
            child: Column(
              children: [
                Text('Credit Card: **** **** **** 1234'),
                Text('CVV: 123'),
                
                // Unmask non-sensitive info within masked area
                EngineUnmaskWidget(
                  child: Text('Expires: 12/25'),
                ),
              ],
            ),
          ),
          
          ElevatedButton(
            onPressed: () => processPayment(),
            child: Text('Pay Now'),
          ),
        ],
      ),
    );
  }
}

EngineStatelessWidget - Enhanced Stateless Widgets

Provides automatic screen tracking and user action logging:

class ProductListPage extends EngineStatelessWidget {
  ProductListPage({super.key});

  @override
  String get screenName => 'product_list';

  @override
  Map<String, dynamic>? get screenParameters => {
    'category': 'electronics',
    'sort_by': 'price',
  };

  @override
  Widget buildWithTracking(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Products')),
      body: ListView.builder(
        itemBuilder: (context, index) {
          return ListTile(
            title: Text('Product $index'),
            onTap: () {
              // Automatically tracked user action
              logUserAction('product_selected', parameters: {
                'product_id': index,
                'product_name': 'Product $index',
              });
              
              // Navigate to product details
              Navigator.push(context, 
                MaterialPageRoute(builder: (_) => ProductDetailPage()));
            },
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // Log custom events
          logCustomEvent('filter_opened');
        },
        child: Icon(Icons.filter_list),
      ),
    );
  }
}

EngineStatefulWidget - Enhanced Stateful Widgets

Includes state change tracking in addition to all EngineStatelessWidget features:

class ShoppingCartPage extends StatefulWidget {
  @override
  State<ShoppingCartPage> createState() => _ShoppingCartPageState();
}

class _ShoppingCartPageState extends EngineStatefulWidgetState<ShoppingCartPage> {
  List<CartItem> _items = [];
  
  @override
  String get screenName => 'shopping_cart';

  @override
  Map<String, dynamic>? get screenParameters => {
    'initial_item_count': _items.length,
    'cart_value': _calculateTotal(),
  };

  @override
  Widget buildWithTracking(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Shopping Cart')),
      body: ListView.builder(
        itemCount: _items.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(_items[index].name),
            trailing: IconButton(
              icon: Icon(Icons.remove),
              onPressed: () => _removeItem(index),
            ),
          );
        },
      ),
    );
  }
  
  void _removeItem(int index) {
    final removedItem = _items[index];
    
    setState(() {
      _items.removeAt(index);
    });
    
    // Track user action
    logUserAction('item_removed', parameters: {
      'item_id': removedItem.id,
      'remaining_items': _items.length,
    });
    
    // Track state change
    logStateChange('cart_updated', additionalData: {
      'action': 'item_removal',
      'new_total': _calculateTotal(),
    });
  }
  
  double _calculateTotal() {
    return _items.fold(0.0, (sum, item) => sum + item.price);
  }
}

Automatic navigation tracking with EngineNavigationObserver:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      // Add the navigation observer for automatic screen tracking
      navigatorObservers: [
        EngineNavigationObserver(),
      ],
      home: HomePage(),
      routes: {
        '/products': (context) => ProductListPage(),
        '/cart': (context) => ShoppingCartPage(),
        '/profile': (context) => ProfilePage(),
      },
    );
  }
}

The EngineNavigationObserver automatically:

  • Tracks route changes and screen transitions
  • Calls EngineAnalytics.setPage() with screen names
  • Provides navigation context for analytics
  • Works seamlessly with both named routes and direct navigation

HTTP Request Tracking #

Engine Tracking provides comprehensive HTTP request/response logging:

import 'package:engine_tracking/engine_tracking.dart';
import 'package:http/http.dart' as http;

void main() async {
  // Initialize Engine Tracking
  await EngineTrackingInitialize.initWithModels(
    analyticsModel: myAnalyticsModel,
    bugTrackingModel: myBugTrackingModel,
    // Add HTTP tracking configuration
    httpTrackingConfig: const EngineHttpTrackingConfig(
      enabled: true,
      enableRequestLogging: true,
      enableResponseLogging: true,
      enableTimingLogging: true,
      enableHeaderLogging: true,
      enableBodyLogging: true,
      maxBodyLogLength: 2000,
      logName: 'HTTP_TRACKING_DEV',
    ),
  );
  
  runApp(MyApp());
}

// HTTP requests are now automatically logged
class ApiService {
  Future<User> getUser(String userId) async {
    // This request will be automatically logged with:
    // - Request details (method, URL, headers, timing)
    // - Response details (status, headers, timing)
    // - Error details (if request fails)
    final response = await http.get(
      Uri.parse('https://api.example.com/users/$userId'),
      headers: {'Authorization': 'Bearer $token'},
    );
    
    if (response.statusCode == 200) {
      return User.fromJson(json.decode(response.body));
    } else {
      throw ApiException('Failed to load user');
    }
  }
  
  Future<void> updateUser(User user) async {
    // POST requests are also automatically tracked
    final response = await http.post(
      Uri.parse('https://api.example.com/users/${user.id}'),
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer $token',
      },
      body: json.encode(user.toJson()),
    );
    
    if (response.statusCode != 200) {
      throw ApiException('Failed to update user');
    }
  }
}

Configuration Examples:

// Development: Full logging with headers and body
const devConfig = EngineHttpTrackingConfig(
  enabled: true,
  enableRequestLogging: true,
  enableResponseLogging: true,
  enableTimingLogging: true,
  enableHeaderLogging: true,
  enableBodyLogging: true,
  maxBodyLogLength: 2000,
  logName: 'API_DEV',
);

// Production: Minimal logging, no sensitive data
const prodConfig = EngineHttpTrackingConfig(
  enabled: true,
  enableRequestLogging: true,
  enableResponseLogging: true,
  enableTimingLogging: true,
  enableHeaderLogging: false, // Disable for security
  enableBodyLogging: false,   // Disable for security
  maxBodyLogLength: 500,
  logName: 'API_PROD',
);

// Error-only: Only log failed requests
const errorConfig = EngineHttpTrackingConfig(
  enabled: true,
  enableRequestLogging: false,
  enableResponseLogging: true,
  enableTimingLogging: true,
  enableHeaderLogging: false,
  enableBodyLogging: false,
  maxBodyLogLength: 0,
  logName: 'API_ERRORS',
);

// Custom configuration
const customConfig = EngineHttpTrackingConfig(
  enabled: true,
  enableRequestLogging: true,
  enableResponseLogging: true,
  enableTimingLogging: true,
  enableHeaderLogging: false, // Disable for security
  enableBodyLogging: false,   // Disable for security
  maxBodyLogLength: 500,
  logName: 'CUSTOM_API',
);

Advanced Usage:

// Temporarily use different configuration
await EngineHttpTracking.withConfig(
  const EngineHttpTrackingConfig(
    enabled: true,
    enableRequestLogging: true,
    enableResponseLogging: true,
    enableTimingLogging: true,
    enableHeaderLogging: true,
    enableBodyLogging: true,
    maxBodyLogLength: 2000,
    logName: 'DEBUG_HTTP',
  ),
  () async {
    // All HTTP requests in this block use development config
    await apiService.debugEndpoint();
  },
);

// Temporarily disable HTTP tracking
final restore = EngineHttpTracking.temporaryDisable();
await sensitiveApiCall(); // This won't be logged
restore(); // Re-enable with previous config

// Chain with existing HttpOverrides (like FaroHttpOverrides)
final config = EngineHttpTrackingConfig(
  enabled: true,
  enableRequestLogging: true,
  enableResponseLogging: true,
  enableTimingLogging: true,
  enableHeaderLogging: false,
  enableBodyLogging: false,
  maxBodyLogLength: 500,
  logName: 'HTTP_TRACKING_PROD',
  baseOverride: FaroHttpOverrides(existingOverride),
);
EngineHttpTracking.initialize(config);

// Log custom HTTP-related events
await EngineHttpTracking.logCustomEvent(
  'API rate limit reached',
  data: {
    'endpoint': '/api/users',
    'retry_after': 60,
    'request_count': 100,
  },
);

// Get HTTP tracking statistics
final stats = EngineHttpTracking.getStats();
print('HTTP Tracking enabled: ${stats['is_enabled']}');

Status Verification #

// Check if analytics is enabled
if (EngineAnalytics.isEnabled) {
  print('✅ Analytics is active');
}

// Check specific services
if (EngineAnalytics.isFirebaseInitialized) {
  print('🔥 Firebase Analytics active');
}

if (EngineAnalytics.isClarityInitialized) {
  print('👁️ Microsoft Clarity active');
}

if (EngineAnalytics.isFaroInitialized) {
  print('📊 Grafana Faro active');
}

if (EngineAnalytics.isSplunkInitialized) {
  print('🔍 Splunk active');
}

if (EngineAnalytics.isGoogleLoggingInitialized) {
  print('☁️ Google Cloud Logging active');
}

Contributing #

Contributions are welcome! Please:

  1. Fork the project
  2. Create a feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

Contribution Guidelines #

  • Follow existing code patterns
  • Document new features
  • Test on both Android and iOS
  • Update the CHANGELOG.md

License #

This project is licensed under the MIT License - see the LICENSE file for details.


About STMR #

Developed by STMR - Mobile solutions specialists.

STMR is a company focused on developing innovative technology solutions for mobile devices, specializing in robust architectures, optimized performance, and exceptional user experiences.

Our Mission #

To provide high-quality Flutter tools and libraries that accelerate enterprise mobile application development while maintaining the highest standards of security, performance, and usability.


Tip: For maximum efficiency, configure only the services you actually use. The library is optimized to work with any combination of enabled or disabled services. With automatic Session ID, you now have complete log correlation and advanced centralization!

1
likes
160
points
584
downloads
screenshot

Publisher

verified publisherstmr.tech

Weekly Downloads

Plugin Flutter para tracking, analytics, crashlytics e logs do Engine Framework

Homepage
Repository (GitHub)
View/report issues

Topics

#tracking #analytics #firebase #crashlytics #logging

Documentation

Documentation
API reference

Funding

Consider supporting this project:

github.com

License

MIT (license)

Dependencies

clarity_flutter, faro, firebase_analytics, firebase_crashlytics, flutter, googleapis, googleapis_auth

More

Packages that depend on engine_tracking