#pragma once #include /** Example usage: DEBUG("error: %d", errno); will print something like [0.123 debug myfile.cpp:45] error: 67 */ #define DEBUG(format, ...) rack::logger::log(rack::logger::DEBUG_LEVEL, __FILE__, __LINE__, __FUNCTION__, format, ##__VA_ARGS__) #define INFO(format, ...) rack::logger::log(rack::logger::INFO_LEVEL, __FILE__, __LINE__, __FUNCTION__, format, ##__VA_ARGS__) #define WARN(format, ...) rack::logger::log(rack::logger::WARN_LEVEL, __FILE__, __LINE__, __FUNCTION__, format, ##__VA_ARGS__) #define FATAL(format, ...) rack::logger::log(rack::logger::FATAL_LEVEL, __FILE__, __LINE__, __FUNCTION__, format, ##__VA_ARGS__) namespace rack { /** Logs messages to a file or the terminal */ namespace logger { extern std::string logPath; enum Level { DEBUG_LEVEL, INFO_LEVEL, WARN_LEVEL, FATAL_LEVEL }; /** Returns whether logger was successfully initialized. */ PRIVATE bool init(); PRIVATE void destroy(); /** Do not use this function directly. Use the macros above. Thread-safe, meaning messages cannot overlap each other in the log. */ __attribute__((format(printf, 5, 6))) void log(Level level, const char* filename, int line, const char* func, const char* format, ...); /** Returns whether the last log file failed to end properly, due to a possible crash. */ PRIVATE bool wasTruncated(); } // namespace logger } // namespace rack