#include "log_file.h" INITIALIZE_EASYLOGGINGPP LogFile::LogFile() { shrink_size_ = 1 * 1024 * 1024; // 1M } static unsigned int log_file_bk_idx_ = 0; static bool check_log_file_exist(const char* filename) { std::stringstream stream; stream << filename << "." << ++log_file_bk_idx_; std::fstream file; file.open(stream.str(), std::ios::in); if(file) { return check_log_file_exist(filename); } return false; } static void roll_out_handler(const char* filename, std::size_t size) { std::stringstream stream; if(!check_log_file_exist(filename)) { stream << filename << "." << log_file_bk_idx_; rename(filename, stream.str().c_str()); } } bool LogFile::init(const char* conf_file, const char* app_name) { el::Loggers::addFlag(el::LoggingFlag::StrictLogFileSizeCheck); el::Loggers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog); el::Loggers::addFlag(el::LoggingFlag::ColoredTerminalOutput); el::Helpers::installPreRollOutCallback(roll_out_handler); size_t file_len = disk_file::get_file_size(conf_file); if(file_len == 0) { ASSERT(false); return false; } char* buffer = (char*)malloc(file_len + 1); size_t read_len = disk_file::file_readstring(conf_file, buffer, file_len); buffer[read_len] = 0; std::string content = buffer; free(buffer); // جن؛؛%appname std::string replaceWhat = "%appname"; size_t pos = -1; while((pos = content.find("%appname", pos + 1)) != std::string::npos) { content.replace(pos, replaceWhat.length(), app_name); } if(!conf_.parseFromText(content)) { ASSERT(false); return false; } el::Loggers::reconfigureAllLoggers(conf_); running_ = true; thread_ = std::thread(&LogFile::check_output, this); return true; } void LogFile::shut() { this->running_ = false; while(msg_queue_.IsDirty()) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } msg_queue_.SwapWriteBuffers(); thread_.join(); } LogFile::~LogFile() { } bool LogFile::trace_log(int log_type, const char* log_content) { if(log_type < E_LOG_DBG || log_type > E_LOG_FATAL) { return false; } if(!msg_queue_.GetWriteBuffer().put((void*)&log_type, sizeof(log_type), (void*)log_content, strlen(log_content) + 1)) { return false; } msg_queue_.SwapWriteBuffers(); return true; } #ifdef _PLATFORM_WINDOWS_ enum E_CONSOLE_COLOR_TYPE { E_CONSOLE_COLOR_RED = 0, E_CONSOLE_COLOR_BLUE, E_CONSOLE_COLOR_GREEN, E_CONSOLE_COLOR_YELLOW, E_CONSOLE_COLOR_PURPLE, E_CONSOLE_COLOR_CYAN, E_CONSOLE_COLOR_LIGHTRED, E_CONSOLE_COLOR_LIGHTBLUE, E_CONSOLE_COLOR_LIGHTGREEN, E_CONSOLE_COLOR_LIGHTYELLOW, E_CONSOLE_COLOR_LOGHTPURPLE, E_CONSOLE_COLOR_LIGHTCYAN, E_CONSOLE_COLOR_GRAY, E_CONSOLE_COLOR_WHITE, E_CONSOLE_COLOR_MAX, }; static unsigned int s_console_colors_[E_CONSOLE_COLOR_MAX] = { FOREGROUND_RED, FOREGROUND_BLUE, FOREGROUND_GREEN, (FOREGROUND_RED | FOREGROUND_GREEN), (FOREGROUND_RED | FOREGROUND_BLUE), (FOREGROUND_GREEN | FOREGROUND_BLUE), (FOREGROUND_RED | FOREGROUND_INTENSITY), (FOREGROUND_BLUE | FOREGROUND_INTENSITY), (FOREGROUND_GREEN | FOREGROUND_INTENSITY), (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY), (FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY), (FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY), (FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN), (FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY), }; #endif void LogFile::check_output() { while(running_ || msg_queue_.IsDirty()) { if(!msg_queue_.IsDirty()) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); continue; } #ifdef _PLATFORM_WINDOWS_ SYSTEMTIME tm; ::GetLocalTime(&tm); char nowtime[32]; ::sprintf(nowtime, "[%02d-%02d %02d:%02d:%02d,%03d]", tm.wMonth, tm.wDay, tm.wHour, tm.wMinute, tm.wSecond, tm.wMilliseconds); #endif msg_queue_.SwapReadBuffers(); auto& read_buffer = msg_queue_.Read(); size_t it = 0; const void* data_ptr{nullptr}; size_t data_len{}; std::string out_buf; while(read_buffer.peek(it, data_ptr, data_len)) { int type = *(int*)(data_ptr); const char* content = (const char*)data_ptr + sizeof(int); #ifdef _PLATFORM_WINDOWS_ utf8_to_str(content, out_buf); switch(type) { case E_LOG_DBG: { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), s_console_colors_[E_CONSOLE_COLOR_LIGHTGREEN]); LOG(DEBUG) << (const char*)content; printf("%s [D] %s\n", nowtime, out_buf.c_str()); } break; case E_LOG_INFORMATION: { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), s_console_colors_[E_CONSOLE_COLOR_WHITE]); LOG(INFO) << (const char*)content; printf("%s [I] %s\n", nowtime, out_buf.c_str()); } break; case E_LOG_WARNING: { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), s_console_colors_[E_CONSOLE_COLOR_LIGHTYELLOW]); LOG(WARNING) << (const char*)content; printf("%s [W] %s\n", nowtime, out_buf.c_str()); } break; case E_LOG_ERROR: { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), s_console_colors_[E_CONSOLE_COLOR_LIGHTRED]); LOG(ERROR) << (const char*)content; printf("%s [E] %s\n", nowtime, out_buf.c_str()); } break; case E_LOG_FATAL: { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), s_console_colors_[E_CONSOLE_COLOR_LIGHTRED]); LOG(FATAL) << (const char*)content; printf("%s [F] %s\n", nowtime, out_buf.c_str()); } break; default: break; } #else switch(_type) { case E_LOG_DBG: LOG(DEBUG) << (const char*)content; break; case E_LOG_INFORMATION: LOG(INFO) << (const char*)content; break; case E_LOG_WARNING: LOG(WARNING) << (const char*)content; break; case E_LOG_ERROR: LOG(ERROR) << (const char*)content; break; case E_LOG_FATAL: LOG(FATAL) << (const char*)content; break; default: break; } #endif } read_buffer.clear(); read_buffer.shrink(shrink_size_); } }