Приложение с мультиклассовым примером для системы регистрации

Я новичок в работе с системой регистрации, но это очень полезно для ваших программ.

Подводя итог моей проблемы. Я использую библиотеку журналов log4cplus

Я делаю и легкий пример с двумя простыми классами и основной программой.

Это мой журнал ошибок:

  • log4cplus: ОШИБКА Не найдено ни одного добавочного файла для регистратора (основной).
  • log4cplus: ОШИБКА Пожалуйста, правильно инициализируйте систему log4cplus.
  • Ошибка сегментации: 11

Проблема в том, что я не знаю, как решить проблему с аппендером.

Это основной код моего примера.
Class1.h

#include <iostream>

#include <log4cplus/configurator.h>
#include <log4cplus/logger.h>

using namespace std;
// Use the log4cplus namespace
using namespace log4cplus;

class one
{
private:
// Create the logger
Logger logger;

public:
bool flag;
int valor;

one();
int multiplica(int a);
};

Class1.cpp

one::one()
{
logger.getInstance(LOG4CPLUS_TEXT("Clase One - constructor."));
}

int one::multiplica(int a)
{
int sol = 0;

sol = valor * a;

// Imprimo un mesaje en el log.
LOG4CPLUS_INFO(logger, "El resultado de la multiplicación es: xx");

return sol;
}

Class2.h

#include <iostream>

#include <log4cplus/configurator.h>
#include <log4cplus/logger.h>

using namespace std;
// Use the log4cplus namespace
using namespace log4cplus;

class two
{
private:
// Create the logger
Logger logger;

public:
bool flag;
int valor;

two();
int suma(int a);
};

Class.cpp

two::two()
{
logger.getInstance(LOG4CPLUS_TEXT("Clase Two - DEconstructor."));
}

int two::suma(int a)
{
int sol = 0;

sol = valor + a;

// Imprimo un mesaje en el log.
LOG4CPLUS_INFO(logger, "El resultado de la suma es: YY ");

return sol;
}

main.cpp

int main(int argc, char** argv)
{
// Load the properties
PropertyConfigurator::doConfigure("logClase.properties");
Logger logger = Logger::getInstance(LOG4CPLUS_TEXT("main"));

// Log with INFO level
if (logger.isEnabledFor(INFO_LOG_LEVEL))
{
LOG4CPLUS_INFO(logger, "Application startup");
}

one uno;
two dos;

uno.valor = dos.valor = 4;
uno.multiplica(7);
dos.suma(7);

// Log with INFO level
if (logger.isEnabledFor(INFO_LOG_LEVEL))
{
LOG4CPLUS_INFO(logger, "Application shutdown");
}

return 0;
}

Что я делаю не так ???
Это правильный способ работы с системой регистрации?

Я использую простой файл свойств, чтобы сохранить все сообщения журнала в файле.

Это мое logClase.properties файл для настройки de logger.

log4cplus.rootLogger=INFO, STDOUT, FILEAPPENDER
log4cplus.logger.main=INFO
log4cplus.logger.utils=FILEAPPENDER

log4cplus.appender.STDOUT=log4cplus::ConsoleAppender
log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout
log4cplus.appender.STDOUT.layout.ConversionPattern=%d{%m/%d/%y %H:%M:%S} [%t] %-5p %c{2} %%%x%% - %m [%l]%n

log4cplus.appender.FILEAPPENDER=log4cplus::RollingFileAppender
log4cplus.appender.FILEAPPENDER.File=KlasseEx.log
log4cplus.appender.FILEAPPENDER.MaxFileSize=5MB
#log4cplus.appender.FILEAPPENDER.MaxFileSize=500KB
log4cplus.appender.FILEAPPENDER.MaxBackupIndex=1
log4cplus.appender.FILEAPPENDER.layout=log4cplus::PatternLayout
log4cplus.appender.FILEAPPENDER.layout.ConversionPattern=%d{%m/%d/%y %H:%M:%S} [%t] %-5p %c{2} %%%x%% - %m [%l]%n

Я хочу использовать FILEAPPENDER и приложение Console, чтобы бросать сообщения в файл и в консоль. Я думаю, что это не должно быть так сложно сделать, это должно быть легко сделать.

