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

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

主要熟练一下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 }

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

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. Java流程控制:三种基本结构

    顺序结构: Java的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行顺序结构是最简单的算法结构语句与语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执行的处理步骤组成的, ...

  2. centos安装rar

    wget https://www.rarlab.com/rar/rarlinux-x64-5.5.0.tar.gz tar -xzvf rarlinux-x64-5.5.0.tar.gz cd rar ...

  3. java内部类 的理解

    * 类的第5个成员:内部类 * 1.相当于说,我们可以在类的内部再定义类.外面的类:外部类.里面定义的类:内部类 * 2.内部类的分类:成员内部类(声明在类内部且方法外的) vs 局部内部类(声明在类 ...

  4. MyBatis:当表字段名和实体类属性名不一致

    第一种解决方法:在sql中使用别名 <select id="getRoleList" resultType="com.ttpfx.domain.Role" ...

  5. FutureTask核心源码分析

    本文主要介绍FutureTask中的核心方法,如果有错误,欢迎大家指出! 首先我们看一下在java中FutureTask的组织关系 我们看一下FutureTask中关键的成员变量以及其构造方法 //表 ...

  6. 给我一个shell我能干翻你内网

    0x00 前言 在去年小菜鸡学了点内网知识就闲着没事跑点jboss的站看看,在经历过很多次内网横向失败之后终于算是人生圆满了一把,阿三的站一般进去之后很难横向,不知道是不是我太菜的原因,反正阿三的站能 ...

  7. 用RUST写流媒体服务器实战——rtmp chunk 深入解析

    用RUST写流媒体服务器实战--rtmp chunk 深入解析 最近几个月断更了,把精力放在了新的开源项目上,一个用rust写的流媒体服务xiu. 实现过程中踩了不少坑,今天说下rtmp中的chunk ...

  8. 阿里妈妈Java后端 社招5面(Offer已拿)

    最近由于个人原因, 由于前面两面的时间过去的有点久了,只能根据记忆大概写些记得问题.   阿里妈妈1面 40mins(2021-02-22) 1. 能简单介绍下自己和自己做的项目吗? 2. 关于项目的 ...

  9. 四单元总结&OO总结

    目录 本单元架构总结 第一次作业 第二次作业 第三次作业 架构设计总结 第一单元 第二单元 第三单元 对测试演进 课程收获 改进建议 线上学习体验 本单元架构总结 第一次作业 第一次作业按照UML正常 ...

  10. OO电梯系列总结与反思

    目录 前言 HW5 度量分析 UML类图与协作图 bug分析 HW6 度量分析 UML类图与协作图 bug分析 HW7 度量分析 UML类图与协作图 bug分析 SOLID原则 感想 前言 紧张刺激的 ...