zlogger

日本語

A lightweight, zone-based structured logger for Dart.

Features

  • Simple API - log.info('message') just works
  • Named Loggers - Log.named('UserService') for class-specific logging
  • Zone Context - Automatic context propagation (like Java's MDC)
  • Structured Logging - Add fields to any log message
  • JSON Output - Machine-readable log format
  • Colored Output - Beautiful terminal output
  • Zero Dependencies - Only uses dart:async, dart:convert, dart:io

Quick Start

import 'package:zlogger/zlogger.dart';

void main() {
  // Simple logging
  log.info('Application started');
  log.debug('Debug info', {'version': '1.0.0'});
  log.warn('Warning message');
  log.error('Error occurred', {'code': 500}, error, stackTrace);
}

Named Loggers

For classes, use Log.named() to include the class name in logs:

class UserService {
  static final log = Log.named('UserService');

  Future<User> findUser(String id) async {
    log.info('Finding user', {'userId': id});
    // Output: 2025-01-01T12:00:00.000 [INFO] Finding user logger=UserService userId=123

    return await repository.find(id);
  }
}

Zone Context (MDC-style)

Propagate context (like request_id) through your entire call stack:

// In your HTTP middleware
Future<void> handleRequest(Request request) async {
  final requestId = generateRequestId();

  await Log.scope({'request_id': requestId}, () async {
    log.info('Request started');

    // All logs in services automatically include request_id!
    await userService.findUser(request.userId);
    await orderService.getOrders(request.userId);

    log.info('Request completed');
  });
}

All log calls within the zone automatically include the context:

2025-01-01T12:00:00.000 [INFO] Request started request_id=abc-123
2025-01-01T12:00:00.010 [INFO] Finding user logger=UserService request_id=abc-123 userId=42
2025-01-01T12:00:00.020 [INFO] Getting orders logger=OrderService request_id=abc-123 userId=42
2025-01-01T12:00:00.030 [INFO] Request completed request_id=abc-123

Configuration

Log Level

LogConfig.global = DefaultLogger(minLevel: LogLevel.info);

JSON Output

LogConfig.global = DefaultLogger(json: true);
// Output: {"time":"2025-01-01T12:00:00.000","level":"info","msg":"Hello","userId":123}

Disable Colors

LogConfig.global = DefaultLogger(color: false);

Custom Formatter

LogConfig.global = DefaultLogger(
  formatter: (record) {
    return '[${record.level.name.toUpperCase()}] ${record.message}';
  },
);
// Output: [INFO] Application started

Custom Handler

LogConfig.global = DefaultLogger(
  handler: (record) {
    // Send to external service, file, etc.
    myLogService.send(record.toJson());
  },
);

API Reference

Log Levels

Level Method Description
debug log.debug() Detailed debugging information
info log.info() General information
warn log.warn() Warning conditions
error log.error() Error conditions

Top-level log

log.info('message');
log.info('message', {'key': 'value'});
log.error('failed', {'op': 'test'}, error, stackTrace);

Named Logger

final log = Log.named('MyClass');
log.info('message');  // includes logger=MyClass

Zone Context

// Sync
Log.scope({'request_id': 'abc'}, () {
  log.info('includes request_id');
});

// Async
await Log.scope({'request_id': 'abc'}, () async {
  await someAsyncWork();
  log.info('still includes request_id');
});

// Access current context
final ctx = Log.currentContext;
print(ctx['request_id']);

Comparison with Other Loggers

Feature zlogger logger logging
Simple API log.info() logger.i() log.info()
Named Loggers
Zone/MDC Context
Structured Fields
JSON Output
Zero Dependencies

License

MIT

Libraries

zlogger
A lightweight, zone-based structured logger for Dart.