I started using Qt with log4cxx to create a trace.
I created a log class that i call every time i want a log, and putted it into my static tool library for my project. i didn't get any error while building it but when i use the lib i get for every macro call :
/home/workspace/testEnvoi/mainwindow.cpp:110: error: undefined reference to `log4cxx::helpers::MessageBuffer::MessageBuffer()'
/home/workspace/testEnvoi/mainwindow.cpp:110: error: undefined reference to `log4cxx::Level::getFatal()'
and so on. It look like a linking error but i don't have any linking error while building my library and my app recognise the macro. So if someone could help me understand why it's doing that and what could be the solution, i would be thankful .
my log class is the following:
.h:
> #ifndef CLOGGER_H
> #define CLOGGER_H
> #include <stdlib.h>
> #include <cstdio>
> #include <unistd.h>
> # include <sys/types.h>
> #include <string.h>
> #include <iostream>
>
> #include <log4cxx/propertyconfigurator.h>
> #include <log4cxx/rollingfileappender.h>
>
> // Logger based on log4cxx standard logger
>
> #define LOG_DEBUG(message) {\
> CLogger * pLogger = CLogger::getInstance(); \
> if (pLogger->isDebugEnabled()) {\
> log4cxx::helpers::MessageBuffer oss_; \
> pLogger->log(::log4cxx::Level::getDebug(), oss_.str(oss_ << message), LOG4CXX_LOCATION); }}
>
> #define LOG_INFO(message) {\
> CLogger * pLogger = CLogger::getInstance(); \
> if (pLogger->isInfoEnabled()) {\
> log4cxx::helpers::MessageBuffer oss_; \
> pLogger->log(::log4cxx::Level::getInfo(), oss_.str(oss_ << message), LOG4CXX_LOCATION); }}
>
> #define LOG_WARNING(message) {\
> CLogger * pLogger = CLogger::getInstance(); \
> if (pLogger->isWarningEnabled()) {\
> log4cxx::helpers::MessageBuffer oss_; \
> pLogger->log(::log4cxx::Level::getWarn(), oss_.str(oss_ << message), LOG4CXX_LOCATION); }}
>
> #define LOG_ERROR(message) {\
> CLogger * pLogger = CLogger::getInstance(); \
> if (pLogger->isErrorEnabled()) {\
> log4cxx::helpers::MessageBuffer oss_; \
> pLogger->log(::log4cxx::Level::getError(), oss_.str(oss_ << message), LOG4CXX_LOCATION); }}
>
> #define LOG_FATAL(message) {\
> log4cxx::helpers::MessageBuffer oss_; \
> CLogger::getInstance()->log(::log4cxx::Level::getFatal(), oss_.str(oss_ << message), LOG4CXX_LOCATION); }
>
>
>
>
> class CLogger { public:
> static void init(const std::wstring & applicationName);
> static CLogger * getInstance();
> static void killInstance();
> void log(const log4cxx::LevelPtr & level, const std::string & message, const log4cxx::spi::LocationInfo& location);
> bool isDebugEnabled();
> bool isInfoEnabled();
> bool isWarningEnabled();
> bool isErrorEnabled(); private:
> CLogger();
> ~CLogger();
> void updateFileAppenderNames();
> void buildHeader(const struct tm * pTime);
> log4cxx::LoggerPtr log4cxxLogger;
> static CLogger * m_pInstance;
> static std::wstring m_appName; };
>
> #endif // CLOGGER_H
.cpp:
#include "Logger.h"
#include "Types.h"
// Singleton initialisation
CLogger * CLogger::m_pInstance = NULL;
// Application name
std::wstring CLogger::m_appName = std::wstring();
CLogger::CLogger()
: log4cxxLogger(0)
{
}
CLogger::~CLogger()
{
}
void CLogger::init(const std::wstring & applicationName)
{
char propertiesFileName[1024];
FILE * fd;
if (strncmp(propertiesFileName, "(null)", 1024) == 0)
{
std::cout << "CLogger: Environment variable not found"
}
else if ((fd = fopen(propertiesFileName, "r")))
{
fclose(fd);
log4cxx::PropertyConfigurator::configure(propertiesFileName);
}
else
{
std::cout << "CLogger: log4cxx configuration file not found"
}
// Application name setting
m_appName = applicationName;
}
CLogger * CLogger::getInstance()
{
if (NULL == m_pInstance)
{
try
{
// Instance creation
m_pInstance = new CLogger();
// Get the logger
m_pInstance->log4cxxLogger = log4cxx::Logger::getLogger(m_appName);
m_pInstance->updateFileAppenderNames();
}
catch(...)
{
m_pInstance = NULL;
}
}
return m_pInstance;
}
void CLogger::killInstance()
{
if (NULL != m_pInstance)
{
if (NULL != m_pInstance->log4cxxLogger)
{
log4cxx::AppenderList appenderList = log4cxx::Logger::getRootLogger()->getAllAppenders();
for (log4cxx::AppenderList::iterator it = appenderList.begin(); it != appenderList.end(); ++it)
{
(*it)->close();
}
delete m_pInstance->log4cxxLogger;
m_pInstance->log4cxxLogger == NULL;
}
delete m_pInstance;
m_pInstance = NULL;
}
}
void CLogger::log(const log4cxx::LevelPtr & level, const std::string & message, const log4cxx::spi::LocationInfo& location)
{
// Check if the file must be rolled over
updateFileAppenderNames();
// Log the message
log4cxx::helpers::MessageBuffer oss_;
log4cxxLogger->forcedLog(level, oss_.str(oss_ << message), location);
}
bool CLogger::isDebugEnabled()
{
return log4cxxLogger->isDebugEnabled();
}
bool CLogger::isInfoEnabled()
{
return log4cxxLogger->isInfoEnabled();
}
bool CLogger::isWarningEnabled()
{
return log4cxxLogger->isWarnEnabled();
}
bool CLogger::isErrorEnabled()
{
return log4cxxLogger->isErrorEnabled();
}
And a piece off my App which is bugging for exemple:
CApp::CApp(int &argc, char *argv[]) : QApplication(argc, argv),
m_pEnvoiScreen(NULL),
m_pLog(NULL)
{
QString appName(QString(argv[0]).section(QDir::separator(), -1));
// Logger initialisation
m_pLog->init(QString("TestTool").toStdWString());
Init();
}
void CApp::Init()
{
QString appName = "TEST";
my_MessagingSystem = CMessagingsystem::getInstance();
if (NULL == my_MessagingSystem)
{
LOG_ERROR("Can not get Messages instance - Stop application")
qApp->exit(-1);
}
m_pEnvoiScreen = new MainWindow();
m_pEnvoiScreen->show();
}