| 39 | |
| 40 | |
| 41 | void LOG_A(int verbosity, const char* format, ...) |
| 42 | { |
| 43 | if (!DO_LOG_DEBUG && verbosity == LOG_DEBUG) { |
| 44 | return; |
| 45 | } |
| 46 | |
| 47 | va_list args; |
| 48 | va_start(args, format); |
| 49 | char buffer[DATA_BUFFER_SIZE] = { 0 }; |
| 50 | vsnprintf_s(buffer, sizeof(buffer), format, args); |
| 51 | //printf("%s\n", buffer); |
| 52 | switch (verbosity) { |
| 53 | case LOG_ERROR: |
| 54 | LOG_F(ERROR, "%s", buffer); |
| 55 | break; |
| 56 | |
| 57 | case LOG_WARNING: |
| 58 | LOG_F(WARNING, "%s", buffer); |
| 59 | break; |
| 60 | |
| 61 | case LOG_INFO: |
| 62 | LOG_F(INFO, "%s", buffer); |
| 63 | break; |
| 64 | |
| 65 | case LOG_DEBUG: |
| 66 | LOG_F(INFO, "%s", buffer); |
| 67 | break; |
| 68 | } |
| 69 | va_end(args); |
| 70 | |
| 71 | std::lock_guard<std::mutex> lock(error_mutex); |
| 72 | |
| 73 | { |
| 74 | using namespace std::chrono; |
| 75 | |
| 76 | // Get current time point |
| 77 | auto now = system_clock::now(); |
| 78 | auto in_time_t = system_clock::to_time_t(now); |
| 79 | auto ms = duration_cast<milliseconds>(now.time_since_epoch()) % 1000; |
| 80 | |
| 81 | // Convert to local time using localtime_s (thread-safe) |
| 82 | std::tm local_tm; |
| 83 | if (localtime_s(&local_tm, &in_time_t) != 0) { |
| 84 | // Fallback in case localtime_s fails |
| 85 | error_messages.push_back("Failed to get local time - " + std::string(buffer)); |
| 86 | return; |
| 87 | } |
| 88 | |
| 89 | // Format time string |
| 90 | std::ostringstream oss; |
| 91 | oss << std::put_time(&local_tm, "%Y-%m-%d %H:%M:%S"); |
| 92 | oss << '.' << std::setfill('0') << std::setw(3) << ms.count(); |
| 93 | oss << " - " << buffer; |
| 94 | |
| 95 | std::string log_entry = oss.str(); |
| 96 | error_messages.push_back(log_entry); |
| 97 | |
| 98 | // Write to file |