ispectify_dio 4.3.6 copy "ispectify_dio: ^4.3.6" to clipboard
ispectify_dio: ^4.3.6 copied to clipboard

An additional package for Dio (logging and handling).

Dio HTTP client integration for ISpectify logging system

pub version License: MIT GitHub stars

Pub likes Pub points

TL;DR #

Capture Dio HTTP traffic with structured request/response/error logging.

🏗️ Architecture #

ISpectifyDio integrates with the Dio HTTP client through interceptors:

Component Description
Dio Interceptor Captures HTTP requests and responses
Request Logger Logs request details (headers, body, params)
Response Logger Logs response data and timing
Error Handler Captures and logs HTTP errors
Performance Tracker Measures request/response times

Overview #

ISpectify Dio integrates the Dio HTTP client with the ISpectify logging system.

ISpectifyDio integrates the Dio HTTP client with the ISpectify logging system for HTTP request monitoring.

Key Features #

  • HTTP Request Logging: Automatic logging of all Dio requests
  • Response Tracking: Detailed response logging with timing information
  • Error Handling: Comprehensive error logging with stack traces
  • Request Inspection: Headers, body, and parameter logging
  • Sensitive Data Redaction: Centralized redaction for headers and bodies (enabled by default, configurable)
  • Performance Metrics: Request/response timing and size tracking
  • Configurable: Flexible configuration options for different environments

Configuration Options #

Basic Setup #

final Dio dio = Dio(
  BaseOptions(
    baseUrl: 'https://api.example.com',
  ),
);

// Initialize in ISpect.run onInit callback
ISpect.run(
  () => runApp(MyApp()),
  logger: iSpectify,
  onInit: () {
    dio.interceptors.add(
      ISpectDioInterceptor(
        logger: iSpectify,
        settings: const ISpectDioInterceptorSettings(
          printRequestHeaders: true,
        ),
      ),
    );
  },
);

Sensitive Data Redaction #

Redaction is enabled by default. Disable globally via settings or provide a custom redactor.

// Disable redaction
dio.interceptors.add(
  ISpectDioInterceptor(
    logger: iSpectify,
    settings: const ISpectDioInterceptorSettings(enableRedaction: false),
  ),
);

// Provide a custom redactor
final redactor = RedactionService();
redactor.ignoreKeys(['x-debug']);
redactor.ignoreValues(['sample-token']);

dio.interceptors.add(
  ISpectDioInterceptor(
    logger: iSpectify,
    redactor: redactor,
  ),
);

Filtering with Optional Predicates #

dio.interceptors.add(
  ISpectDioInterceptor(
    logger: iSpectify,
    settings: const ISpectDioInterceptorSettings(
      printRequestHeaders: true,
      // requestFilter: (requestOptions) =>
      //     requestOptions.path != '/sensitive-endpoint',
      // responseFilter: (response) => response.statusCode != 404,
      // errorFilter: (error) => error.response?.statusCode != 404,
    ),
  ),
);

Multiple Dio Instances #

final Dio mainDio = Dio(BaseOptions(baseUrl: 'https://api.example.com'));
final Dio uploadDio = Dio(BaseOptions(baseUrl: 'https://upload.example.com'));

mainDio.interceptors.add(ISpectDioInterceptor(logger: iSpectify));
uploadDio.interceptors.add(ISpectDioInterceptor(logger: iSpectify));

Installation #

Add ispectify_dio to your pubspec.yaml:

dependencies:
  ispectify_dio: ^4.3.6

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:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:ispect/ispect.dart';
import 'package:ispectify_dio/ispectify_dio.dart';

// Use dart define to control ISpectify Dio integration
const bool kEnableISpectDio = bool.fromEnvironment('ENABLE_ISPECT', defaultValue: false);

final Dio dio = Dio(
  BaseOptions(
    baseUrl: 'https://jsonplaceholder.typicode.com',
  ),
);

void main() {
  if (kEnableISpectDio) {
    _initializeWithISpect();
  } else {
    // Production initialization without ISpect
    runApp(MyApp());
  }
}

