any_logger 1.1.3 copy "any_logger: ^1.1.3" to clipboard
any_logger: ^1.1.3 copied to clipboard

A powerful, flexible, and intuitive logging library for Dart and Flutter with progressive complexity - from one-line setup to enterprise configurations.

example/any_logger_example.dart

import 'dart:convert';
import 'dart:io';
import 'dart:math';

import 'package:any_logger/any_logger.dart';

void main() async {
  // Start with the simplest examples and progress to more complex ones
  await cleanupExampleFiles();

  // Run examples from the first file
  await runExamples();

  // Run examples from the second file
  await runProfessionalExamples();
}

// ============================================================
// BASIC TO ADVANCED EXAMPLES
// ============================================================

Future<void> runExamples() async {
  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║  Example 1: Zero Config - Just Start Logging!    ║');
  print('╚══════════════════════════════════════════════════╝');
  await zeroConfigExample();

  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║  Example 2: One-Liner Configurations             ║');
  print('╚══════════════════════════════════════════════════╝');
  await oneLineConfigExamples();

  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║  Example 3: Pro Console Configurations           ║');
  print('╚══════════════════════════════════════════════════╝');
  await proConsoleExamples();

  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║  Example 4: Built-in Presets                     ║');
  print('╚══════════════════════════════════════════════════╝');
  await presetExamples();

  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║  Example 5: AnyLogger Mixin for Classes          ║');
  print('╚══════════════════════════════════════════════════╝');
  await mixinExample();

  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║  Example 6: Performance Optimization             ║');
  print('╚══════════════════════════════════════════════════╝');
  await performanceExample();

  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║  Example 7: MDC Custom Context Tracking          ║');
  print('╚══════════════════════════════════════════════════╝');
  await mdcExample();

  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║  Example 8: Custom Builder Configuration         ║');
  print('╚══════════════════════════════════════════════════╝');
  await customBuilderExample();

  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║  Example 9: Custom device / session id provider ║');
  print('╚══════════════════════════════════════════════════╝');
  await exampleWithCustomIdProvider();

  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║ Example 10: AppenderBuilder for Granular Control  ║');
  print('╚══════════════════════════════════════════════════╝');
  await appenderBuilderExample();

  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║  Example 11: Configuration from JSON File        ║');
  print('╚══════════════════════════════════════════════════╝');
  await jsonConfigExample();

  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║  Example 12: Pro Service with Self Tracking      ║');
  print('╚══════════════════════════════════════════════════╝');
  await proServiceExample();

  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║  Example 13: Production-Ready Setup              ║');
  print('╚══════════════════════════════════════════════════╝');
  await productionExample();

  await LoggerFactory.dispose();
}

/// Example 1: Zero configuration - just start logging!
///
/// 20:50:17.721 INFO Application started
/// 20:50:17.736 WARN Warning: Low memory
/// 20:50:17.736 ERROR Failed to connect to server
Future<void> zeroConfigExample() async {
  await LoggerFactory.dispose();
  await LoggerBuilder().console().build();
  Logger.info('Application started');
  Logger.warn('Warning: Low memory');
  Logger.error('Failed to connect to server');
}

/// Example 2: One-liner configurations for common needs
/// 20:37:56.705 DEBUG Now debug messages are visible
/// 🚀 INFO: Custom format with emoji!
/// 🚀 WARN: Warning with style
Future<void> oneLineConfigExamples() async {
  await LoggerFactory.dispose();
  await LoggerBuilder().console(level: Level.DEBUG).build();
  Logger.debug('Now debug messages are visible');

  await LoggerFactory.dispose();
  await LoggerBuilder().console(format: '🚀 %l: %m').build();
  Logger.info('Custom format with emoji!');
  Logger.warn('Warning with style');

  await LoggerFactory.dispose();
  await LoggerBuilder()
      .file(filePattern: 'myapp', path: 'logs/')
      .console(level: Level.WARN)
      .build();
  Logger.warn('This goes to both file and console');
}

/// Example 3: Pro Console Configurations
///
/// [20:51:14.871][ROOT_LOGGER][INFO][proConsoleExamples:158] Info message with method and line number [package:any_logger/example/any_logger_example.dart(158:10)]
/// [20:51:14.871][ROOT_LOGGER][ERROR][proConsoleExamples:159] Error with complete file location [package:any_logger/example/any_logger_example.dart(159:10)]
/// [20:51:14.872][ROOT_LOGGER][INFO][proConsoleExamples:160] Includes auto-generated device and session IDs [package:any_logger/example/any_logger_example.dart(160:10)]
Future<void> proConsoleExamples() async {
  await LoggerFactory.dispose();
  await LoggerBuilder()
      .console(
        format: '[%d][%i][%l][%c] %m [%f]',
        dateFormat: 'HH:mm:ss.SSS',
      )
      .build();
  Logger.info('Info message with method and line number');
  Logger.error('Error with complete file location');
  Logger.info('Includes auto-generated device and session IDs');
}

/// Example 4: Use built-in presets for common scenarios
///
/// [20:55:53.902][f111296f][72c13fcd][ROOT_LOGGER][DEBUG][presetExamples:167] developmentPro mode [package:any_logger/example/any_logger_example.dart(167:10)]
/// [20:55:53][36826b80][INFO] productionPro mode
/// [20:55:53.909][f111296f][a21fecd0][INFO][presetExamples:175] mobileDevelopment mode
Future<void> presetExamples() async {
  await LoggerFactory.dispose();
  await LoggerFactory.initWithPreset(LoggerPresets.developmentPro);
  Logger.debug('developmentPro mode');

  await LoggerFactory.dispose();
  await LoggerFactory.initWithPreset(LoggerPresets.productionPro);
  Logger.info('productionPro mode');

  await LoggerFactory.dispose();
  await LoggerFactory.initWithPreset(LoggerPresets.mobileDevelopment);
  Logger.info('mobileDevelopment mode');
}

/// Example 5: Using AnyLogger mixin in your classes
///
/// 20:55:53.912 INFO Creating user: alice@example.com
/// 20:55:54.023 INFO User created successfully
/// 20:55:54.025 INFO Authentication attempt for: alice@example.com
Future<void> mixinExample() async {
  await LoggerFactory.dispose();
  await LoggerBuilder().console(level: Level.DEBUG).build();
  final userService = UserService();
  final authService = AuthService();
  await userService.createUser('alice@example.com');
  await authService.authenticate('alice@example.com', 'password123');
}

/// Example 6: Performance optimization patterns
///
/// [LoggerFactory] Initialized console appender: Appender(type: CONSOLE, level: INFO, format: %d %l %m, dateFormat: HH:mm:ss.SSS, created: 2025-08-24 20:55:54.239989, enabled: true) ConsoleAppender(mode: ConsoleLoggerMode.stdout, sequenceNumber: 1, level: INFO, format: %d %l %m, dateFormat: HH:mm:ss.SSS, created: 2025-08-24 20:55:54.239989, enabled: true)
/// 20:55:54.241 INFO Setting level for all appenders to DEBUG
/// 20:55:54.243 DEBUG Self-debugging enabled
Future<void> performanceExample() async {
  await LoggerFactory.dispose();
  LoggerBuilder()
      .replaceAll()
      .console(level: Level.INFO)
      .withSelfDebug()
      .buildSync();
  final logger = LoggerFactory.getLogger('Performance');
  // This next line will NOT print, because the logger level is INFO
  logger
      .logDebugSupplier(() => 'This expensive computation is never executed.');
}

/// Example 7: Custom MDC for tracking application context
///
/// [production][user-123][req-001] INFO: Request started
/// [production][user-123][req-001] INFO: Request completed
/// [production][user-456][req-002] INFO: Request started
Future<void> mdcExample() async {
  await LoggerFactory.dispose();
  await LoggerBuilder()
      .replaceAll()
      .console(format: '[%X{env}][%X{userId}][%X{requestId}] %l: %m')
      .build();
  LoggerFactory.setMdcValue('env', 'production');
  await handleUserRequest('user-123', 'req-001');
  await handleUserRequest('user-456', 'req-002');
}

/// Example 8a: Custom IdProvider
///
/// [f111296f][f742d81d] 20:55:54.251 [INFO] Info - goes to console and file
/// [f111296f][f742d81d] 20:55:54.251 [INFO] Same here
/// [f111296f][f742d81d] 20:55:54.251 [INFO] ...and here
Future<void> customBuilderExample() async {
  await LoggerFactory.dispose();
  await LoggerBuilder()
      .replaceAll()
      .console(
        format: '[%did][%sid] %d [%l] %m',
        dateFormat: 'HH:mm:ss.SSS',
      )
      .file(
        filePattern: 'app',
        path: 'logs/',
        format: '[%did][%sid][%X{env}] %d [%l][%c] %m [%f]',
      )
      .withMdcValue('env', 'staging')
      .withSelfDebug()
      .build();
  Logger.info('Info - goes to console and file');
  Logger.info('Same here');
  Logger.info('...and here');
}

/// Example 9: With custom IdProvider for %did and %sid
///
/// [my-device-id][my-session-id] Using custom ID provider
/// [my-device-id][my-session-id] Device ID: my-device-id
/// [my-device-id][my-session-id] Session ID: my-session-id
Future<void> exampleWithCustomIdProvider() async {
  await LoggerFactory.dispose();

  // Set custom ID provider BEFORE initialization
  LoggerFactory.setIdProvider(MyCustomIdProvider());

  // Initialize with CONSOLE appender so you can see the output
  await LoggerFactory.init({
    'appenders': [
      {
        'type': 'CONSOLE', // Changed to CONSOLE so you can see output
        'format': '[%did][%sid] %m', // Simple format to clearly show IDs
        'level': 'INFO',
      }
    ]
  });

  final logger = LoggerFactory.getLogger('MyApp');
  logger.logInfo('Using custom ID provider'); // Fixed message
  logger.logInfo('Device ID: ${LoggerFactory.deviceId}');
  logger.logInfo('Session ID: ${LoggerFactory.sessionId}');
}

/// Example 10: Using AppenderBuilder for granular control
///
/// [INFO] This info message goes to both console and file.
/// [INFO] And so does this.
/// [INFO] And also this one.
Future<void> appenderBuilderExample() async {
  await LoggerFactory.dispose();
  final fileAppender =
      await fileAppenderBuilder('app_builder_log').withPath('logs/').build();
  final consoleAppender =
      consoleAppenderBuilder().withFormat('[%l] %m').buildSync();
  await LoggerBuilder()
      .replaceAll()
      .addAppender(consoleAppender)
      .addAppender(fileAppender)
      .build();
  Logger.info('This info message goes to both console and file.');
  Logger.info('And so does this.');
  Logger.info('And also this one.');
}

/// Example 11: Loading configuration from JSON file
///
/// [20:55:54.269][f111296f][ff300524][ROOT_LOGGER][INFO][jsonConfigExample:261] Logger configured from JSON with automatic IDs
/// [20:55:54.272][f111296f][ff300524][ROOT_LOGGER][INFO][jsonConfigExample:265] Line two
/// [20:55:54.272][f111296f][ff300524][ROOT_LOGGER][INFO][jsonConfigExample:266] Line three
Future<void> jsonConfigExample() async {
  await LoggerFactory.dispose();
  final configFile = File('logger_config.json');
  final config = {
    'appenders': [
      {
        'type': 'CONSOLE',
        'format': '[%d][%did][%sid][%i][%l][%c] %m',
        'dateFormat': 'HH:mm:ss.SSS',
      }
    ]
  };
  await configFile.writeAsString(json.encode(config));
  await LoggerFactory.initFromFile('logger_config.json', selfDebug: true);
  Logger.info('Logger configured from JSON with automatic IDs');
  if (await configFile.exists()) {
    await configFile.delete();
  }
  Logger.info('Line two');
  Logger.info('Line three');
}

/// Example 12: Pro Service with automatic tracking
///
/// [20:55:54.276][1f953c8b][ErrorProneService][ERROR][ErrorProneService.handleNetworkRequest:610] Network request failed
/// 	SocketException: Connection timeout
/// [20:55:54.277][1f953c8b][ErrorProneService][INFO][ErrorProneService.processUserInput:618] Valid input processed: invalid@data
/// [20:55:54.279][1f953c8b][ROOT_LOGGER][INFO][proServiceExample:282] The end.
Future<void> proServiceExample() async {
  await LoggerFactory.dispose();
  await LoggerBuilder()
      .replaceAll()
      .file(
        filePattern: 'error_prone_service',
        path: 'logs/',
      )
      .console(format: '[%d][%sid][%i][%l][%c] %m')
      .withSelfDebug()
      .build();
  final service = ErrorProneService();
  await service.handleNetworkRequest();
  await service.processUserInput('invalid@data');
  Logger.info('The end.');
}

/// Example 13: Production-ready setup
///
/// [2025-236-55 20:55:54.280][f111296f][4a6ec577][production][INFO][productionExample:296] Application started in production mode [package:any_logger/example/any_logger_example.dart(296:10)]
/// [2025-236-55 20:55:54.282][f111296f][4a6ec577][production][INFO][productionExample:297] You got deviceId, sessionId, Logger name, Log level... [package:any_logger/example/any_logger_example.dart(297:10)]
/// [2025-236-55 20:55:54.284][f111296f][4a6ec577][production][INFO][productionExample:298] ...and class.method linnumber, and then again actual file with line and column number if available [package:any_logger/example/any_logger_example.dart(298:10)]
Future<void> productionExample() async {
  await LoggerFactory.dispose();
  final consoleAppender = ConsoleAppenderBuilder()
      .withFormat('[%d][%did][%sid][%X{env}][%l][%c] %m [%f]')
      .withDateFormat('yyyy-DD-mm HH:mm:ss.SSS')
      .buildSync();
  await LoggerBuilder()
      .replaceAll()
      .addAppender(consoleAppender)
      .withMdcValue('env', 'production')
      .build();
  Logger.info('Application started in production mode');
  Logger.info('You got deviceId, sessionId, Logger name, Log level...');
  Logger.info(
      '...and class.method linnumber, and then again actual file with line and column number if available');
}

// ============================================================
// PROFESSIONAL SCENARIO EXAMPLES
// ============================================================

Future<void> runProfessionalExamples() async {
  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║  Example 14: Professional Production Format      ║');
  print('╚══════════════════════════════════════════════════╝');
  await professionalSetupExample();

  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║  Example 15: Performance Monitoring              ║');
  print('╚══════════════════════════════════════════════════╝');
  await performanceMonitoringExample();

  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║ Example 16: AppenderBuilder Granular Control     ║');
  print('╚══════════════════════════════════════════════════╝');
  await builderWithAppenderBuilderExample();

  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║  Example 17: Error Tracking & Debugging          ║');
  print('╚══════════════════════════════════════════════════╝');
  await errorTrackingExample();

  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║  Example 18: App Lifecycle with Self Tracking    ║');
  print('╚══════════════════════════════════════════════════╝');
  await appLifecycleExample();

  print('\n');
  print('╔══════════════════════════════════════════════════╗');
  print('║  Example 19: Multi-Service Architecture          ║');
  print('╚══════════════════════════════════════════════════╝');
  await multiServiceExample();

  await LoggerFactory.dispose();
}

/// Example 14: Professional production-ready format, variation
///
/// [20:55:54.285][f111296f][265db391][ANYLOGGER_SELF_LOGGER][INFO][LoggerFactory._setupSelfLogger:837] Setting level for all appenders to INFO [package:any_logger/src/logger_factory.dart(837:18)]
/// [20:55:54.286][f111296f][265db391][ROOT_LOGGER][INFO][professionalSetupExample:356] Application initialized with automatic ID tracking [package:any_logger/example/any_logger_example.dart(356:10)]
/// [20:55:54.286][f111296f][265db391][ROOT_LOGGER][DEBUG][professionalSetupExample:357] Device ID persists across app restarts [package:any_logger/example/any_logger_example.dart(357:10)]
Future<void> professionalSetupExample() async {
  await LoggerFactory.dispose();
  await LoggerBuilder()
      .replaceAll()
      .console(
        level: Level.DEBUG,
        format: '[%d][%did][%sid][%i][%l][%c] %m [%f]',
        dateFormat: 'HH:mm:ss.SSS',
      )
      .withSelfDebug(Level.INFO)
      .build();
  Logger.info('Application initialized with automatic ID tracking');
  Logger.debug('Device ID persists across app restarts');
  final componentLogger = LoggerFactory.getLogger('AudioController');
  componentLogger.logDebug('Audio system initialized');
  componentLogger.logInfo('Playing background music');
}

/// Example 15: Simulated app lifecycle with automatic tracking
///
/// CONSOLE [INFO]: This info message goes to both console and file.
/// CONSOLE [ERROR]: This error also goes to both appenders.
/// CONSOLE [INFO]: And i am here because three lines look better...
Future<void> appLifecycleExample() async {
  await LoggerFactory.dispose();
  await LoggerBuilder()
      .replaceAll()
      .console(
        level: Level.DEBUG,
        format: '[%d][%did][%sid][%X{env}][%i][%l][%c] %m [%f]',
        dateFormat: 'HH:mm:ss.SSS',
      )
      .withMdcValue('env', 'staging')
      .withSelfDebug()
      .build();
  final app = MyApplication();
  await app.initialize();
  await app.start();
  await app.handleUserAction('button_click');
  await app.stop();
  await app.dispose();
}

/// Example 16: Multi-service architecture
///
/// [2025-08-24T20:55:54.987][f111296f][fc77d2cb][enterprise][AuthService][INFO][AuthenticationService.login:542] Login attempt for user: user@example.com [package:any_logger/example/any_logger_example.dart(542:5)]
/// [2025-08-24T20:55:54.987][f111296f][fc77d2cb][enterprise][AuthService][DEBUG][AuthenticationService.login:543] Validating credentials [package:any_logger/example/any_logger_example.dart(543:5)]
/// [2025-08-24T20:55:55.089][f111296f][fc77d2cb][enterprise][AuthService][DEBUG][AuthenticationService.login:545] Credentials validated successfully [package:any_logger/example/any_logger_example.dart(545:5)]
Future<void> multiServiceExample() async {
  await LoggerFactory.dispose();
  // FIXME: keeps .withSelfDebug() from previous method: appLifecycleExample. All methods should start fresh, atomically, new born
  await LoggerBuilder()
      .replaceAll()
      .console(
        level: Level.DEBUG,
        format: '[%d][%did][%sid][%X{tenant}][%i][%l][%c] %m [%f]',
        dateFormat: 'yyyy-MM-ddTHH:mm:ss.SSS',
      )
      .withMdcValue('tenant', 'enterprise')
      .build();
  final authService = AuthenticationService();
  final dataService = DataService();
  final uiController = UIController();
  await authService.login('user@example.com', 'password');
  await dataService.fetchUserData('user-123');
  await uiController.updateDisplay('Welcome back!');
  await uiController.navigateTo('HomeScreen');
  await dataService.syncData();
  await authService.refreshToken();
}

/// Example 17: Error tracking with full context
///
/// [20:55:54.758][f111296f][24752026][b2025.08.24][ErrorProneService][INFO][ErrorProneService.performRiskyOperation:596] Starting risky operation [package:any_logger/example/any_logger_example.dart(596:5)]
/// [20:55:54.758][f111296f][24752026][b2025.08.24][ErrorProneService][ERROR][ErrorProneService.performRiskyOperation:601] Risky operation failed [package:any_logger/example/any_logger_example.dart(601:7)]
/// 	Exception: Random processing failure
Future<void> errorTrackingExample() async {
  await LoggerFactory.dispose();
  await LoggerBuilder()
      .replaceAll()
      .console(
        level: Level.DEBUG,
        format: '[%d][%did][%sid][%X{build}][%i][%l][%c] %m [%f]',
        dateFormat: 'HH:mm:ss.SSS',
      )
      .withMdcValue('build', 'b2025.08.24')
      .build();
  final errorService = ErrorProneService();
  await errorService.performRiskyOperation();
  await errorService.handleNetworkRequest();
  await errorService.processUserInput('invalid@data');
}

/// Example 18: Performance monitoring with detailed logging
///
/// [20:55:54.761][f111296f][6e7c3349][staging][ANYLOGGER_SELF_LOGGER][INFO][LoggerFactory._setupSelfLogger:837] Setting level for all appenders to DEBUG [package:any_logger/src/logger_factory.dart(837:18)]
/// [20:55:54.761][f111296f][6e7c3349][staging][ANYLOGGER_SELF_LOGGER][DEBUG][LoggerFactory._setupSelfLogger:839] Self-debugging enabled [package:any_logger/src/logger_factory.dart(839:5)]
/// [20:55:54.761][f111296f][6e7c3349][staging][ANYLOGGER_SELF_LOGGER][DEBUG][LoggerFactory.initWithLoggerConfig:567] Logging system initialized with programmatic LoggerConfig with 1 active appenders [package:any_logger/src/logger_factory.dart(567:7)]
Future<void> performanceMonitoringExample() async {
  await LoggerFactory.dispose();
  await LoggerBuilder()
      .replaceAll()
      .console(
        level: Level.DEBUG,
        format: '[%d][%did][%sid][%X{node}][%i][%l][%c] %m [%f]',
        dateFormat: 'HH:mm:ss.SSS',
      )
      .withMdcValue('node', 'node-03')
      .build();
  final perfMonitor = PerformanceMonitor();
  await perfMonitor.measureDatabaseQuery();
  await perfMonitor.measureApiCall();
  await perfMonitor.measureUIRendering();
  sleep(const Duration(milliseconds: 100));
}

/// Example 16: Using AppenderBuilder for granular control
///
/// CONSOLE [INFO]: This info message goes to both console and file.
/// CONSOLE [ERROR]: This error also goes to both appenders.
/// CONSOLE [INFO]: And i am here because three lines look better...
Future<void> builderWithAppenderBuilderExample() async {
  await LoggerFactory.dispose();
  final fileAppender = await FileAppenderBuilder('granular_log')
      .withLevel(Level.TRACE)
      .withPath('logs/')
      .build();
  final consoleAppender = consoleAppenderBuilder()
      .withLevel(Level.INFO)
      .withFormat('CONSOLE [%i][%l]: %m')
      .buildSync();
  await LoggerBuilder()
      .replaceAll()
      .withRootLevel(Level.TRACE)
      .addAppender(fileAppender)
      .addAppender(consoleAppender)
      .withSelfDebug()
      .build();
  Logger.info('This info message goes to both console and file.');
  Logger.error('This error also goes to both appenders.');
  Logger.info('And i am here because three lines look better...');
}

// ============================================================
// HELPER FUNCTIONS & CLASSES
// ============================================================
class UserService with AnyLogger {
  Future<void> createUser(String email) async {
    logInfo('Creating user: $email');
    await Future.delayed(const Duration(milliseconds: 100));
    logInfo('User created successfully');
  }
}

class AuthService with AnyLogger {
  @override
  String get loggerName => 'AUTH';

  Future<bool> authenticate(String email, String password) async {
    logInfo('Authentication attempt for: $email');
    logDebug('Validating credentials');
    await Future.delayed(const Duration(milliseconds: 200));
    logInfo('Authentication successful');
    return true;
  }
}

Future<void> handleUserRequest(String userId, String requestId) async {
  LoggerFactory.setMdcValue('userId', userId);
  LoggerFactory.setMdcValue('requestId', requestId);
  Logger.info('Request started');
  Logger.info('Request completed');
  LoggerFactory.removeMdcValue('userId');
  LoggerFactory.removeMdcValue('requestId');
}

class MyApplication with AnyLogger {
  @override
  String get loggerName => 'MyApplication';

  Future<void> initialize() async {
    logInfo('Initializing application');
    await Future.delayed(const Duration(milliseconds: 50));
    logDebug('Loading configuration');
    logDebug('Setting up database connection');
    logInfo('Application initialized successfully');
  }

  Future<void> start() async {
    logInfo('Starting application');
    await Future.delayed(const Duration(milliseconds: 30));
    logDebug('Starting background services');
    logInfo('Application started');
  }

  Future<void> handleUserAction(String action) async {
    logDebug('User action received: $action');
    await Future.delayed(const Duration(milliseconds: 20));
    logInfo('Processed user action: $action');
  }

  Future<void> stop() async {
    logInfo('Stopping application');
    await Future.delayed(const Duration(milliseconds: 30));
    logDebug('Stopping background services');
    logInfo('Application stopped');
  }

  Future<void> dispose() async {
    logInfo('Disposing application resources');
    await Future.delayed(const Duration(milliseconds: 20));
    logDebug('Closing database connections');
    logInfo('Application disposed');
  }
}

class AuthenticationService with AnyLogger {
  @override
  String get loggerName => 'AuthService';

  Future<void> login(String email, String password) async {
    logInfo('Login attempt for user: $email');
    logDebug('Validating credentials');
    await Future.delayed(const Duration(milliseconds: 100));
    logDebug('Credentials validated successfully');
    logInfo('User logged in: $email');
  }

  Future<void> refreshToken() async {
    logDebug('Refreshing authentication token');
    await Future.delayed(const Duration(milliseconds: 50));
    logInfo('Token refreshed successfully');
  }
}

class DataService with AnyLogger {
  @override
  String get loggerName => 'DataService';

  Future<void> fetchUserData(String userId) async {
    logDebug('Fetching data for user: $userId');
    await Future.delayed(const Duration(milliseconds: 80));
    logInfo('User data retrieved successfully');
  }

  Future<void> syncData() async {
    logInfo('Starting data synchronization');
    logDebug('Checking for local changes');
    await Future.delayed(const Duration(milliseconds: 150));
    logInfo('Data synchronization completed');
  }
}

class UIController with AnyLogger {
  @override
  String get loggerName => 'UIController';

  Future<void> updateDisplay(String message) async {
    logDebug('Updating display with message: $message');
    await Future.delayed(const Duration(milliseconds: 30));
    logInfo('Display updated');
  }

  Future<void> navigateTo(String screen) async {
    logInfo('Navigating to: $screen');
    await Future.delayed(const Duration(milliseconds: 50));
    logInfo('Navigation completed: $screen');
  }
}

class ErrorProneService with AnyLogger {
  @override
  String get loggerName => 'ErrorProneService';

  Future<void> performRiskyOperation() async {
    logInfo('Starting risky operation');
    try {
      if (1 == 1) throw Exception('Random processing failure');
      logInfo('Risky operation completed successfully');
    } catch (e, stack) {
      logError('Risky operation failed', exception: e, stackTrace: stack);
    }
  }

  Future<void> handleNetworkRequest() async {
    try {
      if (1 == 1) throw const SocketException('Connection timeout');
      logInfo('Network request successful');
    } catch (e) {
      logError('Network request failed', exception: e);
    }
  }

  Future<void> processUserInput(String input) async {
    if (!input.contains('@')) {
      logWarn('Invalid input format detected: $input');
    } else {
      logInfo('Valid input processed: $input');
    }
  }
}

class PerformanceMonitor with AnyLogger {
  @override
  String get loggerName => 'PerfMonitor';

  Future<void> measureDatabaseQuery() async {
    final stopwatch = Stopwatch()..start();
    await Future.delayed(Duration(milliseconds: Random().nextInt(100) + 50));
    stopwatch.stop();
    final elapsed = stopwatch.elapsedMilliseconds;
    if (elapsed > 100) {
      logWarn('Slow database query: ${elapsed}ms');
    } else {
      logInfo('Database query completed: ${elapsed}ms');
    }
  }

  Future<void> measureApiCall() async {
    final stopwatch = Stopwatch()..start();
    await Future.delayed(Duration(milliseconds: Random().nextInt(200) + 100));
    stopwatch.stop();
    final elapsed = stopwatch.elapsedMilliseconds;
    if (elapsed > 200) {
      logWarn('Slow API response: ${elapsed}ms');
    } else {
      logInfo('API call completed: ${elapsed}ms');
    }
  }

  Future<void> measureUIRendering() async {
    final stopwatch = Stopwatch()..start();
    await Future.delayed(Duration(milliseconds: Random().nextInt(50) + 10));
    stopwatch.stop();
    final elapsed = stopwatch.elapsedMilliseconds;
    if (elapsed > 16) {
      logWarn('UI rendering exceeded frame budget: ${elapsed}ms');
    } else {
      logDebug('UI rendering within budget: ${elapsed}ms');
    }
  }
}

Future<void> cleanupExampleFiles() async {
  final logDir = Directory('logs');
  if (await logDir.exists()) {
    try {
      await for (final entity in logDir.list()) {
        if (entity is File) {
          await entity.delete();
        }
      }
    } catch (e) {
      //
    }
  }
}

class MyCustomIdProvider implements IdProvider {
  // Don't use 'late' - initialize with null
  String? _deviceId;
  String? _sessionId;

  @override
  String? get deviceId => _deviceId;

  @override
  String? get sessionId => _sessionId;

  @override
  Future<void> initialize() async {
    // In a real implementation, you might load from secure storage
    _deviceId = 'my-device-id';
    _sessionId = 'my-session-id';
  }

  @override
  void initializeSync() {
    _deviceId = 'my-device-id';
    _sessionId = 'my-session-id';
  }

  @override
  void regenerateSessionId() {
    // Keep device ID, generate new session
    _deviceId ??= 'my-device-id';
    _sessionId = 'my-session-${DateTime.now().millisecondsSinceEpoch}';
  }

  @override
  void reset() {
    _deviceId = null;
    _sessionId = null;
  }

  @override
  void resetSession() {
    _sessionId = null;
  }

  @override
  // TODO: implement isInitialized
  bool get isInitialized => true;
}
0
likes
150
points
988
downloads

Publisher

verified publisherraoulsson.com

Weekly Downloads

A powerful, flexible, and intuitive logging library for Dart and Flutter with progressive complexity - from one-line setup to enterprise configurations.

Repository (GitHub)
View/report issues
Contributing

Topics

#logging

Documentation

Documentation
API reference

Funding

Consider supporting this project:

github.com
www.buymeacoffee.com

License

MIT (license)

More

Packages that depend on any_logger