blob: 86c65dbc86a8bfb9362e271c8d1f2b0681169390 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
#include "cru/base/log/Logger.h"
#include "cru/base/log/StdioLogTarget.h"
#include <ctime>
#include <algorithm>
#ifdef CRU_PLATFORM_WINDOWS
#include "cru/base/platform/win/DebugLogTarget.h"
#endif
namespace cru::log {
Logger *Logger::GetInstance() {
static Logger logger;
logger.AddLogTarget(std::make_unique<StdioLogTarget>());
#ifdef CRU_PLATFORM_WINDOWS
logger.AddLogTarget(std::make_unique<platform::win::WinDebugLogTarget>());
#endif
return &logger;
}
void Logger::AddLogTarget(std::unique_ptr<ILogTarget> target) {
std::lock_guard<std::mutex> lock(target_list_mutex_);
target_list_.push_back(std::move(target));
}
void Logger::RemoveLogTarget(ILogTarget *target) {
std::lock_guard<std::mutex> lock(target_list_mutex_);
target_list_.erase(
std::remove_if(target_list_.begin(), target_list_.end(),
[target](const auto &t) { return t.get() == target; }),
target_list_.end());
}
namespace {
String LogLevelToString(LogLevel level) {
switch (level) {
case LogLevel::Debug:
return u"DEBUG";
case LogLevel::Info:
return u"INFO";
case LogLevel::Warn:
return u"WARN";
case LogLevel::Error:
return u"ERROR";
default:
std::terminate();
}
}
String GetLogTime() {
auto time = std::time(nullptr);
auto calendar = std::localtime(&time);
return Format(u"{}:{}:{}", calendar->tm_hour, calendar->tm_min,
calendar->tm_sec);
}
String MakeLogFinalMessage(const LogInfo &log_info) {
return Format(u"[{}] {} {}: {}\n", GetLogTime(),
LogLevelToString(log_info.level), log_info.tag,
log_info.message);
}
} // namespace
Logger::Logger()
: log_thread_([this] {
while (true) {
auto log_info = log_queue_.Pull();
std::lock_guard<std::mutex> lock_guard{target_list_mutex_};
for (const auto &target : target_list_) {
target->Write(log_info.level, MakeLogFinalMessage(log_info));
}
}
}) {}
Logger::~Logger() { log_thread_.detach(); }
void Logger::Log(LogInfo log_info) {
#ifndef CRU_DEBUG
if (log_info.level == LogLevel::Debug) {
return;
}
#endif
log_queue_.Push(std::move(log_info));
}
} // namespace cru::log
|