1

Решение

См. Appenders в документации log4cplus. Вы, вероятно, пропустили какой-то шаг инициализации этого регистратора — я имею в виду, что вы не добавили appenders.

Увидеть http://www.codeproject.com/Articles/15955/logging-made-easy-in-your-c-applications

После:

Logger logger = Logger::getInstance(LOG4CPLUS_TEXT("main"));

Отсутствует:

SharedAppenderPtr consoleAppender(new ConsoleAppender());
consoleAppender->setName("myAppenderName");
consoleAppender->setLayout(new log4cplus::TTCCLayout());
logger.addAppender(consoleAppender);
2

Другие решения

PiotrNycz упомянул, что вам действительно нужно выполнить больше шагов инициализации для ведения журнала log4cplus, в частности, добавив дополнения. Я хочу подробнее остановиться на этом.

Документация заявляет, что до версии 2.0 инициализация должна быть сделана с:

log4cplus::initialize();

и деинициализации, позвонив shutdown() на Logger вот так:

log4cplus::Logger::getRoot().shutdown();

, в то время как после версии 2.0 инициализация должна происходить с созданием экземпляра класса RAII log4cplus::Initializer initializer; и деинициализация, когда этот экземпляр разрушен.

тем не мение У меня есть версия 2.0.0, и предыдущий метод — это то, что на самом деле работает для меня. Со вторым методом я получил точно такую ​​же ошибку, как и вы.

Тогда минимальная реализация ведения журнала для класса может быть такой:

const wchar_t* PATTERN = LOG_PATTERN; // optional - create an initial log status message
log4cplus::SharedAppenderPtr consoleApp(new log4cplus::ConsoleAppender());  // for console output
consoleApp->setLayout(std::unique_ptr<log4cplus::Layout>(new log4cplus::PatternLayout(PATTERN))); // again optional
log4cplus::Logger m_logger = log4cplus::Logger::getRoot();  // get root logger
m_logger.setLogLevel(log4cplus::ALL_LOG_LEVEL);     // set root logger log level

// finally add appenders
this->m_logger.addAppender(consoleApp); // at least one appender must be set in order for you to be able to actually log to the console or file or to an output device (multiple appender types exist).

Теперь обычай MyLogger класс должен как минимум содержать log4cplus::Logger, функции регистрации — как следующие logError — и шаги инициализации, упомянутые выше, выполняются в его конструкторе. Также ему нужна функция-член GetLogger определяется как таковой: log4cplus::Logger* GetLogger(const char* logger = DEFAULT_LOGGER); получить экземпляр MyLogger и использовать его в качестве члена класса, для которого вы хотите предоставить средства ведения журналов.

Для записи конкретного сообщения вам также нужна такая функция в MyLogger:

template<typename... Args>
inline void logError(const char* stringOptionallyFormatted, Args&&... args)
{
LOG4CPLUS_ERROR_FMT(m_logger, fmt, std::forward<Args>(args)...);
}

(Аналогично для других уровней журнала.)

Теперь создайте экземпляр экземпляра logger в конструкторе некоторого класса (или в main):

MyLogger myLoggerInstance;
myLoggerInstance.GetLogger(L"File System Logger");

и войти с:

myLoggerInstance.logError|Info|Debug("like today is %s No%d", "Sunday", 7 );

или же:

logger.logDebug(L"no formatted string");


Дополнительные примечания:

  • Я нашел документацию для log4cplus относительно плохой. это (который предназначен для log4j! — оригинал java) — лучший, который я нашел. Это очень хорошо объясняет основы. Затем на страницу, на которую я ссылался выше.
  • Убедитесь, что вы звоните log4cplus::initialize() первым делом, чтобы предотвратить SIOF.
  • Как правило, вы хотите один Logger объект-член для каждого интересующего вас класса.
  • Если вы работаете над многопоточным вызовом приложения log4cplus::threadCleanup(); в качестве дополнительного шага деинициализации после призвание shutdown,
  • Только тривиальное приложение Hello World ссылка на сайт не понадобится аппендиру
0

По вопросам рекламы [email protected]