Why Choose api_network_logger?
The api_network_logger Flutter package gives you a ready‑made, production‑grade logger for every network call your app makes. It removes the need to write custom interceptors, file writers, or SQLite helpers just to keep a trace of API traffic. If you need quick visibility into request URLs, headers, payloads, and response status while still keeping the logger behind a clear architectural boundary, this package is a solid fit.
Installation
Add the dependency with the Flutter CLI:
flutter pub add api_network_loggerAfter the command finishes, run flutter pub get to fetch the package.
Basic Setup
Initialize the logger before your UI starts. The typical place is at the top of main() after ensuring the Flutter bindings are ready.
import 'package:flutter/material.dart';
import 'package:api_network_logger/api_network_logger.dart';
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
// The exact API may differ – verify the parameters on pub.dev.
await ApiNetworkLogger.initialize(
storagePath: 'api_logs', // Directory where logs are stored
maxFileSizeInBytes: 5 * 1024 * 1024, // Rotate after 5 MiB
enableOfflineQueue: true, // Optional: store failed calls
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'FlutterFever Demo',
home: const HomePage(),
);
}
}Creating a Network Service
Wrap your HTTP client in a service class so the logger stays isolated from UI code. Below is a minimal example using the popular http package.
import 'package:http/http.dart' as http;
import 'package:api_network_logger/api_network_logger.dart';
class ApiService {
final http.Client _client;
final ApiNetworkLogger _logger = ApiNetworkLogger.instance;
ApiService({http.Client? client}) : _client = client ?? http.Client();
Future fetchPosts() async {
final uri = Uri.parse('https://jsonplaceholder.typicode.com/posts');
// Log the outgoing request
_logger.logRequest(
uri: uri,
method: 'GET',
headers: {},
);
final response = await _client.get(uri);
// Log the incoming response
_logger.logResponse(
uri: uri,
statusCode: response.statusCode,
body: response.body,
);
return response;
}
}Using the Service in a Widget
Keep UI code clean by calling the service from a stateful widget or a provider.
import 'package:flutter/material.dart';
import 'api_service.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final ApiService _api = ApiService();
String _output = '';
Future _loadPosts() async {
final response = await _api.fetchPosts();
setState(() {
_output = response.body;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Api Network Logger Demo')),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ElevatedButton(
onPressed: _loadPosts,
child: const Text('Fetch Posts'),
),
const SizedBox(height: 20),
Expanded(
child: SingleChildScrollView(
child: Text(_output),
),
),
],
),
),
);
}
}Advanced Usage
The package also supports logging navigation routes and offline event queues. While the exact APIs may evolve, the general pattern is:
- Call
logRouteChange(String routeName)from yourNavigatorObserver. - Enable the offline queue during initialization to automatically store failed requests and replay them when connectivity returns.
Tip: Keep the logger behind an abstraction (e.g.,
ILogger) so you can swap it out or mock it in unit tests without pulling the package into your domain layer.
Common Pitfalls & How to Avoid Them
- Missing initialization: Forgetting to call
ApiNetworkLogger.initializewill cause runtime null‑pointer errors. Always initialize inmain()before.runApp() - Logging sensitive data: By default the logger records full request bodies. Filter or mask authentication tokens before calling
logRequestif you need to comply with privacy regulations. - Unbounded file growth: Without a
maxFileSizeInBytesor rotation strategy, log files can grow indefinitely on the device. Configure a sensible limit and consider a daily rotation policy. - Version incompatibility: The package may change its API across releases. Pin a version in
pubspec.yamland review the changelog before upgrading.
Best Practices for Production Apps
- Wrap all logger calls in a dedicated service class.
- Provide a compile‑time flag (e.g.,
bool kDebugMode = !kReleaseMode;) to disable verbose logging in release builds. - Store logs in a location that respects platform guidelines (e.g.,
getApplicationDocumentsDirectory()on iOS/Android). - Expose a simple UI for developers to view or export logs during QA.
When to Consider an Alternative
If your app already uses a full‑featured HTTP client like dio with interceptors, you might prefer integrating logging directly into that stack. The api_network_logger shines when you need a lightweight, package‑only solution without pulling in a larger dependency graph.
Frequently Asked Questions
Do I need to add any platform-specific permissions to use api_network_logger?
The package writes logs to the app's internal storage, which does not require extra permissions on iOS or Android. If you configure the logger to write to external storage on Android, you will need the appropriate storage permission.
Can api_network_logger be used with Dio or other HTTP clients?
Yes. The package provides generic <code>logRequest</code> and <code>logResponse</code> methods that you can call from any HTTP client, including Dio interceptors. Just make sure to forward the relevant data (URL, method, headers, body, status code) to the logger.
How do I prevent sensitive data like auth tokens from being logged?
Filter or mask sensitive fields before calling <code>logRequest</code>. For example, create a helper that removes the <code>Authorization</code> header or replaces password fields with asterisks, then pass the sanitized map to the logger.
Is there a way to export logs for debugging on a remote server?
The package stores logs as files on the device. You can read those files using standard Dart I/O APIs and upload them via your own endpoint. Check the package README for the exact file location and format.
Will the logger impact app performance?
Logging introduces minimal overhead because it writes asynchronously to disk. However, avoid logging large binary payloads in production and configure a reasonable <code>maxFileSizeInBytes</code> to keep I/O bounded.