Skip to content

janlionly/flutter_dev_colorized_log

Repository files navigation

Dev Colorized Log

pub packageStar on Github

A powerful and flexible Flutter/Dart logging utility with colorized console output, advanced filtering, performance optimizations, and developer-friendly features for efficient debugging and monitoring.

Key Features

  • 🎨 Colorized Output: 7 log levels with distinct ANSI colors (verbose, normal, info, success, warn, error, fatal)
  • 🔍 Smart Filtering: Dual-level filtering with logLevel (console output) and exeLevel (custom callbacks)
  • 🏷️ Tag-Based Filtering: Filter logs by module/feature tags for focused debugging and modular development
  • ⚡ Performance Optimized: Lightweight mode and optimized stack trace parsing (40-60% faster) for production use
  • 🚫 Debounce & Deduplication: Prevent log spam with debounceMs and one-time logging with printOnceIfContains
  • 📍 File Location Tracking: Automatic file name and line number detection for quick debugging
  • 🔧 Custom Callbacks: Execute custom functions (exeFinalFunc) for remote logging, analytics, or file writing
  • 📱 Multi-Platform Support: Enhanced formatting for Xcode, VS Code, Terminal, and other consoles
  • ⏰ Timestamps: Optional date/time display in logs
  • 📝 Multi-line Handling: Automatic newline replacement for better console searchability
  • 🎯 Flexible Configuration: Global settings with per-log overrides for maximum control

Usage

See examples in the /example folder. For more details, please run the example project.

/* V 2.3.0 New debug-level methods for better semantics */
// The DevLevel.normal enum value now displays as "debug" in logs via the alias property
// New convenient methods for debug-level logging:
Dev.logDebug('Debug message'); // Equivalent to Dev.log('...', level: DevLevel.normal)
Dev.exeDebug('Debug with callback'); // Equivalent to Dev.exe('...', level: DevLevel.normal)

// Note: DevLevel.normal enum value remains unchanged for backward compatibility
// Only the display name changed from "normal" to "debug" for better semantic clarity
// Original log() and exe() methods continue to work as before

/* Global settings:*/
Dev.enable = true; // Whether to log messages
Dev.isLogFileLocation = true; // Whether to log the file location info
Dev.defaultColorInt = 0; // Default text color, int value from 0 to 107
Dev.isDebugPrint = true; // Whether Dev.print logs only in debug mode

/// V 2.2.1 Automatic memory management for debounce cache
/// Configure automatic cleanup to prevent unbounded memory growth in long-running applications
Dev.maxDebounceEntries = 1000; // Maximum debounce entries to keep (default: 1000)
Dev.debounceCleanupCount = 100; // Number of oldest entries to remove when limit is exceeded (default: 100)
// Set maxDebounceEntries to 0 or negative to disable automatic cleanup (unlimited entries)
Dev.maxDebounceEntries = 0; // Disable automatic cleanup

/// V 2.2.0 Emoji display control for log levels
/// Control whether to show emoji indicators in log output
/// Defaults to true in debug mode (kDebugMode), false in release mode
Dev.isShowLevelEmojis = true; // Show emojis (default in debug mode)
Dev.isShowLevelEmojis = false; // Hide emojis (default in release mode)

// Example with emojis enabled (default in debug mode):
Dev.logVerbose('Debug info'); // Output: [🔍:verbose]...
Dev.logInfo('Information'); // Output: [📬:info]...
Dev.logSuccess('Success!'); // Output: [🎉:success]...
Dev.logWarn('Warning'); // Output: [🚧:warn]...
Dev.logError('Error'); // Output: [❌:error]...
Dev.logFatal('Critical!'); // Output: [💣:fatal]...

// Example with emojis disabled (default in release mode):
Dev.isShowLevelEmojis = false;
Dev.logInfo('Information'); // Output: [info]...
Dev.logError('Error'); // Output: [error]...

