Logger представляет собой компоненту для организации вывода сообщений в log файл и организации вызова пользовательских функций по событиям.
Этот документ представляет собой неформальное описание, полная спецификация
пакета приводится в API reference (www.gradsoft.kiev.ua/common/ToolBox/Logger/API/index.html).
Процесс работы пользовательского приложения с Logger выглядит следующим образом:
logger.errors() << "This is error:" << 334 << endl;
После выполнения этой строки в log файл будет записана строка "This is error:334" и если была установленна callback функция для ошибок, то она будет вызванна с аргументом "This is error:334"
Возможно отключать (или включать) запись в потоки вывода во время компиляции, определяя соответствующие препроцессорные символы в true или false:
LOG_DEBUG_ENABLE - включить вывод в поток отладки.
Когда LOG_DEBUG_ENABLE установленно в true,
выражение logger.debugs() << msg << endl; выполняется так,
как было описанно выше. В противном случае это выражение на
этапе компиляции редуцируется в предложение, не выполняющее никаких
операций. По умолчанию этот символ установлен в false.
LOG_INFO_ENABLE - включить вывод в информационный поток.
По умолчанию этот символ установлен в true.
LOG_WARNING_ENABLE - включить вывод в поток предупреждений.
По умолчанию этот символ установлен в true.
LOG_ERROR_ENABLE - включить вывод в поток ошибок.
По умолчанию этот символ установлен в true.
LOG_FATAL_ENABLE - включить вывод в поток критических ошибок.
По умолчанию этот символ установлен в true.
Также, во время выполнения можно установить следующие свойства Logger:
void Logger::setOutputFile(const char* fname) throw(Logger::IOException)Этот метод генерирует прерывание
IOException в случае неудачи.
IOException.what() возвращает в строке сообщение об ошибке.
void Logger::setDuppedToStderr(bool x)
void Logger::setSysLogOutput(bool x)Этот метод устанавливает флаг генерирования
SysLog сообщений.
По умолчанию, Logger записывает сообщение в системный журнал (для UNIX).
setSysLogOutput(false) отключает это свойство,
setSysLogOutput(true) - включает.
Заметим, что в Windows NT эта опция не имеет никакого эффекта.
#define LOG_DEBUG_ENABLE true
#include <GradSoft/Logger.h>
void debug_callback(const char* msg)
{
cerr << "debug_callback:" << msg << endl;
}
int main(int argc, char** argv)
{
try {
GradSoft::Logger logger("file.log");
logger.setCallback(GradSoft::Debug,debug_callback);
logger.debugs() << "debug output 1 for " << argv[0] << endl;
}catch(Logger::IOException){
cerr << "can't open log file" << endl;
return 1;
}
return 0;
}
Вы можете использовать Logger в мультипоточных программах:
вызов всех методов Logger безопасен; При обращении к
потокам вывода Logger существует потенциальноая опасность
интерференции сообщений, поступающих из разных потоков.
Для предотвращения этого мы резервируем для каждого типа сообщений
соответствующий mutex и определяем класс - блокировщик доступа
к этому mutex-у, который блокирует его при создании и разблокирует
при удаленнии.
Соответствующий фрагмент кода приведен ниже:
{
Logger::DebugLocker guard(logger.debugs());
logger.debugs() << "print " << what << " you want";
}
Теперь повторим то-же самое более формально с указанием схемы наименования:
Для каждого типа событий <Xxx>EventType определен класс
Loggex::<Xxx>Locker у которого определенны следующие методы:
XxxLocker(XxxStream&) - конструктор,
принимает во владение
mutex, блокирующий операторы вывода в соответствующий поток,
~XxxLocker() - освобождает его.
LoggerConfig.h, генерируемом при компиляции пакета (для UNIX),
и LoggerConfigNT.h для NT.
Потенциально возможен конфликт между определениями в этом файле
и определениями из других макропакетов. Для того, что-бы этого не
произошло мы рекомендуем заключать ваши макроопределения autoconf в
предложения условной компиляции:
#ifndef HAVE_Xxx #undef HAVE_Xxx #endif
GradSoft/Logger больше не используется.