闲得无聊,瞎写的一个东西。

好多地方能够优化甚至可能重写,也没写,就记下了个思路在这里。

主要熟练一下C++17的内容。

version = 0.1

lc_log .h

  1. 1 #pragma once
  2. 2 #include <stdio.h>
  3. 3
  4. 4 namespace LC
  5. 5 {
  6. 6 namespace LC_LOG
  7. 7 {
  8. 8 class Log final
  9. 9 {
  10. 10 public:
  11. 11 Log(const Log&) = delete;
  12. 12 Log& operator=(const Log&) = delete;
  13. 13
  14. 14 Log(const char* szPath = nullptr);
  15. 15 ~Log();
  16. 16
  17. 17 private:
  18. 18 bool __Open(const char* szPath);
  19. 19 int __Close();
  20. 20 bool __Write(const char* szTime, const char* szFile, const char* szLine, const char* szType, const char* szMsg);
  21. 21 //int __Lock(bool isLock);
  22. 22
  23. 23 private:
  24. 24 friend class LogMgr;
  25. 25 friend class LogFileInfo;
  26. 26 FILE* _pFile = nullptr;
  27. 27 };
  28. 28
  29. 29 };
  30. 30 };

lc_log.cpp

  1. 1 #include "lc_log.h"
  2. 2 #include <sys/fcntl.h>
  3. 3 #include <unistd.h>
  4. 4 #include <stdlib.h>
  5. 5 #include <sstream>
  6. 6
  7. 7 namespace LC
  8. 8 {
  9. 9 namespace LC_LOG
  10. 10 {
  11. 11 Log::Log(const char* szPath)
  12. 12 {
  13. 13 if(szPath == nullptr)
  14. 14 return;
  15. 15
  16. 16 __Close();
  17. 17 __Open(szPath);
  18. 18 }
  19. 19
  20. 20 Log::~Log()
  21. 21 {
  22. 22 __Close();
  23. 23 }
  24. 24
  25. 25 bool Log::__Open(const char* szPath)
  26. 26 {
  27. 27 if(szPath == nullptr)
  28. 28 return false;
  29. 29
  30. 30 #ifdef WIN32
  31. 31 fopen_s(&_pFile, szPath, "at+");
  32. 32 #else
  33. 33 _pFile = fopen(szPath, "at+");
  34. 34 #endif
  35. 35
  36. 36 return _pFile == nullptr;
  37. 37 }
  38. 38
  39. 39 bool Log::__Write(const char* szTime, const char* szFile, const char* szLine, const char* szType, const char* szMsg)
  40. 40 {
  41. 41 if(_pFile == nullptr)
  42. 42 return false;
  43. 43
  44. 44 std::stringstream szlog;
  45. 45 szlog \
  46. 46 << "[" << szType \
  47. 47 << "] time: " << szTime \
  48. 48 << " file: " << szFile \
  49. 49 << " line: " << szLine \
  50. 50 << " " << szMsg \
  51. 51 << std::endl;
  52. 52
  53. 53 //__Lock(true);
  54. 54 int res = fputs(szlog.str().c_str(), _pFile);
  55. 55 //__Lock(false);
  56. 56
  57. 57 return res >= 0;
  58. 58 }
  59. 59
  60. 60 // int Log::__Lock(bool isLock)
  61. 61 // {
  62. 62 // #ifdef _LINUX
  63. 63 // return lockf(fileno(_pFile), isLock ? F_LOCK : F_ULOCK, 0);
  64. 64 // #else //windows
  65. 65 // //TOOD:
  66. 66 // //
  67. 67 // return 0;
  68. 68 // #endif
  69. 69 // }
  70. 70
  71. 71 int Log::__Close()
  72. 72 {
  73. 73 if(!_pFile) return 0;
  74. 74 return fclose(_pFile);
  75. 75 }
  76. 76 };
  77. 77 };

