Rendering Engine 0.2.9
Modular Graphics Rendering Engine | v0.2.9
logger.cpp
Go to the documentation of this file.
1// This file is part of the Rendering Engine project.
2// Author: Alexander Obzherin
3// Distributed under the terms of the zlib License. See LICENSE.md for details.
4
5#include "logger.hpp"
6
7#include "utility.hpp"
8
9#include "boost/filesystem.hpp"
10#include <chrono>
11#include <iomanip>
12#include <sstream>
13#include <thread>
14
15namespace rendering_engine
16{
17
18namespace
19{
20std::string LogLevelToString(LogLevel level)
21{
22 switch (level)
23 {
24 case LogLevel::Debug: return "DEBUG";
25 case LogLevel::Info: return "INFO";
26 case LogLevel::Warning: return "WARNING";
27 case LogLevel::Error: return "ERROR";
28 default: return "UNKNOWN";
29 }
30}
31}
32
34{
35 static Logger instance;
36 return instance;
37}
38
39void Logger::Initialize(const std::string& appName)
40{
41 std::lock_guard<std::mutex> lock(mMutex);
42
43 if (mFile.is_open())
44 return;
45
46 auto logFolderPath = Utility::GetLogsFolderPath();
47 if (!boost::filesystem::exists(logFolderPath))
48 {
49 boost::filesystem::create_directory(logFolderPath);
50 }
51
52 // System clock for human-readable timestamp
53 auto now = std::chrono::system_clock::now();
54 auto nowTimeT = std::chrono::system_clock::to_time_t(now);
55 auto nowMs = std::chrono::duration_cast<std::chrono::milliseconds>(
56 now.time_since_epoch()) % 1000;
57
58 std::tm localTime{};
59#ifdef _WIN32
60 localtime_s(&localTime, &nowTimeT);
61#else
62 localtime_r(&nowTimeT, &localTime);
63#endif
64
65 std::ostringstream filename;
66 filename << logFolderPath.string() << "/"
67 << appName << "_"
68 << std::put_time(&localTime, "%Y-%m-%d_%H-%M-%S")
69 << ".log";
70
71 mFile.open(filename.str(), std::ios::out | std::ios::trunc);
72
73 mCurrentLevel = ReadConfiguredLogLevel();
74
75 if (mFile.is_open())
76 {
77 mFile << "===== Engine Log Started =====" << std::endl;
78 mFile.flush();
79 }
80}
81
83{
84 std::lock_guard<std::mutex> lock(mMutex);
85
86 if (mFile.is_open())
87 {
88 mFile << "===== Engine Log Shutdown =====" << std::endl;
89 mFile.flush();
90 mFile.close();
91 }
92}
93
94LogLevel Logger::ReadConfiguredLogLevel()
95{
96 LogLevel configuredLevel = LogLevel::Info;
97
98 const std::string confLogLevelStr = Utility::ReadConfigFile().logLevel;
99 if (confLogLevelStr == std::string{ "Debug" })
100 {
101 configuredLevel = LogLevel::Debug;
102 }
103 if (confLogLevelStr == std::string{ "Warning" })
104 {
105 configuredLevel = LogLevel::Warning;
106 }
107 if (confLogLevelStr == std::string{ "Error" })
108 {
109 configuredLevel = LogLevel::Error;
110 }
111
112 return configuredLevel;
113}
114
115void Logger::SetLogLevel(LogLevel level)
116{
117 std::lock_guard<std::mutex> lock(mMutex);
118 mCurrentLevel = level;
119}
120
122 const std::string& message,
123 const char* file,
124 int line)
125{
126 if (level < mCurrentLevel)
127 return;
128
129 if (!mFile.is_open())
130 return;
131
132 // Capture time outside lock for minimal contention
133 auto nowSystem = std::chrono::system_clock::now();
134 auto nowTimeT = std::chrono::system_clock::to_time_t(nowSystem);
135 auto nowMs = std::chrono::duration_cast<std::chrono::milliseconds>(
136 nowSystem.time_since_epoch()) % 1000;
137
138 std::tm localTime{};
139#ifdef _WIN32
140 localtime_s(&localTime, &nowTimeT);
141#else
142 localtime_r(&nowTimeT, &localTime);
143#endif
144
145 std::ostringstream timestampStream;
146 timestampStream << std::put_time(&localTime, "%Y-%m-%d %H:%M:%S")
147 << "." << std::setfill('0') << std::setw(3) << nowMs.count();
148
149 const auto threadId = std::this_thread::get_id();
150
151 std::lock_guard<std::mutex> lock(mMutex);
152
153 mFile << "[" << timestampStream.str() << "] "
154 << "[" << LogLevelToString(level) << "] "
155 << "[Thread " << threadId << "] "
156 << message
157 << " (" << file << ":" << line << ")"
158 << std::endl;
159
160 mFile.flush();
161}
162
163} // namespace rendering_engine
Singleton engine-wide logging system.
Definition: logger.hpp:76
void Shutdown()
Finalizes logging system and closes the log file.
Definition: logger.cpp:82
void Log(LogLevel level, const std::string &message, const char *file, int line)
Writes a formatted log message.
Definition: logger.cpp:121
void Initialize(const std::string &appName)
Initializes logging system and creates a new log file.
Definition: logger.cpp:39
static Logger & Get()
Returns singleton logger instance.
Definition: logger.cpp:33
static boost::filesystem::path GetLogsFolderPath()
Returns absolute path to Logs folder.
Definition: utility.cpp:269
static AppConfig ReadConfigFile()
Reads application settings from the JSON config file.
Definition: utility.cpp:34
Engine-wide logging system for runtime diagnostics and performance tracking.
LogLevel
Defines severity levels for log messages.
Definition: logger.hpp:56
@ Warning
Non-critical issues or unexpected states.
@ Info
General informational messages.
@ Error
Critical errors affecting functionality.
@ Debug
Detailed diagnostic information.
std::string logLevel
Logging verbosity level ("Error", "Warning", "Info", "Debug").
Definition: utility.hpp:41