// Recommendation:
// - Development: true (default in debug mode) for better visual feedback
// - Production: false (default in release mode) for cleaner logs and better compatibility

/// V 2.2.0 Tag-based filtering for modular development and focused debugging
/// Filter logs by tags to show only logs from specific modules or features
/// Tags can be auto-detected from file path or manually specified per log
Dev.isFilterByTags = false; // Default: show all logs with tag information displayed
Dev.tags = null; // Default: no tags defined

// Step 1: Show tag information without filtering (default behavior)
Dev.isFilterByTags = false; // Filtering disabled - all logs shown
Dev.tags = {'auth', 'network'}; // Optional: define available tags for reference

// All logs are displayed with their tag information
Dev.logInfo('User logged in successfully', tag: 'auth'); // ✓ Shown with [tag:auth]
Dev.logInfo('API call started', tag: 'network'); // ✓ Shown with [tag:network]
Dev.logInfo('Cache updated', tag: 'database'); // ✓ Shown with [tag:database]
Dev.logInfo('Untagged log'); // ✓ Shown without tag

// Step 2: Enable tag filtering - only show logs with matching tags
Dev.isFilterByTags = true; // Enable filtering
Dev.tags = {'auth', 'network'}; // Only show logs tagged with 'auth' or 'network'

// Manual tag specification - specify tag per log call
Dev.logInfo('User logged in successfully', tag: 'auth'); // ✓ Shown (matches 'auth' tag)
Dev.logInfo('API call started', tag: 'network'); // ✓ Shown (matches 'network' tag)
Dev.logInfo('Cache updated', tag: 'database'); // ✗ Hidden (tag doesn't match)
Dev.logInfo('Untagged log'); // ✗ Hidden (no tag provided)

// Auto-detection from file path (directory names in path checked against Dev.tags)
// Example: If log is from lib/features/auth/login.dart
// And Dev.tags = {'features', 'auth'}, the tag 'features' or 'auth' will be auto-detected
Dev.logInfo('Auto-detected tag from file path'); // Tag auto-extracted from path

// Practical example: Debug only payment feature
Dev.isFilterByTags = true;
Dev.tags = {'payment'};
Dev.logInfo('Initiating transaction', tag: 'payment'); // ✓ Shown
Dev.logInfo('Contacting payment gateway', tag: 'network'); // ✗ Hidden
Dev.logSuccess('Transaction completed', tag: 'payment'); // ✓ Shown

// Development environment: Focus on debug and test logs
Dev.isFilterByTags = true;
Dev.tags = {'debug', 'test'};
Dev.logVerbose('Variable state = loading', tag: 'debug'); // ✓ Shown
Dev.logInfo('Running integration test', tag: 'test'); // ✓ Shown
Dev.logInfo('Analytics event tracked', tag: 'analytics'); // ✗ Hidden

// Important: Tag filtering only affects console output
// exeFinalFunc callback will ALWAYS execute regardless of tag matching
Dev.isFilterByTags = true;
Dev.tags = {'critical'};
Dev.exeError('Critical error', tag: 'critical'); // ✓ Console shown + callback executed
Dev.exeWarn('Normal warning', tag: 'normal'); // ✗ Console hidden BUT callback still executed

// Disable tag filtering
Dev.isFilterByTags = false; // Show all logs with tag information
// or
Dev.tags = null; // Clear tags

// All log/print/exe methods support the optional 'tag' parameter:
Dev.log('Message', tag: 'mytag');
Dev.print('Message', tag: 'mytag');
Dev.exe('Message', tag: 'mytag');
Dev.logInfo('Message', tag: 'mytag');
Dev.logSuccess('Message', tag: 'mytag');
Dev.logWarn('Message', tag: 'mytag');
Dev.logError('Message', tag: 'mytag');
Dev.logFatal('Message', tag: 'mytag');
Dev.exeInfo('Message', tag: 'mytag');
Dev.exeSuccess('Message', tag: 'mytag');
Dev.exeWarn('Message', tag: 'mytag');
Dev.exeError('Message', tag: 'mytag');
Dev.exeFatal('Message', tag: 'mytag');

