DEV Community

Cover image for Importance Of Using Log in Your Project
Imran Hossain (Rubab)
Imran Hossain (Rubab)

Posted on • Edited on

Importance Of Using Log in Your Project

As a developer you should write Log in your project. It plays a very important role in your project. Some developers don't know the importance so they don't write it or ignore writing proper logs in their projects.

I have seen the absence of writing logs in small/mid level projects from junior/mid level developers. Even some senior developers don't write it properly. This scenario is very common in single developer based projects or in a freelance based project or in startups. In this article I'm going to show you how to use it properly in your project.

But first, What is Log?
Log helps developers to track what is happening within your application. When a product goes to production server then we don't know what happened in between a user's request and response. So in order to investigate a failed scenario we need check the Log.

Some real life scenarios:

Case One:
When Log is not given: Payment is given for an order from an eCommerce website via payment gateway. Customer got a payment receipt generated from the gateway. Customer sees the transaction is not present after the successful payment. The eCommerce site does not have a log of the payment request so the request data can be found. Just assume how difficult it is to solve this issue. It will require investigating whether the actual customer paid or not, checking customer related data, customer’s concern of his/her payment, several cross check meetings from both companies involving developers, managers, operation team members and other stakeholders. If nothing can be found and the customer’s claim is valid then manually adding the data to a database where tables may have relations for the new payment data. Just think how much time will be wasted for solving the problem where a request and response log would just take a minute to write it.

Case 2:
When Detailed logs are not provided: Let’s say you have a shipping request. In this case you are a logistics Aggregator. An API request comes from a merchant website for shipping, you process the requested data which goes through some complex logic in your application through several scripts, and at one point it creates a new request data based on the provided request which is then sent over a third party logistic partner that actually takes the order. Based on the third party api's response the aggregator application returns a response to the merchant website. See how complex it is if you don’t log the merchant request, different logic states, log of formatted request and response data of the third party services. If something happens during a shipping order, it will be very hard to identify what went wrong to the request.

Commonly used Logs:

  • Info
  • Debug
  • Warning
  • Error
  • Alert

If you are using Laravel then you can use these Log function as below,

// Import the Log Class
use Illuminate\Support\Facades\Log;

Log::emergency($message);
Log::alert($message);
Log::critical($message);
Log::error($message);
Log::warning($message);
Log::notice($message);
Log::info($message);
Log::debug($message);

// Or Without importing the class
\Log::error($message);

//Example
Log::info('place order to partner.');
Log::debug("Processing Payment Payload- " . print_r($input, true));
Enter fullscreen mode Exit fullscreen mode

We can structure our Log data and reuse in any file of our project.
First create a class and then add add it under autoload as below,

"autoload": {
        .....
        "files": [
            "app/Helpers/CommonHelper.php"
        ]
        .....
}
Enter fullscreen mode Exit fullscreen mode

Here I have created a CommonHelper file and placed inside the app/Helpers directory.

Inside CommonHelper.php file.

/**
 * Generalize the debug log format.
 */
if (!function_exists('__formatDebugLog')) {
    /**
     * @param string $label
     * @param mixed $data
     * @param string $tag
     * @return string
     */
    function __formatDebugLog($label, $data = null, $tag = '')
    {
        $tag = empty($tag) ? '' : "{$tag} ";

        $data = is_string($data) ? $data : json_encode($data);

        return $tag . $label . ': ' . $data;
    }
}

/**
 * Generalize the log format for exception.
 */
if (!function_exists('__formatExceptionLog')) {
    /**
     * @param Throwable $e
     * @param $class
     * @param $fn
     * @param $tag
     * @return string
     */
    function __formatExceptionLog(Throwable $e, $class, $fn, $tag = '')
    {
        $tag = empty($tag) ? '' : "{$tag} ";
        return $tag . 'Found Exception: ' . $e->getMessage() . ' [Script: ' . $class . '@' . $fn . '] [Origin: ' . $e->getFile() . '-' . $e->getLine() . ']';
    }
}

// Generalize data log format 

if (!function_exists('__formatLogData')) {
    function __formatLogData($data)
    {
        if(is_object($data)){
            $data = (array) $data;
        }

        return $data;
    }
}
Enter fullscreen mode Exit fullscreen mode

Example of usage:

try{
    Log::error(__formatDebugLog("order placement failed to partner", $order));
} catch (\Throwable $e) {
    Log::error(__formatExceptionLog($e, __CLASS__, __FUNCTION__));
}
Enter fullscreen mode Exit fullscreen mode

Use tag for tacking log data.

$tag = isset($request->merchant_order_id) ? "MER_ORD_ID[{$request->merchant_order_id}]" : '';

try{
    Log::info("{$tag} Order => request data: " . json_encode(__formatLogData($this->all())));
    Log::debug("[{$tag}]: city list load failed");
} catch (\Throwable $e) {
    Log::error(__formatExceptionLog($e, __CLASS__, __FUNCTION__, $tag));
}
Enter fullscreen mode Exit fullscreen mode

Sample Log output:
Sample Log output

Be careful when adding a log data. We should not write sensitive data in the scenario when an attacker can steal our log data.

So, avoid logging sensitive data such as,

  • Credit card no (use masking if required), CVV of a card.
  • Any kind of user login credentials, Token, API Key, API secret etc.
  • Plain data of encrypted data.
  • Any sensitive information from config data.

Happy Coding!


Thank you for reading my article. You can join code with rubab for web development-related queries & discussions.

Also, you can find me on:

Linkedin For Regular Posts

My website

My Facebook Page

My Youtube Channel

Top comments (0)