dl
dl_log.h
浏览该文件的文档.
1
12#pragma once
13
14#include <string>
15#include <iostream>
16#include <stack>
17#include <array>
18#include <mutex>
19
20#include "system/dl_platform.h"
21
22#if DL_PLATFORM == DL_PLATFORM_WIN32
23#include <stacktrace>
24#include <source_location>
25#define DL_SOURCE_LOCATION std::source_location location = std::source_location::current()
26#define DL_SOURCE_LOCATION_IMP std::source_location location
27#define DL_SOURCE_LOCATION_CALL std::source_location::current()
28#define DL_SOURCE_LOCATION_FORWARD location
29#else
30#define DL_SOURCE_LOCATION const char* file = __FILE__, int line = __LINE__
31#define DL_SOURCE_LOCATION_IMP const char* file, int line
32#define DL_SOURCE_LOCATION_CALL __FILE__, __LINE__
33#define DL_SOURCE_LOCATION_FORWARD file, line
34#endif
35
36namespace dl
37{
39 {
40 const char* _file;
41 const char* _func;
42 int _line;
44 };
45}
46
47#if DL_PLATFORM == DL_PLATFORM_WIN32
48#define DL_MAKE_SOURCE_LOCATION(loc) \
49 LogSourceLocation loc;\
50 loc._file = location.file_name();\
51 loc._func = location.function_name();\
52 loc._line = location.line();\
53 loc._column = location.column();
54#else
55#define DL_MAKE_SOURCE_LOCATION(loc) \
56 LogSourceLocation loc;\
57 loc._file = file;\
58 loc._func = __func__;\
59 loc._line = line;\
60 loc._column = 0;
61#endif
62
63#include <fmt/format.h>
64
65namespace dl
66{
67constexpr std::array<std::string_view, 9> DL_LOG_SYSTEM_LEVLE_NAME = {
68 "damage", "err", "warn", "notice", "msg", "info", "test", "pause",
69};
70
72void Output(std::string_view str);
73
74
77{
78 friend class LogLimit;
79 friend class LogStackTrack;
80 friend class LogLevelSet;
81public:
94 struct Setting
95 {
97 bool _bSourceLocation = true;
98 bool _bTimeStamp = true;
99 bool _bStackTrace = false;
100 };
102
105 {
106 _mutexSetting.lock();
107 Setting& ret = _stackSetting.top();
108 _mutexSetting.unlock();
109 return ret;
110 }
111
118 void SetLogFile(std::string_view path, std::string_view name = {}, bool clear = true);
119 std::string GetLogFile()
120 {
121 return _logFile;
122 }
123
124 bool IsLevelLimit(Level level)
125 {
126 _mutexLevel.lock();
127 bool ret = level > _stackLevel.top();
128 _mutexLevel.unlock();
129 return ret;
130 }
131
134 {
135 return level <= _levelMsgBox;
136 }
137
139 {
140 _levelMsgBox = level;
141 }
142
143 std::mutex& GetMutex() { return _mutexOutput; }
144
148 static std::string_view Level2String(Level level)
149 {
150 size_t index = (size_t)level;
151 if (index >= DL_LOG_SYSTEM_LEVLE_NAME.size())
152 return "NONE";
153 return DL_LOG_SYSTEM_LEVLE_NAME[index];
154 }
155private:
156 std::stack<Setting> _stackSetting;
157 std::stack<Level> _stackLevel;
158 Level _levelMsgBox;// 弹窗等级
159 static std::string _logFile;// 日志文件夹(为空时不生成)
160 std::recursive_mutex _mutexSetting;// 当前设置锁
161 std::recursive_mutex _mutexLevel; // level锁
162 std::mutex _mutexOutput; // 输出锁
163
164 // 容易错误使用,改为私有(请使用LogLimit)
170 void Push(const Setting& setting)
171 {
172 _mutexSetting.lock();
173 _stackSetting.push(setting);
174 }
176 void Pop()
177 {
178 _stackSetting.pop();
179 _mutexSetting.unlock();
180 }
186 void PushLevel(Level level)
187 {
188 Setting setting = GetSetting();
189 setting._level = level;
190 Push(setting);
191 }
197 void PushLevelLimit(Level level)
198 {
199 _mutexLevel.lock();
200 _stackLevel.push(level);
201 }
202 void PopLevelLimit()
203 {
204 _stackLevel.pop();
205 _mutexLevel.unlock();
206 }
207};
208extern LogSystem* g_log;
211{
212public:
214 {
215 g_log->PushLevel(level);
216 }
218 {
219 g_log->Pop();
220 }
221};
222
224{
225public:
228 {
229 g_log->PushLevelLimit(level);
230 }
232 {
233 g_log->PopLevelLimit();
234 }
235};
236
238{
239public:
240 LogStackTrack(bool open = true)
241 {
242 LogSystem::Setting s = g_log->GetSetting();
243 s._bStackTrace = open;
244 g_log->Push(s);
245 }
247 {
248 g_log->Pop();
249 }
250};
251
255inline void log_easy(std::string_view str)
256{
257 printf("%s", str.data()); // printf线程安全
258 //std::cout << str << std::endl;
259}
260
261void log_pause0(std::string_view str, DL_SOURCE_LOCATION);
262void log_test0(std::string_view str, DL_SOURCE_LOCATION);
263void log_info0(std::string_view str, DL_SOURCE_LOCATION);
264void log_msg0(std::string_view str, DL_SOURCE_LOCATION);
265void log_notice0(std::string_view str, DL_SOURCE_LOCATION);
266void log_warn0(std::string_view str, DL_SOURCE_LOCATION);
267void log_err0(std::string_view str, DL_SOURCE_LOCATION);
268void log_damage0(std::string_view str, DL_SOURCE_LOCATION);
269
271void log(std::string_view str, DL_SOURCE_LOCATION);
272
274void log_err0(const std::exception& e, DL_SOURCE_LOCATION);
275void log_err0(const std::system_error& e, DL_SOURCE_LOCATION);
276
277#define log_(...) log(fmt::format(__VA_ARGS__), DL_SOURCE_LOCATION_CALL)
278#define log_pause(...) log_pause0(fmt::format(__VA_ARGS__), DL_SOURCE_LOCATION_CALL)
279#define log_test(...) log_test0(fmt::format(__VA_ARGS__), DL_SOURCE_LOCATION_CALL)
280#define log_info(...) log_info0(fmt::format(__VA_ARGS__), DL_SOURCE_LOCATION_CALL)
281#define log_msg(...) log_msg0(fmt::format(__VA_ARGS__), DL_SOURCE_LOCATION_CALL)
282#define log_notice(...) log_notice0(fmt::format(__VA_ARGS__), DL_SOURCE_LOCATION_CALL)
283#define log_warn(...) log_warn0(fmt::format(__VA_ARGS__), DL_SOURCE_LOCATION_CALL)
284#define log_err(...) log_err0(fmt::format(__VA_ARGS__), DL_SOURCE_LOCATION_CALL)
285#define log_damage(...) log_damage0(fmt::format(__VA_ARGS__), DL_SOURCE_LOCATION_CALL)
286
287
288
289
290}
LogLevelSet(LogSystem::Level level)
LogLimit(LogSystem::Level level=LogSystem::Level::DAMAGE)
默认为最高等级,用于屏蔽消息输出
LogStackTrack(bool open=true)
日志系统
bool IsLevelLimit(Level level)
const Setting & GetSetting()
返回当前设置
void SetLogFile(std::string_view path, std::string_view name={}, bool clear=true)
设置日志文件路径(非线程安全)
std::mutex & GetMutex()
static std::string_view Level2String(Level level)
日志等级转字符串
friend class LogLevelSet
bool IsLevelMsgBox(Level level)
检查等级是否可以弹窗(小于等于自己)
friend class LogLimit
Level
日志等级 越小越严重
friend class LogStackTrack
std::string GetLogFile()
void SetLevelMsgBox(Level level)
设置弹窗等级(小于等于自己才弹,越小越严重)
#define DL_SOURCE_LOCATION
平台宏
constexpr std::array< std::string_view, 9 > DL_LOG_SYSTEM_LEVLE_NAME
void log_msg0(std::string_view str, DL_SOURCE_LOCATION)
void log_easy(std::string_view str)
输出日志
void Output(std::string_view str)
打印到标准输出、vs、日志文件
void log(std::string_view str, DL_SOURCE_LOCATION)
以当前设置输出
LogSystem * g_log
void log_err0(std::string_view str, DL_SOURCE_LOCATION)
void log_info0(std::string_view str, DL_SOURCE_LOCATION)
void log_test0(std::string_view str, DL_SOURCE_LOCATION)
void log_pause0(std::string_view str, DL_SOURCE_LOCATION)
void log_warn0(std::string_view str, DL_SOURCE_LOCATION)
void log_notice0(std::string_view str, DL_SOURCE_LOCATION)
void log_damage0(std::string_view str, DL_SOURCE_LOCATION)