flex_logger_isolate 1.0.3 copy "flex_logger_isolate: ^1.0.3" to clipboard
flex_logger_isolate: ^1.0.3 copied to clipboard

Isolate logging integration for FlexLogger - enables logging from Dart isolates to the main isolate logger.

example/lib/main.dart

import 'dart:async';
import 'dart:isolate';
import 'dart:math';

import 'package:flex_logger/flex_logger.dart';
import 'package:flex_logger_console/flex_logger_console.dart';
import 'package:flex_logger_isolate/flex_logger_isolate.dart';
import 'package:flutter/material.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  FlexLogger.instance.configure(
    providers: [
      ConsoleLoggerProvider(),
      IsolateLoggerProvider(),
    ],
  );
  await FlexLogger.instance.initialize();

  FlexLogger.instance.info('Application started with isolate logging support');

  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void dispose() {
    FlexLogger.instance.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FlexLogger Isolate Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final List<String> _activeIsolates = [];
  bool _isProcessing = false;

  void _updateActiveIsolates() {
    setState(() {
      _activeIsolates.clear();
      final provider = FlexLogger.instance.getProvider<IsolateLoggerProvider>();
      if (provider != null) {
        _activeIsolates.addAll(provider.activeIsolateIds);
      }
    });
  }

  /// Run two workers concurrently: worker-1 and worker-2
  Future<void> _runTwoWorkers() async {
    FlexLogger.instance.info('Starting two worker isolates');

    setState(() {
      _isProcessing = true;
    });

    final sendPort1 = FlexLogger.instance.initializeIsolate('worker-1');
    final sendPort2 = FlexLogger.instance.initializeIsolate('worker-2');
    _updateActiveIsolates();

    await Future.wait([
      Isolate.spawn(_worker1EntryPoint, sendPort1),
      Isolate.spawn(_worker2EntryPoint, sendPort2),
    ]);

    // Give workers time to finish (Isolate.spawn completes when spawned, not when isolate exits)
    await Future<void>.delayed(const Duration(seconds: 5));

    FlexLogger.instance.disposeIsolate('worker-1');
    FlexLogger.instance.disposeIsolate('worker-2');
    _updateActiveIsolates();

    FlexLogger.instance.success('Both workers completed');

    setState(() {
      _isProcessing = false;
    });
  }

  /// Test main thread logging
  void _testMainThreadLogs() {
    FlexLogger.instance.debug('Debug from main thread');
    FlexLogger.instance.info('Info from main thread');
    FlexLogger.instance.success('Success from main thread');
    FlexLogger.instance.warning('Warning from main thread');
    FlexLogger.instance.error('Error from main thread');
    FlexLogger.instance.critical('Critical from main thread');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('FlexLogger + Isolate Demo'),
      ),
      body: Column(
        children: [
          Container(
            width: double.infinity,
            padding: const EdgeInsets.all(12),
            color: Colors.purple.shade50,
            child: const Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Row(
                  children: [
                    Icon(Icons.info_outline, size: 16),
                    SizedBox(width: 8),
                    Text(
                      'Isolate Logging Demo',
                      style: TextStyle(fontWeight: FontWeight.bold),
                    ),
                  ],
                ),
                SizedBox(height: 4),
                Text(
                  'Logs from isolates are forwarded to FlexLogger.instance and displayed in console',
                  style: TextStyle(fontSize: 12),
                ),
              ],
            ),
          ),
          Container(
            width: double.infinity,
            padding: const EdgeInsets.all(16),
            color: Colors.blue.shade50,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  'Active Isolates: ${_activeIsolates.length}',
                  style: const TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: 16,
                  ),
                ),
                if (_activeIsolates.isNotEmpty) ...[
                  const SizedBox(height: 8),
                  Wrap(
                    spacing: 8,
                    children: _activeIsolates
                        .map(
                          (id) => Chip(
                            label: Text(id),
                            avatar: const CircleAvatar(
                              backgroundColor: Colors.green,
                              child: Icon(Icons.play_arrow, size: 16, color: Colors.white),
                            ),
                          ),
                        )
                        .toList(),
                  ),
                ],
              ],
            ),
          ),
          Expanded(
            child: SingleChildScrollView(
              padding: const EdgeInsets.all(16),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: [
                  const Text(
                    'Main Thread Logging:',
                    style: TextStyle(fontWeight: FontWeight.w600, fontSize: 16),
                  ),
                  const SizedBox(height: 8),
                  ElevatedButton.icon(
                    onPressed: _testMainThreadLogs,
                    icon: const Icon(Icons.playlist_add_check),
                    label: const Text('Test All Log Levels (Main Thread)'),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.blue.shade100,
                    ),
                  ),
                  const SizedBox(height: 24),
                  const Divider(),
                  const SizedBox(height: 16),
                  const Text(
                    'Isolate Logging:',
                    style: TextStyle(fontWeight: FontWeight.w600, fontSize: 16),
                  ),
                  const SizedBox(height: 8),
                  ElevatedButton.icon(
                    onPressed: _isProcessing ? null : _runTwoWorkers,
                    icon: const Icon(Icons.group_work),
                    label: const Text('Run worker-1 and worker-2'),
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.green.shade100,
                    ),
                  ),
                  const SizedBox(height: 24),
                  Container(
                    padding: const EdgeInsets.all(16),
                    decoration: BoxDecoration(
                      color: Colors.grey.shade100,
                      borderRadius: BorderRadius.circular(8),
                    ),
                    child: const Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          'Check your console/terminal for logs!',
                          style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 14,
                          ),
                        ),
                        SizedBox(height: 8),
                        Text(
                          'Logs from both main thread and isolates will appear '
                          'in the console with their respective keys (worker-1, worker-2).',
                          style: TextStyle(fontSize: 12),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ),
          if (_isProcessing)
            Container(
              padding: const EdgeInsets.all(16),
              color: Colors.orange.shade50,
              child: const Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  SizedBox(
                    width: 20,
                    height: 20,
                    child: CircularProgressIndicator(strokeWidth: 2),
                  ),
                  SizedBox(width: 12),
                  Text('Workers are running...'),
                ],
              ),
            ),
        ],
      ),
    );
  }
}

