Tuesday, 30 April 2013

A generic logger class


Sharing the design of a generic logger class in C++ that can be instantiated by any class that need logging facility. IT supports various features like different verbosity level, dynamic configuration of logging and C++ style streaming operator control.




Here is the Source Code..
The Header File:

*/
/**
 * This is a Debug Log class used to log all the messages into a file from internal
 * module functions. The file name will be set by the configuration file
 * through a configuration parameter.
 */
class file_log_util_t
{
  
public:
    static const unsigned int LOWEST_VERBOSITY =0;
    static const unsigned int ERROR_VERBOSITY = 1;
    static const unsigned int WARNING_VERBOSITY = 2;
    static const unsigned int INFO_VERBOSITY = 3;
    static const unsigned int DEBUG_VERBOSITY =4;
    static const unsigned int HIGHEST_VERBOSITY = 5;

    public:
        //! Default Constructor
        file_log_util_t();

        //! constructor
        file_log_util_t(const char *file_name, const char* name);


        /**
         * @brief The Constructor of the file_log_util_t class
         * @param Takes a file name as a parameter
         */
        file_log_util_t(const char *file_name);

         /**
         * @brief The Constructor of the file_log_util_t class
         * @param Takes a file name as a parameter
         */
        file_log_util_t(std::ostream &opstream);

         /**
         * @brief The Constructor of the file_log_util_t class
         * @param Takes a file name as a parameter
         */
        file_log_util_t(std::ostream &opstream,const char* name);

        /**
         * @brief This function returns the file stream where we can log
         * the NOTE messages
         * @param none
         * @return reference to ofstream
         */
        std::ostream& info();

        /**
         * @brief This function returns the file stream where we can log
         * the WARNING messages
         * @param none
         * @return reference to ofstream
         */
        std::ostream& warn();

        /**
         * @brief This function returns the file stream where we can log
         * the ERROR messages
         * @param none
         * @return reference to ofstream
         */
        std::ostream& error();

         /**
         * @brief This function returns the file stream where we can log
         * the DEBUG messages
         * @param none
         * @return reference to ofstream
         */
        std::ostream& debug();


        /**
         * @brief The destructor of file_log_util_t logger class
         * This destructor is used to close the file stream
         */
        ~file_log_util_t();

        /**
         * @brief Function to set the container class name
         */
        void set_parent_name( const char *name );

        /**
         * @brief Function to set the verbosity level. Return the old verbosity level
         */
        unsigned int set_verbosity_level( unsigned int level );

        /**
         * @brief Function to return the stream to write
         */
        std::ostream& get_ostream();

        /**
         * @brief Function to change the file stream. It return the existing file stream.
         */
        std::ostream* set_stream(std::ostream* stream);

        /**
         * @brief Function to get the verbosity level
         */
        unsigned int get_verbosity();

    private:

        //! File stream used to store the log message
        std::ostream *m_opstream;
       
        //My local file stream
        std::ofstream myFile;

        /**
         * Null file stream same as /dev/null in Unix. If no file is
         * specified then the log message will go to some null stream
         */
        std::ofstream null_file;

        //! name of the containing class module
        std::string m_name;

        unsigned int m_verbosity;
        void init(const char *name,std::ostream *opstream);
};


The Source File:
#include "file_log_util.h"
using namespace std;
using namespace ti_infra;
//! Default constructor
file_log_util_t::file_log_util_t()
{
    init("",&null_file);
}

/**
 * @brief The Constructor of the file_log_util_t class
 * @param Takes a file name as a parameter
 */
file_log_util_t::file_log_util_t(const char *file_name)
{
    myFile.open(file_name,ios::out | ios::binary);
    init("",&myFile);
}

/**
 * @brief The Constructor of the file_log_util_t class
 * @param Takes a file name as a parameter
 * @param Takes the container class name as second parameter
 */
file_log_util_t::file_log_util_t(const char *file_name, const char* name)
{
    myFile.open(file_name,ios::out | ios::binary);
    init(name,&myFile);
}

 /**
 * @brief The Constructor of the file_log_util_t class
 * @param Takes a file name as a parameter
 */
file_log_util_t::file_log_util_t( std::ostream &opstream)
{
    init("",&opstream);
}

 /**
 * @brief The Constructor of the file_log_util_t class
 * @param Takes a file name as a parameter
 */
file_log_util_t::file_log_util_t( std::ostream &opstream, const char* name)
{
    init(name,&opstream);
}

void file_log_util_t::init(const char *name,std::ostream *opstream)
{
    m_opstream  = opstream;
    m_verbosity = ERROR_VERBOSITY;

}

/**
 * @brief This function returns the file stream where we can log
 * the NOTE messages
 * @param none
 * @return reference to ofstream
 */
ostream& file_log_util_t::info()
{
    if ( m_verbosity>=INFO_VERBOSITY)
    {
        (*m_opstream)<< "[INFO]:" << m_name << ":";
        (*m_opstream).flush();
        return (*m_opstream);
    }
    return null_file;
}

/**
 * @brief This function returns the file stream where we can log
 * the WARNING messages
 * @param none
 * @return reference to ofstream
 */
ostream& file_log_util_t::warn()
{
    if ( m_verbosity>=WARNING_VERBOSITY)
    {
        (*m_opstream)<< "[WARN]:" <<m_name<<":";
        (*m_opstream).flush();
        return (*m_opstream);
    }
    return null_file;
}

/**
 * @brief This function returns the file stream where we can log
 * the ERROR messages
 * @param none
 * @return reference to ofstream
 */
ostream& file_log_util_t::error()
{
    if (m_verbosity>=ERROR_VERBOSITY)
    {
        (*m_opstream) << "[ERROR]:" << m_name << ":";
        (*m_opstream).flush();
        return (*m_opstream);
    }
    return null_file;
}

/**
 * @brief This function returns the file stream where we can log
 * the ERROR messages
 * @param none
 * @return reference to ofstream
 */
ostream& file_log_util_t::debug()
{
    if (m_verbosity>=DEBUG_VERBOSITY)
    {
        //(*m_opstream) << "[DBG]:" << m_name << ":";
         (*m_opstream) << "[DBG]:";
        (*m_opstream).flush();
        return (*m_opstream);
    }
    return null_file;
}


/**
 * @brief The destructor of file_log_util_t logger class
 * This destructor is used to close the file stream
 */
file_log_util_t::~file_log_util_t()
{
    myFile.close();
    null_file.close();
}

/**
 * @brief Function to set the container class name
 */
void file_log_util_t::set_parent_name( const char *name )
{
    m_name = name;
}

unsigned int file_log_util_t::set_verbosity_level( unsigned int level )
{
    unsigned int oldlevel = m_verbosity;
    if(m_verbosity>HIGHEST_VERBOSITY || m_verbosity<LOWEST_VERBOSITY)
    {
        this->error()<<"Setting Invalid verbosity level:"<<level<<" Ignored.";
        return oldlevel;
    }
    m_verbosity = level;
    return oldlevel;
}
unsigned int file_log_util_t::get_verbosity()
{
return m_verbosity;
}

std::ostream& file_log_util_t::get_ostream()
{
    return (*m_opstream);
}

std::ostream* file_log_util_t::set_stream(std::ostream* stream)
{
    std::ostream  *temp = m_opstream;
    m_opstream          = stream;
    return temp;
}


Sample Usage:
//Instantiate the class instance using any of the constructor
EG
file_log_util_t logger("log_file_name");

//To Log a error use:
logger.error()<<"Logging an Error"<<endl;
//Similarly for logging Warning
logger.warn()<<"Logging a Warning"<<endl;



No comments:

Post a Comment