dev_colorized_log 2.1.0
dev_colorized_log: ^2.1.0 copied to clipboard
A Flutter package for logging colorized text in developer mode.
Dev Colorized Log #
A Flutter package for logging colorized text in developer mode.
Usage #
See examples to /example folder, more please run example project.
/* Global settings:*/
Dev.enable = true; // whether log msg
Dev.isLogFileLocation = true; // whether log the location file info
Dev.defaultColorInt = 0; // default color text, int value from 0 to 107
Dev.isDebugPrint = true; // Dev.print whether only log on debug mode
/// V 2.1.0 Log level filtering - control which logs are printed to console
/// Set the minimum log level threshold - logs below this level will be filtered from console
/// Note: logLevel only filters console output, execFinalFunc callbacks still execute
Dev.logLevel = DevLevel.verbose; // Default: show all logs in console
Dev.logLevel = DevLevel.info; // Console: only show info, success, warning, error, fatal
Dev.logLevel = DevLevel.warn; // Console: only show warning, error, fatal
Dev.logLevel = DevLevel.error; // Console: only show error and fatal
// Example: Production environment - only show warnings and above in console
Dev.logLevel = DevLevel.warn;
Dev.exeLevel = DevLevel.error; // Only error+ will trigger exeFinalFunc
Dev.logVerbose('Debug details'); // Console: filtered, Callback: filtered
Dev.log('Normal log'); // Console: filtered, Callback: filtered
Dev.logInfo('API response received'); // Console: filtered, Callback: filtered
Dev.logSuccess('Task completed'); // Console: filtered, Callback: filtered
Dev.logWarn('Deprecated API used'); // Console: ✓ shown, Callback: filtered (below exeLevel)
Dev.logError('Network error'); // Console: ✓ shown, Callback: ✓ executed
Dev.logFatal('Critical failure!'); // Console: ✓ shown, Callback: ✓ executed
/// V 2.0.9 debounceMs + debounceKey for throttling rapid log calls
/// Use debounceMs parameter to prevent log spam from repeated calls
/// Use debounceKey when log message contains dynamic content (timestamps, counters, etc.)
Dev.logWarning('Button clicked', debounceMs: 2000); // Only logs once every 2 seconds
Dev.logInfo('API call at ${DateTime.now()}', debounceMs: 1000, debounceKey: 'api_call'); // Logs with dynamic content
Dev.clearDebounceTimestamps(); // Clear all debounce states if needed
/// V 2.0.8 Performance optimization options
Dev.isLightweightMode = false; // Skip stack trace capture for maximum performance (recommended for production)
Dev.useOptimizedStackTrace = true; // Use stack_trace package for 40-60% better performance (default: true)
/// V 2.0.7 printOnceIfContains for one-time logging when message contains keyword
/// Use printOnceIfContains parameter to ensure only first log containing the keyword is printed
Dev.log('Error: USER-001 login failed', printOnceIfContains: 'USER-001');
Dev.log('Retry: USER-001 timeout again', printOnceIfContains: 'USER-001'); // Skipped! (message contains 'USER-001' which was already logged)
Dev.clearCachedKeys(); // Clear all cached keywords if needed
/// V 2.0.4 newline replacement for better search visibility in console
Dev.isReplaceNewline = true; // whether replace newline characters (default false)
Dev.newlineReplacement = ' | '; // replacement string for newlines (default ' | ')
/// V 2.0.3 prefix name
Dev.prefixName = 'MyApp'; // prefix name
/// V 2.0.2 execFinalFunc with different color
Dev.isExeDiffColor = false; // whether execFinalFunc with different color
/// V 2.0.0 the lowest level threshold to execute the function of customFinalFunc
Dev.exeLevel = DevLevel.logWar;
Dev.customFinalFunc = (msg, level) {
// e.g.: your custom write msg to file
writeToFile(msg, level);
};
/// V 1.2.8 colorize multi lines
Dev.log('===================== Colorize multi lines log =====================');
const multiLines = '''
🔴 [ERROR] UniqueID: 1
🕒 Timestamp: 2
📛 ErrorType: 3
💥 ErrorMessage: 4
📚 StackTrace: 5
''';
const multiLines2 = 'Error1\nError2\nError3';
Dev.logError(multiLines);
Dev.logError(multiLines2);
/// V 1.2.8 special error format log
Dev.print(e, error: e, level: DevLevel.logErr);
Dev.logError('$e', error: e);
Dev.exeError('$e', error: e, colorInt: 91);
/// V1.2.6 whether log on multi platform consoles like Xcode, VS Code, Terminal, etc.
Dev.isMultConsoleLog = true;
/// V1.2.2 log settings
Dev.isLogShowDateTime = true; // whether log the date time
Dev.isExeWithShowLog = true; // whether execFinalFunc with showing log
Dev.isExeWithDateTime = false; // whether execFinalFunc with date time
/// V1.2.1 exe methods
Dev.exe("Exec Normal");
Dev.exeInfo("Exec Info");
Dev.exeSuccess("Exec Success");
Dev.exeWarning("Exec Warning");
Dev.exeError("Exec Error");
Dev.exeBlink("Exec Blink");
Dev.exe("Exec Normal without log", isLog: false);
Dev.log('1.log success level', level: DevLevel.logSuc);
Dev.logSuccess('2.log success level');
Dev.log('1.log success level and exec', level: DevLevel.logSuc, execFinalFunc: true);
Dev.exe('2.log success level and exec', level: DevLevel.logSuc);
Dev.exeSuccess('3.log success level and exec');
// END
/// V1.2.0 Execute the custom function
Dev.exe('!!! Exec Normal');
Dev.exe('!!! Exec Colorized text Info Without log', level: DevLevel.logInf, isMultConsole: true, isLog: false, colorInt: 101);
Dev.print('Colorized text print with the given level', level: DevLevel.logWar);
// END
// then every level log func contains execFinalFunc param:
Dev.log('Colorized text log to your process of log', execFinalFunc: true);
/// V1.1.6 custom function to support your process of log
// Deprecated: Use exeFinalFunc instead (customFinalFunc will be removed in future versions)
// Dev.customFinalFunc = (msg, level) {
// writeToFile(msg, level);
// };
## Migration Guide
### DevLevel Enum Renaming (v2.1.0+)
In version 2.1.0, the `DevLevel` enum values have been renamed for better readability:
**Old names → New names:**
- `DevLevel.logVer` → `DevLevel.verbose`
- `DevLevel.logNor` → `DevLevel.normal`
- `DevLevel.logInf` → `DevLevel.info`
- `DevLevel.logSuc` → `DevLevel.success`
- `DevLevel.logWar` → `DevLevel.warn`
- `DevLevel.logErr` → `DevLevel.error`
- `DevLevel.logBlk` → `DevLevel.fatal`
**Migration example:**
```dart
// Old way (v2.0.x and earlier):
Dev.log('Message', level: DevLevel.logWar); // → DevLevel.warn
Dev.exeLevel = DevLevel.logErr;
Dev.print('Print', level: DevLevel.logInf);
// New way (v2.1.0+):
Dev.log('Message', level: DevLevel.warn);
Dev.exeLevel = DevLevel.error;
Dev.print('Print', level: DevLevel.info);
// Quick find & replace in your codebase:
// DevLevel.logVer → DevLevel.verbose
// DevLevel.logNor → DevLevel.normal
// DevLevel.logInf → DevLevel.info
// DevLevel.logSuc → DevLevel.success
// DevLevel.logWar → DevLevel.warn
// DevLevel.logErr → DevLevel.error
// DevLevel.logBlk → DevLevel.fatal
Note: The log method names remain unchanged (logInfo, logWarning, logError, etc.).
Method Renaming: logBlink/exeBlink → logFatal/exeFatal (v2.1.0+) #
For consistency with the new enum naming, the "blink" methods have been renamed to "fatal":
Old methods → New methods:
Dev.logBlink()→Dev.logFatal()✅Dev.exeBlink()→Dev.exeFatal()✅
Migration example:
// Old way (v2.0.x and earlier):
Dev.logBlink('System crash!');
Dev.exeBlink('Critical error!');
// New way (v2.1.0+):
Dev.logFatal('System crash!');
Dev.exeFatal('Critical error!');
Note: The old methods (logBlink, exeBlink) have been removed. Please update your code to use the new method names logFatal and exeFatal.
New Shorter Method Names: logWarn/exeWarn (v2.1.0+) #
For consistency with the shortened enum value DevLevel.warn, new shorter method names are now recommended:
Old methods → New recommended methods:
Dev.logWarning()→Dev.logWarn()✅Dev.exeWarning()→Dev.exeWarn()✅
Migration example:
// Old way (still works, but deprecated):
Dev.logWarning('Slow query detected');
Dev.exeWarning('Memory usage high');
// New recommended way (v2.1.0+):
Dev.logWarn('Slow query detected');
Dev.exeWarn('Memory usage high');
Note: The old methods (logWarning, exeWarning) are deprecated but still functional for backward compatibility. We recommend migrating to the shorter names for consistency.
From customFinalFunc to exeFinalFunc (v2.0.6+) #
The customFinalFunc has been renamed to exeFinalFunc for better naming consistency. The old name is deprecated but still works for backward compatibility.
Old way (deprecated):
Dev.customFinalFunc = (msg, level) {
writeToFile(msg, level);
};
New way (recommended):
Dev.exeFinalFunc = (msg, level) {
writeToFile(msg, level);
};
Priority: If both exeFinalFunc and customFinalFunc are set, exeFinalFunc takes priority.
Infinite Recursion Prevention: The library automatically prevents infinite recursion when exeFinalFunc or customFinalFunc calls Dev logging methods (like Dev.exeError, Dev.exe, etc.) internally.
// Safe: This won't cause infinite recursion
Dev.exeFinalFunc = (msg, level) {
writeToFile(msg, level);
Dev.exeError('Also log this error'); // Won't trigger exeFinalFunc again
};
/* Log usage: */ Dev.log('Colorized text log'); // default yellow text Dev.logInfo('Colorized text Info'); // blue text Dev.logSuccess('Colorized text Success', execFinalFunc: true); // green text Dev.logWarning('Colorized text Warning'); // yellow text Dev.logError('Colorized text Error'); // red text Dev.logBlink('Colorized text blink', isSlow: true, isLog: true); // blink orange text
// Support to log on multi platform consoles like Xcode and VS Code Dev.print('Dev text print', isDebug: true); // default log only on debug mode
// Others: Dev.log('Colorized text log other customs', fileLocation: 'main.dart:90xx', colorInt: 96);
// Example: Multi-line log for better search visibility const errorDetails = '''Error occurred:
- File: user.dart:123
- Function: validateEmail()
- Reason: Invalid format''';
// With replacement enabled (default): Dev.logError(errorDetails); // Output: Error occurred: | - File: user.dart:123 | - Function: validateEmail() | - Reason: Invalid format
// Example with messy whitespace:
const messyLog = ''' Error:
Multiple spaces and tabs
End with spaces ''';
// With replacement enabled - cleans up extra whitespace: Dev.logError(messyLog); // Output: Error: | Multiple spaces and tabs | End with spaces
// Without replacement: Dev.isReplaceNewline = false; Dev.logError(errorDetails); // Output: Error occurred: // - File: user.dart:123 // - Function: validateEmail() // - Reason: Invalid format
// Example: printOnceIfContains for one-time logging (v2.0.7+) // Useful for preventing duplicate error logs in loops or repeated function calls for (var i = 0; i < 100; i++) { // Only logs the FIRST time a message contains 'API-ERROR-500' Dev.logWarning('Request failed: API-ERROR-500 timeout', printOnceIfContains: 'API-ERROR-500'); // Subsequent logs containing 'API-ERROR-500' are skipped }
// Different keywords are independent Dev.log('User login failed: ERROR-001', printOnceIfContains: 'ERROR-001'); // ✓ Logged Dev.log('Database error: ERROR-002', printOnceIfContains: 'ERROR-002'); // ✓ Logged Dev.log('Retry login: ERROR-001 again', printOnceIfContains: 'ERROR-001'); // ✗ Skipped (contains 'ERROR-001') Dev.log('DB connection lost: ERROR-002', printOnceIfContains: 'ERROR-002'); // ✗ Skipped (contains 'ERROR-002')
// Message doesn't contain keyword - always logs Dev.log('Normal log without error code', printOnceIfContains: 'ERROR-999'); // ✓ Logged (doesn't contain 'ERROR-999')
// Clear cache to allow re-logging Dev.clearCachedKeys(); Dev.log('After clear: ERROR-001 can log again', printOnceIfContains: 'ERROR-001'); // ✓ Logged (cache was cleared)
// Practical use case: Log user actions only once per session Dev.logInfo('User user-123 logged in', printOnceIfContains: 'user-123'); Dev.logInfo('User user-123 clicked button', printOnceIfContains: 'user-123'); // ✗ Skipped Dev.logInfo('User user-456 logged in', printOnceIfContains: 'user-456'); // ✓ Logged (different user)
// Works with all log methods Dev.logInfo('Info: token-abc expired', printOnceIfContains: 'token-abc'); Dev.logError('Error: connection-lost', printOnceIfContains: 'connection-lost'); Dev.exe('Execute: task-001 started', printOnceIfContains: 'task-001'); Dev.print('Print: session-xyz created', printOnceIfContains: 'session-xyz');
// Debounce Examples (v2.0.9+) // Prevent log spam from rapid repeated calls
// Example 1: Debounce button clicks void onButtonPressed() { // Only logs once every 2 seconds, even if clicked 100 times Dev.logInfo('Button clicked!', debounceMs: 2000); }
// Example 1b: Debounce with dynamic message content void onButtonPressedWithTimestamp() { // Use debounceKey when message contains dynamic content (timestamp, counter, etc.) Dev.logInfo('Button clicked at ${DateTime.now()}', debounceMs: 2000, debounceKey: 'button_click'); // Without debounceKey, each click would have a unique message and wouldn't be debounced }
// Example 2: Debounce scroll events with dynamic values void onScroll(double offset) { // Use debounceKey because offset value changes every time Dev.log('Scroll offset: $offset px', debounceMs: 500, debounceKey: 'scroll_event'); // All scroll events share the same debounceKey, so only logs once per 500ms }
// Example 3: Debounce API requests with attempt counter int attemptCount = 0; void fetchData() { attemptCount++; // Use debounceKey because message contains dynamic attemptCount Dev.exeWarning('API request attempt $attemptCount', debounceMs: 1000, debounceKey: 'api_fetch'); // Only logs once per second, even though attemptCount changes }
// Example 4: Different messages have independent debounce Dev.logWarning('Message A', debounceMs: 1000); // ✓ Logged immediately Dev.logWarning('Message B', debounceMs: 1000); // ✓ Logged (different message) Dev.logWarning('Message A', debounceMs: 1000); // ✗ Skipped (within 1s of first 'Message A')
// Example 5: Combine with execFinalFunc Dev.exeFinalFunc = (msg, level) { writeToFile(msg, level); }; // Prevents overwhelming the log file with repeated errors Dev.exeError('Network timeout', debounceMs: 3000); // Only written once every 3 seconds
// Example 6: Clear debounce state // ❌ Wrong - message changes each iteration, so all 10 logs will print // for (int i = 0; i < 10; i++) { // Dev.logInfo('Loop iteration $i', debounceMs: 500); // }
// ✓ Correct - use debounceKey for dynamic message content for (int i = 0; i < 10; i++) { Dev.logInfo('Loop iteration $i', debounceMs: 500, debounceKey: 'loop_log'); // Only first logs } Dev.clearDebounceTimestamps(); // Reset all debounce states Dev.logInfo('Loop iteration 0', debounceMs: 500, debounceKey: 'loop_log'); // ✓ Now logs again
// Important: When to use debounceKey // ✓ Use debounceKey when message contains dynamic content: // - Timestamps: 'Event at ${DateTime.now()}' // - Counters: 'Attempt $count' // - User input: 'Search query: $userInput' // - Positions: 'Scroll offset: $offset' // ✗ No need for debounceKey when message is static: // - 'Button clicked' - message is always the same // - 'API failed' - no dynamic content
// Practical use cases: // - Button click handlers (prevent double-click spam) // - Scroll event listeners (reduce noise during continuous scrolling) // - API retry logic (avoid flooding logs with repeated failures) // - Form validation (throttle real-time validation logs) // - Animation frame callbacks (limit logs during animations) // - Mouse move/hover events with coordinates (use debounceKey: 'mouse_move') // - Network status changes with timestamps (use debounceKey: 'network_status')
// Works with all log methods Dev.log('Normal log', debounceMs: 1000); Dev.logInfo('Info log', debounceMs: 1500); Dev.logSuccess('Success log', debounceMs: 2000); Dev.logWarning('Warning log', debounceMs: 2500); Dev.logError('Error log', debounceMs: 3000); Dev.exe('Execute log', debounceMs: 1000); Dev.print('Print log', debounceMs: 1000);
// Performance Optimization Examples (v2.0.8+)
// Mode 1: Default optimized mode (recommended for development) Dev.useOptimizedStackTrace = true; // Uses stack_trace package (40-60% faster) Dev.isLightweightMode = false; Dev.logError('Development error with file location'); // Shows: (main.dart:123): Development error...
// Mode 2: Basic optimized mode (no external dependency) Dev.useOptimizedStackTrace = false; // Uses basic string operations (10-20% faster) Dev.isLightweightMode = false; Dev.logWarning('Warning with basic stack trace'); // Shows: (main.dart:456): Warning...
// Mode 3: Maximum performance mode (recommended for production) Dev.isLightweightMode = true; // Skips stack trace completely Dev.logInfo('Production log'); // No file location shown, maximum performance
// Recommendation: // - Development: useOptimizedStackTrace = true, isLightweightMode = false // - Production: isLightweightMode = true (or disable Dev.enable entirely)
// printOnceIfContains Examples (v2.0.7+) // Useful for preventing duplicate error logs in loops or repeated function calls
for (var i = 0; i < 100; i++) { // Only logs the FIRST time a message contains 'API-ERROR-500' Dev.logWarning('Request failed: API-ERROR-500 timeout', printOnceIfContains: 'API-ERROR-500'); // Subsequent logs containing 'API-ERROR-500' are skipped }
// Different keywords are independent Dev.log('User login failed: ERROR-001', printOnceIfContains: 'ERROR-001'); // ✓ Logged Dev.log('Database error: ERROR-002', printOnceIfContains: 'ERROR-002'); // ✓ Logged Dev.log('Retry login: ERROR-001 again', printOnceIfContains: 'ERROR-001'); // ✗ Skipped (contains 'ERROR-001') Dev.log('DB connection lost: ERROR-002', printOnceIfContains: 'ERROR-002'); // ✗ Skipped (contains 'ERROR-002')
// Message doesn't contain keyword - always logs Dev.log('Normal log without error code', printOnceIfContains: 'ERROR-999'); // ✓ Logged (doesn't contain 'ERROR-999')
// Clear cache to allow re-logging Dev.clearCachedKeys(); Dev.log('After clear: ERROR-001 can log again', printOnceIfContains: 'ERROR-001'); // ✓ Logged (cache was cleared)
// Practical use case: Log user actions only once per session Dev.logInfo('User user-123 logged in', printOnceIfContains: 'user-123'); Dev.logInfo('User user-123 clicked button', printOnceIfContains: 'user-123'); // ✗ Skipped Dev.logInfo('User user-456 logged in', printOnceIfContains: 'user-456'); // ✓ Logged (different user)
// Works with all log methods Dev.logInfo('Info: token-abc expired', printOnceIfContains: 'token-abc'); Dev.logError('Error: connection-lost', printOnceIfContains: 'connection-lost'); Dev.exe('Execute: task-001 started', printOnceIfContains: 'task-001'); Dev.print('Print: session-xyz created', printOnceIfContains: 'session-xyz');
## Author
Visit my github: [janlionly](https://github.com/janlionly)<br>
Contact with me by email: [email protected]
## Contribute
I would love you to contribute to **DevColorizedLog**
## License
**DevColorizedLog** is available under the MIT license. See the [LICENSE](https://github.com/janlionly/flutter_dev_colorized_log/blob/master/LICENSE) file for more info.