lc_logmgr.h

  1. 1 #pragma once
  2. 2 #include "lc_log.h"
  3. 3 #include <unordered_map>
  4. 4 #include <time.h>
  5. 5 #include <filesystem>
  6. 6 #include <sstream>
  7. 7 #include <string>
  8. 8 #include <future>
  9. 9 #include <condition_variable>
  10. 10
  11. 11 namespace LC
  12. 12 {
  13. 13 namespace LC_LOG
  14. 14 {
  15. 15 #define LOG_INFO "INFO"
  16. 16 #define LOG_WARNING "WARNING"
  17. 17 #define LOG_CHECKIT "CHECKIT"
  18. 18 #define LOG_ERROR "ERROR"
  19. 19 #define LOG_FATAL "FATAL"
  20. 20
  21. 21 #define LOGFILE_MAX_SIZE (10 * 1024 * 1024)
  22. 22 #define LOGNAME_MAX_LENGTH 128
  23. 23 #define LOGNAME_PREFIX "Log"
  24. 24 #define LOGNAME_SUFFIX ".log"
  25. 25 #define LOG_IS_NEED_LOCK true
  26. 26
  27. 27 // #ifdef _WIN32
  28. 28 // #define SEP "\\"
  29. 29 // #else
  30. 30 #define SEP "/"
  31. 31 //#endif
  32. 32
  33. 33 #define LOGID uint64_t
  34. 34
  35. 35 #define __STR_LC(s) #s
  36. 36 #define _STR_LC(s) __STR_LC(s)
  37. 37
  38. 38 //@format "%Y-%m-%d %H:%M:%S"
  39. 39 extern void __str_time(char* out, const char* format = "%Y-%m-%d");
  40. 40
  41. 41 template<typename T>
  42. 42 void __getmsg(std::stringstream& ss, T&& value)
  43. 43 {
  44. 44 ss << value;
  45. 45 }
  46. 46
  47. 47 template<typename T, typename ... Ts>
  48. 48 void __getmsg(std::stringstream& ss, T&& value, Ts&& ... args)
  49. 49 {
  50. 50 ss << value;
  51. 51 __getmsg(ss, std::forward<Ts>(args) ...);
  52. 52 }
  53. 53
  54. 54 struct __LogMsgBase
  55. 55 {
  56. 56 std::string _file;
  57. 57 std::string _line;
  58. 58 std::string _time;
  59. 59
  60. 60 __LogMsgBase& instance()
  61. 61 {
  62. 62 static __LogMsgBase ins;
  63. 63 return ins;
  64. 64 }
  65. 65 };
  66. 66
  67. 67 struct LogFileInfo
  68. 68 {
  69. 69 LogFileInfo()
  70. 70 : _num(0)
  71. 71 , _pLog(nullptr)
  72. 72 {
  73. 73 }
  74. 74
  75. 75 ~LogFileInfo();
  76. 76
  77. 77 std::string _title;
  78. 78 std::string _basePath;
  79. 79 int _num;
  80. 80
  81. 81 std::string _name;
  82. 82 Log* _pLog;
  83. 83
  84. 84 void GetPath(std::string& out) const;
  85. 85 void InitName();
  86. 86 void ReOpen();
  87. 87 static void BaseName(const std::string& title, std::string& out);
  88. 88 };
  89. 89
  90. 90 class LogMgr final
  91. 91 {
  92. 92 private:
  93. 93 LogMgr();
  94. 94
  95. 95 public:
  96. 96 ~LogMgr();
  97. 97
  98. 98 static LogMgr& Instance()
  99. 99 {
  100. 100 static LogMgr ins;
  101. 101 return ins;
  102. 102 }
  103. 103
  104. 104 bool Register(LOGID id, const char* path, const char* title);
  105. 105
  106. 106 template<typename ... TArgs>
  107. 107 bool WriteLog(LOGID id, const char* type, const char* time, const char* file, const char* line, TArgs&& ... args);
  108. 108
  109. 109 private:
  110. 110 std::unordered_map<LOGID, LogFileInfo* > _mLogs;
  111. 111
  112. 112 #if LOG_IS_NEED_LOCK
  113. 113 std::mutex _mx;
  114. 114 #endif
  115. 115 //std::future<bool> _thRun;
  116. 116 };
  117. 117
  118. 118
  119. 119 template<typename ... TArgs>
  120. 120 bool LogMgr::WriteLog(LOGID id, const char* type, const char* time, const char* file, const char* line, TArgs&& ... args)
  121. 121 {
  122. 122 #if LOG_IS_NEED_LOCK
  123. 123 std::unique_lock<std::mutex> ul(_mx);
  124. 124 #endif
  125. 125
  126. 126 auto it = _mLogs.find(id);
  127. 127 if(it == _mLogs.end())
  128. 128 return false;
  129. 129
  130. 130 LogFileInfo* pInfo = it->second;
  131. 131 Log* pLog = pInfo->_pLog;
  132. 132 if(nullptr == pLog)
  133. 133 return false;
  134. 134
  135. 135 std::string fullPath;
  136. 136 pInfo->GetPath(fullPath);
  137. 137
  138. 138 while(std::filesystem::exists(fullPath.c_str())
  139. 139 && std::filesystem::file_size(fullPath.c_str()) >= LOGFILE_MAX_SIZE)
  140. 140 {
  141. 141 pInfo->_num++;
  142. 142 pInfo->InitName();
  143. 143 pInfo->GetPath(fullPath);
  144. 144 pInfo->ReOpen();
  145. 145 }
  146. 146
  147. 147 std::stringstream ss;
  148. 148 __getmsg(ss, args...);
  149. 149
  150. 150 return pLog->__Write(time, file, line, type, ss.str().c_str());
  151. 151 }
  152. 152
  153. 153 #define RegisterLogger(id, path, title) LC::LC_LOG::LogMgr::Instance().Register(id, path, title)
  154. 154
  155. 155 #define LogWriteBase(id, type, msg...) \
  156. 156 do{ \
  157. 157 char timestr[64]; \
  158. 158 LC::LC_LOG::__str_time(timestr, "%Y-%m-%d %H:%M:%S"); \
  159. 159 LC::LC_LOG::LogMgr::Instance().WriteLog(id, type, timestr, __FILE__, _STR_LC(__LINE__), msg); \
  160. 160 }while(0)
  161. 161 };
  162. 162 };

