閑得無聊,瞎寫的一個東西。
好多地方能夠優化甚至可能重寫,也沒寫,就記下了個思路在這里。
主要熟練一下C++17的內容。
version = 0.1
lc_log .h
1 #pragma once 2 #include <stdio.h> 3 4 namespace LC 5 { 6 namespace LC_LOG 7 { 8 class Log final 9 { 10 public: 11 Log(const Log&) = delete; 12 Log& operator=(const Log&) = delete; 13 14 Log(const char* szPath = nullptr); 15 ~Log(); 16 17 private: 18 bool __Open(const char* szPath); 19 int __Close(); 20 bool __Write(const char* szTime, const char* szFile, const char* szLine, const char* szType, const char* szMsg); 21 //int __Lock(bool isLock); 22 23 private: 24 friend class LogMgr; 25 friend class LogFileInfo; 26 FILE* _pFile = nullptr; 27 }; 28 29 }; 30 };
lc_log.cpp
1 #include "lc_log.h" 2 #include <sys/fcntl.h> 3 #include <unistd.h> 4 #include <stdlib.h> 5 #include <sstream> 6 7 namespace LC 8 { 9 namespace LC_LOG 10 { 11 Log::Log(const char* szPath) 12 { 13 if(szPath == nullptr) 14 return; 15 16 __Close(); 17 __Open(szPath); 18 } 19 20 Log::~Log() 21 { 22 __Close(); 23 } 24 25 bool Log::__Open(const char* szPath) 26 { 27 if(szPath == nullptr) 28 return false; 29 30 #ifdef WIN32 31 fopen_s(&_pFile, szPath, "at+"); 32 #else 33 _pFile = fopen(szPath, "at+"); 34 #endif 35 36 return _pFile == nullptr; 37 } 38 39 bool Log::__Write(const char* szTime, const char* szFile, const char* szLine, const char* szType, const char* szMsg) 40 { 41 if(_pFile == nullptr) 42 return false; 43 44 std::stringstream szlog; 45 szlog \ 46 << "[" << szType \ 47 << "] time: " << szTime \ 48 << " file: " << szFile \ 49 << " line: " << szLine \ 50 << " " << szMsg \ 51 << std::endl; 52 53 //__Lock(true); 54 int res = fputs(szlog.str().c_str(), _pFile); 55 //__Lock(false); 56 57 return res >= 0; 58 } 59 60 // int Log::__Lock(bool isLock) 61 // { 62 // #ifdef _LINUX 63 // return lockf(fileno(_pFile), isLock ? F_LOCK : F_ULOCK, 0); 64 // #else //windows 65 // //TOOD: 66 // // 67 // return 0; 68 // #endif 69 // } 70 71 int Log::__Close() 72 { 73 if(!_pFile) return 0; 74 return fclose(_pFile); 75 } 76 }; 77 };
lc_logmgr.h
1 #pragma once 2 #include "lc_log.h" 3 #include <unordered_map> 4 #include <time.h> 5 #include <filesystem> 6 #include <sstream> 7 #include <string> 8 #include <future> 9 #include <condition_variable> 10 11 namespace LC 12 { 13 namespace LC_LOG 14 { 15 #define LOG_INFO "INFO" 16 #define LOG_WARNING "WARNING" 17 #define LOG_CHECKIT "CHECKIT" 18 #define LOG_ERROR "ERROR" 19 #define LOG_FATAL "FATAL" 20 21 #define LOGFILE_MAX_SIZE (10 * 1024 * 1024) 22 #define LOGNAME_MAX_LENGTH 128 23 #define LOGNAME_PREFIX "Log" 24 #define LOGNAME_SUFFIX ".log" 25 #define LOG_IS_NEED_LOCK true 26 27 // #ifdef _WIN32 28 // #define SEP "\\" 29 // #else 30 #define SEP "/" 31 //#endif 32 33 #define LOGID uint64_t 34 35 #define __STR_LC(s) #s 36 #define _STR_LC(s) __STR_LC(s) 37 38 //@format "%Y-%m-%d %H:%M:%S" 39 extern void __str_time(char* out, const char* format = "%Y-%m-%d"); 40 41 template<typename T> 42 void __getmsg(std::stringstream& ss, T&& value) 43 { 44 ss << value; 45 } 46 47 template<typename T, typename ... Ts> 48 void __getmsg(std::stringstream& ss, T&& value, Ts&& ... args) 49 { 50 ss << value; 51 __getmsg(ss, std::forward<Ts>(args) ...); 52 } 53 54 struct __LogMsgBase 55 { 56 std::string _file; 57 std::string _line; 58 std::string _time; 59 60 __LogMsgBase& instance() 61 { 62 static __LogMsgBase ins; 63 return ins; 64 } 65 }; 66 67 struct LogFileInfo 68 { 69 LogFileInfo() 70 : _num(0) 71 , _pLog(nullptr) 72 { 73 } 74 75 ~LogFileInfo(); 76 77 std::string _title; 78 std::string _basePath; 79 int _num; 80 81 std::string _name; 82 Log* _pLog; 83 84 void GetPath(std::string& out) const; 85 void InitName(); 86 void ReOpen(); 87 static void BaseName(const std::string& title, std::string& out); 88 }; 89 90 class LogMgr final 91 { 92 private: 93 LogMgr(); 94 95 public: 96 ~LogMgr(); 97 98 static LogMgr& Instance() 99 { 100 static LogMgr ins; 101 return ins; 102 } 103 104 bool Register(LOGID id, const char* path, const char* title); 105 106 template<typename ... TArgs> 107 bool WriteLog(LOGID id, const char* type, const char* time, const char* file, const char* line, TArgs&& ... args); 108 109 private: 110 std::unordered_map<LOGID, LogFileInfo* > _mLogs; 111 112 #if LOG_IS_NEED_LOCK 113 std::mutex _mx; 114 #endif 115 //std::future<bool> _thRun; 116 }; 117 118 119 template<typename ... TArgs> 120 bool LogMgr::WriteLog(LOGID id, const char* type, const char* time, const char* file, const char* line, TArgs&& ... args) 121 { 122 #if LOG_IS_NEED_LOCK 123 std::unique_lock<std::mutex> ul(_mx); 124 #endif 125 126 auto it = _mLogs.find(id); 127 if(it == _mLogs.end()) 128 return false; 129 130 LogFileInfo* pInfo = it->second; 131 Log* pLog = pInfo->_pLog; 132 if(nullptr == pLog) 133 return false; 134 135 std::string fullPath; 136 pInfo->GetPath(fullPath); 137 138 while(std::filesystem::exists(fullPath.c_str()) 139 && std::filesystem::file_size(fullPath.c_str()) >= LOGFILE_MAX_SIZE) 140 { 141 pInfo->_num++; 142 pInfo->InitName(); 143 pInfo->GetPath(fullPath); 144 pInfo->ReOpen(); 145 } 146 147 std::stringstream ss; 148 __getmsg(ss, args...); 149 150 return pLog->__Write(time, file, line, type, ss.str().c_str()); 151 } 152 153 #define RegisterLogger(id, path, title) LC::LC_LOG::LogMgr::Instance().Register(id, path, title) 154 155 #define LogWriteBase(id, type, msg...) \ 156 do{ \ 157 char timestr[64]; \ 158 LC::LC_LOG::__str_time(timestr, "%Y-%m-%d %H:%M:%S"); \ 159 LC::LC_LOG::LogMgr::Instance().WriteLog(id, type, timestr, __FILE__, _STR_LC(__LINE__), msg); \ 160 }while(0) 161 }; 162 };
lc_logmgr.cpp
1 #include "lc_logmgr.h" 2 #include <stdio.h> 3 #include <stdlib.h> 4 5 namespace LC 6 { 7 namespace LC_LOG 8 { 9 void __str_time(char* out, const char* format) 10 { 11 if(out == nullptr) 12 return; 13 14 time_t t = time(NULL); 15 strftime(out, 64, format, localtime(&t)); 16 } 17 18 LogFileInfo::~LogFileInfo() 19 { 20 delete _pLog; 21 } 22 23 void LogFileInfo::GetPath(std::string& out) const 24 { 25 out.clear(); 26 27 out += _basePath; 28 const char& last = _basePath.back(); 29 if(!(last == '/' || last == '\\')) 30 out.append(SEP); 31 32 out.append(_name); 33 } 34 35 void LogFileInfo::InitName() 36 { 37 BaseName(_title, _name); 38 if(_num > 0) 39 _name.append("_").append(std::to_string(_num)); 40 41 _name.append(LOGNAME_SUFFIX); 42 } 43 44 void LogFileInfo::ReOpen() 45 { 46 if(_pLog == nullptr) 47 return; 48 49 std::string fullpath; 50 GetPath(fullpath); 51 _pLog->__Close(); 52 _pLog->__Open(fullpath.c_str()); 53 } 54 55 void LogFileInfo::BaseName(const std::string& title, std::string& out) 56 { 57 out.clear(); 58 59 char strtime[64]; 60 __str_time(strtime); 61 out 62 .append(LOGNAME_PREFIX) 63 .append("_") 64 .append(title) 65 .append("_") 66 .append(strtime); 67 } 68 69 LogMgr::LogMgr() 70 { 71 // _thRun = std::async(std::launch::deferred, 72 // []() -> bool 73 // { 74 75 // }, 76 // ); 77 } 78 79 LogMgr::~LogMgr() 80 { 81 for (auto& pairEach : _mLogs) 82 { 83 LogFileInfo* pInfo = pairEach.second; 84 delete pInfo; 85 } 86 _mLogs.clear(); 87 } 88 89 bool LogMgr::Register(LOGID id, const char* path, const char* title) 90 { 91 #if LOG_IS_NEED_LOCK 92 std::unique_lock<std::mutex> ul(_mx); 93 #endif 94 95 if(_mLogs.find(id) != _mLogs.end()) 96 return true; 97 98 LogFileInfo* pInfo = new LogFileInfo(); 99 if(pInfo == nullptr) 100 return false; 101 102 pInfo->_basePath = path; 103 pInfo->_title = title; 104 { 105 pInfo->InitName(); 106 107 std::string fullPath; 108 pInfo->GetPath(fullPath); 109 110 if(!(std::filesystem::exists(fullPath.c_str()) 111 && std::filesystem::file_size(fullPath.c_str()) >= LOGFILE_MAX_SIZE)) 112 { 113 pInfo->_pLog = new Log(fullPath.c_str()); 114 if(pInfo->_pLog == nullptr) 115 { 116 delete pInfo; 117 return false; 118 } 119 _mLogs.insert(std::make_pair(id, pInfo)); 120 return true; 121 } 122 } 123 124 int num = 1; 125 do 126 { 127 pInfo->_num = num; 128 pInfo->InitName(); 129 130 std::string fullPath; 131 pInfo->GetPath(fullPath); 132 if(std::filesystem::exists(fullPath.c_str()) 133 && std::filesystem::file_size(fullPath.c_str()) >= LOGFILE_MAX_SIZE) 134 { 135 ++num; continue; 136 } 137 138 pInfo->_pLog = new Log(fullPath.c_str()); 139 if(pInfo->_pLog == nullptr) 140 { 141 //delete pInfo; 142 return false; 143 } 144 _mLogs.insert(std::make_pair(id, pInfo)); 145 return true; 146 } while (num < 10000); 147 148 return false; 149 } 150 }; 151 };
main.cpp
1 #include <iostream> 2 #include <vector> 3 4 #include <time.h> 5 #include <string> 6 #include <thread> 7 #include <future> 8 #include <sstream> 9 #include <chrono> 10 #include "lc_logmgr.h" 11 12 #define C_SS(s) # s 13 #define _GETMSG(ss, args...) getmsg(ss, args) 14 15 #define __STR_LC(s) #s 16 #define _STR_LC(s) __STR_LC(s) 17 18 struct item 19 { 20 void show(const std::string& s) 21 { 22 std::cout << s << std::endl; 23 } 24 }; 25 26 template<typename T> 27 void getmsg(std::stringstream& ss, T&& value) 28 { 29 ss << value; 30 } 31 32 template<typename T, typename ... Ts> 33 void getmsg(std::stringstream& ss, T&& value, Ts&& ... args) 34 { 35 ss << value; 36 getmsg(ss, std::forward<Ts>(args) ...); 37 return; 38 } 39 40 using namespace std::chrono; 41 int main() 42 { 43 item t; 44 std::string sss = "qwe"; 45 RegisterLogger(0x01, "./", "TEST"); 46 47 std::thread th1([](){ 48 for (size_t i = 0; i < 100000; i++) 49 { 50 LogWriteBase(0x01, LOG_INFO, "a ", i, " ", 2 * i + 3); 51 } 52 std::cout << "log a over. " << std::endl; 53 }); 54 55 std::thread th2([](){ 56 for (size_t i = 0; i < 100000; i++) 57 { 58 LogWriteBase(0x01, LOG_INFO, "b ", i, " ", 2 * i + 3); 59 } 60 std::cout << "log b over. " << std::endl; 61 }); 62 63 std::thread th3([](){ 64 for (size_t i = 0; i < 100000; i++) 65 { 66 LogWriteBase(0x01, LOG_INFO, "c ", i, " ", 2 * i + 3); 67 } 68 std::cout << "log c over. " << std::endl; 69 }); 70 71 th1.join(); 72 th2.join(); 73 th3.join(); 74 75 // auto time_now = system_clock::now(); 76 // auto duration_in_ms = duration_cast<milliseconds>(time_now.time_since_epoch()); 77 // uint64_t nFactTime = duration_in_ms.count(); 78 // for (size_t i = 0; i < 100000; i++) 79 // { 80 // LogWriteBase(0x01, LOG_INFO, "qwe", i, " ", 2 * i + 3); 81 // } 82 83 // auto time_now2 = system_clock::now(); 84 // auto duration_in_ms2 = duration_cast<milliseconds>(time_now2.time_since_epoch()); 85 // uint64_t nFactTime2 = duration_in_ms2.count(); 86 // std::cout << nFactTime2 - nFactTime << std::endl; 87 88 std::cout << "-----over-----" << std::endl; 89 return 0; 90 }
我發現我越來越懶,咋辦。。。