LOG4CPP下载与编译
Log4cpp是一个开源的C++类库,它提供了在C++程序中使用日志和跟踪调试的功能。使用log4cpp,可以很便利地将日志或者跟踪调试信息写入字符流、内存字符串队列、文件、回滚文件、调试器、Windows日志、本地syslog和远程syslog服务器中。
下载地址为:http://sourceforge.net/projects/log4cpp/files/latest/download。(log4cpp-1.1.2rc1.tar.gz,仅 577K )
解压后,进入对应的msvc 文件夹(本人使用vs2013,进入了vsvc10,双击msvc10.sln 打开vs,项目列表如下:
)
直接编译(log4cpp项目,(log4cppLIB编译失败,失败原因:LINK : fatal error LNK1181: 无法打开输入文件“.\Debug\NTEventLogCategories.res”)),暂不处理,再次编译testDll,编译成功后,启动testDLL,显示文件找出不到。(log4cpp\msvc10\log4cpp\Debug\log4cpp.dll 到 log4cpp\msvc10\testDLL\Debug 即可。)
LOG4CPP 在项目中使用
#include <string>
#include "log4cpp/Priority.hh"
#include "log4cpp/Category.hh"
class Log4CppLog
{
public:
Log4CppLog();
Log4CppLog(std::wstring logPath, std::wstring logLevel);
~Log4CppLog();
void SetLogPath(std::wstring logPath, std::wstring logLevel);
bool IsDebugEnable();
void WriteLog(std::wstring logLevel, const std::string& msg);
void WriteLog(std::wstring logLevel, const std::string& fmt, const std::string& arg0);
void WriteLog(std::wstring logLevel, const std::string& fmt, const std::string& arg0, const std::string& arg1);
void WriteLog(std::wstring logLevel, const std::string& fmt, const std::string& arg0, const std::string& arg1, const std::string& arg2);
private:
log4cpp::Priority::PriorityLevel ChangeStringToPriorityLevel(std::wstring level);
void WriteLog4CppLog(log4cpp::Priority::PriorityLevel level, std::string logDate);
private:
std::string strProcessId;
std::wstring strLogPath;
log4cpp::Category* LpLogCategory;
};
extern Log4CppLog g_Log4CppLog; //外部写日志的实例
#include "logging.h"
#include "log4cpp/RollingFileAppender.hh"
#include "log4cpp/PatternLayout.hh"
#include "../public/CutilToolAll.h"
using namespace log4cpp;
extern Log4CppLog g_Log4CppLog;//外部写日志的实例
Log4CppLog::Log4CppLog()
{
strProcessId = "";
strLogPath = L"";
LpLogCategory = nullptr;
}
Log4CppLog::Log4CppLog(wstring logPath, wstring logLevel)
{
strProcessId = "";
strLogPath = L"";
LpLogCategory = nullptr;
SetLogPath(logPath, logLevel);
}
Log4CppLog::~Log4CppLog()
{
log4cpp::Category::shutdown();
}
void Log4CppLog::SetLogPath(wstring logPath, wstring logLevel)
{
if (logPath.empty()) return;
if (!strLogPath.empty()) return;
try
{
logPath = CUtilSystemPath::FormatPath(logPath, false);
if (!CUtilSystemPath::CheckLongPath(logPath))
{
logPath = CUtilSystemPath::GetCurrenRunpath() + logPath;
}
CUtilSystemPath::CheckFoldPath(CUtilFile::GetFilePath(logPath), true);
strProcessId = CutilTool::IntToString(GetCurrentProcessId());
strLogPath = CUtilSystemPath::FormatPath(logPath, false);
//strLogPath = CUtilFile::GetFilePath(logPath) + L"\\" + CUtilFile::GetFileName(logPath)
// + CutilTool::IntToWString(GetCurrentProcessId()) + L".log";
string strLogFile = ChineseCode::UnicodeToGB2312String(strLogPath);
// 1实例化一个layout 对象
/*log4cpp::Layout* layout =
new log4cpp::BasicLayout();*/
/// %c category;
// %d 日期;日期可以进一步的设置格式,用花括号包围,例如%d{ %H:%M : %S, %l } 或者 %d{ %d %m %Y%H:%M : %S, %l }。如果不设置具体日期格式,则如下默认格式被使用“Wed Jan 02 02:03 : 55 1980”。日期的格式符号与ANSI C函数strftime中的一致。但增加了一个格式符号%l,表示毫秒,占三个十进制位。
// %m 消息;
// %n 换行符,会根据平台的不同而不同,但对于用户透明;
// %p 优先级;
// %r 自从layout被创建后的毫秒数;
// %R 从1970年1月1日0时开始到目前为止的秒数;
// %u 进程开始到目前为止的时钟周期数;
// %x NDC。*/
//07-14 09:49:57 473 : DEBUG : begin log
log4cpp::PatternLayout* pLayout = new log4cpp::PatternLayout();
pLayout->setConversionPattern("%d{%m-%d %H:%M:%S %l} ProcessId=" + strProcessId + ": %p %c : %m%n");
// 2. 初始化一个appender 对象,滚动日志记录(1M一个文件,保存10个文件)
log4cpp::Appender* appender = newlog4cpp::RollingFileAppender("RollingFileAppender",
strLogFile.c_str(), 1 * 1024* 1024 , 10);
// 3. 把layout对象附着在appender对象上
appender->setLayout(pLayout);
// 4. 实例化一个category对象,如果全局仅一个日志对象,可使用log4cpp::Category::getRoot()。
log4cpp::Category& LogCategory = log4cpp::Category::getRoot().getInstance(
ChineseCode::UnicodeToGB2312String(CUtilFile::GetFileName(strLogPath)));
// 5. 设置additivity为false,替换已有的appender
LogCategory.setAdditivity(false);
// 5. 把appender对象附到category上
LogCategory.setAppender(appender);
// 6. 设置category的优先级,低于此优先级的日志不被记录
LogCategory.setPriority(ChangeStringToPriorityLevel(logLevel));
LpLogCategory = &LogCategory;
}
catch (...)
{
strProcessId = "";
strLogPath = L"";
}
}
void Log4CppLog::WriteLog4CppLog(Priority::PriorityLevel level,string logDate )
{
if (strLogPath.empty()) return;
if (!LpLogCategory)
{
log4cpp::Category& LogCategory = log4cpp::Category::getRoot().getInstance(
ChineseCode::UnicodeToGB2312String(CUtilFile::GetFileName(strLogPath)));
LpLogCategory = &LogCategory;
}
else
{
switch (level)
{
case Priority::PriorityLevel::DEBUG:
{
LpLogCategory->debug(logDate);
break;
}
case Priority::PriorityLevel::INFO:
{
LpLogCategory->info(logDate);
break;
}
case Priority::PriorityLevel::WARN:
{
LpLogCategory->warn(logDate);
break;
}
case Priority::PriorityLevel::ERROR:
{
LpLogCategory->error(logDate);
break;
}
default:
LpLogCategory->debug(logDate);
break;
}
}
}
bool Log4CppLog::IsDebugEnable()
{
return (!strLogPath.empty());
}
string LoggerFormat(const string& fmt, const string& arg0)
{
string formatString = fmt;
string FindString = "$0";
string::size_type findPos = formatString.find(FindString);
if (findPos == string::npos)
{
FindString = "$$";
findPos = fmt.find(FindString);
}
if (findPos != string::npos)
{
formatString = formatString.substr(0, findPos) + arg0 + formatString.substr(findPos + 2, formatString.length() - findPos - 2);
}
return formatString;
}
string LoggerFormat(const string& fmt, const string& arg0, const string& arg1)
{
string formatString = LoggerFormat(fmt, arg0);
string FindString = "$1";
string::size_type findPos = formatString.find(FindString);
if (findPos == string::npos)
{
FindString = "$$";
findPos = fmt.find(FindString);
}
if (findPos != string::npos)
{
formatString = formatString.substr(0, findPos) + arg1 + formatString.substr(findPos + 2, formatString.length() - findPos - 2);
}
return formatString;
}
string LoggerFormat(const string& fmt, const string& arg0, const string& arg1, const string& arg2)
{
string formatString = LoggerFormat(fmt, arg0,arg1);
string FindString = "$2";
string::size_type findPos = formatString.find(FindString);
if (findPos == string::npos)
{
FindString = "$$";
findPos = fmt.find(FindString);
}
if (findPos != string::npos)
{
formatString = formatString.substr(0, findPos) + arg2 + formatString.substr(findPos + 2, formatString.length() - findPos - 2);
}
return formatString;
}
Priority::PriorityLevel Log4CppLog::ChangeStringToPriorityLevel(wstring level)
{
if (level.empty()) return Priority::PriorityLevel::ERROR;
level = CutilTool::FormatString(level,true);
if (level == L"DEBUG")
{
return Priority::PriorityLevel::DEBUG;
}
else if (level == L"INFO")
{
return Priority::PriorityLevel::INFO;
}
else if (level == L"WARN")
{
return Priority::PriorityLevel::WARN;
}
//if (level == L"ERROR")
return Priority::PriorityLevel::ERROR;
}
void Log4CppLog::WriteLog(wstring logLevel, const string& msg) {
WriteLog4CppLog(ChangeStringToPriorityLevel(logLevel), msg);
}
void Log4CppLog::WriteLog(wstring legLevel, const string& fmt, const string& arg0) {
WriteLog(legLevel,LoggerFormat(fmt, arg0));
}
void Log4CppLog::WriteLog(wstring legLevel, const string& fmt, const string& arg0, const string& arg1) {
WriteLog(legLevel,LoggerFormat(fmt, arg0, arg1));
}
void Log4CppLog::WriteLog(wstring legLevel, const string& fmt, const string& arg0, const string& arg1, const string& arg2) {
WriteLog(legLevel,LoggerFormat(fmt, arg0, arg1, arg2));
}
//程序启动时,初始化日志对象。仅初始化后,才能开始写日志。
g_Log4CppLog.SetLogPath(logFileName,L"DEBUG");