/// V 2.2.0 Fast print mode for better console output performance
/// Defaults to true in debug mode (kDebugMode), false in release mode
Dev.useFastPrint = true; // Use print() instead of debugPrint() for faster output (default in debug mode)
Dev.useFastPrint = false; // Use debugPrint() for safer logging with throttling (default in release mode)
// Note: debugPrint throttles output (~800 chars at a time) to prevent log loss
//       print is faster but may lose logs if output is too frequent
//
// Recommendation:
// - Development: true (default in debug mode) for faster feedback
// - Production/Testing: false (default in release mode) for safer logging

/// V 2.2.0 newline replacement for better search visibility in the console
/// Defaults to true in debug mode (kDebugMode), false in release mode
Dev.isReplaceNewline = true; // Replace newlines (default: true in debug mode)
Dev.isReplaceNewline = false; // Preserve newlines (default: false in release mode)
Dev.newlineReplacement = ' • '; // Replacement string (default: ' • ' - bullet point for clear separation)

// Recommendation:
// - Development: true (default in debug mode) for better console searchability
// - Production: false (default in release mode) to preserve original formatting

/// V 2.1.0 Log level filtering - control which logs are printed to the console
/// Set the minimum log level threshold - logs below this level will be filtered from the console
/// Note: logLevel only filters console output, exeFinalFunc callbacks still execute for all levels
Dev.logLevel = DevLevel.verbose; // Default: show all logs in the console
Dev.logLevel = DevLevel.info; // Console: only show info, success, warning, error, and fatal
Dev.logLevel = DevLevel.warn; // Console: only show warning, error, and fatal
Dev.logLevel = DevLevel.error; // Console: only show error and fatal

// Example: Production environment - only show warnings and above in the 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 the debounceMs parameter to prevent log spam from repeated calls
/// Use debounceKey when the 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 the message contains a keyword
/// Use the printOnceIfContains parameter to ensure only the 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.3.0 custom execution suffix for execution mode logs
Dev.exeSuffix = '&exe'; // Default suffix appended to log names when executing final function
Dev.exeSuffix = '@exe'; // Customize to your preferred execution indicator
Dev.exeSuffix = '|exec'; // Use pipe separator
Dev.exeSuffix = ':execute'; // Use colon separator
// Example output: [📬:debug&exe] for default, [📬:debug@exe] with custom suffix

/// V 2.0.3 prefix name for all logs
Dev.prefixName = 'MyApp'; // Custom prefix name to prepend to all log messages

/// V 2.0.2 execFinalFunc with different color
Dev.isExeDiffColor = false; // Whether to use different colors for exeFinalFunc logs

/// V 2.0.0 Set the minimum level threshold to execute the custom final function
Dev.exeLevel = DevLevel.logWar;
Dev.customFinalFunc = (msg, level) {
  // Example: write message to file or send to analytics
  writeToFile(msg, level);
};

