| 108 | |
| 109 | |
| 110 | void LOG_W(int verbosity, const wchar_t* format, ...) |
| 111 | { |
| 112 | if (!DO_LOG_DEBUG && verbosity == LOG_DEBUG) { |
| 113 | return; |
| 114 | } |
| 115 | |
| 116 | va_list args; |
| 117 | va_start(args, format); |
| 118 | wchar_t wide_buffer[DATA_BUFFER_SIZE]; |
| 119 | vswprintf_s(wide_buffer, sizeof(wide_buffer) / sizeof(wchar_t), format, args); |
| 120 | char buffer[DATA_BUFFER_SIZE]; |
| 121 | int result = WideCharToMultiByte(CP_UTF8, 0, wide_buffer, -1, buffer, sizeof(buffer), NULL, NULL); |
| 122 | |
| 123 | switch (verbosity) { |
| 124 | case LOG_ERROR: |
| 125 | LOG_F(ERROR, "%s", buffer); |
| 126 | break; |
| 127 | |
| 128 | case LOG_WARNING: |
| 129 | LOG_F(WARNING, "%s", buffer); |
| 130 | break; |
| 131 | |
| 132 | case LOG_INFO: |
| 133 | LOG_F(INFO, "%s", buffer); |
| 134 | break; |
| 135 | |
| 136 | case LOG_DEBUG: |
| 137 | LOG_F(INFO, "%s", buffer); |
| 138 | break; |
| 139 | } |
| 140 | va_end(args); |
| 141 | |
| 142 | std::lock_guard<std::mutex> lock(error_mutex); |
| 143 | |
| 144 | { |
| 145 | using namespace std::chrono; |
| 146 | |
| 147 | // Get current time point |
| 148 | auto now = system_clock::now(); |
| 149 | auto in_time_t = system_clock::to_time_t(now); |
| 150 | auto ms = duration_cast<milliseconds>(now.time_since_epoch()) % 1000; |
| 151 | |
| 152 | // Convert to local time using localtime_s (thread-safe) |
| 153 | std::tm local_tm; |
| 154 | if (localtime_s(&local_tm, &in_time_t) != 0) { |
| 155 | // Fallback in case localtime_s fails |
| 156 | error_messages.push_back("Failed to get local time - " + std::string(buffer)); |
| 157 | return; |
| 158 | } |
| 159 | |
| 160 | // Format time string |
| 161 | std::ostringstream oss; |
| 162 | oss << std::put_time(&local_tm, "%Y-%m-%d %H:%M:%S"); |
| 163 | oss << '.' << std::setfill('0') << std::setw(3) << ms.count(); |
| 164 | oss << " - " << std::string(buffer); |
| 165 | |
| 166 | std::string log_entry = oss.str(); |
| 167 | error_messages.push_back(log_entry); |