ispectify 4.4.8-dev02 
ispectify: ^4.4.8-dev02 copied to clipboard
Foundation logging system for ISpect toolkit (based on Talker)
TL;DR #
Logging backbone: structured logs, filtering, history, export, redaction.
Interface Preview #
  
  
  
  
  
Live Web Demo #
Try out ISpect in your browser! Visit https://yelmuratoff.github.io/ispect/ to drag and drop an ISpect log file and explore its contents interactively.
Architecture #
ISpectLogger serves as the logging foundation for the ISpect ecosystem:
| Component | Description | 
|---|---|
| Core Logger | Based on Talker with enhanced features | 
| Log Filtering | Advanced filtering and search capabilities | 
| Performance Tracking | Built-in performance monitoring | 
| Export System | Log export and analysis tools | 
| Integration Layer | Seamless integration with ISpect toolkit | 
Overview #
ISpectLogger is the foundation logging system that powers the ISpect debugging toolkit.
ISpectLogger is the logging foundation for the ISpect ecosystem. It builds on the Talker logging library and adds features for debugging and monitoring Flutter applications.
Key Features #
- Structured Logging: Advanced logging with categorization and filtering
 - Custom Log Types: Define your own log types with custom colors and icons
 - Real-time Filtering: Filter logs by type, level, and custom criteria
 - Performance Monitoring: Track application performance metrics
 - Export Functionality: Export logs for analysis and debugging
 - Easy Integration: Simple setup with minimal configuration
 
Logging Configuration #
Quick Flags (ISpectLoggerOptions) #
| Option | Default | Effect | Use Case | 
|---|---|---|---|
| enabled | true | Global on/off | Feature flag / release build | 
| useConsoleLogs | true | Print to stdout | CI, local dev | 
| useHistory | true | Keep in-memory history | Disable in load tests | 
| maxHistoryItems | 10000 | Ring buffer size | Tune memory footprint | 
| logTruncateLength | 10000 | Trim long console payloads | Prevent huge JSON spam | 
Disable Console Output #
final logger = ISpectLogger(
  logger: ISpectLoggerLogger(
    settings: LoggerSettings(enableColors: false),
  ),
  options: ISpectLoggerOptions(useConsoleLogs: false),
);
Stdout stays clean; history + streams still work.
Disable History (Stateless Mode) #
final logger = ISpectLogger(options: ISpectLoggerOptions(useHistory: false));
No retention; stream subscribers still receive real-time logs. Memory overhead minimal.
Minimal Footprint (CI / Benchmarks) #
final logger = ISpectLogger(
  options: ISpectLoggerOptions(
    enabled: true,
    useConsoleLogs: true, // or false for JSON parsing scenarios
    useHistory: false,
    logTruncateLength: 400,
  ),
  logger: ISpectLoggerLogger(
    settings: LoggerSettings(
      enableColors: false, // deterministic output
      maxLineWidth: 80,
    ),
  ),
);
Memory Control #
Keep history bounded; large payloads are truncated before print:
ISpectLoggerOptions(
  maxHistoryItems: 2000,
  logTruncateLength: 2000,
);
Custom Titles & Colors #
ISpectLoggerOptions(
  titles: { 'http-request': '➡ HTTP', 'http-response': '⬅ HTTP' },
  colors: { 'http-error': AnsiPen()..red(bg:true) },
);
Unknown keys fallback to the key string + gray pen.
Dynamic Reconfigure (Hot) #
final i = ISpectLogger(...);
// Later
i.configure(options: i.options.copyWith(useConsoleLogs: false));
Existing stream listeners unaffected. History retained unless useHistory becomes false (existing entries remain; future ones not stored).
Filtering (Custom) #
Provide a filter implementation to drop noise early:
class OnlyErrorsFilter implements ISpectFilter {
  @override
  bool apply(ISpectLogData d) => d.logLevel?.priority >= LogLevel.error.priority;
}
final logger = ISpectLogger(filter: OnlyErrorsFilter());
Route / Analytics / Provider Logs #
Use dedicated helpers: route('/home'), track('login', event: 'login'), provider('UserRepository created'). Customize visibility at UI layer (ISpect theme) via logDescriptions.
Disabling Print Hijack #
When using ISpect.run set isPrintLoggingEnabled: false to leave print() untouched.
ISpect.run(
  () => runApp(App()),
  logger: logger,
  isPrintLoggingEnabled: false,
);
Safe Production Pattern #
Keep code tree-shaken out:
flutter run --dart-define=ENABLE_ISPECT=true
flutter build apk # default false -> removed
const kEnable = bool.fromEnvironment('ENABLE_ISPECT');
if (kEnable) {
  ISpect.run(() => runApp(App()), logger: logger);
} else {
  runApp(App());
}
Avoid Log Flood (Large JSON / Streams) #
Pre-truncate before logging if payload > N:
logger.debug(json.length > 2000 ? json.substring(0, 2000) + '…' : json);
Or adjust logTruncateLength.
History Export (Pattern) #
History object:
final copy = logger.history; // List<ISpectLogData>
Serialize manually (avoid bundling secrets). Provide redaction upstream before logging.
Toggle On-the-fly (Dev Tools) #
Expose a switch:
setState(() => logger.options.enabled = !logger.options.enabled);
Prefer a wrapper method to avoid direct state in UI tests.
When to Disable History #
- Long running integration tests
 - GPU / memory profiling sessions
 - High-frequency streaming (WS metrics)
 