lc_logmgr.cpp

  1. 1 #include "lc_logmgr.h"
  2. 2 #include <stdio.h>
  3. 3 #include <stdlib.h>
  4. 4
  5. 5 namespace LC
  6. 6 {
  7. 7 namespace LC_LOG
  8. 8 {
  9. 9 void __str_time(char* out, const char* format)
  10. 10 {
  11. 11 if(out == nullptr)
  12. 12 return;
  13. 13
  14. 14 time_t t = time(NULL);
  15. 15 strftime(out, 64, format, localtime(&t));
  16. 16 }
  17. 17
  18. 18 LogFileInfo::~LogFileInfo()
  19. 19 {
  20. 20 delete _pLog;
  21. 21 }
  22. 22
  23. 23 void LogFileInfo::GetPath(std::string& out) const
  24. 24 {
  25. 25 out.clear();
  26. 26
  27. 27 out += _basePath;
  28. 28 const char& last = _basePath.back();
  29. 29 if(!(last == '/' || last == '\\'))
  30. 30 out.append(SEP);
  31. 31
  32. 32 out.append(_name);
  33. 33 }
  34. 34
  35. 35 void LogFileInfo::InitName()
  36. 36 {
  37. 37 BaseName(_title, _name);
  38. 38 if(_num > 0)
  39. 39 _name.append("_").append(std::to_string(_num));
  40. 40
  41. 41 _name.append(LOGNAME_SUFFIX);
  42. 42 }
  43. 43
  44. 44 void LogFileInfo::ReOpen()
  45. 45 {
  46. 46 if(_pLog == nullptr)
  47. 47 return;
  48. 48
  49. 49 std::string fullpath;
  50. 50 GetPath(fullpath);
  51. 51 _pLog->__Close();
  52. 52 _pLog->__Open(fullpath.c_str());
  53. 53 }
  54. 54
  55. 55 void LogFileInfo::BaseName(const std::string& title, std::string& out)
  56. 56 {
  57. 57 out.clear();
  58. 58
  59. 59 char strtime[64];
  60. 60 __str_time(strtime);
  61. 61 out
  62. 62 .append(LOGNAME_PREFIX)
  63. 63 .append("_")
  64. 64 .append(title)
  65. 65 .append("_")
  66. 66 .append(strtime);
  67. 67 }
  68. 68
  69. 69 LogMgr::LogMgr()
  70. 70 {
  71. 71 // _thRun = std::async(std::launch::deferred,
  72. 72 // []() -> bool
  73. 73 // {
  74. 74
  75. 75 // },
  76. 76 // );
  77. 77 }
  78. 78
  79. 79 LogMgr::~LogMgr()
  80. 80 {
  81. 81 for (auto& pairEach : _mLogs)
  82. 82 {
  83. 83 LogFileInfo* pInfo = pairEach.second;
  84. 84 delete pInfo;
  85. 85 }
  86. 86 _mLogs.clear();
  87. 87 }
  88. 88
  89. 89 bool LogMgr::Register(LOGID id, const char* path, const char* title)
  90. 90 {
  91. 91 #if LOG_IS_NEED_LOCK
  92. 92 std::unique_lock<std::mutex> ul(_mx);
  93. 93 #endif
  94. 94
  95. 95 if(_mLogs.find(id) != _mLogs.end())
  96. 96 return true;
  97. 97
  98. 98 LogFileInfo* pInfo = new LogFileInfo();
  99. 99 if(pInfo == nullptr)
  100. 100 return false;
  101. 101
  102. 102 pInfo->_basePath = path;
  103. 103 pInfo->_title = title;
  104. 104 {
  105. 105 pInfo->InitName();
  106. 106
  107. 107 std::string fullPath;
  108. 108 pInfo->GetPath(fullPath);
  109. 109
  110. 110 if(!(std::filesystem::exists(fullPath.c_str())
  111. 111 && std::filesystem::file_size(fullPath.c_str()) >= LOGFILE_MAX_SIZE))
  112. 112 {
  113. 113 pInfo->_pLog = new Log(fullPath.c_str());
  114. 114 if(pInfo->_pLog == nullptr)
  115. 115 {
  116. 116 delete pInfo;
  117. 117 return false;
  118. 118 }
  119. 119 _mLogs.insert(std::make_pair(id, pInfo));
  120. 120 return true;
  121. 121 }
  122. 122 }
  123. 123
  124. 124 int num = 1;
  125. 125 do
  126. 126 {
  127. 127 pInfo->_num = num;
  128. 128 pInfo->InitName();
  129. 129
  130. 130 std::string fullPath;
  131. 131 pInfo->GetPath(fullPath);
  132. 132 if(std::filesystem::exists(fullPath.c_str())
  133. 133 && std::filesystem::file_size(fullPath.c_str()) >= LOGFILE_MAX_SIZE)
  134. 134 {
  135. 135 ++num; continue;
  136. 136 }
  137. 137
  138. 138 pInfo->_pLog = new Log(fullPath.c_str());
  139. 139 if(pInfo->_pLog == nullptr)
  140. 140 {
  141. 141 //delete pInfo;
  142. 142 return false;
  143. 143 }
  144. 144 _mLogs.insert(std::make_pair(id, pInfo));
  145. 145 return true;
  146. 146 } while (num < 10000);
  147. 147
  148. 148 return false;
  149. 149 }
  150. 150 };
  151. 151 };

