简介
最近在调试一款SATA加密设备,发现设备有时加密出来的数据,再解密时与明文对不上,怀疑是通信问题。因此,急需要在测试工具中加入通信日志。由于对第三方日志库都不熟悉,所以随便选了个log4cplus软件集成到现有工具中。
下载地址:在这里
同时还要下载catch2, 在这里
同时还要下载threadpool, 在这里
下载完上述3个开源软件后,用Visual C++进行编译。
编译步骤如下:
- 分别解压log4cpp, catch2和threadpool到不同的目录。
- 把catch2解压后的内容复制到log4cplus的catch目录下,不包括最外层文件夹。
- 把threadpool解压后的内容复制到log4cplus目录下,包括threadpool文件夹本身。
进入到log4cplus/msvc14目录下,在log4cplus.sln上右键,使用visual studio 2019打开项目。
编译
打开项目后,面临编译选择:如下图:
其中,
log4cplus工程编译出来的是动态库
log4cplusS工程编译出来的是静态库。
由于我的工具很小,不希望依赖动态库,因此我选择了编译log4cplusS工程。
编译前要选择编译时使用的C++标准,否则编译时会报错。‘
如果下载的是log4cplus2.0.x版本,这版使用的是C++11标准,所以上图中的选择就可以。
如果下载的是log4cplus-master版本,2024年的今天,它使用的是C++20标准,所以要选择要C++20那行。
其他项目属性都不用动,直接编译x64 debug和 release版本,生成静态库。
静态库引入工程
封装一个类
此处参考:C++日志库log4cplus如何使用
#pragma once
#include <log4cplus/logger.h>
#include <log4cplus/fileappender.h>
#include <log4cplus/layout.h>
#include <log4cplus/ndc.h>
#include <log4cplus/helpers/loglog.h>
#include <log4cplus/helpers/property.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/initializer.h>
using namespace log4cplus;
using namespace log4cplus::helpers;
class MyLogger
{
private:
MyLogger()
{
log4cplus::initialize();
helpers::LogLog::getLogLog()->setInternalDebugging(true);
SharedObjectPtr<Appender> append_root(new RollingFileAppender(LOG4CPLUS_TEXT("root.log"), 10 * 1024 * 1024, 10, true, true));
append_root->setName(LOG4CPLUS_TEXT("root"));
std::string pattern = "%d [%c] %m %n";
std::unique_ptr<Layout> root_layout(new PatternLayout(pattern));
append_root->setLayout(move(root_layout));
m_rootLog = log4cplus::Logger::getRoot();
m_rootLog.addAppender(append_root);
m_rootLog.setLogLevel(ALL_LOG_LEVEL);
}
~MyLogger()
{
if (m_logger)
{
delete m_logger;
}
}
static MyLogger* m_logger;
public:
static MyLogger* getInstance()
{
if (m_logger == NULL)
{
m_logger = new MyLogger();
}
return m_logger;
}
log4cplus::Logger m_rootLog;
};
记录日志啦
//在需要记录日志的类中,添加include
#include "MyLogger.h"
//在通信异常的地方记录日志:
//如果明文与加密后又被解密出的数据不相等
if (0 != memcmp(data, output, param->datalen)) {
int iilen;
MyLogger* log = MyLogger::getInstance();
char* hex = new char[8192 * 3];
sprintf(hex, "Plain algo=%02X, mode=%d, len=%d:", param->algo, param->mode, param->datalen);
iilen = (int)strlen(hex);
StringUtil::Bin2Hex(data, &hex[iilen], param->datalen);
//记录明文数据
LOG4CPLUS_INFO(log->m_rootLog, hex);
sprintf(hex, "Encrypted algo=%02X, mode=%d, len=%d:", param->algo, param->mode, elen);
iilen = (int)strlen(hex);
StringUtil::Bin2Hex(endata, &hex[iilen], elen);
//记录密文数据
LOG4CPLUS_INFO(log->m_rootLog, hex);
sprintf(hex, "Decrypted algo=%02X, mode=%d, len=%d:", param->algo, param->mode, olen);
iilen = (int)strlen(hex);
StringUtil::Bin2Hex(output, &hex[iilen], olen);
//记录解密数据
LOG4CPLUS_INFO(log->m_rootLog, hex);
delete[] hex;
}
由于MyLogger::getInstance()返回的是静态成员指针,所以不需要每次用完都释放,可以在程序退出时释放一次就可以了。
完!