talker_dio_logger_plus 1.1.0 copy "talker_dio_logger_plus: ^1.1.0" to clipboard
talker_dio_logger_plus: ^1.1.0 copied to clipboard

Advanced and feature-rich Dio HTTP client logger with cURL export, JSON viewer, detail views, image support, and more

Talker Dio Logger Plus #

pub package pub points downloads license

A Dio HTTP logger built on top of Talker that goes beyond what talker_dio_logger offers out of the box.

This is a personal pet project. It scratches a specific itch and is shared as-is — contributions and feedback are welcome, but support and maintenance are best-effort.

Motivation #

talker_dio_logger is great as a foundation, but its HTTP output is fairly minimal — large JSON bodies get dumped as a wall of text in the console, and there's no dedicated UI for inspecting individual requests.

The goal here was something closer to Chucker (the Android HTTP inspector) but built with Talker design and with more features on top:

  • Each request shows up as a card in Talker's log list with a small preview of the response — enough context to spot problems without opening anything
  • Tapping a card opens a detail screen with tabbed views for the request, response, and a ready-to-run cURL command — similar to Chucker's layout, but extended
  • Large JSON responses are truncated in the card view so the list stays readable, while the full payload is accessible in the detail view
  • cURL export includes auth token masking so you can share commands with teammates without leaking credentials
  • ZIP export for sending full request/response logs across tools or to other people (system sharing via a custom FileSaverInterface)

The JSON detail viewer is functional but still has rough edges — a migration to a more robust JSON viewer library is planned.

⚠️ Breaking changes in 1.1.0 — share_plus removed #

What changed. share_plus is no longer a dependency of this package. DefaultFileSaver now exports by saving locally only (ZIP under <app documents>/talker_logs/). The Share action in the detail screen and the shareFile / shareText / saveAndShareHttpLog methods no longer open the system share sheet — they save and report the file location.

Why. This mirrors upstream talker#505 (merged into talker_flutter), which removed share_plus because its Android plugin applies the Kotlin Gradle Plugin directly and triggers Flutter's built-in KGP warning at build time (tracked upstream as talker#502). Every Flutter package that depends on share_plus inherits that warning; the fix is to make the dependency opt-in instead of forced. Bonus: apps that don't need sharing no longer pull share_plus's transitive dependency chain at all.

Is sharing gone? No — it's opt-in. FileSaverInterface is unchanged; only the default implementation changed.

How to mitigate (restore the share sheet):

  1. Add share_plus to your app's pubspec:
    dependencies:
      share_plus: ^12.0.1
    
  2. Provide a custom saver (full working copy in example/lib/sharing_file_saver.dart):
    class SharingFileSaver implements FileSaverInterface {
      const SharingFileSaver();
      static const DefaultFileSaver _default = DefaultFileSaver();
    
      @override
      Future<void> shareFile({required String filepath, String? subject, String? text}) =>
          SharePlus.instance.share(ShareParams(files: [XFile(filepath)], subject: subject, text: text));
    
      @override
      Future<void> shareText(String text, {String? subject}) =>
          SharePlus.instance.share(ShareParams(text: text, subject: subject));
    
      @override
      Future<void> saveAndShareHttpLog(HttpLogData logData) async {
        final path = await _default.saveHttpLogToZip(logData);
        if (path != null) await shareFile(filepath: path, subject: 'HTTP Log');
      }
    
      // saveToFile / saveHttpLogToZip / getBytes: delegate to _default
      // ... (see example/lib/sharing_file_saver.dart)
    }
    
  3. Pass it to the logger:
    AdvancedDioLogger(
      settings: AdvancedDioLoggerSettings(
        fileSaver: const SharingFileSaver(),
      ),
    );
    

If you do nothing, all file exports still work — you just get "saved to" instead of a share sheet. To disable file operations entirely, set fileSaver: null.

Screenshots #

Log List #

Cards show method, endpoint, status, response time, and a small response preview — including inline image thumbnails when the response is an image.

JSON response Image response
Log list Log list with image

Detail View #

Tapping a card opens a tabbed detail screen.

Overview Request
Overview tab Request tab

Response tab — rendered differently depending on content type:

JSON HTML Image
JSON response HTML response Image response

Features #

Core Features #

  • cURL Command Generation - Copy requests as cURL with option to hide sensitive data
  • JSON Viewer - Basic JSON viewer with search and syntax highlighting (current implementation has known limitations — a migration to a more robust JSON viewer library is planned)
  • Smart Truncation - Automatically truncate large payloads while preserving full data for detail view
  • Multi-format Response Support - JSON, HTML, Image, and plain text handling

Security Features #

  • Hidden Headers - Automatically hide sensitive headers like Authorization, API keys
  • Safe cURL Export - Export cURL commands with hidden auth tokens
  • Bearer Token Masking - Show Bearer ***** instead of actual token

Content Type Handling #

  • JSON - Basic viewer with search and syntax highlighting (migration to a more robust viewer planned)
  • Images - Inline preview for small images, tap to view for large images
  • HTML - Preview with option to view full rendered content
  • Text - Plain text display with full content support

