Search code examples
c++error-logging

Get name of calling function, line number and file name in c++


I have wrote following code to write logs in my log file. This code is working fine for logging messages but now i have to integrate this in multiple files i need file path of caller, caller function name and line number.

Kindly help me to achieve this .

#include "Source.h"

bool CLogManager::fileOpenError = false;
std::string CLogManager::logFileName = "";
CLogManager* CLogManager::logManager = NULL;
FILE* CLogManager::file = NULL;

CLogManager :: CLogManager(){}
CLogManager :: ~CLogManager()
{
    if (file)
        fclose(file);
}
CLogManager* CLogManager::getInstance()
{
    if(logManager==NULL)
    {
        logManager = new CLogManager();
        logFileName = currentDateTime();
    }
    return logManager;
}
const std::string CLogManager::currentDateTime()
{
    time_t now = time(0);
    char currTime[30];
    strftime(currTime, sizeof(currTime), "Log_%Y_%m_%dT%H_%M_%S.xml", localtime(&now));
    return currTime;
}
void CLogManager::Log (char *message)
{
    file = fopen(logFileName.c_str(), "a+");
    if(file == NULL) 
    {
        if(fileOpenError == false)
        {
            std::cout << "There was an error While opening Log File."<<std::endl;
            fileOpenError = true;
        }
        return;
    }
    fputs(message, file);
    fputs("\n", file);
}

int main ()
{
    CLogManager::getInstance();
    CLogManager::Log("Sorry some error occured");
    CLogManager::Log("Please try again");
    CLogManager::Log("Wait");
    return 0;
}

Solution

  • When I need a fast "printf" logging, I use this marco for message logging that is branded with filename and line:

    #define _MSG(msg) do{ std::cerr << __FILE__ << "(@" << __LINE__ << "): " << msg << '\n'; } while( false )
    

    The above macro will inject a msg into a std::cerr pipeline. You can take out parts you need or modify it for your purposes. It hinges on __FILE__ and __LINE__ macros, which are defined by standard:

    __FILE__ The presumed name of the current source file (a character string literal).

    __LINE__ The presumed line number (within the current source file) of the current source line (an integer constant).

    Function names are not so easy to get, and I don't think there is a nice way to get it.

    If you want logging through functions I would define some macro, or make function that would take int and char* for line and file respectively. Something like log(int line, char* source_file, string message).