main.cpp

  1. 1 #include <iostream>
  2. 2 #include <vector>
  3. 3
  4. 4 #include <time.h>
  5. 5 #include <string>
  6. 6 #include <thread>
  7. 7 #include <future>
  8. 8 #include <sstream>
  9. 9 #include <chrono>
  10. 10 #include "lc_logmgr.h"
  11. 11
  12. 12 #define C_SS(s) # s
  13. 13 #define _GETMSG(ss, args...) getmsg(ss, args)
  14. 14
  15. 15 #define __STR_LC(s) #s
  16. 16 #define _STR_LC(s) __STR_LC(s)
  17. 17
  18. 18 struct item
  19. 19 {
  20. 20 void show(const std::string& s)
  21. 21 {
  22. 22 std::cout << s << std::endl;
  23. 23 }
  24. 24 };
  25. 25
  26. 26 template<typename T>
  27. 27 void getmsg(std::stringstream& ss, T&& value)
  28. 28 {
  29. 29 ss << value;
  30. 30 }
  31. 31
  32. 32 template<typename T, typename ... Ts>
  33. 33 void getmsg(std::stringstream& ss, T&& value, Ts&& ... args)
  34. 34 {
  35. 35 ss << value;
  36. 36 getmsg(ss, std::forward<Ts>(args) ...);
  37. 37 return;
  38. 38 }
  39. 39
  40. 40 using namespace std::chrono;
  41. 41 int main()
  42. 42 {
  43. 43 item t;
  44. 44 std::string sss = "qwe";
  45. 45 RegisterLogger(0x01, "./", "TEST");
  46. 46
  47. 47 std::thread th1([](){
  48. 48 for (size_t i = 0; i < 100000; i++)
  49. 49 {
  50. 50 LogWriteBase(0x01, LOG_INFO, "a ", i, " ", 2 * i + 3);
  51. 51 }
  52. 52 std::cout << "log a over. " << std::endl;
  53. 53 });
  54. 54
  55. 55 std::thread th2([](){
  56. 56 for (size_t i = 0; i < 100000; i++)
  57. 57 {
  58. 58 LogWriteBase(0x01, LOG_INFO, "b ", i, " ", 2 * i + 3);
  59. 59 }
  60. 60 std::cout << "log b over. " << std::endl;
  61. 61 });
  62. 62
  63. 63 std::thread th3([](){
  64. 64 for (size_t i = 0; i < 100000; i++)
  65. 65 {
  66. 66 LogWriteBase(0x01, LOG_INFO, "c ", i, " ", 2 * i + 3);
  67. 67 }
  68. 68 std::cout << "log c over. " << std::endl;
  69. 69 });
  70. 70
  71. 71 th1.join();
  72. 72 th2.join();
  73. 73 th3.join();
  74. 74
  75. 75 // auto time_now = system_clock::now();
  76. 76 // auto duration_in_ms = duration_cast<milliseconds>(time_now.time_since_epoch());
  77. 77 // uint64_t nFactTime = duration_in_ms.count();
  78. 78 // for (size_t i = 0; i < 100000; i++)
  79. 79 // {
  80. 80 // LogWriteBase(0x01, LOG_INFO, "qwe", i, " ", 2 * i + 3);
  81. 81 // }
  82. 82
  83. 83 // auto time_now2 = system_clock::now();
  84. 84 // auto duration_in_ms2 = duration_cast<milliseconds>(time_now2.time_since_epoch());
  85. 85 // uint64_t nFactTime2 = duration_in_ms2.count();
  86. 86 // std::cout << nFactTime2 - nFactTime << std::endl;
  87. 87
  88. 88 std::cout << "-----over-----" << std::endl;
  89. 89 return 0;
  90. 90 }