// ============================================================================
// Isolate Entry Points
// ============================================================================

void _worker1EntryPoint(SendPort sendPort) {
  final logger = IsolateLogger(
    tag: 'worker-1',
    sendPort: sendPort,
  );

  logger.info('Worker-1 started');
  logger.debug('Worker-1: Initializing...');

  for (int i = 1; i <= 3; i++) {
    logger.debug('Worker-1: Processing step $i/3');
    final sum = List.generate(50000 * i, (i) => i).reduce((a, b) => a + b);
    logger.info('Worker-1: Step $i completed (sum: $sum)');
  }

  logger.success('Worker-1 finished successfully');
}

void _worker2EntryPoint(SendPort sendPort) {
  final logger = IsolateLogger(
    tag: 'worker-2',
    sendPort: sendPort,
  );

  logger.info('Worker-2 started');
  logger.debug('Worker-2: Starting heavy computation...');

  final random = Random();
  var total = 0;
  const iterations = 500000;

  for (int i = 0; i < iterations; i++) {
    total += random.nextInt(100);

    if (i == iterations ~/ 4) {
      logger.debug('Worker-2: 25% complete');
    } else if (i == iterations ~/ 2) {
      logger.info('Worker-2: 50% complete');
    } else if (i == (iterations * 3) ~/ 4) {
      logger.debug('Worker-2: 75% complete');
    }
  }

  logger.success('Worker-2 finished with total: $total');
}
0
likes
160
points
274
downloads

Publisher

verified publisherkrajna.dev

Weekly Downloads

Isolate logging integration for FlexLogger - enables logging from Dart isolates to the main isolate logger.

Homepage
Repository (GitLab)
View/report issues

Topics

#logging #isolate #concurrency #dart

Documentation

API reference

License

MIT (license)

Dependencies

flex_logger, flutter

More

Packages that depend on flex_logger_isolate