Log4cplus在VS2015配置教程

这两天,之前使用的Log4cxx出现了一些bug,比如l同一个线程的og逻辑顺序错乱,逻辑顺序本应该是a->b->c,结果出现的顺序是b->a->c,然后还有log打印的文件出现错误,本应该打印在a文件的log出现在b文件,其次还出现了log丢失的情况,因此,准备将几年不更新的log4cxx变成于前两个月刚刚更新的log4cplus-2.0.1版本。但是配置的时候出现了很多错误,在这里总结成教程,以免后面人入坑太难。

这里仅仅介绍windows环境下VS2015配置Log4cplus。

1.首先需要下载log4cplus源代码,这里是地址:log4cplus。

2.解压完成后,将log4cplus-2.0.1\include\log4cplus文件夹,复制到你的VS的库中。打开log4cplus-2.0.1\imsvc14文件夹下的log4cplus.sln文件,启动VS2015。

3.选择你想要的版本,这里我选择的是DEBUG_Unicode与Release_Unicode分别对应我工程的Debug与Release版本,然后找到log4cplus与log4cplusS,分别在两个模式下编译他们,如图。

Log4cplus在VS2015配置教程_第1张图片Log4cplus在VS2015配置教程_第2张图片

4.然后在log4cplus-2.01/msvc14X64中,生成两个含有静态库的文件夹,名称如图所示,分别对应debug与release版本。静态库名称为log4cplusSUD.lib(debug)与log4cplusSU.lib(release)。将这两个静态库放入你的工程的根目录下。

.Log4cplus在VS2015配置教程_第3张图片

5.用vs打开你的工程,在工程的属性里,选择链接器->输入->附加依赖项将对应版本的lib添加到工程中。

 Log4cplus在VS2015配置教程_第4张图片

6.在工程属性里,选择常规->字符集,选择对应版本的字符集。我这里选择的Unicode。

这样,你就将log4cplus就给配置好了,下面来讲一讲怎么使用log4cplus。若还是有不清楚的,可以参考这篇博客。我们的需求是log按照日期,存放在不同的日期文件夹中。

然后是MyLogger.h文件

#pragma once
#include 
#include 
#include 
#include 
#include 

#pragma warning (disable: 4996) 
#ifdef DEBUG_LOG
#pragma comment (lib, "log4cplusSUD.lib")
#else 
#pragma comment (lib, "log4cplusSU.lib")
#endif // DEBUG
using namespace log4cplus;
using namespace std;
using namespace log4cplus::helpers;
Logger LogConsole;
Logger LogInfo;
inline static void InitLogger()
{
	PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("./Config/logConfig.properties"));
	LogConsole = Logger::getInstance(LOG4CPLUS_TEXT("console"));
	LogInfo = Logger::getInstance(LOG4CPLUS_TEXT("info"));
}

inline static void LogConsole(char *format, ...)
{
	va_list st;
	va_start(st, format);
	vsprintf(logOutput, format, st);
	va_end(st);
	LOG4CPLUS_INFO(LogConsole, logOutput);
}
inline static void LogInfo(char *format, ...)
{
	va_list st;
        char logOutput[1024];
	va_start(st, format);
	vsprintf(logOutput, format, st);
	va_end(st);
	LOG4CPLUS_INFO(LogInfo, logOutput);
}

main.cpp

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include
#include 
#include"MyLogger.h"
using namespace log4cplus;
using namespace std;
using namespace log4cplus::helpers;
int main()
{
	InitLogger();
	for (int i = 0; i < 100; i++)
	{
		LogConsole("LogConsole:%d", i);
		LogInfo("LogInfo:%d", i);
	}
	return 0;
}

配置文件logConfig.properties

#设置日志对象
log4cplus.logger.console=INFO,logConsole
log4cplus.logger.info=INFO,logInfo

#不向默认对象(rootLogger)输出,因此信息只能输出到文件
log4cplus.additivity.file=false