Export & Download #

  • Download as ZIP - Export request/response as a ZIP file (iOS/Android/Web compatible)
  • Export - Save logs as a ZIP locally; plug in system sharing via a custom FileSaverInterface
  • Copy - Copy individual sections or full cURL command
  • Pluggable File Saver - Customize or disable file saving behavior

Detail View Features #

  • Tabbed Interface - Overview, Request, Response, and cURL tabs
  • Search in JSON - Find specific keys or values with highlighting (may have edge-case issues; viewer migration planned)
  • Full Headers View - See all request and response headers
  • Response Time - Track request duration

Installation #

Add to your pubspec.yaml:

dependencies:
  talker_dio_logger_plus: ^1.0.6

Requirements #

This package depends on the following packages. They are declared as direct dependencies and will be installed automatically, but your project must meet the minimum version constraints listed below:

Package Version Purpose
dio ^5.4.0 HTTP client — the interceptor hooks into Dio's request/response pipeline
talker >=4.5.0 Core logging sink — all HTTP events are sent to a Talker instance
talker_flutter >=4.5.0 Flutter UI components (TalkerScreen, TalkerScreenTheme) used by HttpLogCard
flutter_inappwebview ^6.1.5 In-app WebView for rendering full-screen HTML responses
path_provider ^2.1.0 Resolves the temporary/documents directory used by DefaultFileSaver
archive ^4.0.2 ZIP creation used by DefaultFileSaver.saveHttpLogToZip
mime >=1.0.4 < 3.0.0 MIME-type lookup used alongside http_parser

Note: path_provider and archive are only exercised by DefaultFileSaver. If you supply a custom FileSaverInterface implementation or set fileSaver: null, those packages are still linked but their code paths are never reached at runtime.

No system share sheet: following upstream talker#505, this package does not depend on share_plus — export means saving locally (ZIP under <app documents>/talker_logs/). This avoids the Flutter Kotlin Gradle Plugin warning that share_plus's Android plugin triggers. Need OS sharing? Implement FileSaverInterface (e.g. wrapping share_plus) and pass it via AdvancedDioLoggerSettings.fileSaver.

Dart & Flutter SDK #

SDK Minimum version
Dart SDK >=3.7.0
Flutter SDK >=3.29.0

Quick Start #

import 'package:dio/dio.dart';
import 'package:talker_flutter/talker_flutter.dart';
import 'package:talker_dio_logger_plus/talker_dio_logger_plus.dart';

void main() {
  final talker = Talker();
  
  final logger = AdvancedDioLogger(
    talker: talker,
    settings: const AdvancedDioLoggerSettings(
      printRequestData: true,
      printResponseData: true,
      printResponseTime: true,
      hiddenHeaders: {'authorization', 'x-api-key'},
      hideAuthorizationValue: true,
    ),
  );
  
  final dio = Dio();
  dio.interceptors.add(logger);
}

Configuration #

AdvancedDioLoggerSettings #

AdvancedDioLoggerSettings(
  // Enable/Disable
  enabled: true,
  logLevel: LogLevel.debug,
  
  // Print settings
  printRequestData: true,
  printRequestHeaders: true,
  printRequestExtra: false,
  printResponseData: true,
  printResponseHeaders: true,
  printResponseMessage: true,
  printResponseTime: true,
  printErrorData: true,
  printErrorHeaders: true,
  printErrorMessage: true,
  
  // Security
  hiddenHeaders: {'authorization', 'x-api-key', 'api-key'},
  hideAuthorizationValue: true,
  
  // Per-content-type display limits (replaces flat truncation thresholds)
  // enablePreview controls whether the UI card/detail screen renders a visual
  // preview widget for that content type. It has NO effect on console output —
  // use printResponseData / printRequestData to suppress console output instead.
  cardDisplayLimit: DisplayLimitRegistry(
    overrides: {
      HttpBodyType.json: DisplayLimit(maxBytes: 500 * 1024, maxLines: 20),
      HttpBodyType.image: DisplayLimit(maxBytes: 5 * 1024),
      HttpBodyType.html: DisplayLimit(enablePreview: false), // hide HTML preview in UI
    },
  ),
  
  // Feature flags
  enableCurlGeneration: true,
  
  // JSON viewer soft wrap width (null = no wrap, horizontal scroll)
  jsonSoftWrapTextValueAtWidth: null,
  
  // Custom file saver (set to null to disable download/share)
  fileSaver: const DefaultFileSaver(), // or null, or your custom implementation
  
  // Filters
  requestFilter: (options) => true,
  responseFilter: (response) => true,
  errorFilter: (exception) => true,
)

Using with TalkerScreen #

To use the custom HTTP log cards in TalkerScreen:

TalkerScreen(
  talker: talker,
  itemsBuilder: (context, data) {
    if (isAdvancedHttpLog(data)) {
      return HttpLogCard(
        data: data,
        expanded: true,
      );
    }
    // Return default card for other log types
    return TalkerDataCard(
      data: data,
      color: data.getFlutterColor(theme),
      backgroundColor: theme.cardColor,
    );
  },
)

