Skip to content
Snippets Groups Projects
Commit 0c57cee5 authored by Andreas Traczyk's avatar Andreas Traczyk
Browse files

logger: add console logging code for Windows

Previously, AllocConsole was called from the client. This has been
moved into the ConsoleLog class. When calling Logger::setConsoleLog
an attempt to attach to the console of the parent process will be
made first. This will be the case when Jami is being run from a
command line with the debug option. Otherwise, the logger will use
AllocConsole to instantiate a console window for the logs. The
latter will have it's lifetime bound by Jami.

Change-Id: I7f1728626962a2f702ad564bb16deadc2d92dfb7
parent f6f8a837
No related branches found
No related tags found
No related merge requests found
......@@ -117,7 +117,6 @@ contextHeader(const char* const file, int line)
// Timestamp
if (timestamp_fmt) {
time_t t;
struct tm tm;
char buf[128];
......@@ -139,7 +138,6 @@ contextHeader(const char* const file, int line)
out << buf;
} else {
unsigned int secs, milli;
struct timeval tv;
......@@ -153,8 +151,7 @@ contextHeader(const char* const file, int line)
const auto prev_fill = out.fill();
out << secs << '.' << std::right << std::setw(3) << std::setfill('0') << milli
<< std::left;
out << secs << '.' << std::right << std::setw(3) << std::setfill('0') << milli << std::left;
out.fill(prev_fill);
}
......@@ -295,57 +292,69 @@ public:
return *self;
}
virtual void consume(jami::Logger::Msg& msg) override
#ifdef _WIN32
void printLogImpl(jami::Logger::Msg& msg, bool with_color)
{
static bool no_color = (getenv("NO_COLOR") ||
getenv("NO_COLORS") ||
getenv("NO_COLOUR") ||
getenv("NO_COLOURS"));
#if defined(_WIN32) && !defined(RING_UWP)
WORD saved_attributes;
HANDLE hConsole;
#endif
static HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
if (with_color) {
static WORD color_header = CYAN;
WORD color_prefix = LIGHT_GREEN;
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
switch (msg.level_) {
case LOG_ERR:
color_prefix = RED;
break;
case LOG_WARNING:
color_prefix = YELLOW;
break;
}
if (not no_color) {
#ifndef _WIN32
const char* color_header = CYAN;
const char* color_prefix = "";
#else
WORD color_prefix = LIGHT_GREEN;
WORD color_header = CYAN;
#endif
#if defined(_WIN32) && !defined(RING_UWP)
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
saved_attributes = consoleInfo.wAttributes;
SetConsoleTextAttribute(hConsole, color_header);
#endif
fputs(msg.header_.c_str(), stderr);
switch (msg.level_) {
case LOG_ERR:
color_prefix = RED;
break;
SetConsoleTextAttribute(hConsole, saved_attributes);
SetConsoleTextAttribute(hConsole, color_prefix);
} else {
fputs(msg.header_.c_str(), stderr);
}
case LOG_WARNING:
color_prefix = YELLOW;
break;
fputs(msg.payload_.get(), stderr);
if (msg.linefeed_) {
putc(ENDL, stderr);
}
#ifndef _WIN32
fputs(color_header, stderr);
#elif !defined(RING_UWP)
GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
saved_attributes = consoleInfo.wAttributes;
SetConsoleTextAttribute(hConsole, color_header);
#endif
fputs(msg.header_.c_str(), stderr);
#ifndef _WIN32
fputs(END_COLOR, stderr);
fputs(color_prefix, stderr);
#elif !defined(RING_UWP)
SetConsoleTextAttribute(hConsole, saved_attributes);
SetConsoleTextAttribute(hConsole, color_prefix);
#endif
if (with_color) {
SetConsoleTextAttribute(hConsole, saved_attributes);
}
}
#else
void printLogImpl(jami::Logger::Msg& msg, bool with_color)
{
if (with_color) {
const char* color_header = CYAN;
const char* color_prefix = "";
switch (msg.level_) {
case LOG_ERR:
color_prefix = RED;
break;
case LOG_WARNING:
color_prefix = YELLOW;
break;
}
fputs(color_header, stderr);
fputs(msg.header_.c_str(), stderr);
fputs(END_COLOR, stderr);
fputs(color_prefix, stderr);
} else {
fputs(msg.header_.c_str(), stderr);
}
......@@ -356,20 +365,46 @@ public:
putc(ENDL, stderr);
}
if (not no_color) {
#ifndef _WIN32
fputs(END_COLOR, stderr);
#elif !defined(RING_UWP)
SetConsoleTextAttribute(hConsole, saved_attributes);
#endif
if (with_color) {
fputs(END_COLOR, stderr);
}
}
#endif /* _WIN32 */
virtual void consume(jami::Logger::Msg& msg) override
{
static bool with_color = !(getenv("NO_COLOR") || getenv("NO_COLORS") || getenv("NO_COLOUR")
|| getenv("NO_COLOURS"));
printLogImpl(msg, with_color);
}
};
void
Logger::setConsoleLog(bool en)
{
ConsoleLog::instance().enable(en);
#ifdef _WIN32
static WORD original_attributes;
if (en) {
if (AttachConsole(ATTACH_PARENT_PROCESS) || AllocConsole()) {
FILE *fpstdout = stdout, *fpstderr = stderr;
freopen_s(&fpstdout, "CONOUT$", "w", stdout);
freopen_s(&fpstderr, "CONOUT$", "w", stderr);
// Save the original state of the console window(in case AttachConsole worked).
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo);
original_attributes = consoleInfo.wAttributes;
SetConsoleCP(CP_UTF8);
SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE),
ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS);
}
} else {
// Restore the original state of the console window in case we attached.
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), original_attributes);
FreeConsole();
}
#endif
}
class SysLog : public jami::Logger::Handler
......@@ -487,7 +522,6 @@ public:
thread_ = std::thread([this] {
while (isEnable()) {
{
std::unique_lock lk(mtx_);
......@@ -570,14 +604,15 @@ Logger::log(int level, const char* file, int line, bool linefeed, const char* fm
}
template<typename T>
void log_to_if_enabled(T& handler, Logger::Msg& msg)
void
log_to_if_enabled(T& handler, Logger::Msg& msg)
{
if (handler.isEnable()) {
handler.consume(msg);
}
}
static std::atomic_bool debugEnabled{false};
static std::atomic_bool debugEnabled {false};
void
Logger::setDebugMode(bool enable)
......@@ -588,15 +623,12 @@ Logger::setDebugMode(bool enable)
DRING_PUBLIC void
Logger::vlog(int level, const char* file, int line, bool linefeed, const char* fmt, va_list ap)
{
if (not debugEnabled.load() and
level < LOG_WARNING) {
if (not debugEnabled.load() and level < LOG_WARNING) {
return;
}
if (not(ConsoleLog::instance().isEnable() or
SysLog::instance().isEnable() or
MonitorLog::instance().isEnable() or
FileLog::instance().isEnable())) {
if (not(ConsoleLog::instance().isEnable() or SysLog::instance().isEnable()
or MonitorLog::instance().isEnable() or FileLog::instance().isEnable())) {
return;
}
......@@ -614,6 +646,10 @@ Logger::fini()
{
// Force close on file and join thread
FileLog::instance().setFile({});
#ifdef _WIN32
Logger::setConsoleLog(false);
#endif /* _WIN32 */
}
} // namespace jami
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment