tag static method

void tag(
  1. String name,
  2. dynamic message, {
  3. Level level = Level.FINE,
  4. Object? error,
  5. StackTrace? stackTrace,
})

Logs a message with a tag for grouping and later export.

Tags allow grouping related logs across different layers (UI, Service, Repository) and exporting them together for AI analysis.

The message is stored with the tag AND printed normally. In release builds, only the normal print occurs (storage is skipped).

Auto stack trace: For error levels (WARNING, SEVERE, SHOUT), the stack trace is captured automatically if not provided. This helps identify the exact code location that caused the error.

Parameters:

  • name: Tag identifier (e.g., 'auth', 'checkout', 'api')
  • message: Log message (String, Map, or any object)
  • level: Log level (default: Level.FINE/DEBUG)
  • error: Optional error object
  • stackTrace: Optional stack trace (auto-captured for errors)

Example:

// Simple message
Log.tag('auth', 'User pressed login');

// With JSON data
Log.tag('auth', {'email': email, 'timestamp': DateTime.now()});

// With specific level
Log.tag('auth', 'Validating token', level: Level.INFO);

// Error with auto stack trace
Log.tag('auth', 'Login failed', level: Level.SEVERE, error: e);

Implementation

static void tag(
  String name,
  dynamic message, {
  Level level = Level.FINE,
  Object? error,
  StackTrace? stackTrace,
}) {
  // Single stack capture for both location resolution and error tracking
  final capturedStack = StackTrace.current;

  // Auto-capture stack trace for error levels if not provided
  final effectiveStackTrace =
      stackTrace ??
      (level == Level.WARNING || level == Level.SEVERE || level == Level.SHOUT
          ? capturedStack
          : null);

  // Resolve location once from the captured stack
  final location = LocationResolver.resolve(capturedStack);

  assert(() {
    final formatted = ObjectFormatter.format(message);
    _tags
        .putIfAbsent(name, () => [])
        .add(
          TaggedEntry(
            message: formatted,
            level: _levelName(level),
            location: location.short,
            timestamp: DateTime.now(),
            error: error,
            stackTrace: effectiveStackTrace,
          ),
        );
    return true;
  }());

  // Use pre-resolved location to avoid double stack capture
  _logWithLocation(
    level,
    message,
    location,
    error: error,
    stackTrace: effectiveStackTrace,
  );
}