/* --- logConsoleGUI.cpp --------------------------------------- System: Log system for gui applications Status: Version 1.0 Release 2 Language: C++ (c) Copyright SD-Innovation 2016 Author: Sylvain Schneider ------------------------------------------------------------- */ #include "logConsoleGUI.h" #include #include #ifdef _WIN32 # include #endif // defined WIN32 t_logConsoleGUI logConsole; using namespace std; using namespace sdiTools; //-------------------------------------------------------------- logConsoleGUI::logConsoleGUI(const std::string &logFilepath) { // Constructor if (!logFilepath.empty()) openLogFile(logFilepath); } //-------------------------------------------------------------- logConsoleGUI::~logConsoleGUI() { // Destructor releaseConsole(); } //-------------------------------------------------------------- void logConsoleGUI::openLogFile(const std::string &logFilepath) { // Open log file m_logFile.open(logFilepath.c_str(), std::ofstream::out | std::ofstream::app); if (!m_logFile.is_open()) throw logic_error("Unable to open log file !"); } //-------------------------------------------------------------- void logConsoleGUI::closeLogFile() { // Close log file if (m_logFile.is_open()) m_logFile.close(); } //-------------------------------------------------------------- int64_t logConsoleGUI::getLogFileSize() { // Return opened log file size if (!m_logFile.is_open()) return -1; return m_logFile.tellp(); } //-------------------------------------------------------------- void logConsoleGUI::initConsole(bool attachOnly) { // Init application console and attach debug console under MSW #ifdef _WIN32 if (hasAttachedConsole()) return; bool hasParentConsole = true; if (!AttachConsole(ATTACH_PARENT_PROCESS)) // Attach application to console { if (attachOnly) return; // No console was available hasParentConsole = false; if (!AllocConsole()) // Create console and attach application to it { // Error during creating console throw logic_error("Unable to attach application to debug console"); } } int err; err = freopen_s(&m_stdoutFile, "CONOUT$", "w", stdout); if (err != 0) { // Error during reopen on stdout throw logic_error("Unable to reopen stdout"); } err = freopen_s(&m_stderrFile, "CONOUT$", "w", stderr); if (err != 0) { // Error during reopen on stderr throw logic_error("Unable to reopen stderr"); } cout.clear(); cerr.clear(); if (hasParentConsole) { cout << endl; } // cout << "logConsoleGUI is ready !" << endl; #endif // defined WIN32 } //-------------------------------------------------------------- void logConsoleGUI::releaseConsole() { // Release application console #ifdef _WIN32 if (!hasAttachedConsole()) return; cout << "logConsoleGUI is terminated !" << endl; cout.clear(); cerr.clear(); FreeConsole(); fclose(m_stdoutFile); fclose(m_stderrFile); #endif // defined WIN32 } //-------------------------------------------------------------- bool logConsoleGUI::hasAttachedConsole() { // Returns true if console was attached, false otherwise #ifdef _WIN32 if (GetConsoleWindow()) return true; return false; #endif // defined WIN32 return false; } //-------------------------------------------------------------- void logConsoleGUI::disable_quickEditMode() { #ifdef _WIN32 HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); if (hInput == INVALID_HANDLE_VALUE || hInput == NULL) { DWORD errorCode = GetLastError(); throw runtime_error("Unable to get input console handle"); } BOOL bRet; DWORD consoleMode; bRet = GetConsoleMode(hInput, &consoleMode); if (bRet == 0) { DWORD errorCode = GetLastError(); throw runtime_error("Unable to get console mode"); } consoleMode = ENABLE_EXTENDED_FLAGS | (consoleMode & ~ENABLE_QUICK_EDIT_MODE); bRet = SetConsoleMode(hInput, consoleMode); if (bRet == 0) { // DWORD errorCode = GetLastError(); throw runtime_error("Unable to set console mode"); } // Disable cursor HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE); if (hOutput == INVALID_HANDLE_VALUE || hOutput == NULL) { DWORD errorCode = GetLastError(); throw runtime_error("Unable to get output console handle"); } CONSOLE_CURSOR_INFO cursorInfo; bRet = GetConsoleCursorInfo(hOutput, &cursorInfo); if (bRet == 0) { throw runtime_error("Unable to get console cursor info"); } cursorInfo.bVisible = false; // set the cursor visibility bRet = SetConsoleCursorInfo(hOutput, &cursorInfo); if (bRet == 0) { throw runtime_error("Unable to set console cursor info"); } #endif // defined WIN32 } //-------------------------------------------------------------- void logConsoleGUI::alwaysOnTop() { #ifdef _WIN32 HWND hWin = GetConsoleWindow(); if (!hWin) throw runtime_error("Unable to get window handle"); BOOL bRet; bRet = SetWindowPos( hWin, // window handle HWND_TOPMOST, // "handle to the window to precede // the positioned window in the Z order // OR one of the following:" // HWND_BOTTOM or HWND_NOTOPMOST or HWND_TOP or HWND_TOPMOST 0, 80, // X, Y position of the window (in client coordinates) 0, 0, // cx, cy => width & height of the window in pixels SWP_DRAWFRAME | /* SWP_NOMOVE | */ SWP_NOSIZE | SWP_SHOWWINDOW // The window sizing and positioning flags. ); if (bRet == 0) { DWORD errorCode = GetLastError(); throw runtime_error("Unable to change window mode"); } #endif // defined WIN32 } //-------------------------------------------------------------- void logConsoleGUI::log(const std::string &msg, e_logLevel level) { // Log message into console and log file string levelStr = ""; switch (level) { case level_DEBUG_COMMUNICATION: #ifndef DEBUG return; #endif levelStr = "[DEBUG_COMM] "; break; case level_DEBUG: #ifndef DEBUG return; #endif levelStr = "[DEBUG] "; break; case level_INFORMATIONS: break; case level_NOTICE: levelStr = "[NOTICE] "; break; case level_WARNING: levelStr = "[WARNING] "; break; case level_ERROR: levelStr = "[ERROR] "; break; case level_CRITICAL: levelStr = "[CRITICAL] "; break; case level_ALERT: levelStr = "[ALERT] "; break; case level_EMERGENCY: levelStr = "[EMERGENCY] "; break; } string logMsg = header() + levelStr + msg; cout << logMsg << endl; if (m_logFile.is_open()) m_logFile << logMsg << endl; } //-------------------------------------------------------------- std::string logConsoleGUI::header() { // Define header to console log char buff[20]; time_t now = time(nullptr); struct tm tm; #ifdef _WIN32 localtime_s(&tm, &now); #elif __linux__ tm = *localtime(&now); #endif strftime(buff, 20, "%Y-%m-%d %H:%M:%S", &tm); ostringstream oss; oss << buff << " - "; return oss.str(); } //--------------------------------------------------------------