##############################logConsole##############################
#设置日志输出到控制台
log4cplus.appender.logConsole = log4cplus::ConsoleAppender
log4cplus.appender.logConsole.layout=log4cplus::PatternLayout
log4cplus.appender.logConsole.layout.ConversionPattern=[%D{%Y-%m-%d %H:%M:%S,%q}]%m%n

##############################logInfo##############################
#设置日志追加到文件尾
log4cplus.appender.logInfo=log4cplus::TimeBasedRollingFileAppender
#设置日志文件大小
log4cplus.appender.logInfo.MaxFileSize=10MB
#设置生成日志最大个数
log4cplus.appender.logInfo.MaxBackupIndex=5
#设置输出日志路径与格式
log4cplus.appender.logInfo.layout=log4cplus::PatternLayout
log4cplus.appender.logInfo.FilenamePattern=Log\%d{yyyyMMdd}\logInfo_%d{yyyyMMdd}.log
#设置可以创建文件夹
log4cplus.appender.logInfo.CreateDirs=true
#设置打印格式
log4cplus.appender.logInfo.layout.ConversionPattern=[%D{%Y-%m-%d %H:%M:%S,%q}]%m%n
#只有匹配相同日志级别,日志才输入到该文件中
log4cplus.appender.logInfo.filters.1=log4cplus::spi::LogLevelMatchFilter
log4cplus.appender.logInfo.filters.1.LogLevelToMatch=INFO
log4cplus.appender.logInfo.filters.1.AcceptOnMatch=true
log4cplus.appender.logInfo.filters.2=log4cplus::spi::DenyAllFilter

当然如果你不继续往下看,只是复制粘贴,那么你的打印的log就会出错,出现打印不了log,或者log被覆盖等情况,甚至还会生成各种莫名其妙的空文件夹,这里是因为,他TimeBasedRollingFileAppender的Appender并没有完善特别好,因此我们需要对他的源码进行修改。

首先处理乱建文件夹的问题。在env.cxx代码中

Log4cplus在VS2015配置教程_第5张图片

第614行的path+=dir_sep。在main函数结束时,log4cplus会先把dsp_sep清空,然后将剩余的缓存里的log输出,导致分隔符"//"dir_sep为空,致使新建了很多空文件夹。因此将这个函数之中的所有dir_sep修改成LOG4CPLUS_TEXT("\\");,当然不同的系统不同的分隔符。这样就处理了乱建文件夹的问题

然后是处理log被覆盖,打印不上的情况。在fileappender.cxx中,void TimeBasedRollingFileAppender::rollover(bool alreadyLocked)函数里

void TimeBasedRollingFileAppender::rollover(bool alreadyLocked)
{
    helpers::LockFileGuard guard;

    if (useLockFile && ! alreadyLocked)
    {
        try
        {
            guard.attach_and_lock (*lockFile);
        }
        catch (std::runtime_error const &)
        {
            return;
        }
    }

    // Close the current file
    out.close();
    // reset flags since the C++ standard specified that all the flags
    // should remain unchanged on a close
    out.clear();

    if (! filename.empty())
    {
        helpers::LogLog & loglog = helpers::getLogLog();
        long ret;

#if defined (_WIN32)
        // Try to remove the target first. It seems it is not
        // possible to rename over existing file.
        ret = file_remove (scheduledFilename);
#endif

        loglog.debug(
            LOG4CPLUS_TEXT("Renaming file ")
            + filename
            + LOG4CPLUS_TEXT(" to ")
            + scheduledFilename);
        ret = file_rename (filename, scheduledFilename);
        loglog_renaming_result (loglog, filename, scheduledFilename, ret);
    }

    Time now = Time::gettimeofday();
    clean(now);

    open(std::ios::out | std::ios::trunc);

    nextRolloverTime = calculateNextRolloverTime(now);
}

倒数第二行的open(std::ios::out|std::iost::trunc)就是罪魁祸首,修改成open(std::ios_base::out | std::ios_base::ate | std::ios_base::app);就可以使用了

你可能感兴趣的:(Log4cplus在VS2015配置教程)