项目中每天都会生成日志文件,日志主要有log4cpp生成,每天生成一个以日期命名的文件夹,磁盘占用空间较大。故对日志进行压缩操作。压缩后的日志按照月为目录,最每天的日志文件夹压缩成一个zip包存放。
封装中用到的库:
1.ZIP开源库 连接地址:https://download.youkuaiyun.com/download/zhengleiaixirui/11161636
2.BOOST库 请自行按照需求自己编译
注意事项:
1.压缩处理只需要在创建CLogBackup对象的时候传入日志源地址和目标地址即可
2.由于CLogBackup类中是在线程中对日志进行压缩处理,因此不能以简单的对象方式在局部作用于中使用,需要使用new来动态创建,保证线程在处理过程中对象的生命周期不会被终止。
头文件定义
#pragma once
class CLogBackup
{
public:
CLogBackup(void);
// strRoot 需要进行操作的根目录
// strBackPath 备份文件存放的根目录
CLogBackup(std::string strRoot, std::string strBackPath);
~CLogBackup(void);
public:
//日期目录下日志文件列表
//如:
// xfs/log/2018-01-07/DEV.log
// xfs/log/2018-01-07/FSN.log
std::map<std::string , std::vector<std::string> > map_file_list;
std::string strRootPath; //文件处理根目录
std::string strCurrentLogRootPath; //当前日志文件所在目录
std::string strLogBackupPath; //日志备份目录
std::string strCurrentZipName; //当前日志备份文件名称
std::string strCurrentData; //当前日期
public:
//遍历日志目录根目录,列出当前目录下的所有日志文件信息
bool researchLogRootPath( std::string strDesPath );
//检查日志备份目录,如果不存在创建备份目录
bool checkBackupFolder( );
//将压缩文件存放到备份目录
//压缩文件存放原则:
//每月第一天生成以当月日志命名的ZIP文件,如2018-01.zip
//本月所生成的按天记录的日志文件夹压缩后存放于该zip文件中
bool zipLogFile( );
//用于将压缩后的原日志文件目录删除
BOOL DeleteDirectory(const char * DirName);
};
CPP实现
#include "LogBackup.h"
#include "zip.h"
#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/path.hpp>
DWORD THREAD_FUNC_BACK( LPVOID lpParam );
CLogBackup::CLogBackup(void)
{
}
CLogBackup::CLogBackup(std::string strRoot, std::string strBackPath):
strRootPath(strRoot)
{
if( !boost::algorithm::ends_with(strRootPath, "\\") )
strRootPath+="\\";
SYSTEMTIME sysTm; //当前操作系统时间和日期信息
GetLocalTime(&sysTm);
boost::format fmt_current_data("%d-%02d-%02d");
fmt_current_data %sysTm.wYear %sysTm.wMonth %sysTm.wDay;
strCurrentData = fmt_current_data.str( );
boost::format fmt_backup_path("%s\\%d-%02d\\");
fmt_backup_path %strBackPath %sysTm.wYear %sysTm.wMonth;
strLogBackupPath = fmt_backup_path.str( );
CLog::getInstace(MODULE_DEV).info("当前日期[%s]", strCurrentData.c_str() );
CLog::getInstace(MODULE_DEV).info("当前日志目录[%s]", strRootPath.c_str() );
CLog::getInstace(MODULE_DEV).info("日志文件备份目录[%s]", strLogBackupPath.c_str() );
DWORD ThreadID = 0;
HANDLE hThread=CreateThread( NULL,
0,
(LPTHREAD_START_ROUTINE)THREAD_FUNC_BACK,
this,
0,
&ThreadID );
if( hThread != NULL )
{
Sleep( 500 );
CloseHandle( hThread );
}
}
CLogBackup::~CLogBackup(void)
{
}
bool CLogBackup::researchLogRootPath( std::string strDesPath )
{
boost::filesystem::path path(strDesPath);
if (!boost::filesystem::exists(path))
{
return false;
}
boost::filesystem::directory_iterator end_iter;
for (boost::filesystem::directory_iterator iter(path); iter!=end_iter; ++iter)
{
if (boost::filesystem::is_regular_file(iter->status()))
{
map_file_list[strDesPath].push_back( iter->path().string() );
}
if (boost::filesystem::is_directory(iter->status()))
{
string strCurrentFolder = iter->path().string().substr(iter->path().string().rfind('\\')+1, -1);
if( strCurrentData.compare(strCurrentFolder)!=0 )
{
researchLogRootPath(iter->path().string());
}
}
}
return true;
}
bool CLogBackup::checkBackupFolder( )
{
boost::filesystem::path pathBackup(strLogBackupPath);
boost::system::error_code c;
if( !boost::filesystem::is_directory(pathBackup.c_str( ), c ) )
{
CLog::getInstace(MODULE_DEV).error("日志备份目录不存在[%s]", strLogBackupPath.c_str() );
//目录不存在重新创建目录
boost::filesystem::create_directories( pathBackup, c) ;
if( !boost::filesystem::exists(pathBackup) )
{
CLog::getInstace(MODULE_DEV).error("日志备份目录创建失败[%s] errorCode[%d]", strLogBackupPath.c_str(), c );
return false;
}
}
return true;
}
bool CLogBackup::zipLogFile( )
{
try
{
std::map<std::string, std::vector<std::string> >::iterator itr_file_list;
for( itr_file_list=map_file_list.begin(); itr_file_list!=map_file_list.end(); ++itr_file_list )
{
boost::filesystem::path pathTmp(itr_file_list->first);
boost::system::error_code c;
if( !boost::filesystem::is_directory(pathTmp.c_str( ), c ) )
{
CLog::getInstace(MODULE_DEV).error("路径异常[%d]", c);
continue;
}
std::string rootPath( itr_file_list->first);
boost::format fmt_current_back_filename("%s\\%s.zip");
fmt_current_back_filename %strLogBackupPath %rootPath.substr(rootPath.rfind('\\')+1, -1);
HZIP hz = CreateZip( (TCHAR*)fmt_current_back_filename.str( ).c_str(), NULL );
if( hz==NULL )
{
CLog::getInstace(MODULE_DEV).error("创建压缩文件失败");
continue;
}
std::vector<std::string>::iterator vec_log_list;
for( vec_log_list=itr_file_list->second.begin(); vec_log_list!=itr_file_list->second.end(); ++vec_log_list )
{
boost::filesystem::path pathLogFile( vec_log_list->c_str( ) );
if( !boost::filesystem::exists( pathLogFile ) )
{
CLog::getInstace(MODULE_DEV).error("路径异常[%s]", vec_log_list->c_str() );
}
else
{
string strLogname( pathLogFile.string( ) );
string strFileName= strLogname.substr(strLogname.rfind('\\')+1,strLogname.length() );
ZipAdd( hz, (TCHAR*)strFileName.c_str( ), (TCHAR*)strLogname.c_str( ) );
}
}
ZRESULT zRet = CloseZip(hz);
if( zRet==ZR_OK )
{
DeleteDirectory( itr_file_list->first.c_str( ) );
}
else
{
CLog::getInstace(MODULE_DEV).error("压缩文件关闭异常 errorCode=%d", zRet );
}
}
}
catch (...)
{
CLog::getInstace(MODULE_DEV).error("日志挂了");
}
return true;
}
DWORD THREAD_FUNC_BACK( LPVOID lpParam )
{
CLog::getInstace(MODULE_DEV).debug("日志压缩线程启动");
CLogBackup* pLogbak = (CLogBackup*)lpParam;
pLogbak->researchLogRootPath( pLogbak->strRootPath );
if( !pLogbak->checkBackupFolder( ) )
return -1;
pLogbak->zipLogFile( );
CLog::getInstace(MODULE_DEV).debug("日志压缩线程结束");
return 0;
}
BOOL CLogBackup::DeleteDirectory(const char * DirName)
{
if( DirName==NULL )
return FALSE;
try
{
boost::filesystem::path b_dir_path(DirName);
if(boost::filesystem::exists(b_dir_path))
{
boost::filesystem::remove_all(b_dir_path);
}
}
catch(boost::filesystem::filesystem_error & e)
{
CLog::getInstace(MODULE_DEV).error("DeleteDirectory what=[%s]", e.what());
return FALSE;
}
return TRUE;
}