我发现我越来越懒,咋办。。。

C++ Log日志系统的更多相关文章

  1. MySQL日志系统:redo log与binlog

    日志系统主要有redo log(重做日志)和binlog(归档日志).redo log是InnoDB存储引擎层的日志,binlog是MySQL Server层记录的日志, 两者都是记录了某些操作的日志 ...

  2. Linux**系统实现log日志自动清理

    Linux系统实现log日志自动清理 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: ...

  3. LOG收集系统(一):原日志至收集

    Date: 20140207Auth: Jin 设置一个LOG收集系统1. 收集原生(不解析,不压缩)的业务日志和WEB日志(NGINX,PHP)2. 提供给开发,测试直接阅读和下载 需求分析原生日志 ...

  4. 成功配置TOMCAT的LOG4J日志系统,格式:HTML+每天以YYYY-MM-DD.LOG命名的日志文件

    关于log4j.properties文件在web项目中放的位置,找过很多,最后实践结果是: 一.web项目 二.放在src的目录里面,然后项目生成后会自动在\WEB-INF\classes文件里有份l ...

  5. Linux系统的LOG日志文件及入侵后日志的清除

    UNIX网管员主要是靠系统的LOG,来获得入侵的痕迹.当然也有第三方工具记录入侵系统的 痕迹,UNIX系统存放LOG文件,普通位置如下: /usr/adm - 早期版本的UNIX/var/adm -  ...

  6. MySQL 日志系统之 redo log 和 binlog

    之前我们了解了一条查询语句的执行流程,并介绍了执行过程中涉及的处理模块.一条查询语句的执行过程一般是经过连接器.分析器.优化器.执行器等功能模块,最后到达存储引擎. 那么,一条 SQL 更新语句的执行 ...

  7. MySQL日志系统bin log、redo log和undo log

    MySQL日志系统bin log.redo log和undo log   今人不见古时月,今月曾经照古人. 简介:日志是MySQL数据库的重要组成部分,记录着数据库运行期间各种状态信息,主要包括错误日 ...

  8. C++ 高性能无锁日志系统

    服务器编程中,日志系统需要满足几个条件 .高效,日志系统不应占用太多资源 .简洁,为了一个简单的日志功能引入大量第三方代码未必值得 .线程安全,服务器中各个线程都能同时写出日志 .轮替,服务器不出故障 ...

  9. Atitit.log日志技术的最佳实践attilax总结

    Atitit.log日志技术的最佳实践attilax总结 1. 日志的意义与作用1 1.1. 日志系统是一种不可或缺的单元测试,跟踪调试工具1 2. 俩种实现[1]日志系统作为一种服务进程存在 [2] ...

