1

我是使用日志系统的新手,但添加到您的程序中非常有用。

总结我的问题。我使用日志库log4cplus

我用两个简单的类和主程序做一个简单的例子。

这是我的错误日志:

  • log4cplus:错误找不到记录器(主)的附加程序。
  • log4cplus:ERROR 请正确初始化 log4cplus 系统。
  • 分段错误:11

问题是我不知道如何用 appender 解决问题。

这是我的示例的基本代码。 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;
}

类2.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);    
};

类.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;
}

主文件

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;
}

我做错了什么???这是使用日志系统的正确方法??

我使用一个简单的属性文件将所有日志消息保存在一个文件中。

那是我配置 de logger的logClase.properties文件。

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 和控制台附加程序将消息扔到文件中并进入控制台。我觉得做起来不一定那么难,做起来一定很容易。

4

2 回答 2

2

请参阅 log4cplus 文档中的附加程序。你可能错过了这个记录器的一些初始化步骤——我的意思是你没有添加附加程序。

请参阅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);
于 2012-09-17T18:46:33.580 回答
0

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)...);
}

(对于其他日志级别也是如此。)

现在在某个类的构造函数(或 )中实例化一个记录器实例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 原版)教程是我找到的最好的教程。它很好地解释了基础知识。然后我上面链接的页面也是如此。
  • 确保在 main 中调用log4cplus::initialize()第一件事以防止 SIOF。
  • 通常,您希望Logger每个感兴趣的类都有一个成员对象。
  • 如果您log4cplus::threadCleanup();调用.shutdown
  • 只有一个微不足道的 hello world 应用程序链接不需要附加程序。
于 2018-10-17T17:41:08.960 回答