Skip to content

log4cxx编译、使用

Published: at 02:22 PM | 5 min read
  1. 下载下面三个文件放在同级目录下解压: http://apr.apache.org/download.cgi apr-1.4.6-win32-src.zip apr-util-1.5.1-win32-src.zip http://logging.apache.org/log4cxx/download.html apache-log4cxx-0.10.0.zip

将apr-1.4.6改名为apr
将apr-util-1.5.1改名为apr-util
  1. 进入apache-log4cxx-0.10.0目录运行两个批处理文件 configure.bat
    configure-aprutil.bat

一般运行第二个批处理文件是不成功的,可能一闪而逝看不到, 但是在文件的末尾再添加一行命令pause,让屏幕暂停一下就可以看到了。 此时需要下载sed for windows解决,路径如下:

http://gnuwin32.sourceforge.net/packages/sed.htm

找到安装后的bin目录将他添加到系统环境变量Path中。

添加系统环境变量:右键我的电脑->属性->高级->环境变量->找到变量名Path, 在变量值的后面增加bin目录,如:“;C:\Program Files\GnuWin32\bin”,再次 运行此文件就可以了。

提示:如果你没有解决这个问题直接进行下一步进行编译会出现两个错误的。

  1. 用vs打开project目录下的log4cxx.dsw文件包含四个工程,编译就可以了,在debug目录下可以找到

我们需要的log4cxx.lib和log4cxx.dll这两个文件。

  1. 使用log4cxx需要头文件(src/main/include目录下的文件)、lib文件,dll文件

1> 默认创建一个测试工程test;
2> 在test目录下新建一个目录lib,将log4cxx.lib和log4cxx.dll两个文件 拷贝到此目录下,另将src/main/include文件夹拷贝到test目录下。
3> 工程属性->C/C++->General->Additional Include Directories加入: $(ProjectDir)\include

工程属性->Linker->General->Additional Library Directories加入: $(ProjectDir)\lib

工程属性->Linker->Input->Additional Dependencies加入:log4cxx.lib

4> 测试代码,如下:

#include "stdafx.h"
#include "log4cxx/logger.h"

int _tmain(int argc, _TCHAR* argv[])
{
log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("MyApp"));

LOG4CXX_INFO(logger, "hello, world");

system("pause");
return 0;
}

5> 在test目录下新建配置文件log4j.properties,内容如下:

log4j.rootLogger=DEBUG, A1
log4j.appender.A1=org.apache.log4j.FileAppender
log4j.appender.A1.File=tjw.log
log4j.appender.A1.layout=org.apache.log4j.PatternLayout

# Print the date in ISO 8601 format
log4j.appender.A1.layout.ConversionPattern=%d %-5p %c - %m%n

# Print only messages of level WARN or above in the package com.foo.
log4j.logger.com.foo=WARN

6> 运行后在test目录下会生成tjw.log日志文件,包含内容:
2013-01-19 23:09:17,421 INFO MyApp - hello, world

7> 最后,上面只是简单的演示一下使用方法,根据配置可以更加灵活的记日志。 封装:


#ifndef MYLOGGER_H_
#define MYLOGGER_H_

#include "log4cxx/logger.h"

class Logger
{

#define msgFormatA(buf, msg) \
	do { \
	va_list ap; \
	va_start(ap, msg); \
	vsprintf_s(buf, sizeof(buf), msg, ap); \
	va_end(ap); \
	} while (0)

#define msgFormatW(buf, msg) \
	do { \
	va_list ap; \
	va_start(ap, msg); \
	vswprintf(buf, sizeof(buf), msg, ap); \
	va_end(ap); \
	} while (0)

public:
	static void SetName(std::string appName)
	{
		appName_ = appName;
	}

	static void Trace(const char *msg, ...)
	{
		char buf[bufferSize_] = {0};
		msgFormatA(buf, msg);
		LOG4CXX_TRACE(Instance(), buf);
	}

	static void Trace(const wchar_t *msg, ...)
	{
		wchar_t buf[bufferSize_] = {0};
		msgFormatW(buf, msg);
		LOG4CXX_TRACE(Instance(), unicode2ansi(buf));
	}

	static void Debug(const char *msg, ...)
	{
		char buf[bufferSize_] = {0};
		msgFormatA(buf, msg);
		LOG4CXX_DEBUG(Instance(), buf);
	}

	static void Debug(const wchar_t *msg, ...)
	{
		wchar_t buf[bufferSize_] = {0};
		msgFormatW(buf, msg);
		LOG4CXX_DEBUG(Instance(), unicode2ansi(buf));
	}

	static void Info(const char *msg, ...)
	{
		char buf[bufferSize_] = {0};
		msgFormatA(buf, msg);
		LOG4CXX_INFO(Instance(), buf);
	}

	static void Info(const wchar_t *msg, ...)
	{
		wchar_t buf[bufferSize_] = {0};
		msgFormatW(buf, msg);
		LOG4CXX_INFO(Instance(), unicode2ansi(buf));
	}

	static void Warn(const char *msg, ...)
	{
		char buf[bufferSize_] = {0};
		msgFormatA(buf, msg);
		LOG4CXX_WARN(Instance(), buf);
	}

	static void Warn(const wchar_t *msg, ...)
	{
		wchar_t buf[bufferSize_] = {0};
		msgFormatW(buf, msg);
		LOG4CXX_WARN(Instance(), unicode2ansi(buf));
	}

	static void Error(const char *msg, ...)
	{
		char buf[bufferSize_] = {0};
		msgFormatA(buf, msg);
		LOG4CXX_ERROR(Instance(), buf);
	}

	static void Error(const wchar_t *msg, ...)
	{
		wchar_t buf[bufferSize_] = {0};
		msgFormatW(buf, msg);
		LOG4CXX_ERROR(Instance(), unicode2ansi(buf));
	}

	static void Fatal(const char *msg, ...)
	{
		char buf[bufferSize_] = {0};
		msgFormatA(buf, msg);
		LOG4CXX_FATAL(Instance(), buf);
	}

	static void Fatal(const wchar_t *msg, ...)
	{
		wchar_t buf[bufferSize_] = {0};
		msgFormatW(buf, msg);
		LOG4CXX_FATAL(Instance(), unicode2ansi(buf));
	}

private:
	static log4cxx::LoggerPtr& Instance()
	{
		static log4cxx::LoggerPtr ptr(log4cxx::Logger::getLogger(appName_));
		return ptr;
	}

	static std::string unicode2ansi(const std::wstring& unicode)
	{
		if (unicode.empty()) {
			return std::string("");
		}
		int len = WideCharToMultiByte(CP_ACP, 0, unicode.c_str(), -1, NULL, 0, NULL, NULL);
		char *tmp = new char[len+1];
		memset(tmp, 0, sizeof(char)*(len+1));
		WideCharToMultiByte(CP_ACP, 0, unicode.c_str(), unicode.size(), tmp, len, NULL, NULL);
		std::string ret = tmp;
		delete [] tmp;
		return ret;
	}

	static const unsigned short bufferSize_ = 4096;
	static std::string appName_;
};

std::string Logger::appName_ = std::string("");

#endif // MYLOGGER_H_

配置文件:

log4j.rootLogger=trace,stdout,R

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.Encoding=UTF-8

# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%d -%5p [%c] %m%n

log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.Encoding=UTF-8
log4j.appender.R.File=mylog.txt
log4j.appender.R.MaxFileSize=1MB
log4j.appender.R.Append=true
# Keep one backup file
log4j.appender.R.MaxBackupIndex=10
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d -%5p [%c] %m%n