#include "logging/logging.h" #include #include // va_start #include #include #if defined(_POSIX_VERSION) || defined(__APPLE__) #include #include #endif #if defined(_WIN32) #define PUBLIC #else #define PUBLIC __attribute__((visibility("default"))) #define INTERNAL __attribute__((visibility("internal"))) #endif static int _log_level = 1; PUBLIC void log_set_level(int level) { _log_level = level; } static int _syslog_enabled = 0; PUBLIC void log_switch_to_syslog(void) { _syslog_enabled = 1; } static int _file_log_enabled = 0; static const char *log_file_path = NULL; static int log_file_fd = -1; static FILE * log_file_stream = NULL; PUBLIC void log_switch_to_file(const char *path) { _file_log_enabled = 1; log_file_path = strdup(path); #if 0 log_file_fd = open(log_file_path, O_WRONLY | O_CREAT | O_APPEND, 0666); #endif log_file_stream = fopen(log_file_path, "a+"); } static int check_log_file_available() { if (log_file_stream) return 1; if (log_file_path) { log_file_stream = fopen(log_file_path, "a+"); } if (log_file_stream) return 1; return 0; } PUBLIC int log_internal_impl(unsigned int level, const char *fmt, ...) { if ((int)level < _log_level) return 0; va_list ap; va_start(ap, fmt); #if defined(__clang__) #pragma clang diagnostic ignored "-Wformat" #endif #if defined(_POSIX_VERSION) || defined(__APPLE__) if (_syslog_enabled) { vsyslog(LOG_ERR, fmt, ap); } #endif if (_file_log_enabled) { if (check_log_file_available()) { #define MAX_PRINT_BUFFER_SIZE 1024 char buffer[MAX_PRINT_BUFFER_SIZE] = {0}; vsnprintf(buffer, MAX_PRINT_BUFFER_SIZE - 1, fmt, ap); if (fwrite(buffer, sizeof(char), strlen(buffer) + 1, log_file_stream) == -1) { // log_file_fd invalid log_file_stream = NULL; if (check_log_file_available()) { // try again fwrite(buffer, sizeof(char), strlen(buffer) + 1, log_file_stream); } } fflush(log_file_stream); } else { vprintf(fmt, ap); } } if (!_syslog_enabled && !_file_log_enabled) { #if defined(__ANDROID__) #define ANDROID_LOG_TAG "Dobby" #include __android_log_vprint(ANDROID_LOG_INFO, ANDROID_LOG_TAG, fmt, ap); #else vprintf(fmt, ap); #endif } #if defined(__clang__) #pragma clang diagnostic warning "-Wformat" #endif va_end(ap); return 0; }