trackly_inspector 0.1.0
trackly_inspector: ^0.1.0 copied to clipboard
An in-app network and log inspector for Flutter. See every Dio and http call with headers and bodies, search them, and copy as cURL.
trackly_inspector #
An in-app network and log inspector for Flutter, like the Network tab of your
browser's DevTools, inside your app. See every Dio and http call with its
headers and bodies, search them, and copy any request as a cURL command.
Features #
- Every request: method, URL, status, duration, size, headers, and body, for requests that are in progress, succeeded, or failed (timeouts, no connection).
- Search and filters: search URLs, status codes, and bodies. Filter by status (2xx, 4xx, 5xx, failed, pending) and method.
- Copy as cURL, or copy the URL, either body, or a full report.
- JSON viewer: a collapsible tree like Chrome's Preview tab, and a raw view with syntax colors and search highlighting.
- Logs tab: logs from trackly_logger next to your requests, with levels, tags, errors, and stack traces.
- Three ways to open it: a draggable floating button, a two-finger long press, or shaking the device. Or from code.
- Dio and
httpout of the box, and a small API for any other client. - Safe by default: off in release builds, can hide sensitive headers, and never blocks your app's gestures.
- Works in right-to-left apps; the inspector itself always reads left to right.
Getting started #
flutter pub add trackly_inspector
1. Add the inspector to your app through MaterialApp.builder:
import 'package:trackly_inspector/trackly_inspector.dart';
MaterialApp(
builder: (context, child) => TracklyInspector(child: child!),
home: const HomePage(),
);
2. Record requests from your HTTP client.
With Dio, add the interceptor last:
import 'package:trackly_inspector/dio.dart';
final dio = Dio()..interceptors.add(TracklyDioInterceptor());
With http, use TracklyHttpClient wherever
you use a Client:
import 'package:trackly_inspector/http.dart';
final client = TracklyHttpClient();
final response = await client.get(Uri.parse('https://example.com/users'));
// Or wrap a client you already have:
final retrying = TracklyHttpClient(inner: RetryClient(http.Client()));
3. Open the inspector by tapping the floating button, or holding two fingers on the screen. You can also open it from code, e.g. from a debug menu:
TracklyInspector.show();
Logs #
trackly_inspector includes
trackly_logger, so you can log
without adding another package, and your logs show up in the Logs tab:
import 'package:trackly_inspector/trackly_inspector.dart';
trackly.info('App started');
trackly.error('Payment failed', error: e, stackTrace: st);
class CartService with TracklyLoggerMixin {
void add(String id) => logger.debug('Added $id');
}
Configuration #
Choose how the inspector opens:
TracklyInspector(
triggers: const {
TracklyTrigger.bubble, // Draggable floating button.
TracklyTrigger.longPress, // Two fingers held on the screen.
TracklyTrigger.shake, // Shaking a real Android or iOS device.
},
child: child!,
)
Pass an empty set to open it only from code. By default, the bubble and the long press are on.
Tune what's recorded through the shared controller, e.g. in main():
TracklyInspector.controller
..maxCalls = 500 // Oldest calls are dropped first. Default: 300.
..maxBodyLength = 1024 * 1024 // Longer bodies are truncated. Default: 512K.
..redactedHeaders = {'authorization', 'cookie'}; // Shown as ••••••.
Redacted values are replaced when a call is recorded, so they are never kept in memory or included in copied cURL commands.
If the inspector can't find your app's navigator, for example with a custom
WidgetsApp, pass it in:
TracklyInspector(navigatorKey: navigatorKey, child: child!)
Release builds #
The inspector does nothing in release builds: no bubble, no gestures, and no
calls or logs are recorded. To use it in a release build, such as an internal
QA build, turn it on before runApp:
TracklyInspector.controller.enabled = true;
Other HTTP clients #
Record calls from any client, such as Chopper or GraphQL, with the controller:
final controller = TracklyInspector.controller;
final call = controller.startCall(
client: 'graphql',
method: 'POST',
uri: Uri.parse('https://api.example.com/graphql'),
headers: {'content-type': 'application/json'},
body: {'query': '{ me { id } }'},
);
// When the response arrives:
if (call != null) {
controller.completeCall(call, statusCode: 200, body: responseJson);
// Or, if it failed without a response:
controller.failCall(call, error);
}
Notes #
TracklyHttpClientreads each response fully so it can record the body. Server-sent event streams (text/event-stream) are passed through untouched.- Shaking uses the accelerometer, which simulators don't have. Use the bubble or the long press there.
License #
MIT. See LICENSE.