strategic_logger 4.0.0
strategic_logger: ^4.0.0 copied to clipboard
Modern, high-performance logging framework for Flutter & Dart applications with multi-strategy logging, isolate-based processing, and beautiful console output.
Strategic Logger #
__ ______ __ ______ __ ___ __ __ __ __ ___ ___
[__ | |__/|__| | |__ | _ | | | | || _ | _ |__ |__/
___] | | \| | | |___|__]_|_ |__ |___|__||__]|__]|___| \
Strategic Logger powered by Hypn Tech (hypn.com.br)
Quick Start #
import 'package:strategic_logger/logger.dart';
// Works immediately - no initialization needed
logger.info('App started');
logger.debug('Debug details', context: {'version': '4.0.0'});
logger.error('Something failed', stackTrace: StackTrace.current);
Output:
14:30:25.123 [INFO ] App started
14:30:25.124 [DEBUG] Debug details
[CONTEXT]
version: 4.0.0
14:30:25.125 [ERROR] Something failed
Stack Trace: ...
Full Configuration #
import 'package:strategic_logger/logger.dart';
void main() async {
await logger.initialize(
projectName: 'My App',
level: LogLevel.info,
strategies: [
ConsoleLogStrategy(useModernFormatting: true, useColors: true),
SentryLogStrategy(),
FirebaseCrashlyticsLogStrategy(),
DatadogLogStrategy(apiKey: 'key', service: 'app', env: 'prod'),
],
);
// One call logs to Console + Sentry + Crashlytics + Datadog
logger.info('User logged in', context: {'userId': '123'});
}
Built-in Strategies #
| Strategy | Use Case | Key Config |
|---|---|---|
ConsoleLogStrategy |
Development & debugging | useModernFormatting, useColors |
FirebaseAnalyticsLogStrategy |
User behavior tracking | Firebase configured externally |
FirebaseCrashlyticsLogStrategy |
Crash reports in production | Firebase configured externally |
SentryLogStrategy |
Error monitoring with context | DSN configured externally |
DatadogLogStrategy |
APM & centralized logs | apiKey, service, env |
NewRelicLogStrategy |
Performance monitoring | licenseKey, appName |
Decision Matrix: When to Use Each Strategy #
| Scenario | Recommended Strategy | Why |
|---|---|---|
| Local development | ConsoleLogStrategy |
Beautiful colored output, zero config |
| User analytics | FirebaseAnalyticsLogStrategy |
Track events, conversions, behavior |
| Crash tracking | FirebaseCrashlyticsLogStrategy |
Non-fatal and fatal crash reports |
| Error monitoring | SentryLogStrategy |
Rich error context, breadcrumbs |
| Full observability | DatadogLogStrategy |
APM, logs, metrics in one platform |
| Performance monitoring | NewRelicLogStrategy |
Application performance insights |
| Custom destination | Extend LogStrategy or HttpLogStrategy |
Full control over log routing |
Features #
Named Loggers #
Organize logs by module or component:
final authLogger = logger.named('auth');
final paymentLogger = logger.named('payment');
authLogger.info('User logged in'); // [auth] User logged in
paymentLogger.error('Payment failed'); // [payment] Payment failed
Lazy Evaluation #
Avoid expensive computations when log level is inactive:
// Always evaluates (even if debug is disabled)
logger.debug('Users: ${expensiveQuery()}');
// Only evaluates if the message is actually logged
logger.debug(() => 'Users: ${expensiveQuery()}');
Stream Listeners #
Listen to log entries for custom processing:
logger.listen((entry) {
myAnalytics.track(entry.message, entry.mergedContext);
});
Shorthand Aliases #
Concise logging inspired by the logger package:
logger.d('Debug'); // Same as logger.debug()
logger.i('Info'); // Same as logger.info()
logger.w('Warning'); // Same as logger.warning()
logger.e('Error'); // Same as logger.error()
logger.f('Fatal'); // Same as logger.fatal()
Structured Logging with Context #
Context is passed to ALL strategies automatically:
logger.info('User action', context: {
'userId': '123',
'action': 'login',
'device': 'iPhone 15',
});
// Context available in Datadog for indexing, Sentry as extra fields,
// Firebase Analytics as parameters, console as formatted output.
Real-time Log Streaming #
logger.logStream.listen((logEntry) {
updateDashboard(logEntry);
});
Creating Custom Strategies #
Simple: Override handleLog() (1 method) #
import 'package:strategic_logger/logger.dart';
class MyCustomStrategy extends LogStrategy {
@override
Future<void> handleLog(LogEntry entry) async {
if (!shouldLog(event: entry.event)) return;
final context = entry.mergedContext;
await sendToMyService(entry.message, context);
}
}
Per-Level: Override individual methods #
class MyDetailedStrategy extends LogStrategy {
@override
Future<void> info(LogEntry entry) async {
// Handle info differently
}
@override
Future<void> error(LogEntry entry) async {
// Handle errors differently
}
}
HTTP Strategy: Extend HttpLogStrategy #
For strategies that send to HTTP endpoints, get batch processing, retry logic, and resource management for free:
class MyHttpStrategy extends HttpLogStrategy {
final String apiKey;
MyHttpStrategy({required this.apiKey})
: super(batchSize: 50, batchTimeout: Duration(seconds: 10));
@override
String get strategyName => 'MyHttpStrategy';
@override
String get endpoint => 'https://api.example.com/logs';
@override
Map<String, String> get headers => {'Authorization': 'Bearer $apiKey'};
@override
Map<String, dynamic> formatLogEntry(LogEntry entry) => {
'message': entry.message.toString(),
'level': entry.level.name,
'context': entry.mergedContext,
};
}
Strategy Configuration #
ConsoleLogStrategy #
ConsoleLogStrategy(
logLevel: LogLevel.debug,
useModernFormatting: true, // Rich formatting with colors
useColors: true, // Enable ANSI colors
autoDetectColors: true, // iOS/Android safe (no ANSI garbage)
showTimestamp: true,
showContext: true,
)
DatadogLogStrategy #
DatadogLogStrategy(
apiKey: 'your-api-key',
service: 'my-app',
env: 'production',
enableCompression: true, // Gzip compression (default)
batchSize: 100, // Send after 100 entries
batchTimeout: Duration(seconds: 5), // Or after 5 seconds
maxRetries: 3, // Retry failed batches
)
NewRelicLogStrategy #
NewRelicLogStrategy(
licenseKey: 'your-license-key',
appName: 'my-app',
batchSize: 50,
batchTimeout: Duration(seconds: 10),
)
Firebase Strategies #
FirebaseAnalyticsLogStrategy(logLevel: LogLevel.info)
FirebaseCrashlyticsLogStrategy(logLevel: LogLevel.error)
SentryLogStrategy #
SentryLogStrategy(logLevel: LogLevel.error)
Flutter App Integration #
import 'package:flutter/material.dart';
import 'package:strategic_logger/logger.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await logger.initialize(
projectName: 'My App',
strategies: [
ConsoleLogStrategy(useModernFormatting: true),
FirebaseCrashlyticsLogStrategy(),
],
);
runApp(const MyApp());
}
Performance #
- Synchronous API - Logging calls return immediately (fire-and-forget)
- Isolate-based processing - Heavy operations run in background isolates
- Batch processing - HTTP strategies batch logs (100 entries or 5s timeout)
- Async queue - Backpressure control with 1000-entry buffer
- Retry logic - Exponential backoff for failed network operations
final stats = logger.getPerformanceStats();
Troubleshooting #
ANSI colors showing as garbage on iOS/Android #
Colors are auto-detected and disabled on platforms that don't support ANSI. If you still see issues:
ConsoleLogStrategy(autoDetectColors: true) // Default - auto-detect
ConsoleLogStrategy(useColors: false) // Force disable
Isolates not working on Web #
Isolates are automatically disabled on web platform. No configuration needed.
HTTP strategy batch delays #
Logs are batched for efficiency. To flush immediately:
logger.flush();
Auto-init warning on startup #
If you see the auto-initialization warning, call initialize() explicitly:
await logger.initialize(strategies: [ConsoleLogStrategy()]);
Migration Guide #
From v3.x to v4.0.0 #
v4.0.0 is backward compatible. New features are additive:
handleLog()- New single-method override for custom strategies (optional, oldlog/info/error/fataloverrides still work)logger.named('module')- Named loggers for organizing by componentlogger.debug(() => 'lazy')- Lazy evaluation supportlogger.listen()- Stream-based extensibilitylogger.d(),i(),w(),e(),f()- Shorthand aliasesHttpLogStrategy- Base class for HTTP strategiesLogEntry- Now exported from mainlogger.dart
From v2.x to v3.0.0 #
// v2.x - required await
await logger.info('message');
// v3.0.0+ - synchronous, no await
logger.info('message');
See CHANGELOG.md for full version history.
API Reference #
LogEntry #
class LogEntry {
final dynamic message;
final LogLevel level;
final DateTime timestamp;
final LogEvent? event;
final Map<String, dynamic>? context;
final StackTrace? stackTrace;
/// Merges context and event.parameters into one map
Map<String, dynamic> get mergedContext;
}
LogStrategy #
abstract class LogStrategy {
Future<void> handleLog(LogEntry entry); // Override this (recommended)
Future<void> log(LogEntry entry); // Or override per-level
Future<void> info(LogEntry entry);
Future<void> error(LogEntry entry);
Future<void> fatal(LogEntry entry);
bool shouldLog({LogEvent? event});
}
Supported Platforms #
- Android, iOS, Web, macOS, Linux, Windows
Contributing #
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Read CLAUDE.md for development guidelines
- Run
flutter testandflutter analyze - Open a Pull Request