29 мар. 2012 г.

Простая система логирования на C++

    Система логирования - нужный и полезный инструмент для протоколирования работы любой программы. Она значительно экономит время, проведенное под отладкой и вылавливанием различных багов.
Существует много готовых библиотек (log4cplus, Apache log4cxx и тд.), однако в ряде случаев гораздо удобней и полезней иметь свою реализацию, которую можно в дальнейшем модифицировать под конкретную задачу.
И так, сначала определимся с требованиями к ней. Это удобство использования, эффективность применения, возможность расширения и дальнейших модификаций, типобезопасность и, по возможности, кросс платформеннсть. Также она будет поддерживать несколько уровней детализации сообщений (info, error, warning, debug ...). 
Для вывода форматированного текста мы воспользуемся функционалом  std::ostringstream, в нашем классе лога это переменная “m_oss”, которая будет накапливать в себе все сообщения. Функция член класса GetMsg() будет обеспечивать доступ к этой переменной.
Допустим мы хотим, чтобы сообщения могли выводиться как в консоль, так и в файл лога. Для этого заведем два класса: один будет отвечать за сбор сообщений, а второй, куда и как именно они будут выводиться.
Листинг шаблонного класса лога:
// уровни протоколирования
enum LogLevel_t { logError, logWarning, logInfo, logDebug,
                  logDebug1, logDebug2, logDebug3 };

template < typename T >
class Logger {
public:
    Logger( void );
    virtual ~Logger( void );

    std::ostringstream& GetMsg(LogLevel_t level = logInfo);
    // устанавливает уровень детализации
    static LogLevel_t& ReportingLevel( void );
 
    static const char* LevelToString(LogLevel_t level);
    static LogLevel_t LevelFromString(const char* ch_level);

protected:
    std::ostringstream m_oss;
private:
    Logger(const Logger&);
    Logger& operator = (const Logger&);
};