Flutter Dio Logger: Simplifying HTTP Request & Response Logging | Custom Log
Explore a comprehensive log utility class for Flutter using the Dio HTTP client.
Learn how to efficiently log HTTP requests, responses, and errors with different log levels and color-coded messages, making debugging and error handling a breeze in your Flutter app development
util / logger_interceptor.dart
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
// Author: Hari Shankar
// Date: 28-07-2023
/*
No 3rd party plugin
Purpose: Flutter Dio Logger: Simplifying HTTP Request & Response Logging.
*/
// Define an enum for the different log levels
enum Level { debug, info, warning, error, alien }
// Define a logDebug function that logs messages at the specified level
// log different colors
void logDebug(String message, {Level level = Level.info}) {
// Define ANSI escape codes for different colors
const String resetColor = '\x1B[0m';
const String redColor = '\x1B[31m'; // Red
const String greenColor = '\x1B[32m'; // Green
const String yellowColor = '\x1B[33m'; // Yellow
const String cyanColor = '\x1B[36m'; // Cyan
// Get the current time in hours, minutes, and seconds
final now = DateTime.now();
final timeString =
'${now.hour.toString().padLeft(2, '0')}:${now.minute.toString().padLeft(2, '0')}:${now.second.toString().padLeft(2, '0')}';
// Only log messages if the app is running in debug mode
if (kDebugMode) {
try {
String logMessage;
switch (level) {
case Level.debug:
logMessage = '$cyanColor[DEBUG][$timeString] $message$resetColor';
break;
case Level.info:
logMessage = '$greenColor[INFO][$timeString] $message$resetColor';
break;
case Level.warning:
logMessage = '$yellowColor[WARNING][$timeString] $message $resetColor';
break;
case Level.error:
logMessage = '$redColor[ERROR][$timeString] $message $resetColor';
break;
case Level.alien:
logMessage = '$redColor[ALIEN][$timeString] $message $resetColor';
break;
}
//print(logMessage);
// Use the DebugPrintCallback to ensure long strings are not truncated
debugPrint(logMessage);
} catch (e) {
print(e.toString());
}
}
}
// Define an interceptor that logs the requests and responses
class LoggerInterceptor extends Interceptor {
@override
void onError(DioException err, ErrorInterceptorHandler handler) {
final options = err.requestOptions;
final requestPath = '${options.baseUrl}${options.path}';
// Log the error request and error message
logDebug('onError: ${options.method} request => $requestPath',
level: Level.error);
logDebug('onError: ${err.error}, Message: ${err.message}',
level: Level.debug);
// Call the super class to continue handling the error
return super.onError(err, handler);
}
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
final requestPath = '${options.baseUrl}${options.path}';
// Log request details
logDebug(
'\n\n\n\n.........................................................................');
logDebug('onRequest: ${options.method} request => $requestPath',
level: Level.info);
logDebug('onRequest: Request Headers => ${options.headers}',
level: Level.info);
logDebug('onRequest: Request Data => ${_prettyJsonEncode(options.data)}',
level: Level.info); // Log formatted request data
// Call the super class to continue handling the request
return super.onRequest(options, handler);
}
@override
void onResponse(Response response, ResponseInterceptorHandler handler) {
// Log the response status code and data
logDebug(
'onResponse: StatusCode: ${response.statusCode}, Data: ${_prettyJsonEncode(response.data)}',
level: Level.debug); // Log formatted response data
logDebug(
'.........................................................................\n\n\n\n');
// Call the super class to continue handling the response
return super.onResponse(response, handler);
}
// Helper method to convert data to pretty JSON format
String _prettyJsonEncode(dynamic data) {
try {
const encoder = JsonEncoder.withIndent(' ');
final jsonString = encoder.convert(data);
return jsonString;
} catch (e) {
return data.toString();
}
}
}
..
data/services/api_service.dart
ApiService class in Flutter with Dio HTTP client for making HTTP requests.
Discover how to perform HTTP operations, including logging request details and response data with a custom logger interceptor.
// data/services/api_service.dart
import 'package:dio/dio.dart';
import '../../utils/logger_interceptor.dart';
class ApiService {
late Dio _dio; // Dio instance to perform HTTP requests.
// ApiService({required Dio dio}) : _dio = dio;
ApiService({required Dio dio}) {
_dio = Dio(BaseOptions(
baseUrl: "https://dummyjson.com/products/",
// connectTimeout: const Duration(seconds:5),
// receiveTimeout: const Duration(seconds: 3),
responseType: ResponseType.json,
))..interceptors.addAll([
LoggerInterceptor(), //
custom logger interceptor.
]);
}
}
..
..
To use the custom log utility in your Flutter app
import 'package:flutter/material.dart';
import 'logger_util.dart';
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
logDebug('this is debug'); // level is optional
logDebug('this is debug', level: LogLevel.debug);
logDebug('this is info', level: LogLevel.info);
logDebug('this is warning', level: LogLevel.warning);
logDebug('this is error', level: LogLevel.error);
logDebug('this is alien', level: LogLevel.alien);
return MaterialApp(
title: 'User List', // Meta Title for the App
theme: ThemeData(
primarySwatch: Colors.green,
),
home: const ProductList(),
);
}
}
..
..
Comments
Post a Comment