سؤال

I am using log4cpp to create a Log class, which is designed in the singleton mode. Here is my Log.h

#include <cstdio>
#include <cstring>
#include <cstdarg>
#include <log4cpp/Category.hh>
#include <log4cpp/Appender.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/Priority.hh>
#include <log4cpp/PatternLayout.hh>

class CtagentLog
{
public:
    static CtagentLog& getInstance() {
        static CtagentLog instance;
        return instance;
    }

    void Log(int type, char *content);

private:
    CtagentLog();
    CtagentLog(CtagentLog const&);
    CtagentLog& operator=(CtagentLog const &);
    ~CtagentLog();


//  char *log_file;
//  log4cpp::PatternLayout *plt;
//  log4cpp::Appender *app;
        void itoa(int n, char* str, int radix);

};

and this is my Log.cpp file:

#include "Log.h"


CtagentLog::CtagentLog()
{
}

CtagentLog::~CtagentLog()
{

}

/*
 * type=1 ERROR
 * type=2 WARN
 * type=3 INFO
 */
void CtagentLog::Log(int type, char *content)
{
    log4cpp::PatternLayout *plt = new log4cpp::PatternLayout();
    plt->setConversionPattern("[%d] %p %c %x: %m%n");
    log4cpp::Appender *app = new log4cpp::FileAppender("fileAppender", "test.log");
    app->setLayout(plt);

    log4cpp::Category &root = log4cpp::Category::getRoot().getInstance("Test");
    root.addAppender(app);
    root.setPriority(log4cpp::Priority::DEBUG);
    switch(type){
        case 1: root.error(content); break;
        case 2: root.warn(content); break;
        case 3: root.info(content); break;
        default: root.info(content); break;
    }
}

And finally my testmain.cpp:

#include "Log.h"
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>


void *func1(void *arg)
{
    printf("thread 1\n");
}

void *func2(void *arg)
{
    printf("thread 2\n");
}

int main(void)
{
    pthread_t tid1;
    pthread_t tid2;

    pthread_create(&tid1, NULL, func1, NULL);
    pthread_join(tid1, NULL);
    CtagentLog::getInstance().Log(1,"Create Thread 1 Return");
    pthread_create(&tid2, NULL, func2, NULL);
    pthread_join(tid2, NULL);
    CtagentLog::getInstance().Log(1,"Create Thread 2 Return");

    return 0;

}

Compile with g++ -g Main.cpp Log.cpp -lpthread -llog4cpp, and run it. the output is :

# ./a.out 
thread 1
thread 2

but the test.log is like this:

[2013-07-29 21:32:34,101] ERROR Test : Create Thread 1 Return
[2013-07-29 21:32:34,101] ERROR Test : Create Thread 2 Return
[2013-07-29 21:32:34,101] ERROR Test : Create Thread 2 Return

I want to know why the second call log twice. Am I using the log4cpp wrong?

هل كانت مفيدة؟

المحلول

It's because you add new appenders every time in the Log function. Each new appender, well, append the output. If you called it a third time you would have gotten three outputs.

Things like adding appenders, setting layouts or other such one-time configuration should be done only once, preferably in a constructor or initialization function.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top