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