nim_duilib/tool_kits/shared/log.cpp
2019-04-19 17:19:57 +08:00

251 lines
4.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "stdafx.h"
#include "log.h"
void QLogImpl::SetLogFile( const std::wstring &file_path )
{
log_file_ = file_path;
}
std::wstring QLogImpl::GetLogFile()
{
return log_file_;
}
void QLogImpl::SetLogLevel( LOG_LEVEL lv )
{
log_level_ = lv;
}
void QLogImpl::WriteLog( LOG_LEVEL lv, const std::wstring &log )
{
#ifdef _DEBUG
fwprintf_s( stdout, L"%s", log.c_str() );
#endif
#ifdef _WINDOWS
OutputDebugStringW( log.c_str() );
#endif
if( lv > log_level_ )
return;
if( log_file_.empty() )
return;
std::string str = nbase::UTF16ToUTF8(log);
nbase::NAutoLock auto_lock( &lock_ );
bool exist = nbase::FilePathIsExist(log_file_, false);
std::unique_ptr<FILE, nbase::DeleterFileClose> fp;
FILE* fp_file = nullptr;
_wfopen_s(&fp_file, log_file_.c_str(), L"a+");
fp.reset(fp_file);
if( !fp )
return;
if( !exist )
{
const char utf8[3] = { (char) 0xEF, (char) 0xBB, (char) 0xBF };
fwrite(utf8, sizeof(char), 3, fp.get() );
}
fwrite(str.c_str(), sizeof(char), str.size(), fp.get());
fp.reset(NULL);
}
void QLogImpl::HalfTo( long max, long to )
{
nbase::NAutoLock auto_lock( &lock_);
//打开文件
std::unique_ptr<FILE, nbase::DeleterFileClose> fp;
FILE* fp_file = nullptr;
_wfopen_s(&fp_file, log_file_.c_str(), L"r");
fp.reset(fp_file);
if(!fp)
{
fp.reset(NULL);
return;
}
//获取长度
int ret = fseek(fp.get(), 0L, SEEK_END);
if (ret != 0)
{
return;
}
//小于max则直接返回
long len = ftell(fp.get());
if(len <= max)
{
return;
}
//大于max只留下最后to
len = max * (-1);
ret = fseek(fp.get(), len, SEEK_END);
if (ret != 0)
{
return;
}
//创建新文件
nbase::PathString new_file = log_file_ + L".old";
std::unique_ptr<FILE, nbase::DeleterFileClose> fp2;
FILE* fp_file2 = nullptr;
_wfopen_s(&fp_file2, new_file.c_str(), L"w");
fp2.reset(fp_file2);
if(!fp2)
{
return;
}
//写入新文件
char cbuf[12 * 1024] = { 0 };
int cn = sizeof(cbuf), n = 0;
while(!feof(fp.get()))
{
n = fread_s(cbuf, cn, sizeof(char), cn, fp.get());
if(n > 0)
{
fwrite(cbuf, sizeof(char), n, fp2.get());
}
else
{
break;
}
}
fp.reset(NULL);
fp2.reset(NULL);
//文件替换
bool del = nbase::DeleteFileW(log_file_);
if(del)
{
::_wrename(new_file.c_str(), log_file_.c_str());
}
else
{
nbase::DeleteFileW(new_file);
}
}
QLogHelper::QLogHelper( const char* file, long line )
{
index_ = 0;
level_ = LV_PRO;
nbase::Time::TimeStruct qt = nbase::Time::Now().ToTimeStruct(true);
time_ = nbase::StringPrintf( L"[%04d-%02d-%02d %02d:%02d:%02d",
qt.year_, qt.month_, qt.day_of_month_, qt.hour_, qt.minute_, qt.second_);
std::wstring str = nbase::UTF8ToUTF16(file);
std::wstring file_name;
nbase::FilePathApartFileName(str, file_name);
file_line_ = nbase::StringPrintf( L" %s:%ld ", file_name.c_str(), line );
}
QLogHelper::~QLogHelper()
{
std::wstring lv;
switch( level_ )
{
case LV_ERR:
lv = L"LV_ERR";
break;
case LV_WAR:
lv = L"LV_WAR";
break;
case LV_APP:
lv = L"LV_APP";
break;
case LV_PRO:
lv = L"LV_PRO";
break;
default:
assert( 0 );
break;
}
lv.append( L"] " );
if( string_.empty() )
string_ = fmt_;
else if( !fmt_.empty() )
string_.append(fmt_);
std::wstring log = time_ + file_line_ + lv + string_ + L"\r\n";
QLogImpl::GetInstance()->WriteLog( level_, log );
}
QLogHelper& QLogHelper::VLog( LOG_LEVEL lv, const std::wstring &fmt )
{
level_ = lv;
fmt_ = fmt;
return *this;
}
QLogHelper& QLogHelper::operator<<(const std::wstring &str)
{
int len = 0;
size_t pos = FindArg( len );
if( pos == fmt_.npos )
{
assert( 0 );
}
else
{
string_.append( fmt_.substr( 0, pos ) );
string_.append( str );
fmt_.erase( 0, pos + len );
}
index_++;
return *this;
}
QLogHelper& QLogHelper::operator<<(const std::string &str)
{
std::wstring wstr = nbase::UTF8ToUTF16(str);
return this->operator<<(wstr);
}
QLogHelper& QLogHelper::operator<<(const long long lld)
{
int len = 0;
size_t pos = FindArg( len );
if( pos == fmt_.npos )
{
assert( 0 );
}
else
{
std::wstring data = nbase::Int64ToString16(lld);
string_.append( fmt_.substr( 0, pos ) );
string_.append( data );
fmt_.erase( 0, pos + len );
}
index_++;
return *this;
}
size_t QLogHelper::FindArg( int &len )
{
assert( !fmt_.empty() );
assert( index_ >= 0 && index_ <= 20 );
std::wstring str = nbase::StringPrintf(L"{%d}", index_);
len = str.size();
return fmt_.find( str );
}