#include "stdafx.h" #include "Logger.h" #define FILE_SIZE 1024*1024 // 1m #include Logger::Logger() { m_isStop = true; m_LogThread = nullptr; m_LogDir = "./log"; m_LogFileName = "log"; m_LogSize = FILE_SIZE * 20; } Logger::~Logger() { Stop(); } bool Logger::Init(const std::string& logDir, const std::string& logFileName) { m_LogDir = logDir; m_LogFileName = logFileName; m_LogSize = FILE_SIZE * 20; if (!boost::filesystem::exists(m_LogDir)) { return boost::filesystem::create_directories(m_LogDir); } return true; } bool Logger::Start() { if (m_isStop) { m_isStop = false; if (m_LogThread == nullptr) { m_LogThread = std::make_shared(std::bind(&Logger::__dealLogItem, this)); } } return true; } bool Logger::Stop() { try { if (!m_isStop) { m_isStop = true; m_LogCond.notify_one(); if (m_LogThread != nullptr && m_LogThread->joinable()) { m_LogThread->join(); } } } catch (const std::exception& e) { std::cout << e.what() << std::endl; return false; } return true; } std::string Logger::Log(const char * format, ...) { if (m_isStop) return ""; boost::posix_time::ptime pt = boost::posix_time::microsec_clock::local_time(); auto ptStr = boost::posix_time::to_iso_extended_string(pt); ptStr = std::regex_replace(ptStr, std::regex("T"), " "); // 解析日志信息参数 char szMsgBuffer[2048]; memset(szMsgBuffer, 0, sizeof(szMsgBuffer)); va_list ap; va_start(ap, format); vsnprintf(szMsgBuffer, sizeof(szMsgBuffer), format, ap); va_end(ap); std::string str(szMsgBuffer); __pushLogItem(ptStr, 1, str); return str; } void Logger::__pushLogItem(const std::string & data, const int & level, const std::string & content) { std::shared_ptr pLogItem = std::make_shared(data); if (pLogItem) { pLogItem->SetItem(level, content); std::unique_locklock(m_LogMut); m_LogList.emplace_back(pLogItem); m_LogCond.notify_one(); } } void Logger::__dealLogItem() { while (!m_isStop) { std::unique_locklock(m_LogMut); m_LogCond.wait(lock); lock.unlock(); if (m_isStop) break; auto pOutFile = __openFile(); for (; !m_isStop;) { std::unique_locklock1(m_LogMut); if (m_LogList.empty()) break; auto pLogItem = std::move(m_LogList.front()) ; m_LogList.pop_front(); lock1.unlock(); if (pLogItem) { std::cout << *pLogItem << std::endl; *pOutFile << *pLogItem << std::endl; pOutFile->flush(); } } pOutFile->close(); } std::cout << "线程结束" << std::endl; } std::shared_ptr Logger::__openFile() { boost::posix_time::ptime pt = boost::posix_time::microsec_clock::local_time(); auto date = boost::posix_time::to_iso_extended_string(pt); date = date.substr(0,date.find("T")); static std::string lastDate = date; static int index = 1; std::streampos size = 0; std::string filePath = "log.txt"; do { // 第二天,文件索引重置 if (lastDate != date) { lastDate = date; index = 1; } // 文件路径拼接,创建 filePath = ""; filePath = filePath.append(m_LogDir).append("/").append(date).append("/"); if (!boost::filesystem::exists(filePath)) { boost::filesystem::create_directories(filePath); } filePath = filePath.append(m_LogFileName).append("_").append(std::to_string(index)).append(".txt"); std::ifstream infile(filePath, std::ifstream::in | std::ifstream::binary); infile.seekg(std::ios::beg, std::ios::end); size = infile.tellg(); // 字节 infile.close(); if (size > m_LogSize) ++index; } while (size > m_LogSize); std::shared_ptr pOutFile = std::make_shared(); pOutFile->open(filePath, std::ios::app); return pOutFile; } //Logger Logger::pInstance; std::shared_ptr Logger::pInstance = std::make_shared();