/// V 1.2.8 Colorize multi-line logs
Dev.log('===================== Colorize multi-line 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 logging with error objects
Dev.print(e, error: e, level: DevLevel.logErr);
Dev.logError('$e', error: e);
Dev.exeError('$e', error: e, colorInt: 91);

/// V1.2.6 Enable logging on multiple platform consoles (Xcode, VS Code, Terminal, etc.)
Dev.isMultConsoleLog = true;

/// V1.2.2 Log display settings
Dev.isLogShowDateTime = true; // Whether to show date and time in logs
Dev.isExeWithShowLog = true; // Whether to show logs when executing exeFinalFunc
Dev.isExeWithDateTime = false; // Whether to include date and time in exeFinalFunc callbacks

/// V1.2.1 Execute methods that trigger custom callbacks
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 custom function with colorized output
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

// All log level functions support the execFinalFunc parameter:
Dev.log('Colorized text log to your custom log processing', execFinalFunc: true);

/// V1.1.6 Custom function to support your own log processing
// 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 internally calls Dev logging methods (such as Dev.exeError, Dev.exe, etc.).

// 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); // Blinking orange text

// Support for logging on multiple platform consoles like Xcode and VS Code
Dev.print('Dev text print', isDebug: true); // Logs only in debug mode by default

// Custom options:
Dev.log('Colorized text log with custom options', 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 (better for searching in console):
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 - automatically cleans up extra whitespace:
Dev.logError(messyLog);
// Output: Error: • Multiple spaces and tabs • End with spaces

// Without replacement (preserves original formatting):
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 containing 'API-ERROR-500' is encountered
  Dev.logWarning('Request failed: API-ERROR-500 timeout', printOnceIfContains: 'API-ERROR-500');
  // Subsequent logs containing 'API-ERROR-500' are automatically skipped
}

// Different keywords are tracked independently
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')

// If message doesn't contain the keyword, it always logs
Dev.log('Normal log without error code', printOnceIfContains: 'ERROR-999'); // ✓ Logged (doesn't contain 'ERROR-999')

// Clear cache to allow logs to appear again
Dev.clearCachedKeys();
Dev.log('After clear: ERROR-001 can log again', printOnceIfContains: 'ERROR-001'); // ✓ Logged (cache was cleared)

// Practical use case: Log unique user actions 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 with static message
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 the 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 the offset value changes every time
  Dev.log('Scroll offset: $offset px',
      debounceMs: 500,
      debounceKey: 'scroll_event');
  // All scroll events share the same debounceKey, so it only logs once per 500ms
}

// Example 3: Debounce API requests with attempt counter
int attemptCount = 0;
void fetchData() {
  attemptCount++;
  // Use debounceKey because the 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 timers
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 exeFinalFunc to prevent overwhelming log files
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 when needed
// ❌ 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 the first one logs
}
Dev.clearDebounceTimestamps(); // Reset all debounce states
Dev.logInfo('Loop iteration 0',
    debounceMs: 500,
    debounceKey: 'loop_log'); // ✓ Now logs again

// Example 7: Memory management for debounce cache (v2.2.1+)
// Configure automatic cleanup to prevent memory issues in long-running apps
Dev.maxDebounceEntries = 500; // Keep max 500 entries (default: 1000)
Dev.debounceCleanupCount = 50; // Remove 50 oldest entries when limit exceeded (default: 100)

// When the cache exceeds maxDebounceEntries, the oldest entries are automatically removed
// For example, if you have a long-running app with many different debounce keys:
for (int i = 0; i < 600; i++) {
  Dev.logInfo('Event $i', debounceMs: 5000, debounceKey: 'event_$i');
}
// After 500 entries, the oldest 50 are automatically cleaned up
// This keeps memory usage bounded while maintaining debounce functionality

// Disable automatic cleanup for unlimited entries (not recommended for production)
Dev.maxDebounceEntries = 0; // No limit, cache can grow indefinitely

// Reset to default values
Dev.maxDebounceEntries = 1000;
Dev.debounceCleanupCount = 100;

// Important: When to use debounceKey
// ✓ Use debounceKey when the 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 the message is static:
//   - 'Button clicked' - message is always the same
//   - 'API failed' - no dynamic content

// Practical use cases for debouncing:
// - 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 the 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 capture completely
Dev.logInfo('Production log'); // No file location shown, maximum performance

// Recommendations:
// - Development: useOptimizedStackTrace = true, isLightweightMode = false
// - Production: isLightweightMode = true (or disable Dev.enable entirely)

Author

Visit my GitHub: janlionly
Contact me by email: [email protected]

Contribute

I would love for you to contribute to DevColorizedLog!

License

DevColorizedLog is available under the MIT license. See the LICENSE file for more information.

About

A Flutter package for logging colorized text in developer mode.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages