Logging in Dart

Logging in Dart

About

  • Logging helps track application behavior and debug issues.
  • Dart offers multiple logging methods: print(), debugPrint(), and the logging package.
  • Logs can be filtered by severity level (INFO, WARNING, ERROR).
  • Essential for both development and production debugging.

Main Topics

  1. Basic Logging with print()

    • Definition: Simple output to console.
    • Example:
      void main() {
        print('Application started'); // Basic log
        print('User ID: ${user.id}'); // Log with variables
      }
  2. debugPrint() for Verbose Output

    • Definition: Handles long lines and throttled output.
    • Example:
      void fetchData() {
        debugPrint('JSON response: ${veryLongResponse}');
      }
  3. Structured Logging Package

    • Definition: Advanced logging with severity levels.

    • Example:

      import 'package:logging/logging.dart';
      
      final logger = Logger('MyApp');
      
      void main() {
        Logger.root.level = Level.ALL;
        Logger.root.onRecord.listen((record) {
          print('${record.level.name}: ${record.message}');
        });
      
        logger.info('User logged in');
        logger.warning('Cache nearly full');
      }
  4. Log Filtering

    • Definition: Controlling log output by level.
    • Example:
      // Set minimum log level
      Logger.root.level = Level.WARNING;
  5. Custom Log Handlers

    • Definition: Routing logs to different outputs.
    • Example:
      Logger.root.onRecord.listen((record) {
        // Send errors to crash reporting
        if (record.level >= Level.SEVERE) {
          CrashReporter.send(record);
        }
      });

How to Use

  • Simple Debugging: Use print() for quick checks
  • Production: Use logging package with severity levels
  • Formatting: debugPrint() for complex data structures
  • Filtering: Adjust levels to reduce noise

How It Works

  • Console Output: Writes to standard output stream
  • Log Levels: Hierarchical severity filtering
  • Asynchronous: Handlers process logs non-blockingly
  • Customization: Extensible through handler interfaces

Example Implementation:

import 'package:logging/logging.dart';

void main() {
  setupLogging();
  runApp();
}

void setupLogging() {
  Logger.root.level = Level.ALL;
  Logger.root.onRecord.listen((record) {
    print('${record.time}: ${record.message}');
  });
}

Conclusion

Logging in Dart provides multiple levels of diagnostic output, from simple print() statements to structured logging package implementations. These tools are essential for tracking application flow, debugging state changes, and monitoring production systems with configurable severity levels.