24 void operator=(
Logger const&) =
delete;
48 static constexpr int LogLevelCount =
static_cast<int>(LogLevel::Count);
63 static const LogLevelInfo GetLogLevelInfo(LogLevel level)
67 case LogLevel::Info:
return LogLevelInfo{
"Info", 0, ImVec4(0.0f, 1.0f, 0.0f, 1.0f) };
68 case LogLevel::Warning:
return LogLevelInfo{
"Warning", 1, ImVec4(1.0f, 1.0f, 0.0f, 1.0f) };
69 case LogLevel::Error:
return LogLevelInfo{
"Error", 2, ImVec4(1.0f, 0.0f, 0.0f, 1.0f) };
70 case LogLevel::Shutdown:
return LogLevelInfo{
"shutdown", 3, ImVec4(0.5f, 0.0f, 0.0f, 1.0f) };
71 case LogLevel::Initialize:
return LogLevelInfo{
"initialize", 4, ImVec4(0.0f, 1.0f, 1.0f, 1.0f) };
72 case LogLevel::Update:
return LogLevelInfo{
"Update", 5, ImVec4(1.0f, 0.0f, 1.0f, 1.0f) };
73 case LogLevel::Render:
return LogLevelInfo{
"render", 6, ImVec4(1.0f, 1.0f, 1.0f, 1.0f) };
74 case LogLevel::Input:
return LogLevelInfo{
"Input", 7, ImVec4(0.5f, 0.5f, 0.5f, 1.0f) };
75 case LogLevel::Physics:
return LogLevelInfo{
"physics", 8, ImVec4(0.5f, 0.5f, 0.5f, 1.0f) };
76 case LogLevel::Audio:
return LogLevelInfo{
"Audio", 9, ImVec4(0.5f, 0.5f, 0.5f, 1.0f) };
77 case LogLevel::Network:
return LogLevelInfo{
"Network", 10, ImVec4(0.5f, 0.5f, 0.5f, 1.0f) };
78 case LogLevel::Scripting:
return LogLevelInfo{
"Scripting", 11, ImVec4(0.5f, 0.5f, 0.5f, 1.0f) };
79 case LogLevel::AI:
return LogLevelInfo{
"AI", 12, ImVec4(0.5f, 0.5f, 0.5f, 1.0f) };
80 case LogLevel::Resource:
return LogLevelInfo{
"Resource", 13, ImVec4(0.5f, 0.5f, 0.5f, 1.0f) };
81 case LogLevel::Memory:
return LogLevelInfo{
"Memory", 14, ImVec4(0.5f, 0.5f, 0.5f, 1.0f) };
82 case LogLevel::Debug:
return LogLevelInfo{
"Debug", 15, ImVec4(0.5f, 0.5f, 0.5f, 1.0f) };
83 default:
return LogLevelInfo{
"Unknown", 16, ImVec4(1.0f, 1.0f, 1.0f, 1.0f) };
89 char* appdata =
nullptr;
91 _dupenv_s(&appdata, &len,
"APPDATA");
92 if (appdata ==
nullptr)
94 m_appdataPath =
"log.log";
98 m_appdataPath = appdata;
101 std::string directoryPath = m_appdataPath +
"\\Khaotic Engine";
102 CreateDirectoryA(directoryPath.c_str(), NULL);
104 ManageLogFiles(directoryPath);
106 m_logFilePath = directoryPath +
"\\" + m_logFileName;
109 for (
int i = 0; i < LogLevelCount; i++)
111 m_disabledLogLevels[i] =
true;
113 if (i ==
static_cast<int>(LogLevel::Error) || i ==
static_cast<int>(LogLevel::Warning) || i ==
static_cast<int>(LogLevel::Shutdown))
115 m_disabledLogLevels[i] =
false;
123 void Log(
const std::string& message,
const std::string& fileName,
int lineNumber, LogLevel level = LogLevel::Info)
126 auto now = std::chrono::system_clock::now();
127 auto in_time_t = std::chrono::system_clock::to_time_t(now);
130 localtime_s(&buf, &in_time_t);
133 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
136 std::string levelStr = GetLogLevelInfo(level).name;
138 std::stringstream ss;
139 ss <<
"[" << std::put_time(&buf,
"%Y-%m-%d") <<
"] "
140 <<
"[" << std::put_time(&buf,
"%X") <<
"." << std::setfill(
'0') << std::setw(3) << ms.count() <<
"] "
141 <<
"[" << levelStr <<
"] "
142 <<
"[" << fileName <<
":" << lineNumber <<
"] "
145 Log(ss.str(), level);
147 std::ofstream file(m_logFilePath, std::ios::app);
150 file << ss.str() << std::endl;
156 void Log(
const std::string& message, LogLevel level)
160 if (m_disabledLogLevels[GetLogLevelInfo(level).value])
165 if (logBuffer.size() >= logBufferSize)
167 logBuffer.pop_front();
169 logBuffer.push_back({ message, level });
172 const std::deque<LogEntry>& GetLogBuffer()
const {
return logBuffer; }
174 void ManageLogFiles(
const std::string& directoryPath)
176 std::vector<std::filesystem::path> logFiles;
179 for (
const auto& entry : std::filesystem::directory_iterator(directoryPath))
182 if (entry.path().extension() ==
".log")
184 logFiles.push_back(entry.path());
189 while (logFiles.size() >= 3)
192 std::sort(logFiles.begin(), logFiles.end(), [](
const std::filesystem::path& a,
const std::filesystem::path& b)
194 return std::filesystem::last_write_time(a) < std::filesystem::last_write_time(b);
198 std::filesystem::remove(logFiles[0]);
201 logFiles.erase(logFiles.begin());
205 auto now = std::chrono::system_clock::now();
206 auto in_time_t = std::chrono::system_clock::to_time_t(now);
208 localtime_s(&buf, &in_time_t);
210 std::stringstream ss;
211 ss <<
"Khaotic_log_" << std::put_time(&buf,
"%Y_%m_%d_%Hh%Mm%Ss") <<
".log";
212 m_logFileName = ss.str();
215 bool m_disabledLogLevels[LogLevelCount];
216 std::string m_logFilePath;
219 std::string m_filename;
220 std::string m_appdataPath;
221 std::string m_logFileName;
223 std::deque<LogEntry> logBuffer;
224 const size_t logBufferSize = 100;