amwal_pay_sdk 1.1.43
SDKflutter
Platformandroid
A Flutter SDK for integrating Amwal Pay payment solutions into your mobile apps, providing secure, seamless, and customizable payment experiences.
Logar - Centralized Logging System for Amwal Pay SDK
Logar is a comprehensive, singleton-based logging utility designed specifically for the Amwal Pay SDK. It provides structured, configurable logging with support for multiple output formats, external collectors, and clean architecture principles.
Features
- Multiple Log Levels: debug, info, warning, error, fatal
- Flexible Output Formats: Pretty-print for development, JSON for production
- External Collectors: Integration with Firebase Crashlytics and custom services
- Tagging System: Organize logs with custom tags
- Global Configuration: Enable/disable logging, set minimum levels
- Platform Agnostic: Works across mobile, web, and backend
- Clean Architecture: Follows dependency injection and SOLID principles
- Migration Support: Easy migration from existing print() and debugPrint() calls
Quick Start
1. Initialize Logar
import 'package:amwal_pay_sdk/core/logger/logger.dart';
// For development
LogarInjector.instance.initializeForDevelopment();
// For production
LogarInjector.instance.initializeForProduction(
minimumLevel: LogLevel.info,
globalPrefix: 'AMWAL_SDK',
);
2. Basic Logging
// Simple logging
Logar.debug('Debug message');
Logar.info('Info message');
Logar.warning('Warning message');
Logar.error('Error message');
Logar.fatal('Fatal error');
// With tags
Logar.debug('Network request started', tag: 'NETWORK');
Logar.info('User logged in', tag: 'AUTH');
// With additional data
Logar.info('User action', data: {
'userId': '123',
'action': 'button_click',
'timestamp': DateTime.now().toIso8601String(),
});
// With errors and stack traces
try {
// some code that might throw
} catch (error, stackTrace) {
Logar.error(
'Operation failed',
error: error,
stackTrace: stackTrace,
tag: 'BUSINESS_LOGIC',
);
}
3. Configuration
// Custom configuration
Logar.configure(LogarConfig(
minimumLevel: LogLevel.warning,
format: LogFormat.json,
enabled: true,
includeStackTrace: true,
includeTimestamp: true,
maxMessageLength: 1000,
globalPrefix: 'MY_APP',
));
// Runtime configuration changes
Logar.setEnabled(false); // Disable logging
Logar.setMinimumLevel(LogLevel.error); // Only log errors and fatal
Logar.setFormat(LogFormat.pretty); // Switch to pretty format
Migration from print() and debugPrint()
Option 1: Drop-in Replacement (Quick Migration)
import 'package:amwal_pay_sdk/core/logger/logger.dart';
// Replace this:
print('Hello World');
debugPrint('Debug info');
// With this:
LogarMigrationHelper.print('Hello World');
LogarMigrationHelper.debugPrint('Debug info');
Option 2: Proper Migration (Recommended)
// Instead of:
print('User clicked button');
// Use:
Logar.info('User clicked button', tag: 'USER_INTERACTION');
// Instead of:
debugPrint('Network response: $response');
// Use:
Logar.debug('Network response received',
tag: 'NETWORK',
data: {'response': response}
);
Advanced Usage
External Log Collectors
// Add Firebase Crashlytics
await Logar.addCollector(FirebaseCrashlyticsCollector());
// Add custom collector
await Logar.addCollector(CustomLogCollector(
collectFunction: (entry) async {
// Send to your custom logging service
await myLoggingService.send(entry.toJson());
},
));
Network Logging
// Log network requests
LogarMigrationHelper.logNetworkRequest(
method: 'POST',
url: 'https://api.example.com/users',
headers: {'Authorization': 'Bearer token'},
body: {'name': 'John'},
);
// Log network responses
LogarMigrationHelper.logNetworkResponse(
method: 'POST',
url: 'https://api.example.com/users',
statusCode: 201,
responseData: {'id': '123', 'name': 'John'},
);
// Log network errors
LogarMigrationHelper.logNetworkError(
method: 'POST',
url: 'https://api.example.com/users',
error: exception,
stackTrace: stackTrace,
);
UI Lifecycle Logging
// Log widget lifecycle events
LogarMigrationHelper.logLifecycle(
widget: 'PaymentScreen',
event: 'initState',
data: {'userId': '123'},
);
// Log user interactions
LogarMigrationHelper.logUserInteraction(
action: 'button_tap',
widget: 'PayButton',
data: {'amount': 100.0},
);
Business Logic Logging
// Log business events
LogarMigrationHelper.logBusinessEvent(
event: 'payment_initiated',
data: {
'amount': 100.0,
'currency': 'USD',
'paymentMethod': 'card',
},
);
Log Levels
| Level | Priority | Usage |
|---|---|---|
debug | 0 | Detailed information for debugging |
info | 1 | General information about app flow |
warning | 2 | Warning messages for potential issues |
error | 3 | Error messages for handled exceptions |
fatal | 4 | Critical errors that might crash the app |
Output Formats
Pretty Format (Development)
[AMWAL_SDK_DEV] [14:30:25.123] [INFO] [NETWORK] Network request started | Data: {"method":"POST","url":"https://api.example.com"}
JSON Format (Production)
{
"level": "INFO",
"message": "Network request started",
"timestamp": "2023-12-07T14:30:25.123Z",
"tag": "NETWORK",
"data": {
"method": "POST",
"url": "https://api.example.com"
},
"prefix": "AMWAL_SDK"
}
Best Practices
1. Use Appropriate Log Levels
// ✅ Good
Logar.debug('Entering function calculateTotal()');
Logar.info('Payment process started');
Logar.warning('Deprecated API endpoint used');
Logar.error('Failed to process payment', error: exception);
Logar.fatal('Critical system failure', error: exception);
// ❌ Bad
Logar.error('User clicked button'); // Should be info
Logar.debug('Payment failed'); // Should be error
2. Use Tags Consistently
// ✅ Good - Consistent tagging
Logar.debug('Request started', tag: 'NETWORK');
Logar.info('Response received', tag: 'NETWORK');
Logar.error('Request failed', tag: 'NETWORK');
// ❌ Bad - Inconsistent tagging
Logar.debug('Request started', tag: 'NETWORK');
Logar.info('Response received', tag: 'HTTP');
Logar.error('Request failed', tag: 'API');
3. Include Relevant Context
// ✅ Good - Rich context
Logar.error(
'Payment processing failed',
tag: 'PAYMENT',
error: exception,
stackTrace: stackTrace,
data: {
'userId': userId,
'amount': amount,
'paymentMethod': paymentMethod,
'transactionId': transactionId,
},
);
// ❌ Bad - No context
Logar.error('Payment failed');
4. Avoid Logging Sensitive Data
// ✅ Good
Logar.info('User authenticated', data: {
'userId': userId,
'loginMethod': 'email',
});
// ❌ Bad - Contains sensitive data
Logar.info('User authenticated', data: {
'email': 'user@example.com',
'password': 'secret123', // Never log passwords!
'creditCard': '1234-5678-9012-3456', // Never log card numbers!
});
Configuration Examples
Development Configuration
LogarInjector.instance.initializeForDevelopment(
minimumLevel: LogLevel.debug,
globalPrefix: 'AMWAL_DEV',
);
Production Configuration
LogarInjector.instance.initializeForProduction(
minimumLevel: LogLevel.warning,
globalPrefix: 'AMWAL_PROD',
collectors: [
FirebaseCrashlyticsCollector(),
CustomLogCollector(
collectFunction: (entry) => sendToAnalytics(entry),
),
],
);
Testing Configuration
Logar.configure(LogarConfig(
minimumLevel: LogLevel.error,
format: LogFormat.json,
enabled: true,
includeStackTrace: false,
includeTimestamp: false,
));
Integration with Existing Code
1. Update Dependency Injection
// In your main injector
class AppInjector {
void initialize() {
// Initialize Logar first
LogarInjector.instance.initializeForDevelopment();
// Then initialize other services
_initializeNetworking();
_initializeRepositories();
}
}
2. Update Network Layer
// In your Dio interceptors
class MyLogInterceptor extends Interceptor {
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
LogarMigrationHelper.logNetworkRequest(
method: options.method,
url: options.uri.toString(),
headers: options.headers,
body: options.data,
);
super.onRequest(options, handler);
}
}
3. Update Error Handling
// In your repositories
class PaymentRepository {
Future<PaymentResult> processPayment(PaymentData data) async {
try {
Logar.info('Processing payment', tag: 'PAYMENT', data: {
'amount': data.amount,
'currency': data.currency,
});
final result = await _networkService.processPayment(data);
Logar.info('Payment processed successfully', tag: 'PAYMENT');
return result;
} catch (error, stackTrace) {
Logar.error(
'Payment processing failed',
tag: 'PAYMENT',
error: error,
stackTrace: stackTrace,
data: {'amount': data.amount},
);
rethrow;
}
}
}
Performance Considerations
- Conditional Logging: Logar automatically checks log levels before processing
- Async Collectors: External collectors run asynchronously to avoid blocking
- Memory Management: Log history is limited to 1000 entries
- Production Optimization: Use JSON format and higher log levels in production
Troubleshooting
Common Issues
- Logs not appearing: Check if logging is enabled and log level is appropriate
- Performance issues: Reduce log level or disable verbose logging in production
- Memory usage: Clear log history periodically in long-running applications
Debug Configuration
// Enable all logs for debugging
Logar.configure(LogarConfig(
minimumLevel: LogLevel.debug,
format: LogFormat.pretty,
enabled: true,
includeStackTrace: true,
includeTimestamp: true,
));
API Reference
See the individual class documentation for detailed API information:
Logar- Main logging classLogarConfig- Configuration optionsLogarInjector- Dependency injection setupLogarMigrationHelper- Migration utilitiesLogCollector- External collector interface