| 96 | }; |
| 97 | |
| 98 | static void logVa(Level level, const char* filename, int line, const char* func, const char* format, va_list args) { |
| 99 | if (!outputFile) |
| 100 | return; |
| 101 | |
| 102 | // Record logging time before calling OS functions |
| 103 | double nowTime = system::getTime(); |
| 104 | |
| 105 | // Check if log size is full |
| 106 | if (outputFile != stderr) { |
| 107 | long pos = std::ftell(outputFile); |
| 108 | if (pos >= maxSize) |
| 109 | return; |
| 110 | } |
| 111 | |
| 112 | std::lock_guard<std::mutex> lock(mutex); |
| 113 | |
| 114 | if (outputFile == stderr) |
| 115 | std::fprintf(outputFile, "\x1B[%dm", levelColors[level]); |
| 116 | std::fprintf(outputFile, "[%.03f %s %s:%d %s] ", nowTime, levelLabels[level], filename, line, func); |
| 117 | if (outputFile == stderr) |
| 118 | std::fprintf(outputFile, "\x1B[0m"); |
| 119 | std::vfprintf(outputFile, format, args); |
| 120 | std::fprintf(outputFile, "\n"); |
| 121 | // Note: This adds around 10us, but it's important for logging to finish writing the file, and logging is not used in performance critical code. |
| 122 | std::fflush(outputFile); |
| 123 | } |
| 124 | |
| 125 | void log(Level level, const char* filename, int line, const char* func, const char* format, ...) { |
| 126 | va_list args; |