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

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

主要熟练一下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. Linux下查看文件内容的几种常用命令

    [常用] 1,cat     由第一行开始显示内容,并将所有内容输出 cat的功能是将文件从第一行开始连续的将内容输出在屏幕上.但是cat并不常用,原因是当文件大,行数比较多时,屏幕无法全部容下时,只 ...

  2. Go语言|类型转换和类型别名

    类型转换 同类型之间的转换 Go语言中只有强制类型转换,没有隐式类型转换.该语法只能在两个类型之间支持相互转换的时候使用. import "fmt" func main() { v ...

  3. 翻译:《实用的Python编程》05_01_Dicts_revisited

    目录 | 上一节 (4.4 异常) | 下一节 (5.2 封装) 5.1 再谈字典 Python 对象系统主要基于字典实现.本节将对此进行讨论. 字典 字典是命名值(named values)的集合. ...

  4. spring 最权威的知识点

    1.Spring是什么? Spring是一个轻量级的IoC和AOP容器框架.是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求.常见的配置方 ...

  5. webpack核心模块tapable用法解析

    前不久写了一篇webpack基本原理和AST用法的文章,本来想接着写webpack plugin的原理的,但是发现webpack plugin高度依赖tapable这个库,不清楚tapable而直接去 ...

  6. CF524F And Yet Another Bracket Sequence 题解

    题目链接 算法:后缀数组+ST表+贪心   各路题解都没怎么看懂,只会常数巨大的后缀数组+ST表,最大点用时 \(4s\), 刚好可以过... 确定合法序列长度   首先一个括号序列是合法的必须满足以 ...

  7. Hznu_0j 1557

    题目链接:http://acm.hznu.edu.cn/OJ/problem.php?id=1557 题解:将两个数组分别升序和降序排序后,累加差的绝对值. Ac代码: #include<std ...

  8. [GDKOI2021] 提高组 Day 2 总结

    [ G D K O I 2021 ]    提 高 组    D a y   2    总 结 不明的感觉今天的题比昨天的简单些,感觉今天爆炸的可能性很低. 嗯,于是乎,就很自信地打完了比赛.然后下午 ...

  9. MindSpore函数拟合

    技术背景 在前面一篇博客中我们介绍过基于docker的mindspore编程环境配置,这里我们基于这个环境,使用mindspore来拟合一个线性的函数,演示一下mindspore的基本用法. 环境准备 ...

  10. 腾讯高级工程师带你完整体验Node.js开发实战

    Node.js拥有广大的 JavaScript程序员基础并且完全开源,它被广泛地用在 Web服务.开发工作流.客户端应用等诸多领域.在 Web 服务开发这个领域,业界对 Node.js 的接受程度最高 ...