随机推荐

  1. R绘图(3): 散点图添加文本注释

    这里以火山图为例进行说明,在转录组分析中,火山图是很常见的一类图,纵轴表示p_value,横轴表示log (fold change).单一的散点图绘制很简单,火山图比较难处理的地方就是一些基因的注释, ...

  2. JavaScript数组的几个常用的API

    一. 扁平化嵌套数组/展平和阵列孔--flat() 1.实现效果 var arr1 = [1, 2, [3, 4]]; arr1.flat(); // [1, 2, 3, 4] var arr2 = ...

  3. hessian简单介绍

    Hessian是基于HTTP的轻量级远程服务解决方案,Hessian像Rmi一样,使用二进制消息进行客户端和服务器端交互.但与其他二进制远程调用技术(例如Rmi)不同的是,它的二进制消息可以移植其他非 ...

  4. python-给一个参数n,例如3:先输出1,2,3,4,5,6,7,8,9,每三个数后换行,后输出1,4,7,2,5,8,3,6,9

    """ 2 定义一个函数,fn(n)其中n表示输入n行n列的矩阵,需要满足的要求是在n为 3时先输出 3 1 2 3 4 4 5 6 5 7 8 9 6 后输出 7 1 ...

  5. 史上超强拷贝仓——GitHub 热点速览 v.21.11

    作者:HelloGitHub-小鱼干 Clone-Wars 是真的强,能细数 70+ 知名应用网站的源码,即便你不看代码,也可以了解下各大网站的所用技术栈.同样很强的是用 OpenCV 实现的图片转 ...

  6. 2021华为软件精英挑战赛(C/C++实现)-苦行僧的实现过程

    下面给出2021华为软件精英挑战赛参与的整个过程,虽然成绩不是很好,但是也是花了一些时间的,希望后面多多学习,多多进步. 代码已经上传到了Github上:https://github.com/myFr ...

  7. badusb论述

    "BadUSB"是2014年计算机安全领域的热门话题之一,该漏洞由Karsten Nohl和Jakob Lell共同发现 攻击原理 TEENSY 攻击者在定制攻击设备时,会向USB ...

  8. JDK8之后,在java语言这条路怎么走?

    前言 自2017年9月以来,Oracle按照免费的开源许可证(类似于Linux的许可证)提供JDK版本 .从Java SE 11(2018年9月,LTS)开始,Oracle不仅为开源许可下的所有用户免 ...

  9. kafka-简介-01

    1.kafka是什么? Kafka是最初由Linkedin公司开发,是一个分布式.支持分区的(partition).多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特 ...

  10. GO-01-GoLang的快捷键