Theme Support #

TalkerThemeProvider #

The package uses TalkerThemeProvider (an InheritedWidget) to provide consistent theming across all screens without prop drilling. When you navigate to detail screens, the theme is automatically available to all child widgets.

The HttpLogCard automatically wraps navigation with TalkerThemeProvider, so child screens like FullScreenImageViewer and FullScreenHtmlPreview can access the theme via:

final theme = TalkerThemeProvider.of(context);

Custom Theme #

You can customize the theme by passing a TalkerScreenTheme to HttpLogCard:

HttpLogCard(
  data: data,
  expanded: true,
  theme: TalkerScreenTheme(
    backgroundColor: Colors.black,
    cardColor: Color(0xFF1E1E1E),
    textColor: Colors.white,
    // ... other theme properties
  ),
)

Custom File Saver #

The package provides a pluggable file saving system through FileSaverInterface. This allows you to:

  • Use the default implementation (DefaultFileSaver)
  • Disable file operations (set fileSaver: null)
  • Provide your own custom implementation

Default Behavior #

By default, the package uses DefaultFileSaver which requires path_provider and archive packages. It saves files locally only — no system share sheet (see Breaking changes in 1.1.0 for the reason and the mitigation). To share via the OS share sheet, provide a custom FileSaverInterface that wraps share_plus — a complete working implementation ships in example/lib/sharing_file_saver.dart.

DefaultFileSaver is exported from the package barrel, so custom savers can delegate file-saving to it and only override the share methods.

Disable File Saving #

If you don't need file saving/sharing functionality:

final logger = AdvancedDioLogger(
  settings: AdvancedDioLoggerSettings(
    fileSaver: null,
  ),
);

Custom Implementation #

Create your own file saver by implementing FileSaverInterface:

class MyCustomFileSaver implements FileSaverInterface {
  @override
  Future<String?> saveToFile({
    required String filename,
    required dynamic data,
    String? directory,
  }) async {
    // Your custom save logic
  }

  @override
  Future<String?> saveHttpLogToZip(HttpLogData logData, {String? filename}) async {
    // Your custom ZIP creation logic
  }

  @override
  Future<void> shareFile({required String filepath, String? subject, String? text}) async {
    // Your custom share logic
  }

  @override
  Future<void> shareText(String text, {String? subject}) async {
    // Your custom text share logic
  }

  @override
  Future<void> saveAndShareHttpLog(HttpLogData logData) async {
    // Your custom save and share logic
  }

  @override
  Uint8List? getBytes(dynamic data) {
    // Convert data to bytes
  }
}

// Use it
final logger = AdvancedDioLogger(
  settings: AdvancedDioLoggerSettings(
    fileSaver: MyCustomFileSaver(),
  ),
);

Content Type Detection #

The logger automatically detects content types:

  • JSON: application/json, text/json
  • HTML: text/html, application/xhtml+xml
  • Images: image/jpeg, image/png, image/gif, etc.
  • XML: text/xml, application/xml
  • Text: text/plain

Size Handling #

Display limits are configured per content type via DisplayLimitRegistry. Defaults:

Content Type maxBytes maxLines enablePreview Behavior
JSON 1 MB 20 true Truncated in card, full in detail view
Text / XML 1 MB 20 true Truncated in card, full in detail view
HTML 1 MB 20 true WebView preview, tap for full screen
Image 5 KB 20 true Inline preview if ≤ 5 KB, placeholder if larger
Unknown 1 MB 20 true Binary sentinel string

enablePreview controls whether the UI card and detail screen render a visual preview widget for that content type. When false, a "preview disabled" notice is shown instead. It has no effect on console/text log output — use printResponseData / printRequestData to suppress console output.

Override defaults via cardDisplayLimit in AdvancedDioLoggerSettings.

Platform Support #

Feature iOS Android Web
cURL Generation ✅ ✅ ✅
JSON Viewer ✅ ✅ ✅
Image Preview ✅ ✅ ✅
Download ZIP ✅ ✅ ⚠️*
Export (local save) ✅ ✅ ⚠️*
System Share via custom FileSaverInterface via custom FileSaverInterface via custom FileSaverInterface

*Web has limited file system access

Development #

This repo ships a git pre-commit hook that runs flutter analyze (package + example) and the full test suite before every commit:

# One-time install after cloning:
git config core.hooksPath .githooks
Escape hatch Effect
git commit --no-verify Skip all pre-commit checks
PRE_HOOK_SKIP_TESTS=1 git commit Run analyze only, skip tests

License #

MIT License

5
likes
150
points
622
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Advanced and feature-rich Dio HTTP client logger with cURL export, JSON viewer, detail views, image support, and more

Repository (GitHub)
View/report issues

Topics

#dio #talker #logging

License

MIT (license)

Dependencies

archive, dio, flutter, flutter_inappwebview, mime, path_provider, talker, talker_flutter

More

Packages that depend on talker_dio_logger_plus