Index: src/liblogger/TLogFile.cpp =================================================================== diff -u -N -r800b6e4dd2e62623eab76ac2d16d63af2a67a045 -r545098ae76e9ce23598d37d2bee4020d6cb59f3c --- src/liblogger/TLogFile.cpp (.../TLogFile.cpp) (revision 800b6e4dd2e62623eab76ac2d16d63af2a67a045) +++ src/liblogger/TLogFile.cpp (.../TLogFile.cpp) (revision 545098ae76e9ce23598d37d2bee4020d6cb59f3c) @@ -25,163 +25,166 @@ namespace logger { - TLogFile::TLogFile(PCTSTR pszPath, const TLoggerRotationInfoPtr& spRotationInfo) : - m_strLogPath(pszPath), - m_spFileHandle(), - m_spRotationInfo(spRotationInfo) + namespace internal { - if(!pszPath) - throw std::invalid_argument("pszPath"); - if(!spRotationInfo) - throw std::invalid_argument("spRotationInfo"); + TLogFile::TLogFile(PCTSTR pszPath, const TLoggerRotationInfoPtr& spRotationInfo) : + m_strLogPath(pszPath), + m_spFileHandle(), + m_spRotationInfo(spRotationInfo) + { + if (!pszPath) + throw std::invalid_argument("pszPath"); + if (!spRotationInfo) + throw std::invalid_argument("spRotationInfo"); - ScanForRotatedLogs(); - } + ScanForRotatedLogs(); + } - void TLogFile::Write(std::list& rListEntries) - { - if (rListEntries.empty()) - return; - - try + void TLogFile::Write(std::list& rListEntries) { - std::wstring_convert> utf8Converter; + if (rListEntries.empty()) + return; - for (const std::wstring& rstrEntry : rListEntries) + try { - std::string strUtf8Line = utf8Converter.to_bytes(rstrEntry); + std::wstring_convert> utf8Converter; - size_t stEntryLen = strUtf8Line.length(); - if (NeedRotation(stEntryLen)) - RotateFile(); + for (const std::wstring& rstrEntry : rListEntries) + { + std::string strUtf8Line = utf8Converter.to_bytes(rstrEntry); - DWORD dwWritten = 0; - if (!WriteFile(GetFileHandle(), strUtf8Line.c_str(), boost::numeric_cast(stEntryLen), &dwWritten, nullptr)) - throw std::runtime_error("Cannot write to log, system error"); + size_t stEntryLen = strUtf8Line.length(); + if (NeedRotation(stEntryLen)) + RotateFile(); + + DWORD dwWritten = 0; + if (!WriteFile(GetFileHandle(), strUtf8Line.c_str(), boost::numeric_cast(stEntryLen), &dwWritten, nullptr)) + throw std::runtime_error("Cannot write to log, system error"); + } } + catch (const std::exception&) + { + rListEntries.clear(); + return; + } + + m_timeLastWriteTime = time(nullptr); + rListEntries.clear(); } - catch (const std::exception&) + + void TLogFile::CloseIfUnused() { - rListEntries.clear(); - return; + if (time(nullptr) - m_timeLastWriteTime > MaxHandleCacheTime) + CloseLogFile(); } - m_timeLastWriteTime = time(nullptr); - rListEntries.clear(); - } + void TLogFile::CloseLogFile() + { + m_spFileHandle.reset(); + } - void TLogFile::CloseIfUnused() - { - if (time(nullptr) - m_timeLastWriteTime > MaxHandleCacheTime) - CloseLogFile(); - } + HANDLE TLogFile::GetFileHandle() + { + if (m_spFileHandle != nullptr) + return m_spFileHandle.get(); - void TLogFile::CloseLogFile() - { - m_spFileHandle.reset(); - } + HANDLE hFile = CreateFile(m_strLogPath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + if (hFile == INVALID_HANDLE_VALUE) + throw std::runtime_error("Cannot open log file"); - HANDLE TLogFile::GetFileHandle() - { - if (m_spFileHandle != nullptr) - return m_spFileHandle.get(); + m_spFileHandle.reset(hFile, CloseHandle); - HANDLE hFile = CreateFile(m_strLogPath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); - if (hFile == INVALID_HANDLE_VALUE) - throw std::runtime_error("Cannot open log file"); + LARGE_INTEGER liSeek = { 0 }; - m_spFileHandle.reset(hFile, CloseHandle); + BOOL bRes = SetFilePointerEx(hFile, liSeek, nullptr, SEEK_END); + if (!bRes) + throw std::runtime_error("Cannot seek to the end of log file"); - LARGE_INTEGER liSeek = { 0 }; + return m_spFileHandle.get(); + } - BOOL bRes = SetFilePointerEx(hFile, liSeek, nullptr, SEEK_END); - if (!bRes) - throw std::runtime_error("Cannot seek to the end of log file"); + unsigned long long TLogFile::GetCurrentLogSize() + { + LARGE_INTEGER liSize = { 0 }; + if (!GetFileSizeEx(GetFileHandle(), &liSize)) + throw std::runtime_error("Cannot determine current log size"); - return m_spFileHandle.get(); - } + return liSize.QuadPart; + } - unsigned long long TLogFile::GetCurrentLogSize() - { - LARGE_INTEGER liSize = { 0 }; - if (!GetFileSizeEx(GetFileHandle(), &liSize)) - throw std::runtime_error("Cannot determine current log size"); + void TLogFile::RotateFile() + { + m_spFileHandle.reset(); - return liSize.QuadPart; - } + std::wstring pathNew = m_strLogPath; + if (boost::iends_with(pathNew, L".log")) + pathNew.erase(pathNew.end() - 4, pathNew.end()); - void TLogFile::RotateFile() - { - m_spFileHandle.reset(); + boost::posix_time::ptime timeNow = boost::posix_time::microsec_clock::local_time(); + boost::posix_time::wtime_facet* facet = new boost::posix_time::wtime_facet(); + facet->format(L"%Y%m%d%H%M%S%f"); + std::wstringstream stream; + stream.imbue(std::locale(std::locale::classic(), facet)); + stream << timeNow; + pathNew += L"."; + pathNew += stream.str().c_str(); + pathNew += L".log"; - std::wstring pathNew = m_strLogPath; - if (boost::iends_with(pathNew, L".log")) - pathNew.erase(pathNew.end() - 4, pathNew.end()); + if (!MoveFile(m_strLogPath.c_str(), pathNew.c_str()) && GetLastError() != ERROR_FILE_NOT_FOUND) + throw std::runtime_error("Cannot rotate file"); - boost::posix_time::ptime timeNow = boost::posix_time::microsec_clock::local_time(); - boost::posix_time::wtime_facet* facet = new boost::posix_time::wtime_facet(); - facet->format(L"%Y%m%d%H%M%S%f"); - std::wstringstream stream; - stream.imbue(std::locale(std::locale::classic(), facet)); - stream << timeNow; - pathNew += L"."; - pathNew += stream.str().c_str(); - pathNew += L".log"; + m_vRotatedFiles.push_back(std::move(pathNew)); + RemoveObsoleteRotatedLogs(); + } - if (!MoveFile(m_strLogPath.c_str(), pathNew.c_str()) && GetLastError() != ERROR_FILE_NOT_FOUND) - throw std::runtime_error("Cannot rotate file"); + void TLogFile::RemoveObsoleteRotatedLogs() + { + while (m_vRotatedFiles.size() > m_spRotationInfo->GetMaxRotatedCount()) + { + auto iterRotatedFile = m_vRotatedFiles.begin(); + if (!DeleteFile(iterRotatedFile->c_str())) + break; - m_vRotatedFiles.push_back(std::move(pathNew)); - RemoveObsoleteRotatedLogs(); - } + m_vRotatedFiles.erase(iterRotatedFile); + } + } - void TLogFile::RemoveObsoleteRotatedLogs() - { - while (m_vRotatedFiles.size() > m_spRotationInfo->GetMaxRotatedCount()) + void TLogFile::ScanForRotatedLogs() { - auto iterRotatedFile = m_vRotatedFiles.begin(); - if (!DeleteFile(iterRotatedFile->c_str())) - break; + std::wstring strSearchMask = m_strLogPath; + std::wstring strDir; - m_vRotatedFiles.erase(iterRotatedFile); - } - } + size_t stDirPos = strSearchMask.find_last_of(L"\\/"); + if (stDirPos != std::wstring::npos) + strDir = strSearchMask.substr(0, stDirPos + 1); - void TLogFile::ScanForRotatedLogs() - { - std::wstring strSearchMask = m_strLogPath; - std::wstring strDir; + if (boost::iends_with(strSearchMask, L".log")) + strSearchMask.erase(strSearchMask.end() - 4, strSearchMask.end()); + strSearchMask += L".*.log"; - size_t stDirPos = strSearchMask.find_last_of(L"\\/"); - if (stDirPos != std::wstring::npos) - strDir = strSearchMask.substr(0, stDirPos + 1); + std::vector vPaths; + WIN32_FIND_DATA wfd = { 0 }; - if (boost::iends_with(strSearchMask, L".log")) - strSearchMask.erase(strSearchMask.end() - 4, strSearchMask.end()); - strSearchMask += L".*.log"; + HANDLE hFind = FindFirstFile(strSearchMask.c_str(), &wfd); + BOOL bFound = (hFind != INVALID_HANDLE_VALUE); + while (bFound) + { + std::wstring strLogFullPath = strDir + wfd.cFileName; + vPaths.push_back(strLogFullPath); - std::vector vPaths; - WIN32_FIND_DATA wfd = { 0 }; + bFound = FindNextFile(hFind, &wfd); + } - HANDLE hFind = FindFirstFile(strSearchMask.c_str(), &wfd); - BOOL bFound = (hFind != INVALID_HANDLE_VALUE); - while (bFound) + std::sort(vPaths.begin(), vPaths.end(), [](const std::wstring& path1, const std::wstring& path2) { return boost::ilexicographical_compare(path1, path2); }); + std::swap(m_vRotatedFiles, vPaths); + } + + bool TLogFile::NeedRotation(size_t stDataSize) { - std::wstring strLogFullPath = strDir + wfd.cFileName; - vPaths.push_back(strLogFullPath); + unsigned long long ullCurrentSize = GetCurrentLogSize(); + unsigned long long ullMaxLogSize = m_spRotationInfo->GetMaxLogSize(); - bFound = FindNextFile(hFind, &wfd); + return ullCurrentSize + stDataSize > ullMaxLogSize; } - - std::sort(vPaths.begin(), vPaths.end(), [](const std::wstring& path1, const std::wstring& path2) { return boost::ilexicographical_compare(path1, path2); }); - std::swap(m_vRotatedFiles, vPaths); } - - bool TLogFile::NeedRotation(size_t stDataSize) - { - unsigned long long ullCurrentSize = GetCurrentLogSize(); - unsigned long long ullMaxLogSize = m_spRotationInfo->GetMaxLogSize(); - - return ullCurrentSize + stDataSize > ullMaxLogSize; - } }