ispectify 4.4.1 copy "ispectify: ^4.4.1" to clipboard
ispectify: ^4.4.1 copied to clipboard

Foundation logging system for ISpect toolkit (based on Talker)

Foundation logging system for ISpect toolkit (based on Talker)

pub version License: MIT GitHub stars

Pub likes Pub points

TL;DR #

Logging backbone: structured logs, filtering, history, export, redaction.

🏗️ Architecture #

ISpectify 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 #

ISpectify is the foundation logging system that powers the ISpect debugging toolkit.

ISpectify 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 (ISpectifyOptions) #

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 = ISpectify(
  logger: ISpectifyLogger(
    settings: LoggerSettings(enableColors: false),
  ),
  options: ISpectifyOptions(useConsoleLogs: false),
);

Stdout stays clean; history + streams still work.

Disable History (Stateless Mode) #

final logger = ISpectify(options: ISpectifyOptions(useHistory: false));

No retention; stream subscribers still receive real-time logs. Memory overhead minimal.

Minimal Footprint (CI / Benchmarks) #

final logger = ISpectify(
  options: ISpectifyOptions(
    enabled: true,
    useConsoleLogs: true, // or false for JSON parsing scenarios
    useHistory: false,
    logTruncateLength: 400,
  ),
  logger: ISpectifyLogger(
    settings: LoggerSettings(
      enableColors: false, // deterministic output
      maxLineWidth: 80,
    ),
  ),
);

Memory Control #

Keep history bounded; large payloads are truncated before print:

ISpectifyOptions(
  maxHistoryItems: 2000,
  logTruncateLength: 2000,
);

Custom Titles & Colors #

ISpectifyOptions(
  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 = ISpectify(...);
// 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 ISpectifyFilter {
  @override
  bool apply(ISpectifyData d) => d.logLevel?.priority >= LogLevel.error.priority;
}

final logger = ISpectify(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<ISpectifyData>

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 ISpectifyError and ISpectifyException; observer callbacks fire before streaming. Provide a custom ISpectifyErrorHandler 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 = ISpectify(
    logger: ISpectifyLogger(
        settings: LoggerSettings(
      enableColors: false,
    )),
    options: ISpectifyOptions(
      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 ISpectifyData {
  CustomLog(
    String super.message,
  ) : super(
          key: 'custom_log',
          title: 'Custom Log',
        );
}

logger.logCustom(CustomLog('This is a custom log message'));

Installation #

Add ispectify to your pubspec.yaml:

dependencies:
  ispectify: ^4.4.1

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 ISpectify inclusion
const bool kEnableISpectify = bool.fromEnvironment('ENABLE_ISPECT', defaultValue: false);

class CustomLog extends ISpectifyData {
  CustomLog(
    String super.message,
  ) : super(
          key: 'custom_log',
          title: 'Custom Log',
        );
}

void main() {
  ISpectify? logger;
  
  if (kEnableISpectify) {
    // Initialize ISpectify only in development/staging
    logger = ISpectify(
      logger: ISpectifyLogger(
          settings: LoggerSettings(
        enableColors: false,
      )),
      options: ISpectifyOptions(
        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('ISpectify initialized successfully');

    // Wrap your app with ISpect
    ISpect.run(
      () => runApp(MyApp()),
      logger: logger,
    );
  } else {
    // Production run without ISpectify
    runApp(MyApp());
  }
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('ISpectify Example')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: () {
                  if (kEnableISpectify) {
                    ISpect.logger.info('Info log message');
                  }
                },
                child: const Text('Log Info'),
              ),
              ElevatedButton(
                onPressed: () {
                  if (kEnableISpectify) {
                    ISpect.logger.logCustom(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 ISpectify? _instance;
  
  static ISpectify? get instance {
    if (!_isEnabled) return null;
    return _instance ??= _createLogger();
  }
  
  static ISpectify _createLogger() {
    return ISpectify(
      logger: ISpectifyLogger(
        settings: LoggerSettings(
          enableColors: kDebugMode, // Disable colors in headless/CI for cleaner output
        )
      ),
      options: ISpectifyOptions(
        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
ISpectify createLogger() {
  const environment = String.fromEnvironment('ENVIRONMENT', defaultValue: 'development');
  final bool isProd = environment == 'production';
  return ISpectify(
    logger: ISpectifyLogger(
      settings: LoggerSettings(
        enableColors: !isProd,
        lineLength: environment == 'development' ? 120 : 80,
      )
    ),
    options: ISpectifyOptions(
      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:

ISpectifyOptions(
  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.


Built with ❤️ for the Flutter community

2
likes
150
points
2.97k
downloads

Publisher

verified publishershodev.live

Weekly Downloads

Foundation logging system for ISpect toolkit (based on Talker)

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

ansicolor, collection, meta, web

More

Packages that depend on ispectify