When to Disable Console #
- Parsing machine-readable test output
 - Prevent noise in CI logs
 - Benchmark harness isolation
 
Line Width vs Wrap #
Use maxLineWidth to constrain horizontal noise; does not truncate content (truncation done via logTruncateLength). Set lower for narrow terminals.
Color Strategy #
Disable colors for: CI, log ingestion systems, snapshot testing. Keep colors locally for readability.
Error / Exception Flow #
logger.handle(exception) decides between ISpectLogError and ISpectLogException; observer callbacks fire before streaming. Provide a custom ISpectErrorHandler to rewrite classification.
Zero-Allocation Path #
For ultra hot loops avoid string interpolation before checking options.enabled. Pattern:
if (logger.options.enabled) logger.debug(buildHeavyString());
Thread / Zone Capturing #
Use ISpect.run with isZoneErrorHandlingEnabled (default true) to automatically route uncaught zone errors through logger.handle. Disable if running inside another error aggregation framework.
Configuration #
Settings #
final logger = ISpectLogger(
    logger: ISpectLoggerLogger(
        settings: LoggerSettings(
      enableColors: false,
    )),
    options: ISpectLoggerOptions(
      enabled: true,
      useHistory: true,
      useConsoleLogs: true,
      maxHistoryItems: 10000,
      logTruncateLength: 10000,
      titles: {
        'error': 'Error Logs',
        'info': 'Info Logs',
        'debug': 'Debug Logs',
      },
      colors: {
        'error': AnsiPen()..red(),
        'info': AnsiPen()..blue(),
        'debug': AnsiPen()..white(),
      },
    ),
  );
Custom Log Types #
class CustomLog extends ISpectLogData {
  CustomLog(
    String super.message,
  ) : super(
          key: 'custom_log',
          title: 'Custom Log',
        );
}
logger.logData(CustomLog('This is a custom log message'));
Installation #
Add ispectify to your pubspec.yaml:
dependencies:
  ispectify: ^4.4.8-dev02