void _initializeWithISpect() {
  final ISpectify iSpectify = ISpectifyFlutter.init();

  ISpect.run(
    () => runApp(MyApp()),
          logger: iSpectify,
    onInit: () {
      // Add ISpectify Dio interceptor only in development/staging
      dio.interceptors.add(
        ISpectDioInterceptor(
          logger: iSpectify,
          settings: const ISpectDioInterceptorSettings(
            printRequestHeaders: true,
          ),
        ),
      );
    },
  );
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('ISpectify Dio Example')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: () {
                  // HTTP requests will be logged only when ISpect is enabled
                  dio.get<dynamic>('/posts/1');
                },
                child: const Text('Send GET Request'),
              ),
              const SizedBox(height: 16),
              ElevatedButton(
                onPressed: () {
                  // Error requests are also logged (when enabled)
                  dio.get<dynamic>('/invalid-endpoint');
                },
                child: const Text('Send Error Request'),
              ),
              const SizedBox(height: 16),
              ElevatedButton(
                onPressed: () {
                  // Upload file with FormData
                  final FormData formData = FormData();
                  formData.files.add(MapEntry(
                    'file',
                    MultipartFile.fromBytes(
                      [1, 2, 3],
                      filename: 'file.txt',
                    ),
                  ));
                  dio.post<dynamic>('/upload', data: formData);
                },
                child: const Text('Upload File'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Minimal Setup #

Advanced Configuration #

Production-Safe HTTP Logging #

// Create a factory for conditional Dio setup
class DioFactory {
  static const bool _isEnabled = bool.fromEnvironment('ENABLE_ISPECT', defaultValue: false);
  
  static Dio createDio({
    String baseUrl = '',
    ISpectify? iSpectify,
  }) {
    final dio = Dio(BaseOptions(baseUrl: baseUrl));
    
    // Only add interceptor when ISpect is enabled
    if (_isEnabled && iSpectify != null) {
      dio.interceptors.add(
        ISpectDioInterceptor(
          logger: iSpectify,
          settings: ISpectDioInterceptorSettings(
            printRequestHeaders: kDebugMode,
            enableRedaction: true, // Keep redaction enabled outside development
          ),
        ),
      );
    }
    
    return dio;
  }
}

// Usage
final dio = DioFactory.createDio(
  baseUrl: 'https://api.example.com',
  iSpectify: ISpect.logger,
);

Environment-Specific Configuration #

class DioConfig {
  static ISpectDioInterceptorSettings getSettings() {
    const environment = String.fromEnvironment('ENVIRONMENT', defaultValue: 'development');
    
    switch (environment) {
      case 'development':
        return const ISpectDioInterceptorSettings(
          printRequestHeaders: true,
          printResponseHeaders: true,
          enableRedaction: false, // Only disable if using non-sensitive test data
        );
      case 'staging':
        return const ISpectDioInterceptorSettings(
          printRequestHeaders: true,
          printResponseHeaders: false,
          enableRedaction: true,
        );
      default: // production
        return const ISpectDioInterceptorSettings(
          printRequestHeaders: false,
          printResponseHeaders: false,
          enableRedaction: true,
        );
    }
  }
}

Conditional Interceptor Setup #

void setupDioInterceptors(Dio dio, ISpectify? iSpectify) {
  const isISpectEnabled = bool.fromEnvironment('ENABLE_ISPECT', defaultValue: false);
  
  if (isISpectEnabled && iSpectify != null) {
    // Custom redactor for sensitive data
    final redactor = RedactionService();
    redactor.ignoreKeys(['authorization', 'x-api-key']);
    redactor.ignoreValues(['<placeholder-secret>', '<another-placeholder>']);
    
    dio.interceptors.add(
      ISpectDioInterceptor(
        logger: iSpectify,
        redactor: redactor,
        settings: DioConfig.getSettings(),
      ),
    );
  }
  
  // Add other production interceptors here (avoid duplicate logging)
}

Examples #

See the example/ directory for complete integration examples with different Dio configurations.

🤝 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

0
likes
160
points
1.69k
downloads

Publisher

verified publishershodev.live

Weekly Downloads

An additional package for Dio (logging and handling).

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

ansicolor, dio, ispectify

More

Packages that depend on ispectify_dio