Files
kwa.fr/src/misc/logConsoleGUI/logConsoleGUI.cpp
2026-03-12 16:32:03 +01:00

296 lines
7.2 KiB
C++

/* --- 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 <ctime>
#include <sstream>
#ifdef _WIN32
# include <Windows.h>
#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();
}
//--------------------------------------------------------------