Security & Production Guidelines #
IMPORTANT: ISpect is development‑only. Keep it out of production builds.
Full security & environment setup (click to expand)
🚀 Quick Start #
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:ispect/ispect.dart';
// Use dart define to control ISpectLogger inclusion
const bool kEnableISpectLogger = bool.fromEnvironment('ENABLE_ISPECT', defaultValue: false);
class CustomLog extends ISpectLogData {
  CustomLog(
    String super.message,
  ) : super(
          key: 'custom_log',
          title: 'Custom Log',
        );
}
void main() {
  ISpectLogger? logger;
  
  if (kEnableISpectLogger) {
    // Initialize ISpectLogger only in development/staging
    logger = ISpectLogger(
      logger: ISpectLoggerLogger(
          settings: LoggerSettings(
        enableColors: false,
      )),
      options: ISpectLoggerOptions(
        enabled: true,
        useHistory: true,
        useConsoleLogs: true,
        maxHistoryItems: 10000,
        logTruncateLength: 10000,
        titles: {
          'error': 'Error Logs',
          'info': 'Info Logs',
          'debug': 'Debug Logs',
        },
        colors: {
          'error': AnsiPen()..red(),
          'info': AnsiPen()..blue(),
          'debug': AnsiPen()..white(),
        },
      ),
    );
    logger.info('ISpectLogger initialized successfully');
    // Wrap your app with ISpect
    ISpect.run(
      () => runApp(MyApp()),
      logger: logger,
    );
  } else {
    // Production run without ISpectLogger
    runApp(MyApp());
  }
}
class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('ISpectLogger Example')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: () {
                  if (kEnableISpectLogger) {
                    ISpect.logger.info('Info log message');
                  }
                },
                child: const Text('Log Info'),
              ),
              ElevatedButton(
                onPressed: () {
                  if (kEnableISpectLogger) {
                    ISpect.logger.logData(CustomLog('Custom log message'));
                  }
                },
                child: const Text('Log Custom'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
Minimal Setup #
Advanced Configuration #
Production-Safe Logging #
// Create a logger wrapper that respects environment settings
class SafeLogger {
  static const bool _isEnabled = bool.fromEnvironment('ENABLE_ISPECT', defaultValue: false);
  static ISpectLogger? _instance;
  
  static ISpectLogger? get instance {
    if (!_isEnabled) return null;
    return _instance ??= _createLogger();
  }
  
  static ISpectLogger _createLogger() {
    return ISpectLogger(
      logger: ISpectLoggerLogger(
        settings: LoggerSettings(
          enableColors: kDebugMode, // Disable colors in headless/CI for cleaner output
        )
      ),
      options: ISpectLoggerOptions(
        enabled: true,
        useHistory: true,
        useConsoleLogs: kDebugMode,
        maxHistoryItems: 10000,
        logTruncateLength: 10000,
      ),
    );
  }
  
  // Safe logging methods that check environment
  static void info(String message) {
    instance?.info(message);
  }
  
  static void error(String message, [Object? error, StackTrace? stackTrace]) {
    instance?.error(message, error, stackTrace);
  }
  
  static void debug(String message) {
    instance?.debug(message);
  }
}
Custom Configuration #
// Environment-specific logger configuration
ISpectLogger createLogger() {
  const environment = String.fromEnvironment('ENVIRONMENT', defaultValue: 'development');
  final bool isProd = environment == 'production';
  return ISpectLogger(
    logger: ISpectLoggerLogger(
      settings: LoggerSettings(
        enableColors: !isProd,
        lineLength: environment == 'development' ? 120 : 80,
      )
    ),
    options: ISpectLoggerOptions(
      enabled: !isProd,
      useHistory: true,
      useConsoleLogs: environment == 'development',
      maxHistoryItems: environment == 'development' ? 10000 : 2000,
      logTruncateLength: environment == 'development' ? 10000 : 2000,
      titles: {
        'error': 'Errors',
        'warning': 'Warnings', 
        'info': 'Information',
        'debug': 'Debug Info',
      },
    ),
  );
}
Memory & History Tuning #
Large history buffers increase memory usage. Adjust for CI, tests, or low-end devices:
ISpectLoggerOptions(
  maxHistoryItems: 2000, // Lower for constrained environments
  logTruncateLength: 4000, // Shorter entries reduce memory footprint
);
Redaction Guidance #
Prefer key-based masking (e.g. 'authorization', 'token', 'apiKey'). Avoid hardcoding actual secret values in ignoreValues; use placeholder markers instead. Disable redaction only with synthetic or non-sensitive data.
Examples #
See the example/ directory for usage examples and integration patterns.
🤝 Contributing #
Contributions are welcome! Please read our contributing guidelines and submit pull requests to the main branch.
📄 License #
This project is licensed under the MIT License - see the LICENSE file for details.
Related Packages #
- ispect - Main debugging interface
 - ispectify_dio - Dio HTTP client integration
 - ispectify_http - Standard HTTP client integration
 - ispectify_db - Database operation logging
 - ispectify_bloc - BLoC state management integration